Skip to content

Commit

Permalink
add labels to applications (#461)
Browse files Browse the repository at this point in the history
Signed-off-by: Manabu McCloskey <[email protected]>
  • Loading branch information
nabuskey authored Nov 25, 2024
1 parent a659417 commit 98b7234
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 45 deletions.
9 changes: 6 additions & 3 deletions api/v1alpha1/localbuild_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ const (
CliStartTimeAnnotation = "cnoe.io/cli-start-time"
FieldManager = "idpbuilder"
// If GetSecretLabelKey is set to GetSecretLabelValue on a kubernetes secret, secret key and values can be used by the get command.
CLISecretLabelKey = "cnoe.io/cli-secret"
CLISecretLabelValue = "true"
PackageNameLabelKey = "cnoe.io/package-name"
CLISecretLabelKey = "cnoe.io/cli-secret"
CLISecretLabelValue = "true"
PackageNameLabelKey = "cnoe.io/package-name"
PackageTypeLabelKey = "cnoe.io/package-type"
PackageTypeLabelCore = "core"
PackageTypeLabelCustom = "custom"

ArgoCDPackageName = "argocd"
GiteaPackageName = "gitea"
Expand Down
8 changes: 7 additions & 1 deletion pkg/controllers/custompackage/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
if !ok {
return ctrl.Result{}, fmt.Errorf("object is not an ArgoCD application %s", resource.Spec.ArgoCD.ApplicationFile)
}
util.SetPackageLabels(app)

res, err := r.reconcileArgoCDApp(ctx, resource, app)
if err != nil {
Expand All @@ -112,7 +113,7 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
}
return ctrl.Result{}, fmt.Errorf("getting argocd application object: %w", err)
}

util.SetPackageLabels(&foundAppObj)
foundAppObj.Spec = app.Spec
foundAppObj.ObjectMeta.Annotations = app.GetAnnotations()
foundAppObj.ObjectMeta.Labels = app.GetLabels()
Expand All @@ -128,10 +129,14 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
if !ok {
return ctrl.Result{}, fmt.Errorf("object is not an ArgoCD application set %s", resource.Spec.ArgoCD.ApplicationFile)
}

util.SetPackageLabels(appSet)

res, err := r.reconcileArgoCDAppSet(ctx, resource, appSet)
if err != nil {
return ctrl.Result{}, err
}

foundAppSetObj := argov1alpha1.ApplicationSet{}
err = r.Client.Get(ctx, client.ObjectKeyFromObject(appSet), &foundAppSetObj)
if err != nil {
Expand All @@ -145,6 +150,7 @@ func (r *Reconciler) reconcileCustomPackage(ctx context.Context, resource *v1alp
return ctrl.Result{}, fmt.Errorf("getting argocd application set object: %w", err)
}

util.SetPackageLabels(&foundAppSetObj)
foundAppSetObj.Spec = appSet.Spec
foundAppSetObj.ObjectMeta.Annotations = appSet.GetAnnotations()
foundAppSetObj.ObjectMeta.Labels = appSet.GetLabels()
Expand Down
91 changes: 50 additions & 41 deletions pkg/controllers/custompackage/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
argov1alpha1 "github.com/cnoe-io/argocd-api/api/argo/application/v1alpha1"
"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -48,17 +49,13 @@ func TestReconcileCustomPkg(t *testing.T) {
}

cfg, err := testEnv.Start()
if err != nil {
t.Fatalf("Starting testenv: %v", err)
}
require.NoError(t, err)
defer testEnv.Stop()

mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: s,
})
if err != nil {
t.Fatalf("getting manager: %v", err)
}
require.NoError(t, err)

ctx, ctxCancel := context.WithCancel(context.Background())
stoppedCh := make(chan error)
Expand All @@ -82,9 +79,8 @@ func TestReconcileCustomPkg(t *testing.T) {
Recorder: mgr.GetEventRecorderFor("test-custompkg-controller"),
}
cwd, err := os.Getwd()
if err != nil {
t.Fatalf("getting cwd %v", err)
}
require.NoError(t, err)

