Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add labels to applications #461

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())
})
}
}
Loading