Skip to content

Commit

Permalink
Fix GetApplication function which requires a namespace
Browse files Browse the repository at this point in the history
Fix UpdateSpec to handle partial updates without specified appNamespace
Fix tests to work with Applications across namespaces

Signed-off-by: Jort Koopmans <[email protected]>
  • Loading branch information
jortkoopmans committed Sep 17, 2024
1 parent 4902053 commit 2748faa
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
47 changes: 43 additions & 4 deletions pkg/argocd/argocd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,66 @@ type k8sClient struct {
kubeClient *kube.KubernetesClient
}

// GetApplication retrieves an application by name across all namespaces.
func (client *k8sClient) GetApplication(ctx context.Context, appName string) (*v1alpha1.Application, error) {
return client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications("").Get(ctx, appName, v1.GetOptions{})
log.Debugf("Getting application %s across all namespaces", appName)

// List all applications across all namespaces (using empty labelSelector)
appList, err := client.ListApplications("")
if err != nil {
log.Errorf("Error listing applications: %v", err)
return nil, err
}

// Filter applications by name using nameMatchesPattern
app, err := findApplicationByName(appList, appName)
if err != nil {
log.Errorf("Error getting application: %v", err)
return nil, err
}

// Retrieve the application in the specified namespace
return client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(ctx, appName, v1.GetOptions{})
}

// ListApplications lists all applications across all namespaces.
func (client *k8sClient) ListApplications(labelSelector string) ([]v1alpha1.Application, error) {
list, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications("").List(context.TODO(), v1.ListOptions{LabelSelector: labelSelector})

list, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(v1.NamespaceAll).List(context.TODO(), v1.ListOptions{LabelSelector: labelSelector})
if err != nil {
log.Errorf("Error listing applications: %v", err)
return nil, err
}

log.Debugf("Applications listed: %d", len(list.Items))
return list.Items, nil
}

// findApplicationByName filters the list of applications by name using nameMatchesPattern.
func findApplicationByName(appList []v1alpha1.Application, appName string) (*v1alpha1.Application, error) {
for _, app := range appList {
log.Debugf("Found application: %s in namespace %s", app.Name, app.Namespace)
if nameMatchesPattern(app.Name, []string{appName}) {
log.Debugf("Successfully found application: %s", app.Name)
return &app, nil
}
}

// If the application is not found, return an error
err := errors.NewNotFound(v1alpha1.Resource("application"), appName)
return nil, err
}

func (client *k8sClient) UpdateSpec(ctx context.Context, spec *application.ApplicationUpdateSpecRequest) (*v1alpha1.ApplicationSpec, error) {
for {
app, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(spec.GetAppNamespace()).Get(ctx, spec.GetName(), v1.GetOptions{})
app, err := client.GetApplication(ctx, spec.GetName())
if err != nil {
log.Errorf("Could not get Application: %s", spec.GetName())
return nil, err
}
app.Spec = *spec.Spec

updatedApp, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(spec.GetAppNamespace()).Update(ctx, app, v1.UpdateOptions{})
updatedApp, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(app.Namespace).Update(ctx, app, v1.UpdateOptions{})
if err != nil {
if errors.IsConflict(err) {
continue
Expand Down
16 changes: 10 additions & 6 deletions pkg/argocd/argocd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,19 +1024,24 @@ func TestKubernetesClient(t *testing.T) {
t.Run("List applications", func(t *testing.T) {
apps, err := client.ListApplications("")
require.NoError(t, err)
require.Len(t, apps, 1)

assert.ElementsMatch(t, []string{"test-app1"}, []string{app1.Name})
require.Len(t, apps, 2)
assert.ElementsMatch(t, []string{"test-app1", "test-app2"}, []string{app1.Name, app2.Name})
})

t.Run("Get application successful", func(t *testing.T) {
t.Run("Get application test-app1 successful", func(t *testing.T) {
app, err := client.GetApplication(context.TODO(), "test-app1")
require.NoError(t, err)
assert.Equal(t, "test-app1", app.GetName())
})

t.Run("Get application test-app2 successful", func(t *testing.T) {
app, err := client.GetApplication(context.TODO(), "test-app2")
require.NoError(t, err)
assert.Equal(t, "test-app2", app.GetName())
})

t.Run("Get application not found", func(t *testing.T) {
_, err := client.GetApplication(context.TODO(), "test-app2")
_, err := client.GetApplication(context.TODO(), "test-app-non-existent")
require.Error(t, err)
assert.True(t, errors.IsNotFound(err))
})
Expand All @@ -1060,7 +1065,6 @@ func TestKubernetesClient_UpdateSpec_Conflict(t *testing.T) {
})

client, err := NewK8SClient(&kube.KubernetesClient{
Namespace: "testns",
ApplicationsClientset: clientset,
})
require.NoError(t, err)
Expand Down

0 comments on commit 2748faa

Please sign in to comment.