customPkgs := []v1alpha1.CustomPackage{
{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -191,45 +187,58 @@ func TestReconcileCustomPkg(t *testing.T) {
}
assert.Equal(t, repo.Spec, expectedRepo.Spec)
ok := reflect.DeepEqual(repo.Spec, expectedRepo.Spec)
if !ok {
t.Fatalf("expected spec does not match")
}
assert.True(t, ok)

// verify argocd apps
localApp := argov1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "my-app",
Namespace: "argocd",
tcs := []struct {
name string
}{
{
name: "my-app",
},
{
name: "my-app2",
},
{
name: "guestbook",
},
}
err = c.Get(context.Background(), client.ObjectKeyFromObject(&localApp), &localApp)
if err != nil {
t.Fatalf("failed getting my-app %v", err)
}
if strings.HasPrefix(localApp.Spec.Source.RepoURL, v1alpha1.CNOEURIScheme) {
t.Fatalf("%s prefix should be removed", v1alpha1.CNOEURIScheme)
}

for _, n := range []string{"guestbook", "guestbook2"} {
err = c.Get(context.Background(), client.ObjectKeyFromObject(&localApp), &localApp)
if err != nil {
t.Fatalf("expected %s arogapp : %v", n, err)
for _, tc := range tcs {
app := argov1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: tc.name,
Namespace: "argocd",
},
}
}
err = c.Get(context.Background(), client.ObjectKeyFromObject(&app), &app)
assert.NoError(t, err)

localApp2 := argov1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "my-app2",
Namespace: "argocd",
},
}
err = c.Get(context.Background(), client.ObjectKeyFromObject(&localApp2), &localApp2)
if err != nil {
t.Fatalf("failed getting my-app2 %v", err)
}
if app.ObjectMeta.Labels == nil {
t.Fatalf("labels not set")
}

_, ok := app.ObjectMeta.Labels[v1alpha1.PackageNameLabelKey]
if !ok {
t.Fatalf("label %s not set", v1alpha1.PackageTypeLabelKey)
}

_, ok = app.ObjectMeta.Labels[v1alpha1.PackageNameLabelKey]
if !ok {
t.Fatalf("label %s not set", v1alpha1.PackageNameLabelKey)
}

if app.Spec.Sources == nil {
if strings.HasPrefix(app.Spec.Source.RepoURL, v1alpha1.CNOEURIScheme) {
t.Fatalf("%s prefix should be removed", v1alpha1.CNOEURIScheme)
}
continue
}
for _, s := range app.Spec.Sources {
if strings.HasPrefix(s.RepoURL, v1alpha1.CNOEURIScheme) {
t.Fatalf("%s prefix should be removed", v1alpha1.CNOEURIScheme)
}
}

if strings.HasPrefix(localApp2.Spec.Sources[0].RepoURL, v1alpha1.CNOEURIScheme) {
t.Fatalf("%s prefix should be removed", v1alpha1.CNOEURIScheme)
}
}

Expand Down
29 changes: 29 additions & 0 deletions pkg/controllers/localbuild/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -234,6 +236,8 @@ func (r *LocalbuildReconciler) reconcileEmbeddedApp(ctx context.Context, appName
},
}

util.SetPackageLabels(app)

if err := controllerutil.SetControllerReference(resource, app, r.Scheme); err != nil {
return ctrl.Result{}, err
}
Expand Down Expand Up @@ -282,6 +286,30 @@ func (r *LocalbuildReconciler) shouldShutDown(ctx context.Context, resource *v1a
return false, err
}

// check if core packages are ready
selector := labels.NewSelector()
req, err := labels.NewRequirement(v1alpha1.PackageTypeLabelKey, selection.Equals, []string{v1alpha1.PackageTypeLabelCore})
if err != nil {
return false, fmt.Errorf("building labels with key %s and value %s : %w", v1alpha1.PackageTypeLabelKey, v1alpha1.PackageTypeLabelCore, err)
}

opts := client.ListOptions{
LabelSelector: selector.Add(*req),
Namespace: "",
}
apps := argov1alpha1.ApplicationList{}
err = r.Client.List(ctx, &apps, &opts)
if err != nil {
return false, fmt.Errorf("listing core packages: %w", err)
}

