Skip to content

Commit

Permalink
Adds the ability to modify containers using overrides (#6)
Browse files Browse the repository at this point in the history
* Adds the ability to modify containers using overrides

* Update version
  • Loading branch information
bobbytables authored Feb 1, 2018
1 parent 92b11eb commit fd335f7
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 45 deletions.
2 changes: 1 addition & 1 deletion cmd/k8s-pipeliner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

const (
// Version defines the current version of k8s-pipeliner
Version = "0.0.4"
Version = "0.0.5"
)

func main() {
Expand Down
94 changes: 58 additions & 36 deletions pipeline/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import (
var (
// ErrNoContainers is returned when a manifest has defined containers in it
ErrNoContainers = errors.New("builder: no containers were found in given manifest file")

// ErrOverrideContention is returned when a manifest defines multiple containers and overrides were provided
ErrOverrideContention = errors.New("builder: overrides were provided to a group that has multiple containers defined")
)

// Builder constructs a spinnaker pipeline JSON from a pipeliner config
Expand Down Expand Up @@ -128,45 +131,64 @@ func (b *Builder) buildDeployStage(index int, s config.Stage) (*types.DeployStag
StageMetadata: buildStageMetadata(s, "deploy", index, b.isLinear),
}

mg, err := ContainersFromManifest(s.Deploy.ManifestFile)
if err != nil {
return nil, err
}
if len(mg.Containers) == 0 {
return nil, ErrNoContainers
}
for _, group := range s.Deploy.Groups {
mg, err := ContainersFromManifest(group.ManifestFile)
if err != nil {
return nil, err
}
if len(mg.Containers) == 0 {
return nil, ErrNoContainers
}

// grab the load balancers for the deployment
var lbs []string
if l, ok := mg.Annotations[SpinnakerLoadBalancersAnnotations]; ok {
lbs = strings.Split(l, ",")
}
// check for overrides defined on the group so we can replace the containers
// values before rendering our spinnaker json.
if overrides := group.ContainerOverrides; overrides != nil {
if len(mg.Containers) > 1 {
return nil, ErrOverrideContention
}

container := mg.Containers[0]
if overrides.Args != nil {
container.Args = overrides.Args
}

if overrides.Command != nil {
container.Command = overrides.Command
}
}

cluster := types.Cluster{
Account: s.Account,
Application: b.pipeline.Application,
Containers: mg.Containers,
LoadBalancers: lbs,
Region: mg.Namespace,
Namespace: mg.Namespace,
MaxRemainingAsgs: s.Deploy.MaxRemainingASGS,
ReplicaSetAnnotations: mg.Annotations,
ScaleDown: s.Deploy.ScaleDown,
Stack: s.Deploy.Stack,
Strategy: s.Deploy.Strategy,
TargetSize: s.Deploy.TargetSize,
VolumeSources: mg.VolumeSources,

// TODO(bobbytables): allow these to be configurable
Events: []interface{}{},
InterestingHealthProviderNames: []string{"KubernetesContainer", "KubernetesPod"},
Provider: "kubernetes",
CloudProvider: "kubernetes",
DNSPolicy: "ClusterFirst",
TerminationGracePeriodSeconds: 30,
}
// grab the load balancers for the deployment
var lbs []string
if l, ok := mg.Annotations[SpinnakerLoadBalancersAnnotations]; ok {
lbs = strings.Split(l, ",")
}

cluster := types.Cluster{
Account: s.Account,
Application: b.pipeline.Application,
Containers: mg.Containers,
LoadBalancers: lbs,
Region: mg.Namespace,
Namespace: mg.Namespace,
MaxRemainingAsgs: group.MaxRemainingASGS,
ReplicaSetAnnotations: mg.Annotations,
ScaleDown: group.ScaleDown,
Stack: group.Stack,
Strategy: group.Strategy,
TargetSize: group.TargetSize,
VolumeSources: mg.VolumeSources,

// TODO(bobbytables): allow these to be configurable
Events: []interface{}{},
InterestingHealthProviderNames: []string{"KubernetesContainer", "KubernetesPod"},
Provider: "kubernetes",
CloudProvider: "kubernetes",
DNSPolicy: "ClusterFirst",
TerminationGracePeriodSeconds: 30,
}

ds.Clusters = []types.Cluster{cluster}
ds.Clusters = append(ds.Clusters, cluster)
}

return ds, nil
}
Expand Down
22 changes: 22 additions & 0 deletions pipeline/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,27 @@ type RunJobStage struct {

// DeployStage is the configuration for deploying a cluster of servers (pods)
type DeployStage struct {
Groups []Group `yaml:"groups"`
}

// Group represents a group to be deployed (Think: Kubernetes Pods). Most of the configuration
// of a group is filled out by the defined manifest file. This means things like commands, env vars,
// etc, are all pulled into the group spec for you.
type Group struct {
ManifestFile string `yaml:"manifestFile"`
MaxRemainingASGS int `yaml:"maxRemainingASGS"`
ScaleDown bool `yaml:"scaleDown"`
Stack string `yaml:"stack"`
Strategy string `yaml:"strategy"`
TargetSize int `yaml:"targetSize"`

// If overrides are provided, the group will run a check to make sure
// the given manifest only defines one container. If it does, the given
// overrides will be written into the spinnaker json output.
// This is useful for using the same container image, env, etc to run in a
// different mode like a queue consumer process that needs the same config,
// image, but different command.
ContainerOverrides *ContainerOverrides `yaml:"containerOverrides"`
}

// ManualJudgementStage is the configuration for pausing a pipeline awaiting
Expand All @@ -99,3 +114,10 @@ type ManualJudgementStage struct {
Instructions string `yaml:"instructions"`
Inputs []string `yaml:"inputs"`
}

// ContainerOverrides are used to override a containers values for simple
// values like the command and arguments
type ContainerOverrides struct {
Args []string `yaml:"args,omitempty"`
Command []string `yaml:"command,omitempty"`
}
3 changes: 2 additions & 1 deletion pipeline/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ func TestNewConfig(t *testing.T) {
assert.Equal(t, cfg.Stages[0].RunJob.ManifestFile, "manifests/deploy/connect.yml")
assert.NotNil(t, cfg.Stages[0].RunJob.Container)

assert.Equal(t, cfg.Stages[1].Deploy.ManifestFile, "manifests/deploy/connect.yml")
require.Len(t, cfg.Stages[1].Deploy.Groups, 1, "no groups on deploy stage")
assert.Equal(t, cfg.Stages[1].Deploy.Groups[0].ManifestFile, "manifests/deploy/connect.yml")
}
3 changes: 2 additions & 1 deletion pipeline/config/testdata/pipeline.full.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ stages:
- account: int-k8s
name: "Deploy INT"
deploy:
manifestFile: manifests/deploy/connect.yml
groups:
- manifestFile: manifests/deploy/connect.yml
14 changes: 8 additions & 6 deletions test-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ stages:
reliesOn:
- "1"
deploy:
manifestFile: test-deployment.yml
maxRemainingASGS: 2 # total amount of replica sets to keep around afterwards before deleting
scaleDown: true
stack: web # primarily for labeling purposes on the created resources
strategy: redblack
targetSize: 2 # this is the total amount of replicas for the deployment
groups:
- manifestFile: test-deployment.yml
maxRemainingASGS: 2 # total amount of replica sets to keep around afterwards before deleting
scaleDown: true
stack: web # primarily for labeling purposes on the created resources
strategy: redblack
targetSize: 2 # this is the total amount of replicas for the deployment
containerOverrides: {}
- account: int-k8s
name: "Proceed to Staging?"
refId: "3"
Expand Down

0 comments on commit fd335f7

Please sign in to comment.