Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Deduplicate parsing used when applying annotations
Browse files Browse the repository at this point in the history
To apply the special "tag all" annotation, we need the names of the
containers in a controller. Instead of having a struct definition to
parse just for this, use the existing resource parsing, extending it
just enough to get the containers from things that have containers.

The prior code also failed to take into account List resources and
multidocs; this is no longer a problem since the resource package
already accounts for them.
  • Loading branch information
squaremo committed Mar 26, 2018
1 parent 6f874c7 commit 64e81c1
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 38 deletions.
51 changes: 13 additions & 38 deletions cluster/kubernetes/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"

"github.com/weaveworks/flux"
"github.com/weaveworks/flux/cluster/kubernetes/resource"
Expand All @@ -22,7 +21,7 @@ func (m *Manifests) UpdatePolicies(in []byte, resourceID flux.ResourceID, update
// what all the containers are.
if tagAll, ok := add.Get(policy.TagAll); ok {
add = add.Without(policy.TagAll)
containers, err := parseForContainers(in)
containers, err := parseForContainers(resourceID, in)
if err != nil {
return nil, err
}
Expand All @@ -48,45 +47,21 @@ func (m *Manifests) UpdatePolicies(in []byte, resourceID flux.ResourceID, update
return (KubeYAML{}).Annotate(in, ns, kind, name, args...)
}

type containerManifest struct {
Spec struct {
Template struct {
Spec struct {
Containers []struct {
Name string `yaml:"name"`
Image string `yaml:"image"`
} `yaml:"containers"`
} `yaml:"spec"`
} `yaml:"template"`
JobTemplate struct {
Spec struct {
Template struct {
Spec struct {
Containers []struct {
Name string `yaml:"name"`
Image string `yaml:"image"`
} `yaml:"containers"`
} `yaml:"spec"`
} `yaml:"template"`
} `yaml:"spec"`
} `yaml:"jobTemplate"`
} `yaml:"spec"`
}

func parseForContainers(def []byte) ([]string, error) {
var m containerManifest
if err := yaml.Unmarshal(def, &m); err != nil {
return nil, errors.Wrap(err, "decoding manifest")
func parseForContainers(id flux.ResourceID, def []byte) ([]string, error) {
all, err := resource.ParseMultidoc(def, "stdin")
if err != nil {
return nil, err
}

var names []string
for _, c := range m.Spec.Template.Spec.Containers {
names = append(names, c.Name)
res, ok := all[id.String()]
if !ok {
return nil, errors.New("resource " + id.String() + " not found")
}
for _, c := range m.Spec.JobTemplate.Spec.Template.Spec.Containers {
names = append(names, c.Name)
workload, ok := res.(resource.Workload)
if !ok {
return nil, errors.New("resource " + id.String() + " does not have containers")
}
return names, nil

return workload.ContainerNames(), nil
}

func (m *Manifests) ServicesWithPolicies(root string) (policy.ResourceMap, error) {
Expand Down
13 changes: 13 additions & 0 deletions cluster/kubernetes/resource/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,17 @@ package resource

type CronJob struct {
baseObject
Spec CronJobSpec
}

type CronJobSpec struct {
JobTemplate struct {
Spec struct {
Template PodTemplate
}
}
}

func (c CronJob) ContainerNames() []string {
return c.Spec.JobTemplate.Spec.Template.ContainerNames()
}
4 changes: 4 additions & 0 deletions cluster/kubernetes/resource/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ type DaemonSet struct {
type DaemonSetSpec struct {
Template PodTemplate
}

func (ds DaemonSet) ContainerNames() []string {
return ds.Spec.Template.ContainerNames()
}
4 changes: 4 additions & 0 deletions cluster/kubernetes/resource/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ type DeploymentSpec struct {
Replicas int
Template PodTemplate
}

func (d Deployment) ContainerNames() []string {
return d.Spec.Template.ContainerNames()
}
5 changes: 5 additions & 0 deletions cluster/kubernetes/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const (
PolicyPrefix = "flux.weave.works/"
)

// Use for extracting the list of containers out of a resource.
type Workload interface {
ContainerNames() []string
}

// -- unmarshaling code for specific object and field types

// struct to embed in objects, to provide default implementation
Expand Down
8 changes: 8 additions & 0 deletions cluster/kubernetes/resource/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ type PodTemplate struct {
Spec PodSpec
}

func (t PodTemplate) ContainerNames() []string {
var result []string
for _, c := range t.Spec.Containers {
result = append(result, c.Name)
}
return result
}

type PodSpec struct {
ImagePullSecrets []struct{ Name string }
Volumes []Volume
Expand Down
4 changes: 4 additions & 0 deletions cluster/kubernetes/resource/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ type StatefulSetSpec struct {
Replicas int
Template PodTemplate
}

func (ss StatefulSet) ContainerNames() []string {
return ss.Spec.Template.ContainerNames()
}

0 comments on commit 64e81c1

Please sign in to comment.