for _, app := range apps.Items {
if app.Status.Health.Status != "Healthy" {
return false, nil
}
}

// check if repositories are ready
repos := &v1alpha1.GitRepositoryList{}
err = r.Client.List(ctx, repos, client.InNamespace(resource.Namespace))
if err != nil {
Expand Down Expand Up @@ -313,6 +341,7 @@ func (r *LocalbuildReconciler) shouldShutDown(ctx context.Context, resource *v1a
}
}

// check if custom packages are ready
pkgs := &v1alpha1.CustomPackageList{}
err = r.Client.List(ctx, pkgs, client.InNamespace(resource.Namespace))
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,19 @@ func DetectKindNodeProvider() (cluster.ProviderOption, error) {
return cluster.DetectNodeProvider()
}
}

func SetPackageLabels(obj client.Object) {
labels := obj.GetLabels()
if labels == nil {
labels = map[string]string{}
obj.SetLabels(labels)
}
labels[v1alpha1.PackageNameLabelKey] = obj.GetName()

switch n := obj.GetName(); n {
case v1alpha1.ArgoCDPackageName, v1alpha1.GiteaPackageName, v1alpha1.IngressNginxPackageName:
labels[v1alpha1.PackageTypeLabelKey] = v1alpha1.PackageTypeLabelCore
default:
labels[v1alpha1.PackageTypeLabelKey] = v1alpha1.PackageTypeLabelCustom
}
}
92 changes: 92 additions & 0 deletions pkg/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ package util
import (
"strconv"
"testing"

"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)

var specialCharMap = make(map[string]struct{})
Expand Down Expand Up @@ -42,3 +48,89 @@ func TestGeneratePassword(t *testing.T) {
}
}
}

type MockObject struct {
v1.ObjectMeta
}

func (m *MockObject) GetObjectKind() schema.ObjectKind {
return nil
}

func (m *MockObject) DeepCopyObject() runtime.Object {
return nil
}

func TestSetPackageLabels(t *testing.T) {
testCases := []struct {
name string
objectName string
initialLabels map[string]string
expectedLabels map[string]string
}{
{
name: "No initial labels",
objectName: "test-package",
initialLabels: nil,
expectedLabels: map[string]string{
v1alpha1.PackageNameLabelKey: "test-package",
v1alpha1.PackageTypeLabelKey: v1alpha1.PackageTypeLabelCustom,
},
},
{
name: "With initial labels",
objectName: "test-package-one",
initialLabels: map[string]string{
"existing": "label",
v1alpha1.PackageNameLabelKey: "incorrect",
},
expectedLabels: map[string]string{
"existing": "label",
v1alpha1.PackageNameLabelKey: "test-package-one",
v1alpha1.PackageTypeLabelKey: v1alpha1.PackageTypeLabelCustom,
},
},
{
name: "ArgoCD package",
objectName: v1alpha1.ArgoCDPackageName,
initialLabels: nil,
expectedLabels: map[string]string{
v1alpha1.PackageNameLabelKey: v1alpha1.ArgoCDPackageName,
v1alpha1.PackageTypeLabelKey: v1alpha1.PackageTypeLabelCore,
},
},
{
name: "Gitea package",
objectName: v1alpha1.GiteaPackageName,
initialLabels: nil,
expectedLabels: map[string]string{
v1alpha1.PackageNameLabelKey: v1alpha1.GiteaPackageName,
v1alpha1.PackageTypeLabelKey: v1alpha1.PackageTypeLabelCore,
},
},
{
name: "IngressNginx package",
objectName: v1alpha1.IngressNginxPackageName,
initialLabels: nil,
expectedLabels: map[string]string{
v1alpha1.PackageNameLabelKey: v1alpha1.IngressNginxPackageName,
v1alpha1.PackageTypeLabelKey: v1alpha1.PackageTypeLabelCore,
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
obj := &MockObject{
ObjectMeta: v1.ObjectMeta{
Name: tc.objectName,
Labels: tc.initialLabels,
},
}

SetPackageLabels(obj)

assert.Equal(t, tc.expectedLabels, obj.GetLabels())
})
}
}

0 comments on commit 98b7234

Please sign in to comment.