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

Commit

Permalink
Adds support for FHRs with simplest image format
Browse files Browse the repository at this point in the history
This commit adds support for interpreting `FluxHelmRelease`s with a
single image, provided in the field `Spec.Values.Image` -- i.e., the
simplest of many different ways of providing image refs to a chart.

The manifest update mechanism is stubbed out for now.
  • Loading branch information
Tamara Kaufler authored and squaremo committed May 30, 2018
1 parent fd67156 commit 6a7343b
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 3 deletions.
4 changes: 4 additions & 0 deletions cluster/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
k8syaml "github.com/ghodss/yaml"
"github.com/go-kit/kit/log"
"github.com/pkg/errors"
ifclient "github.com/weaveworks/flux/integrations/client/clientset/versioned"
"gopkg.in/yaml.v2"
apiv1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -39,6 +40,7 @@ type extendedClient struct {
v1beta1extensions.ExtensionsV1beta1Interface
v1beta1apps.StatefulSetsGetter
v1beta1batch.CronJobsGetter
ifclient.Interface
}

// --- internal types for keeping track of syncing
Expand Down Expand Up @@ -131,6 +133,7 @@ type Cluster struct {

// NewCluster returns a usable cluster.
func NewCluster(clientset k8sclient.Interface,
ifclientset ifclient.Interface,
applier Applier,
sshKeyRing ssh.KeyRing,
logger log.Logger) *Cluster {
Expand All @@ -142,6 +145,7 @@ func NewCluster(clientset k8sclient.Interface,
clientset.Extensions(),
clientset.AppsV1beta1(),
clientset.BatchV1beta1(),
ifclientset,
},
applier: applier,
logger: logger,
Expand Down
90 changes: 90 additions & 0 deletions cluster/kubernetes/resource/fluxhelmrelease.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package resource

import (
"fmt"
"io"

"github.com/weaveworks/flux"
ifv1 "github.com/weaveworks/flux/apis/helm.integrations.flux.weave.works/v1alpha2"
"github.com/weaveworks/flux/image"
"github.com/weaveworks/flux/resource"
apiv1 "k8s.io/api/core/v1"
)

type FluxHelmRelease struct {
baseObject
Spec ifv1.FluxHelmReleaseSpec
}

func (fhr FluxHelmRelease) Containers() []resource.Container {
containers, err := fhr.createFluxFHRContainers()
if err != nil {
// log ?
}
return containers
}

// CreateK8sContainers creates a list of k8s containers as
func CreateK8sFHRContainers(spec ifv1.FluxHelmReleaseSpec) []apiv1.Container {
containers := []apiv1.Container{}

values := spec.Values
if len(values) == 0 {
return containers
}

imgInfo, ok := values["image"]

// image info appears on the top level, so is associated directly with the chart
if ok {
imgInfoStr, ok := imgInfo.(string)
if !ok {
return containers
}

cont := apiv1.Container{Name: spec.ChartGitPath, Image: imgInfoStr}
containers = append(containers, cont)

return containers
}

return []apiv1.Container{}
}

func TryFHRUpdate(def []byte, resourceID flux.ResourceID, container string, newImage image.Ref, out io.Writer) error {
fmt.Println("FAKE Updating image tag info for FHR special")
fmt.Println("=========================================")
fmt.Println("\t\t*** in tryFHRUpdate")
fmt.Printf("\t\t*** container: %s\n", container)
fmt.Printf("\t\t*** newImage: %+v\n", newImage)

fmt.Println("Updating image tag info for FHR special")
fmt.Println("=========================================")

return nil
}

// assumes only one image in the Spec.Values
func (fhr FluxHelmRelease) createFluxFHRContainers() ([]resource.Container, error) {
values := fhr.Spec.Values
containers := []resource.Container{}

if len(values) == 0 {
return containers, nil
}

imgInfo, ok := values["image"]

// image info appears on the top level, so is associated directly with the chart
if ok {
imgInfoStr := imgInfo.(string)
imageRef, err := image.ParseRef(imgInfoStr)
if err != nil {
return containers, err
}
containers = append(containers, resource.Container{Name: fhr.Spec.ChartGitPath, Image: imageRef})
return containers, nil
}

return []resource.Container{}, nil
}
1 change: 1 addition & 0 deletions cluster/kubernetes/resource/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func Load(base, atLeastOne string, more ...string) (map[string]resource.Resource
return objs, err
}
}

return objs, nil
}

