Documentation ¶
Overview ¶
Package api implements a client API for working with digitalrebar/provision.
Index ¶
- Constants
- func DecodeYaml(buf []byte, ref interface{}) error
- func GenPatch(source, target interface{}, paranoid bool) (jsonpatch2.Patch, error)
- func Pretty(f string, obj interface{}) ([]byte, error)
- type AgentState
- type Client
- func (c *Client) Agent(m *models.Machine, exitOnNotRunnable, exitOnFailure, actuallyPowerThings bool, ...) error
- func (c *Client) AllIndexes() (map[string]map[string]models.Index, error)
- func (c *Client) Authorize(req *http.Request) error
- func (c *Client) BundleContent(src string, dst store.Store, params map[string]string) error
- func (c *Client) Close()
- func (c *Client) CreateContent(content *models.Content) (*models.ContentSummary, error)
- func (c *Client) CreateModel(ref models.Model) error
- func (c *Client) DeleteBlob(at ...string) error
- func (c *Client) DeleteContent(name string) error
- func (c *Client) DeleteModel(prefix, key string) (models.Model, error)
- func (c *Client) Endpoint() string
- func (c *Client) Events() (*EventStream, error)
- func (c *Client) ExistsModel(prefix, key string) (bool, error)
- func (c *Client) FillModel(ref models.Model, key string) error
- func (c *Client) GetBlob(dest io.Writer, at ...string) error
- func (c *Client) GetContentItem(name string) (*models.Content, error)
- func (c *Client) GetContentSummary() ([]*models.ContentSummary, error)
- func (c *Client) GetModel(prefix, key string, params ...string) (models.Model, error)
- func (c *Client) GetModelForPatch(prefix, key string, params ...string) (models.Model, models.Model, error)
- func (c *Client) Indexes(prefix string) (map[string]models.Index, error)
- func (c *Client) Info() (*models.Info, error)
- func (c *Client) InstallBootEnvFromFile(src string) (*models.BootEnv, error)
- func (c *Client) InstallISOForBootenv(env *models.BootEnv, src string, downloadOK bool) error
- func (c *Client) InstallRawTemplateFromFile(src string) (*models.Template, error)
- func (c *Client) InstallRawTemplateFromFileWithId(src, tid string) (*models.Template, error)
- func (c *Client) JobActions(j *models.Job) ([]*models.JobAction, error)
- func (c *Client) JobLog(j *models.Job, dst io.Writer) error
- func (c *Client) ListBlobs(at string, params ...string) ([]string, error)
- func (c *Client) ListModel(prefix string, params ...string) ([]models.Model, error)
- func (c *Client) Logs() ([]logger.Line, error)
- func (c *Client) NewAgent(m *models.Machine, exitOnNotRunnable, exitOnFailure, actuallyPowerThings bool, ...) (*MachineAgent, error)
- func (c *Client) OneIndex(prefix, param string) (models.Index, error)
- func (c *Client) PatchModel(prefix, key string, patch jsonpatch2.Patch) (models.Model, error)
- func (c *Client) PatchTo(old models.Model, new models.Model) (models.Model, error)
- func (c *Client) PatchToFull(old models.Model, new models.Model, paranoid bool) (models.Model, error)
- func (c *Client) PostBlob(blob io.Reader, at ...string) (models.BlobInfo, error)
- func (c *Client) PostEvent(evt *models.Event) error
- func (c *Client) PutModel(obj models.Model) error
- func (c *Client) ReplaceContent(content *models.Content) (*models.ContentSummary, error)
- func (c *Client) Req() *R
- func (c *Client) Token() string
- func (c *Client) Trace(lvl string)
- func (c *Client) TraceToken(t string)
- func (c *Client) UnbundleContent(content store.Store, dst string) error
- func (c *Client) UploadISOForBootEnv(env *models.BootEnv, src io.Reader) (models.BlobInfo, error)
- func (c *Client) UrlFor(args ...string) (*url.URL, error)
- func (c *Client) Username() string
- type Decoder
- type Encoder
- type EventStream
- func (es *EventStream) Close() error
- func (es *EventStream) Deregister(handle int64) error
- func (es *EventStream) Register(events ...string) (int64, <-chan RecievedEvent, error)
- func (es *EventStream) Subscribe(handle int64, events ...string) error
- func (es *EventStream) WaitFor(item models.Model, test TestFunc, timeout time.Duration) (string, error)
- type MachineAgent
- func (a *MachineAgent) ChangeStage()
- func (a *MachineAgent) Init()
- func (a *MachineAgent) Logf(f string, args ...interface{})
- func (a *MachineAgent) Run() error
- func (a *MachineAgent) RunTask()
- func (a *MachineAgent) Timeout(t time.Duration) *MachineAgent
- func (a *MachineAgent) WaitChangeStage()
- func (a *MachineAgent) WaitRunnable()
- type R
- func (r *R) Body(b interface{}) *R
- func (r *R) Del() *R
- func (r *R) Delete(m models.Model) error
- func (r *R) Do(val interface{}) error
- func (r *R) FailFast() *R
- func (r *R) Fill(m models.Model) error
- func (r *R) Filter(prefix string, filterArgs ...string) *R
- func (r *R) Get() *R
- func (r *R) Head() *R
- func (r *R) Headers(args ...string) *R
- func (r *R) List(prefix string) *R
- func (r *R) Meth(v string) *R
- func (r *R) Params(args ...string) *R
- func (r *R) ParanoidPatch() *R
- func (r *R) Patch(b jsonpatch2.Patch) *R
- func (r *R) PatchObj(old, new interface{}) *R
- func (r *R) PatchTo(old, new models.Model) *R
- func (r *R) PatchToFull(old models.Model, new models.Model, paranoid bool) (models.Model, error)
- func (r *R) Post(b interface{}) *R
- func (r *R) Put(b interface{}) *R
- func (r *R) Trace(lvl string) *R
- func (r *R) TraceToken(t string) *R
- func (r *R) UrlFor(args ...string) *R
- func (r *R) UrlForM(m models.Model, rest ...string) *R
- type RecievedEvent
- type TaskRunner
- type TestFunc
Constants ¶
const ( AGENT_INIT = AgentState(iota) AGENT_WAIT_FOR_RUNNABLE AGENT_RUN_TASK AGENT_WAIT_FOR_CHANGE_STAGE AGENT_CHANGE_STAGE AGENT_EXIT AGENT_REBOOT AGENT_POWEROFF )
const APIPATH = "/api/v3"
APIPATH is the base path for all API endpoints that digitalrebar provision provides.
Variables ¶
This section is empty.
Functions ¶
func DecodeYaml ¶
DecodeYaml is a helper function for dealing with user input -- when accepting input from the user, we want to treat both YAML and JSON as first-class citizens. The YAML library we use makes that easier by using the json struct tags for all marshalling and unmarshalling purposes.
Note that the REST API does not use YAML as a wire protocol, so this function should never be used to decode data coming from the provision service.
Types ¶
type AgentState ¶
type AgentState int
type Client ¶
Client wraps *http.Client to include our authentication routines and routines for handling some of the biolerplate CRUD operations against digitalrebar provision.
func TokenSession ¶
TokenSession creates a new api.Client that will use the passed-in Token for authentication. It should be used whenever the API is not acting on behalf of a user.
func UserSession ¶
UserSession creates a new api.Client that can act on behalf of a user. It will perform a single request using basic authentication to get a token that expires 600 seconds from the time the session is crated, and every 300 seconds it will refresh that token.
UserSession does not currently attempt to cache tokens to persistent storage, although that may change in the future.
func (*Client) Agent ¶
func (c *Client) Agent(m *models.Machine, exitOnNotRunnable, exitOnFailure, actuallyPowerThings bool, logger io.Writer) error
Agent runs the machine Agent on the current machine. It assumes there is only one Agent, which is not actually a safe assumption. We should make it safe someday.
func (*Client) AllIndexes ¶
AllIndexes returns all the static indexes available for all object types on the server.
func (*Client) Authorize ¶
Authorize sets the Authorization header in the Request with the current bearer token. The rest of the helper methods call this, so you don't have to unless you are building your own http.Requests.
func (*Client) BundleContent ¶
func (*Client) Close ¶
func (c *Client) Close()
Close should be called whenever you no longer want to use this client connection. It will stop any token refresh routines running in the background, and force any API calls made to this client that would communicate with the server to return an error
func (*Client) CreateContent ¶
func (*Client) CreateModel ¶
CreateModel takes the passed-in model and creates an instance of it on the server. It will return an error if the passed-in model does not validate or if it already exists on the server.
func (*Client) DeleteBlob ¶
DeleteBlob deletes a blob on the server at the location indicated by 'at'
func (*Client) DeleteContent ¶
func (*Client) DeleteModel ¶
DeleteModel deletes the model matching the passed-in prefix and key. It returns the object that was deleted.
func (*Client) Events ¶
func (c *Client) Events() (*EventStream, error)
Events creates a new EventStream from the client.
func (*Client) ExistsModel ¶
ExistsModel tests to see if an object exists on the server following the same rules as GetModel
func (*Client) FillModel ¶
FillModel fills the passed-in model with new information retrieved from the server.
func (*Client) GetBlob ¶
GetBlob fetches a binary blob from the server, writing it to the passed io.Writer.
func (*Client) GetContentItem ¶
func (*Client) GetContentSummary ¶
func (c *Client) GetContentSummary() ([]*models.ContentSummary, error)
func (*Client) GetModel ¶
GetModel returns an object if type prefix with the unique identifier key, if such an object exists. Key can be either the unique key for an object, or any field on an object that has an index that enforces uniqueness.
func (*Client) GetModelForPatch ¶
func (*Client) Indexes ¶
Indexes returns all the static indexes available for a given type of object on the server.
func (*Client) Info ¶
Info returns some basic system information that was retrieved as part of the initial authentication.
func (*Client) InstallBootEnvFromFile ¶
func (*Client) InstallISOForBootenv ¶
func (*Client) InstallRawTemplateFromFile ¶
func (*Client) InstallRawTemplateFromFileWithId ¶
func (*Client) JobActions ¶
JobActions returns the expanded list of templates that should be written or executed for a specific Job.
func (*Client) JobLog ¶
JobLog gets the log for a specific Job and writes it to the passed io.Writer
func (*Client) ListBlobs ¶
ListBlobs lists the names of all the binary objects at 'at', using the indexing parameters suppied by params.
func (*Client) NewAgent ¶
func (c *Client) NewAgent(m *models.Machine, exitOnNotRunnable, exitOnFailure, actuallyPowerThings bool, logger io.Writer) (*MachineAgent, error)
NewAgent creates a new FSM based Machine Agent that starts out in the AGENT_INIT state.
func (*Client) OneIndex ¶
OneIndex tests to see if there is an index on the object type indicated by prefix for a specific parameter. If the returned Index is empty, there is no such Index.
func (*Client) PatchModel ¶
PatchModel attempts to update the object matching the passed prefix and key on the server side with the passed-in JSON patch (as sepcified in https://tools.ietf.org/html/rfc6902). To ensure that conflicting changes are rejected, your patch should contain the appropriate test stanzas, which will allow the server to detect and reject conflicting changes from different sources.
func (*Client) PatchToFull ¶
func (*Client) PostBlob ¶
PostBlob uploads the binary blob contained in the passed io.Reader to the location specified by at on the server. You are responsible for closing the passed io.Reader.
func (*Client) PutModel ¶
PutModel replaces the server-side object matching the passed-in object with the passed-in object. Note that PutModel does not allow the server to detect and reject conflicting changes from multiple sources.
func (*Client) ReplaceContent ¶
func (*Client) Req ¶
Req creates a new R for the current client. It defaults to using the GET method.
func (*Client) Trace ¶
Trace sets the log level that incoming requests generated by a Client will be logged at, overriding the levels they would normally be logged at on the server side. Setting lvl to an empty string turns off tracing.
func (*Client) TraceToken ¶
TraceToken is a unique token that the server-side logger will emit a log for at the Error log level. It can be used to tie logs generated on the server side to requests made by a specific Client.
func (*Client) UnbundleContent ¶
func (*Client) UploadISOForBootEnv ¶
type EventStream ¶
type EventStream struct {
// contains filtered or unexported fields
}
EventStream recieves events from the digitalrebar provider. You can read recieved events by reading from its Events channel.
func (*EventStream) Close ¶
func (es *EventStream) Close() error
Close closes down the EventStream. You should drain the Events until you read a RecievedEvent that has an empty E and a non-nil Err
func (*EventStream) Deregister ¶
func (es *EventStream) Deregister(handle int64) error
Deregister directs the EventStream to unsubscribe from Events from the digitalrebar provisioner. It takes the same parameters as Register.
func (*EventStream) Register ¶
func (es *EventStream) Register(events ...string) (int64, <-chan RecievedEvent, error)
Register directs the EventStream to subscribe to Events from the digital rebar provisioner.
Event subscriptions consist of a string with the following format:
type.action.key
type is the object type that you want to listen for events about. * means to listen for events about all object types.
action is the action that caused the event to be created. * means to listen for all actions.
key is the unique identifier of the object to listen for. * means to listen for events from all objects
func (*EventStream) Subscribe ¶
func (es *EventStream) Subscribe(handle int64, events ...string) error
func (*EventStream) WaitFor ¶
func (es *EventStream) WaitFor( item models.Model, test TestFunc, timeout time.Duration) (string, error)
WaitFor waits for an item to match test. It subscribes to an EventStream that watches all update and save envents for the object in question, and returns a string indicating whether the match succeeded, failed, or timed out.
The API for this function is subject to refactoring and change, and should not be considered to be stable yet.
type MachineAgent ¶
type MachineAgent struct {
// contains filtered or unexported fields
}
func (*MachineAgent) ChangeStage ¶
func (a *MachineAgent) ChangeStage()
ChangeStage handles determining what to do when the Agent runs out of tasks to run in the current Stage. It may transition to the following states:
- AGENT_WAIT_FOR_CHANGE_STAGE if there is no next stage for this machine in the change stage map and it is not in an -install bootenv.
- AGENT_EXIT if there is no next stage in the change stage map and the machine is in an -install bootenv. In this case, ChangeStage will set the machine stage to `local`.
- AGENT_REBOOT if the next stage has the Reboot flag, the change stage map has a Reboot specifier, or the next stage has a different bootenv than the machine and the machine is not in an -install bootenv
- AGENT_EXIT if the machine is in an -install bootenv and the next stage requires a different bootenv.
- AGENT_POWEROFF if the change stage map wants to power the system off after changing the stage.
* AGENT_WAIT_FOR_RUNNABLE if no other condition applies
func (*MachineAgent) Init ¶
func (a *MachineAgent) Init()
Init resets the Machine Agent back to its initial state. This consists of marking any current running jobs as Failed and repoening the event stream from dr-provision.
func (*MachineAgent) Logf ¶
func (a *MachineAgent) Logf(f string, args ...interface{})
Logf is a helper function to make logging of Agent actions a bit easier.
func (*MachineAgent) Run ¶
func (a *MachineAgent) Run() error
Run kicks off the state machine for this agent.
func (*MachineAgent) RunTask ¶
func (a *MachineAgent) RunTask()
RunTask attempts to run the next task on the Machine. It may transition to the following states:
* AGENT_CHANGE_STAGE if there are no tasks to run.
* AGENT_REBOOT if the task signalled that the machine should reboot
* AGENT_POWEROFF if the task signalled that the machine should shut down
* AGENT_EXIT if the task signalled that the agent should stop.
* AGENT_WAIT_FOR_RUNNABLE if no other conditions were met.
func (*MachineAgent) Timeout ¶
func (a *MachineAgent) Timeout(t time.Duration) *MachineAgent
Timeout allows you to change how long the Agent will wait for an event from dr-provision from the default of 1 hour.
func (*MachineAgent) WaitChangeStage ¶
func (a *MachineAgent) WaitChangeStage()
WaitChangeStage has waitOn wait for any of the following on the machine to change:
* The CurrentTask index * The task list * The Runnable flag * The boot environment * The stage
func (*MachineAgent) WaitRunnable ¶
func (a *MachineAgent) WaitRunnable()
WaitRunnable has waitOn wait for the Machine to become runnable.
type R ¶
R encapsulates a single Request/Response round trip. It has a slew of helper methods that can be chained together to handle all common operations with this API. It handles capturing any errors that may occur in building and executing the request.
func (*R) Body ¶
Body arranges for b to be used as the body of the request. It also sets the Content-Type of the request depending on what the body is:
If b is an io.Reader or a raw byte array, Content-Type will be set to application/octet-stream, otherwise Content-Type will be set to application/json.
If b is something other than nil, an io.Reader, or a byte array, Body will attempt to marshal the object as a JSON byte array and use that.
func (*R) Do ¶
Do attempts to execute the reqest built up by previous method calls on R. If any errors occurred while building up the request, they will be returned and no API interaction will actually take place. Otherwise, Do will generate am http.Request, perform it, and marshal the results to val. If any errors occur while processing the request, fibbonaci based backoff will be performed up to 6 times.
If val is an io.Writer, the body of the response will be copied verbatim into val using io.Copy
Otherwise, the response body will be unmarshalled into val as directed by the Content-Type header of the response.
func (*R) FailFast ¶
FailFast skips the usual fibbonaci backoff retry in the case of transient errors.
func (*R) Filter ¶
Filter is a helper for using freeform index operations. The prefix arg is the type of object you want to filter, and filterArgs describes how you want the results filtered. Currently, filterArgs must be in the following format:
"reverse" to reverse the order of the results "sort" "indexName" to sort the results according to indexName's native ordering "limit" "number" to limit the number of results returned "offset" "number" to skip <number> of results before returning "indexName" "Eq/Lt/Lte/Gt/Gte/Ne" "value" to return results Equal, Less Than, Less Than Or Equal, Greater Than, Greater Than Or Equal, or Not Equal to value according to IndexName "indexName" "Between/Except" "lowerBound" "upperBound" to return values Between(inclusive) lowerBound and Upperbound or its complement for Except.
If formatArgs does not contain some valid combination of the above, the request will fail.
func (*R) Headers ¶
Headers arranges for its arguments to be added as HTTP headers. You must pass an even number of arguments to Headers
func (*R) Params ¶
Params appends query parameters to the URL R will use. r.UrlFor() or r.UrlForM() must have already been called. You must pass an even number of parameters to Params
func (*R) Patch ¶
func (r *R) Patch(b jsonpatch2.Patch) *R
Patch sets the R method to PATCH, and arranges for b (which must be a valid JSON patch) to be used as the body of the request by calling r.Body().
func (*R) PatchToFull ¶
func (*R) Post ¶
Post sets the R method to POST, and arranged for b to be the body of the request by calling r.Body().
func (*R) Put ¶
Put sets the R method to PUT, and arranges for b to be used as the body of the request by calling r.Body(). If no body is desired, b can be nil
func (*R) Trace ¶
Trace will arrange for the server to log this specific request at the passed-in Level, overriding any client Trace requests or the levels things would usually be logged at by the server.
func (*R) TraceToken ¶
TraceToken is a unique token that the server-side logger will emit a log for at the Error log level. It can be used to tie logs generated on the server side to requests made by a specific Req.
type RecievedEvent ¶
RecievedEvent contains an event recieved from the digitalrebar provision server along with any errors that occurred while recieving the event.
type TaskRunner ¶
type TaskRunner struct {
// contains filtered or unexported fields
}
TaskRunner is responsible for expanding templates and running scripts for a single task.
func NewTaskRunner ¶
func NewTaskRunner(c *Client, m *models.Machine, agentDir string, logger io.Writer) (*TaskRunner, error)
NewTaskRunner creates a new TaskRunner for the passed-in machine. It creates the matching Job (or resumes the previous incomplete one), and handles making sure that all relavent output is written to the job log as well as local stderr
func (*TaskRunner) Close ¶
func (r *TaskRunner) Close()
Close() shuts down the writer side of the logging pipe. This will also flush any remaining data to stderr
func (*TaskRunner) Expand ¶
func (r *TaskRunner) Expand(action *models.JobAction, taskDir string) error
Expand a writes a file template to the appropriate location.
func (*TaskRunner) Log ¶
func (r *TaskRunner) Log(s string, items ...interface{})
Log writes the string (with a timestamp) to stderr and to the server-side log for the current job.
func (*TaskRunner) Perform ¶
func (r *TaskRunner) Perform(action *models.JobAction, taskDir string) error
Perform runs a single script action.
func (*TaskRunner) Run ¶
func (r *TaskRunner) Run() error
Run loops over all of the actions for a particular job, placing files and executing scripts as appropriate. It also arranges for all logging output for the actions to go to the right places.