Skip to content

Commit

Permalink
Support flux v2.2.0
Browse files Browse the repository at this point in the history
This adds the latest source-controller v1.2.2 as a marker for Flux
v2.1.2.

Dependencies are updated to allow us to pull in the latest Flux code.

And we now pull the internal Helm release storage version from the
history, rather than the latest version field.

If there's no history, we retain the old version.
  • Loading branch information
bigkevmcd committed Dec 18, 2023
1 parent 8821d9b commit afd1cd4
Show file tree
Hide file tree
Showing 29 changed files with 1,869 additions and 452 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ download-test-crds:
curl -sL "https://raw.githubusercontent.com/fluxcd/source-controller/v1.0.0/config/crd/bases/$${group}.toolkit.fluxcd.io_$${resource}.yaml" -o "tools/testcrds/$${group}.toolkit.fluxcd.io_$${resource}.yaml"; \
done
curl -sL "https://raw.githubusercontent.com/fluxcd/kustomize-controller/v1.0.0/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml" -o "tools/testcrds/kustomize.toolkit.fluxcd.io_kustomizations.yaml"
curl -sL "https://raw.githubusercontent.com/fluxcd/helm-controller/v0.35.0/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml" -o "tools/testcrds/helm.toolkit.fluxcd.io_helmreleases.yaml"
curl -sL "https://raw.githubusercontent.com/fluxcd/helm-controller/v0.37.0/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml" -o "tools/testcrds/helm.toolkit.fluxcd.io_helmreleases.yaml"

.PHONY: help
# Thanks to https://www.thapaliya.com/en/writings/well-documented-makefiles/
Expand Down
7 changes: 1 addition & 6 deletions cmd/gitops/create/terraform/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,9 @@ gitops create terraform -n default my-resource --source GitRepository/my-project
kubeConfigArgs.Namespace = &namespace
kubeConfigArgs.Context = &context

cfg, err := kubeConfigArgs.ToRESTConfig()
if err != nil {
return err
}

v := viper.New()
v.Set("namespace", namespace)
if err := app.Init(cfg, v); err != nil {
if err := app.Init(kubeConfigArgs, v); err != nil {
return err
}

Expand Down
10 changes: 3 additions & 7 deletions cmd/gitops/delete/terraform/cmd.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package terraform

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/weaveworks/tf-controller/tfctl"
"github.com/weaveworks/weave-gitops/cmd/gitops/config"
"github.com/weaveworks/weave-gitops/pkg/run"
"k8s.io/cli-runtime/pkg/genericclioptions"
"os"
)

var kubeConfigArgs *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -38,14 +39,9 @@ gitops delete terraform -n default my-resource
kubeConfigArgs.Namespace = &namespace
kubeConfigArgs.Context = &context

cfg, err := kubeConfigArgs.ToRESTConfig()
if err != nil {
return err
}

v := viper.New()
v.Set("namespace", namespace)
if err := app.Init(cfg, v); err != nil {
if err := app.Init(kubeConfigArgs, v); err != nil {
return err
}

Expand Down
10 changes: 3 additions & 7 deletions cmd/gitops/replan/terraform/cmd.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package terraform

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/weaveworks/tf-controller/tfctl"
"github.com/weaveworks/weave-gitops/cmd/gitops/config"
"github.com/weaveworks/weave-gitops/pkg/run"
"k8s.io/cli-runtime/pkg/genericclioptions"
"os"
)

var kubeConfigArgs *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -38,14 +39,9 @@ gitops replan terraform --namespace flux-system my-resource
kubeConfigArgs.Namespace = &namespace
kubeConfigArgs.Context = &context

cfg, err := kubeConfigArgs.ToRESTConfig()
if err != nil {
return err
}

v := viper.New()
v.Set("namespace", namespace)
if err := app.Init(cfg, v); err != nil {
if err := app.Init(kubeConfigArgs, v); err != nil {
return err
}

Expand Down
10 changes: 3 additions & 7 deletions cmd/gitops/resume/terraform/cmd.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package terraform

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/weaveworks/tf-controller/tfctl"
"github.com/weaveworks/weave-gitops/cmd/gitops/config"
"github.com/weaveworks/weave-gitops/pkg/run"
"k8s.io/cli-runtime/pkg/genericclioptions"
"os"
)

var kubeConfigArgs *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -38,14 +39,9 @@ gitops resume terraform --namespace flux-system my-resource
kubeConfigArgs.Namespace = &namespace
kubeConfigArgs.Context = &context

cfg, err := kubeConfigArgs.ToRESTConfig()
if err != nil {
return err
}

v := viper.New()
v.Set("namespace", namespace)
if err := app.Init(cfg, v); err != nil {
if err := app.Init(kubeConfigArgs, v); err != nil {
return err
}

Expand Down
10 changes: 3 additions & 7 deletions cmd/gitops/suspend/terraform/cmd.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package terraform

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/weaveworks/tf-controller/tfctl"
"github.com/weaveworks/weave-gitops/cmd/gitops/config"
"github.com/weaveworks/weave-gitops/pkg/run"
"k8s.io/cli-runtime/pkg/genericclioptions"
"os"
)

