plank

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2020 License: Apache-2.0 Imports: 11 Imported by: 3

README

plank

Spinnaker SDK for Go.

Plank is a work in progress and will change drastically over the next few months.

What is it?

A package used by services that interact with Spinnaker's micro-services. It is not intended to be a client which interacts with Spinnaker's outward facing API.

Why is it named plank?

Because it's funny.

How do I use it?

Very carefully. 😃

Basic concept is that you instantiate a Plank client thusly:

client := plank.New()

If you'd like to supply your own http client (we use a pooled client by default):

client := plank.New(plank.WithClient(&http.Client{}))

To tune the maxiumum number of retries or set an exponential backoff value:

client := plank.New(plank.WithMaxRetries(5), plank.WithRetryIncrement(5 * time.Second))

You can (or may need to) replace the base URLs for the microservices by assign them to the keys in the client.URLs map:

client.URLs["orca"] = "http://my-orca:8083"
client.URLs["front50"] = config.Front50.BaseURL

After that, you just use the Plank functions to "do stuff":

app, err := client.GetApplication("myappname")
pipelines, err := client.GetPipelines(app.Name)
// etc...

Development

Build the project:

$ go build

Test the project:

$ go test
Cutting a New Release
  1. Update the [CHANGELOG.md]'s ##Unreleased section with the next version and today's date in YYYY-MM-DD format.
  • Don't forget to update the release URL so that it's easy to diff what was changed (look at the bottom of the CHANGELOG for existing examples).
  1. git tag vx.x.x where x.x.x is the version you're releasing, and git push --tags to make sure it's persisted to the project.

Documentation

Overview

  • Copyright 2019 Armory, Inc. *

  • 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.

  • Copyright 2019 Armory, Inc. *

  • 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.

  • Copyright 2019 Armory, Inc. *

  • 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.

  • Copyright 2019 Armory, Inc. *

  • 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 plank is a SDK for Spinnaker. It allows you to write Go code that interacts with Spinnaker's subservices.

  • Copyright 2019 Armory, Inc. *
  • 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.

Index

Constants

This section is empty.

Variables

View Source
var DefaultURLs = map[string]string{
	"orca":    "http://armory-orca:8083",
	"front50": "http://armory-front50:8080",
	"fiat":    "http://armory-fiat:7003",
	"gate":    "http://armory-gate:8084",
}

DefaultURLs

Functions

This section is empty.

Types

type Application

type Application struct {
	Name        string          `json:"name" mapstructure:"name" yaml:"name" hcl:"name"`
	Email       string          `json:"email" mapstructure:"email" yaml:"email" hcl:"email"`
	Description string          `json:"description,omitempty" mapstructure:"description" yaml:"description,omitempty" hcl:"description,omitempty"`
	User        string          `json:"user,omitempty" mapstructure:"user" yaml:"user,omitempty" hcl:"user,omitempty"`
	DataSources DataSourcesType `json:"dataSources,omitempty" mapstructure:"dataSources" yaml:"datasources,omitempty" hcl:"datasources,omitempty"`
	Permissions PermissionsType `json:"permissions,omitempty" mapstructure:"permissions" yaml:"permissions,omitempty" hcl:"permissions,omitempty"`
}

Application as returned from the Spinnaker API.

type Authorization

type Authorization struct {
	Name string `json:"name" yaml:"name" hcl:"name"`
	// Authorizations can be 'READ' 'WRITE'
	Authorizations []string `json:"authorizations" yaml:"authorizations" hcl:"authorizations"`
}

Authorization describes permissinos for an account or application.

type Client

type Client struct {
	URLs            map[string]string
	FiatUser        string
	ArmoryEndpoints bool
	// contains filtered or unexported fields
}

Client for working with API servers that accept and return JSON payloads.

func New

func New(opts ...ClientOption) *Client

New constructs a Client using a default client and sane non-shared http transport

func (*Client) ArmoryEndpointsEnabled added in v1.3.0

func (c *Client) ArmoryEndpointsEnabled() bool

func (*Client) CreateApplication

func (c *Client) CreateApplication(a *Application) error

CreateApplication does what it says.

func (*Client) CreateTask

func (c *Client) CreateTask(app, desc string, payload interface{}) (*TaskRefResponse, error)

Create task puts the payload into the Task wrapper.

func (*Client) Delete

func (c *Client) Delete(url string) error

func (*Client) DeletePipeline

func (c *Client) DeletePipeline(p Pipeline) error

DeletePipeline does what it says.

func (*Client) DeletePipelineByName

func (c *Client) DeletePipelineByName(app, pipeline string) error

func (*Client) DeleteWithRetry

func (c *Client) DeleteWithRetry(url string) error

func (*Client) DisableARmoryEndpoints added in v1.3.0

