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

Commit

Permalink
Merge pull request #45 from fluxcd/jp-sync-viz
Browse files Browse the repository at this point in the history
Show child objects of a Kustomization
  • Loading branch information
jpellizzari committed Jun 1, 2021
2 parents 0ce609e + 8e2343c commit f48d23e
Show file tree
Hide file tree
Showing 13 changed files with 2,906 additions and 735 deletions.
7 changes: 6 additions & 1 deletion go.mod
Expand Up @@ -11,13 +11,18 @@ require (
github.com/fluxcd/source-controller/api v0.12.2
github.com/go-logr/logr v0.4.0
github.com/golang/protobuf v1.4.3
github.com/onsi/ginkgo v1.14.1
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo v1.14.2
github.com/onsi/gomega v1.10.2
github.com/prometheus/client_golang v1.7.1
github.com/twitchtv/twirp v7.1.0+incompatible
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3 // indirect
google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
k8s.io/api v0.20.4
k8s.io/apimachinery v0.20.4
k8s.io/client-go v0.20.4
sigs.k8s.io/controller-runtime v0.8.3
sigs.k8s.io/kustomize/kstatus v0.0.2
)
182 changes: 177 additions & 5 deletions go.sum

Large diffs are not rendered by default.

183 changes: 168 additions & 15 deletions pkg/clustersserver/clustersserver.go
Expand Up @@ -15,10 +15,14 @@ import (
pb "github.com/fluxcd/webui/pkg/rpc/clusters"
"github.com/fluxcd/webui/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/kustomize/kstatus/status"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -150,23 +154,60 @@ func doReconcileAnnotations(annotations map[string]string) {
}
}