var kubeConfigArgs *genericclioptions.ConfigFlags
Expand Down Expand Up @@ -38,14 +39,9 @@ gitops suspend terraform --namespace flux-system my-resource
kubeConfigArgs.Namespace = &namespace
kubeConfigArgs.Context = &context

cfg, err := kubeConfigArgs.ToRESTConfig()
if err != nil {
return err
}

v := viper.New()
v.Set("namespace", namespace)
if err := app.Init(cfg, v); err != nil {
if err := app.Init(kubeConfigArgs, v); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion core/fluxsync/adapters.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fluxsync

import (
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2"
imgautomationv1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
Expand Down
2 changes: 1 addition & 1 deletion core/server/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"testing"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
. "github.com/onsi/gomega"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
Expand Down
2 changes: 1 addition & 1 deletion core/server/fluxruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
Expand Down
2 changes: 1 addition & 1 deletion core/server/helm_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"strings"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2"
"github.com/weaveworks/weave-gitops/core/clustersmngr"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
)
Expand Down
109 changes: 80 additions & 29 deletions core/server/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"
"sync"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/ssa"
"github.com/go-logr/logr"
Expand All @@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/cli-utils/pkg/object"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
)

// ObjectWithChildren is a recursive data structure containing a tree of Unstructured
Expand All @@ -48,17 +49,24 @@ func (cs *coreServer) GetInventory(ctx context.Context, msg *pb.GetInventoryRequ

var inventoryRefs []*unstructured.Unstructured

defaultNS := msg.Namespace

switch msg.Kind {
case kustomizev1.KustomizationKind:
inventoryRefs, err = cs.getKustomizationInventory(ctx, client, msg.Name, msg.Namespace)
if err != nil {
return nil, fmt.Errorf("failed getting kustomization inventory: %w", err)
}
case helmv2.HelmReleaseKind:
inventoryRefs, err = cs.getHelmReleaseInventory(ctx, client, msg.Name, msg.Namespace)
hr, err := cs.getHelmRelease(ctx, client, msg.Name, msg.Namespace)
if err != nil {
return nil, fmt.Errorf("failed getting Helm Release for inventory: %w", err)
}
inventoryRefs, err = cs.getHelmReleaseInventory(ctx, client, hr)
if err != nil {
return nil, fmt.Errorf("failed getting helm Release inventory: %w", err)
return nil, fmt.Errorf("failed getting Helm Release inventory: %w", err)
}
defaultNS = hr.GetReleaseNamespace()
default:
gvk, err := cs.primaryKinds.Lookup(msg.Kind)
if err != nil {
Expand All @@ -70,10 +78,7 @@ func (cs *coreServer) GetInventory(ctx context.Context, msg *pb.GetInventoryRequ
}
}

objsWithChildren, err := GetObjectsWithChildren(ctx, inventoryRefs, client, msg.WithChildren, cs.logger)
if err != nil {
return nil, fmt.Errorf("failed getting objects with children: %w", err)
}
objsWithChildren := getObjectsWithChildren(ctx, defaultNS, inventoryRefs, client, msg.WithChildren, cs.logger)

entries := []*pb.InventoryEntry{}
clusterUserNamespaces := cs.clustersManager.GetUserNamespaces(auth.Principal(ctx))
Expand Down Expand Up @@ -123,7 +128,7 @@ func (cs *coreServer) getKustomizationInventory(ctx context.Context, k8sClient c
return objects, nil
}

func (cs *coreServer) getHelmReleaseInventory(ctx context.Context, k8sClient client.Client, name, namespace string) ([]*unstructured.Unstructured, error) {
func (cs *coreServer) getHelmRelease(ctx context.Context, k8sClient client.Client, name, namespace string) (*helmv2.HelmRelease, error) {
release := &helmv2.HelmRelease{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Expand All @@ -132,10 +137,14 @@ func (cs *coreServer) getHelmReleaseInventory(ctx context.Context, k8sClient cli
}

if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(release), release); err != nil {
return nil, fmt.Errorf("failed to get kustomization: %w", err)
return nil, fmt.Errorf("failed to get helm release: %w", err)
}

objects, err := getHelmReleaseObjects(ctx, k8sClient, release)
return release, nil
}

func (cs *coreServer) getHelmReleaseInventory(ctx context.Context, k8sClient client.Client, hr *helmv2.HelmRelease) ([]*unstructured.Unstructured, error) {
objects, err := getHelmReleaseObjects(ctx, k8sClient, hr)
if err != nil {
return nil, fmt.Errorf("failed to get helm release objects: %w", err)
}
Expand All @@ -145,29 +154,18 @@ func (cs *coreServer) getHelmReleaseInventory(ctx context.Context, k8sClient cli

// Returns the list of resources applied in the helm chart.
func getHelmReleaseObjects(ctx context.Context, k8sClient client.Client, helmRelease *helmv2.HelmRelease) ([]*unstructured.Unstructured, error) {
storageNamespace := helmRelease.GetStorageNamespace()

storageName := helmRelease.GetReleaseName()

storageVersion := helmRelease.Status.LastReleaseRevision
if storageVersion < 1 {
secretName := secretNameFromHelmRelease(helmRelease)
if secretName == nil {
// skip release if it failed to install
return nil, nil
}

storageSecret := &v1.Secret{}
secretName := fmt.Sprintf("sh.helm.release.v1.%s.v%v", storageName, storageVersion)
key := client.ObjectKey{
Name: secretName,
Namespace: storageNamespace,
}

if helmRelease.Spec.KubeConfig != nil {
// helmrelease secret is on another cluster so we cannot inspect it to figure out the inventory and version and other things
return nil, nil
}

if err := k8sClient.Get(ctx, key, storageSecret); err != nil {
if err := k8sClient.Get(ctx, *secretName, storageSecret); err != nil {
return nil, err
}

Expand Down Expand Up @@ -258,18 +256,51 @@ func unstructuredToInventoryEntry(clusterName string, objWithChildren ObjectWith
// GetObjectsWithChildren returns objects with their children populated if withChildren is true.
// Objects are retrieved in parallel.
// Children are retrieved recusively, e.g. Deployment -> ReplicaSet -> Pod
func GetObjectsWithChildren(ctx context.Context, objects []*unstructured.Unstructured, k8sClient client.Client, withChildren bool, logger logr.Logger) ([]*ObjectWithChildren, error) {
func getObjectsWithChildren(ctx context.Context, defaultNS string, objects []*unstructured.Unstructured, k8sClient client.Client, withChildren bool, logger logr.Logger) []*ObjectWithChildren {
result := []*ObjectWithChildren{}
resultMu := sync.Mutex{}

wg := sync.WaitGroup{}
var (
isNamespacedGVK = map[string]bool{}
resultMu sync.Mutex
gvkMu sync.RWMutex
wg sync.WaitGroup
err error
)

for _, o := range objects {
wg.Add(1)

go func(obj unstructured.Unstructured) {
defer wg.Done()

// Set the namespace of the object if it is not set.
if obj.GetNamespace() == "" {
// Manifest does not contain the namespace of the release.
// Figure out if the object is namespaced if the namespace is not
// explicitly set, and configure the namespace accordingly.
objGVK := obj.GetObjectKind().GroupVersionKind().String()
gvkMu.RLock()
namespaced, ok := isNamespacedGVK[objGVK]
gvkMu.RUnlock()

if !ok {
namespaced, err = apiutil.IsObjectNamespaced(&obj, k8sClient.Scheme(), k8sClient.RESTMapper())
if err != nil {
logger.Error(err, "failed to determine if %s is namespace scoped", obj.GetObjectKind().GroupVersionKind().Kind)
return
}

// Cache the result, so we don't have to do this for every object
gvkMu.Lock()
isNamespacedGVK[objGVK] = namespaced
gvkMu.Unlock()
}

if namespaced {
obj.SetNamespace(defaultNS)
}
}

if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(&obj), &obj); err != nil {
logger.Error(err, "failed to get object", "entry", obj)
return
Expand All @@ -291,14 +322,14 @@ func GetObjectsWithChildren(ctx context.Context, objects []*unstructured.Unstruc
}

resultMu.Lock()
defer resultMu.Unlock()
result = append(result, entry)
resultMu.Unlock()
}(*o)
}

wg.Wait()

return result, nil
return result
}

func getChildren(ctx context.Context, k8sClient client.Client, parentObj unstructured.Unstructured) ([]*ObjectWithChildren, error) {
Expand Down Expand Up @@ -446,3 +477,23 @@ func parseInventoryFromUnstructured(obj *unstructured.Unstructured) ([]*unstruct

return objects, nil
}

const helmSecretNameFmt = "sh.helm.release.v1.%s.v%v"

func secretNameFromHelmRelease(helmRelease *helmv2.HelmRelease) *client.ObjectKey {
if latest := helmRelease.Status.History.Latest(); latest != nil {
return &client.ObjectKey{
Name: fmt.Sprintf(helmSecretNameFmt, latest.Name, latest.Version),
Namespace: helmRelease.GetStorageNamespace(),
}
}

if latestRevision := helmRelease.Status.LastReleaseRevision; latestRevision > 0 {
return &client.ObjectKey{
Name: fmt.Sprintf(helmSecretNameFmt, helmRelease.GetReleaseName(), latestRevision),
Namespace: helmRelease.GetStorageNamespace(),
}
}

return nil
}
Loading

0 comments on commit afd1cd4

Please sign in to comment.