func (c *Client) DisableARmoryEndpoints()

func (*Client) EnableArmoryEndpoints added in v1.3.0

func (c *Client) EnableArmoryEndpoints()

func (*Client) Execute

func (c *Client) Execute(application, pipeline string) (*PipelineRef, error)

Execute a pipeline by application and pipeline.

func (*Client) Get

func (c *Client) Get(url string, dest interface{}) error

Get a JSON payload from the URL then decode it into the 'dest' arguement.

func (*Client) GetApplication

func (c *Client) GetApplication(name string) (*Application, error)

GetApplication returns the Application data struct for the given application name.

func (*Client) GetApplications

func (c *Client) GetApplications() (*[]Application, error)

GetApplications returns all applications (you can see, at least)

func (*Client) GetPipelines

func (c *Client) GetPipelines(app string) ([]Pipeline, error)

Get returns an array of all the Spinnaker pipelines configured for app

func (*Client) GetTask

func (c *Client) GetTask(refURL string) (*ExecutionStatusResponse, error)

func (*Client) GetUser

func (c *Client) GetUser(name string) (*User, error)

GetUser gets a user by name.

func (*Client) GetWithRetry

func (c *Client) GetWithRetry(url string, dest interface{}) error

func (*Client) HasAppWriteAccess

func (c *Client) HasAppWriteAccess(username, app string) (bool, error)

HasAppWriteAccess returns whether or not a user can write pipelines/configs/etc. for an app.

func (*Client) IsAdmin

func (c *Client) IsAdmin(username string) (bool, error)

Admin returns whether or not a user is an admin.

func (*Client) PollTaskStatus

func (c *Client) PollTaskStatus(refURL string) (*ExecutionStatusResponse, error)

func (*Client) Post

func (c *Client) Post(url string, contentType ContentType, body interface{}, dest interface{}) error

Post a JSON payload from the URL then decode it into the 'dest' arguement.

func (*Client) PostWithRetry

func (c *Client) PostWithRetry(url string, contentType ContentType, body interface{}, dest interface{}) error

func (*Client) Put

func (c *Client) Put(url string, contentType ContentType, body interface{}, dest interface{}) error

Post a JSON payload from the URL then decode it into the 'dest' arguement.

func (*Client) PutWithRetry

func (c *Client) PutWithRetry(url string, contentType ContentType, body interface{}, dest interface{}) error

func (*Client) RequestWithRetry

func (c *Client) RequestWithRetry(f RequestFunction) error

func (*Client) ResyncFiat added in v1.3.0

func (c *Client) ResyncFiat() error

ResyncFiat calls to Fiat to tell it to resync its cache of applications and permissions. This uses an endpoint specific to Armory's distribution of Fiat; if ArmoryEndpoints is not set (it's false by default) this is a no-op.

func (*Client) UpsertPipeline

func (c *Client) UpsertPipeline(p Pipeline, id string) error

UpsertPipeline creates/updates a pipeline defined in the struct argument.

type ClientOption added in v1.1.0

type ClientOption func(*Client)

func WithClient added in v1.1.0

func WithClient(client *http.Client) ClientOption

func WithFiatUser added in v1.1.0

func WithFiatUser(user string) ClientOption

func WithMaxRetries added in v1.1.0

func WithMaxRetries(retries int) ClientOption

func WithRetryIncrement added in v1.1.0

func WithRetryIncrement(t time.Duration) ClientOption

func WithTransport added in v1.1.0

func WithTransport(transport *http.Transport) ClientOption

func WithURLs added in v1.1.0

func WithURLs(urls map[string]string) ClientOption

type ContentType

type ContentType string
const (
	ApplicationJson        ContentType = "application/json"
	ApplicationContextJson ContentType = "application/context+json"
)

type DataSourcesType

type DataSourcesType struct {
	Enabled  []string `json:"enabled" mapstructure:"enabled" yaml:"enabled" hcl:"enabled"`
	Disabled []string `json:"disabled" mapstructure:"disabled" yaml:"disabled" hcl:"disabled"`
}

DataSourcesType creates this block:

"dataSources": {
  "disabled": [],
  "enabled": ["canaryConfigs"]
}

type ErrUnsupportedStatusCode added in v1.3.0

type ErrUnsupportedStatusCode struct {
	Code int
}

func (*ErrUnsupportedStatusCode) Error added in v1.3.0

func (e *ErrUnsupportedStatusCode) Error() string

type ExecutionStatusResponse

type ExecutionStatusResponse struct {
	ID      string `json:"id"`
	Status  string `json:"status"`
	EndTime int    `json:"endTime"`
}

type FailedResponse added in v1.3.0

type FailedResponse struct {
	Response   []byte
	StatusCode int
}