Expand Down
6 changes: 6 additions & 0 deletions cluster/kubernetes/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ func unmarshalKind(base baseObject, bytes []byte) (resource.Resource, error) {
var list List
unmarshalList(base, &raw, &list)
return &list, nil
case "FluxHelmRelease":
var fhr = FluxHelmRelease{baseObject: base}
if err := yaml.Unmarshal(bytes, &fhr); err != nil {
return nil, err
}
return &fhr, nil
case "":
// If there is an empty resource (due to eg an introduced comment),
// we are returning nil for the resource and nil for an error
Expand Down
50 changes: 49 additions & 1 deletion cluster/kubernetes/resourcekinds.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kubernetes
import (
"fmt"

ifv1 "github.com/weaveworks/flux/apis/helm.integrations.flux.weave.works/v1alpha2"
apiapps "k8s.io/api/apps/v1beta1"
apibatch "k8s.io/api/batch/v1beta1"
apiv1 "k8s.io/api/core/v1"
Expand All @@ -11,6 +12,7 @@ import (

"github.com/weaveworks/flux"
"github.com/weaveworks/flux/cluster"
k8sresource "github.com/weaveworks/flux/cluster/kubernetes/resource"
"github.com/weaveworks/flux/image"
"github.com/weaveworks/flux/resource"
)
Expand All @@ -32,6 +34,7 @@ func init() {
resourceKinds["daemonset"] = &daemonSetKind{}
resourceKinds["deployment"] = &deploymentKind{}
resourceKinds["statefulset"] = &statefulSetKind{}
resourceKinds["fluxhelmrelease"] = &fluxHelmReleaseKind{}
}

type podController struct {
Expand Down Expand Up @@ -270,4 +273,49 @@ func makeCronJobPodController(cronJob *apibatch.CronJob) podController {
}

/////////////////////////////////////////////////////////////////////////////
//
// helm.integrations.flux.weave.works/v1alpha2 FluxHelmRelease

type fluxHelmReleaseKind struct{}

func (fhr *fluxHelmReleaseKind) getPodController(c *Cluster, namespace, name string) (podController, error) {
fluxHelmRelease, err := c.client.HelmV1alpha2().FluxHelmReleases(namespace).Get(name, meta_v1.GetOptions{})
if err != nil {
return podController{}, err
}

return makeFluxHelmReleasePodController(fluxHelmRelease), nil
}

func (fhr *fluxHelmReleaseKind) getPodControllers(c *Cluster, namespace string) ([]podController, error) {
fluxHelmReleases, err := c.client.HelmV1alpha2().FluxHelmReleases(namespace).List(meta_v1.ListOptions{})
if err != nil {
return nil, err
}

var podControllers []podController
for _, f := range fluxHelmReleases.Items {
podControllers = append(podControllers, makeFluxHelmReleasePodController(&f))
}

return podControllers, nil
}

func makeFluxHelmReleasePodController(fluxHelmRelease *ifv1.FluxHelmRelease) podController {
containers := k8sresource.CreateK8sFHRContainers(fluxHelmRelease.Spec)

podTemplate := apiv1.PodTemplateSpec{
ObjectMeta: fluxHelmRelease.ObjectMeta,
Spec: apiv1.PodSpec{
Containers: containers,
ImagePullSecrets: []apiv1.LocalObjectReference{},
},
}

return podController{
apiVersion: "helm.integrations.flux.weave.works/v1alpha2",
kind: "FluxHelmRelease",
name: fluxHelmRelease.ObjectMeta.Name,
status: StatusReady,
podTemplate: podTemplate,
apiObject: fluxHelmRelease}
}
9 changes: 8 additions & 1 deletion cmd/fluxd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag"
k8sifclient "github.com/weaveworks/flux/integrations/client/clientset/versioned"
k8sclient "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"

Expand Down Expand Up @@ -182,6 +183,12 @@ func main() {
os.Exit(1)
}

ifclientset, err := k8sifclient.NewForConfig(restClientConfig)
if err != nil {
logger.Log("error", fmt.Sprintf("Error building integrations clientset: %v", err))
os.Exit(1)
}

serverVersion, err := clientset.ServerVersion()
if err != nil {
logger.Log("err", err)
Expand Down Expand Up @@ -229,7 +236,7 @@ func main() {
logger.Log("kubectl", kubectl)

kubectlApplier := kubernetes.NewKubectl(kubectl, restClientConfig)
k8sInst := kubernetes.NewCluster(clientset, kubectlApplier, sshKeyRing, logger)
k8sInst := kubernetes.NewCluster(clientset, ifclientset, kubectlApplier, sshKeyRing, logger)

if err := k8sInst.Ping(); err != nil {
logger.Log("ping", err)
Expand Down
2 changes: 1 addition & 1 deletion remote/rpc/clientV8.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type clientV8 interface {

var _ clientV8 = &RPCClientV8{}

var supportedKindsV8 = []string{"deployment", "daemonset", "statefulset", "cronjob"}
var supportedKindsV8 = []string{"deployment", "daemonset", "statefulset", "cronjob", "fluxhelmrelease"}

// NewClient creates a new rpc-backed implementation of the server.
func NewClientV8(conn io.ReadWriteCloser) *RPCClientV8 {
Expand Down

0 comments on commit 6a7343b

Please sign in to comment.