func convertKustomization(kustomization kustomizev1.Kustomization) (*pb.Kustomization, error) {
reconcileRequestAt := kustomization.Annotations[meta.ReconcileRequestAnnotation]
func addSnapshots(out []*pb.GroupVersionKind, collection []schema.GroupVersionKind) []*pb.GroupVersionKind {
for _, gvk := range collection {
out = append(out, &pb.GroupVersionKind{
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
})
}

return out
}

func convertKustomization(kustomization kustomizev1.Kustomization, namespace string) (*pb.Kustomization, error) {
reconcileRequestAt := kustomization.Annotations[meta.ReconcileRequestAnnotation]
reconcileAt := kustomization.Annotations[meta.ReconcileAtAnnotation]

k := &pb.Kustomization{
Name: kustomization.Name,
Namespace: kustomization.Namespace,
TargetNamespace: kustomization.Spec.TargetNamespace,
Path: kustomization.Spec.Path,
SourceRef: kustomization.Spec.SourceRef.Name,
SourceRefKind: getSourceTypeEnum(kustomization.Spec.SourceRef.Kind),
Conditions: mapConditions(kustomization.Status.Conditions),
Interval: kustomization.Spec.Interval.Duration.String(),
Prune: kustomization.Spec.Prune,
ReconcileRequestAt: reconcileRequestAt,
ReconcileAt: reconcileAt,
Name: kustomization.Name,
Namespace: kustomization.Namespace,
TargetNamespace: kustomization.Spec.TargetNamespace,
Path: kustomization.Spec.Path,
SourceRef: kustomization.Spec.SourceRef.Name,
SourceRefKind: getSourceTypeEnum(kustomization.Spec.SourceRef.Kind),
Conditions: mapConditions(kustomization.Status.Conditions),
Interval: kustomization.Spec.Interval.Duration.String(),
Prune: kustomization.Spec.Prune,
ReconcileRequestAt: reconcileRequestAt,
ReconcileAt: reconcileAt,
Snapshots: []*pb.SnapshotEntry{},
LastAppliedRevision: kustomization.Status.LastAppliedRevision,
LastAttemptedRevision: kustomization.Status.LastAttemptedRevision,
}
kinds := []*pb.GroupVersionKind{}

// The current test environment does not append a Snapshot,
// so check for it here. Should only be nil in tests.
if kustomization.Status.Snapshot != nil {
for ns, gvks := range kustomization.Status.Snapshot.NamespacedKinds() {
kinds = addSnapshots(kinds, gvks)

k.Snapshots = append(k.Snapshots, &pb.SnapshotEntry{
Namespace: ns,
Kinds: kinds,
})
}

for _, gvk := range kustomization.Status.Snapshot.NonNamespacedKinds() {
kinds = addSnapshots(kinds, []schema.GroupVersionKind{gvk})

k.Snapshots = append(k.Snapshots, &pb.SnapshotEntry{
Namespace: "",
Kinds: kinds,
})
}
}

return k, nil
Expand All @@ -188,7 +229,7 @@ func (s *Server) ListKustomizations(ctx context.Context, msg *pb.ListKustomizati

k := []*pb.Kustomization{}
for _, kustomization := range result.Items {
m, err := convertKustomization(kustomization)
m, err := convertKustomization(kustomization, msg.Namespace)
if err != nil {
return nil, err
}
Expand All @@ -200,6 +241,118 @@ func (s *Server) ListKustomizations(ctx context.Context, msg *pb.ListKustomizati

}

const KustomizeNameKey string = "kustomize.toolkit.fluxcd.io/name"
const KustomizeNamespaceKey string = "kustomize.toolkit.fluxcd.io/namespace"

func (s *Server) GetReconciledObjects(ctx context.Context, msg *pb.GetReconciledObjectsReq) (*pb.GetReconciledObjectsRes, error) {
c, err := s.getClient(msg.ContextName)

if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}

result := []unstructured.Unstructured{}

for _, gvk := range msg.Kinds {
list := unstructured.UnstructuredList{}

list.SetGroupVersionKind(schema.GroupVersionKind{
Group: gvk.Group,
Kind: gvk.Kind,
Version: gvk.Version,
})

opts := client.MatchingLabels{
KustomizeNameKey: msg.KustomizationName,
KustomizeNamespaceKey: msg.KustomizationNamespace,
}

if err := c.List(ctx, &list, opts); err != nil {
return nil, fmt.Errorf("could not get unstructured list: %s\n", err)
}

result = append(result, list.Items...)

}

objects := []*pb.UnstructuredObject{}
for _, obj := range result {
res, err := status.Compute(&obj)

if err != nil {
return nil, fmt.Errorf("could not get status for %s: %w", obj.GetName(), err)
}

objects = append(objects, &pb.UnstructuredObject{
GroupVersionKind: &pb.GroupVersionKind{
Group: obj.GetObjectKind().GroupVersionKind().Group,
Version: obj.GetObjectKind().GroupVersionKind().GroupVersion().Version,
Kind: obj.GetKind(),
},
Name: obj.GetName(),
Namespace: obj.GetNamespace(),
Status: res.Status.String(),
Uid: string(obj.GetUID()),
})
}
return &pb.GetReconciledObjectsRes{Objects: objects}, nil
}

func (s *Server) GetChildObjects(ctx context.Context, msg *pb.GetChildObjectsReq) (*pb.GetChildObjectsRes, error) {
c, err := s.getClient(msg.ContextName)

if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}

list := unstructured.UnstructuredList{}

list.SetGroupVersionKind(schema.GroupVersionKind{
Group: msg.GroupVersionKind.Group,
Version: msg.GroupVersionKind.Version,
Kind: msg.GroupVersionKind.Kind,
})

if err := c.List(ctx, &list, namespaceOpts("default")); err != nil {
return nil, fmt.Errorf("could not get unstructured object: %s\n", err)
}

objects := []*pb.UnstructuredObject{}

Items:
for _, obj := range list.Items {

refs := obj.GetOwnerReferences()

for _, ref := range refs {
if ref.UID != types.UID(msg.ParentUid) {
// This is not the child we are looking for.
// Skip the rest of the operations in the outer loop
continue Items
}
}

res, err := status.Compute(&obj)

if err != nil {
return nil, fmt.Errorf("could not get status for %s: %w", obj.GetName(), err)
}
objects = append(objects, &pb.UnstructuredObject{
GroupVersionKind: &pb.GroupVersionKind{
Group: obj.GetObjectKind().GroupVersionKind().Group,
Version: obj.GetObjectKind().GroupVersionKind().GroupVersion().Version,
Kind: obj.GetKind(),
},
Name: obj.GetName(),
Namespace: obj.GetNamespace(),
Status: res.Status.String(),
Uid: string(obj.GetUID()),
})
}

return &pb.GetChildObjectsRes{Objects: objects}, nil
}

func kindToSourceType(kind string) pb.Source_Type {
switch kind {
case "Git":
Expand Down Expand Up @@ -414,7 +567,7 @@ func (s *Server) SyncKustomization(ctx context.Context, msg *pb.SyncKustomizatio
return nil, err
}

k, err := convertKustomization(kustomization)
k, err := convertKustomization(kustomization, msg.Namespace)

if err != nil {
return nil, err
Expand Down

0 comments on commit f48d23e

Please sign in to comment.