FailedResponse captures a 4xx/5xx response from the upstream Spinnaker service. It is expected that the caller destructures the response according to the structure they expect.

func (*FailedResponse) Error added in v1.3.0

func (e *FailedResponse) Error() string

type PermissionsType added in v1.3.0

type PermissionsType struct {
	Read    []string `json:"READ" mapstructure:"READ" yaml:"READ" hcl:"READ"`
	Write   []string `json:"WRITE" mapstructure:"WRITE" yaml:"WRITE" hcl:"WRITE"`
	Execute []string `json:"EXECUTE" mapstructure:"EXECUTE" yaml:"EXECUTE" hcl:"EXECUTE"`
}

PermissionsType creates this block:

"permissions": {
  "READ": ["armory-io", "core"],
  "WRITE": ["armory-io", "core"]
}

type Pipeline

type Pipeline struct {
	ID                   string                   `json:"id,omitempty" yaml:"id,omitempty" hcl:"id,omitempty"`
	Type                 string                   `json:"type,omitempty" yaml:"type,omitempty" hcl:"type,omitempty"`
	Name                 string                   `json:"name" yaml:"name" hcl:"name"`
	Application          string                   `json:"application" yaml:"application" hcl:"application"`
	Description          string                   `json:"description,omitempty" yaml:"description,omitempty" hcl:"description,omitempty"`
	ExecutionEngine      string                   `json:"executionEngine,omitempty" yaml:"executionEngine,omitempty" hcl:"executionEngine,omitempty"`
	Parallel             bool                     `json:"parallel" yaml:"parallel" hcl:"parallel"`
	LimitConcurrent      bool                     `json:"limitConcurrent" yaml:"limitConcurrent" hcl:"limitConcurrent"`
	KeepWaitingPipelines bool                     `json:"keepWaitingPipelines" yaml:"keepWaitingPipelines" hcl:"keepWaitingPipelines"`
	Stages               []map[string]interface{} `json:"stages,omitempty" yaml:"stages,omitempty" hcl:"stages,omitempty"`
	Triggers             []map[string]interface{} `json:"triggers,omitempty" yaml:"triggers,omitempty" hcl:"triggers,omitempty"`
	Parameters           []map[string]interface{} `json:"parameterConfig,omitempty" yaml:"parameterConfig,omitempty" hcl:"parameterConfig,omitempty"`
	Notifications        []map[string]interface{} `json:"notifications,omitempty" yaml:"notifications,omitempty" hcl:"notifications,omitempty"`
	ExpectedArtifacts    []map[string]interface{} `json:"expectedArtifacts,omitempty" yaml:"expectedArtifacts,omitempty" hcl:"expectedArtifacts,omitempty"`
	LastModifiedBy       string                   `json:"lastModifiedBy" yaml:"lastModifiedBy" hcl:"lastModifiedBy"`
	Config               interface{}              `json:"config,omitempty" yaml:"config,omitempty" hcl:"config,omitempty"`
	UpdateTs             string                   `json:"updateTs" yaml:"updateTs" hcl:"updateTs"`
	Locked               PipelineLockType         `json:"locked,omitempty" yaml:"locked,omitempty" hcl:"locked,omitempty"`
}

Pipeline is the structure that comes back from Spinnaker representing a pipeline definition (different than an execution)

func (*Pipeline) Lock

func (p *Pipeline) Lock() *Pipeline

type PipelineLockType

type PipelineLockType struct {
	UI            bool `json:"ui" yaml:"ui" hcl:"ui"`
	AllowUnlockUI bool `json:"allowUnlockUi" yaml:"allowUnlockUi" hcl:"allowUnlockUi"`
}

type PipelineRef

type PipelineRef struct {
	// Ref is the path the the execution. Use it to get status updates.
	Ref string `json:"ref" yaml:"ref" hcl:"ref"`
}

type RequestFunction

type RequestFunction func() error

type Task

type Task struct {
	Application string        `json:"application"`
	Description string        `json:"description"`
	Job         []interface{} `json:"job,omitempty"`
}

type TaskRefResponse

type TaskRefResponse struct {
	Ref string `json:"ref"`
}

type User

type User struct {
	Name         string          `json:"name" yaml:"name" hcl:"name"`
	Admin        bool            `json:"admin" yaml:"admin" hcl:"admin"`
	Accounts     []Authorization `json:"accounts" yaml:"accounts" hcl:"accounts"`
	Applications []Authorization `json:"applications" yaml:"applications" hcl:"applications"`
}

User is returned by Fiat's /authorize endpoint.

func (*User) HasAppWriteAccess

func (u *User) HasAppWriteAccess(app string) bool

HasAppWriteAccess returns true if user has write access to given app.

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin returns true if the user has admin permissions

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL