asteris-llc/converge

View on GitHub
resource/resource.go

Summary

Maintainability
A
35 mins
Test Coverage
// Copyright © 2016 Asteris, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package resource

import "golang.org/x/net/context"

// Tasker is a struct that is or contains an embedded resource.Task and a
// resource.Status.  It's implemented by plan.Result and apply.Result
type Tasker interface {
    GetTask() (Task, bool)
    GetStatus() TaskStatus
}

// Task controls checks and application inside the system. Check will be called
// first; if it indicates changes will be made then Apply will also be called.
// Check will be called again if Apply succeeds with no error to get the final
// status of the resource.
type Task interface {
    Check(context.Context, Renderer) (TaskStatus, error)
    Apply(context.Context) (TaskStatus, error)
}

// Resource adds metadata about the executed tasks
type Resource interface {
    Prepare(context.Context, Renderer) (Task, error)
}

// Value is anything that can be in a renderer's Value
type Value interface{}

// Renderer is passed to resources
type Renderer interface {
    GetID() string
    Value() (value Value, present bool)
    Render(name, content string) (string, error)
}

// TaskWrapper provides an implementation of render.Tasker for tasks
type TaskWrapper struct {
    Task
}

// GetTask provides Tasker.GetTask ontop of a task
func (t *TaskWrapper) GetTask() (Task, bool) {
    return t.Task, true
}

// GetStatus returns a nil status for a wrapped task
func (t *TaskWrapper) GetStatus() TaskStatus {
    return nil
}

// WrapTask creates a new TaskWrapper
func WrapTask(t Task) *TaskWrapper {
    return &TaskWrapper{t}
}

// ResolveTask unwraps Tasker layers until it finds an underlying Task or fails
func ResolveTask(w interface{}) (Task, bool) {
    if w == nil {
        return nil, false
    }
    if tasker, ok := w.(Tasker); ok {
        taskerTask, found := tasker.GetTask()
        if !found {
            return nil, false
        }
        return ResolveTask(taskerTask)
    } else if task, ok := w.(Task); ok {
        return task, true
    }
    return nil, false
}