-
Notifications
You must be signed in to change notification settings - Fork 259
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
k8sClient get resources across all namespaces (#601) #854
Merged
chengfang
merged 4 commits into
argoproj-labs:master
from
EnergyExchangeEnablersBV:bugfix/601_k8sclient_all_namespaces
Oct 14, 2024
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4902053
k8sClient get resources across all namespaces. WIP (#601)
jortkoopmans d440337
Fix GetApplication function which requires a namespace
jortkoopmans d4b988f
- Ensure a unique application is found (findApplicationByName)
jortkoopmans fd619ae
Merge branch 'master' into bugfix/601_k8sclient_all_namespaces
jortkoopmans File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import ( | |
"os" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
|
||
"github.com/argoproj-labs/argocd-image-updater/pkg/common" | ||
"github.com/argoproj-labs/argocd-image-updater/pkg/image" | ||
|
@@ -25,40 +26,97 @@ 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(client.kubeClient.Namespace).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 { | ||
return nil, fmt.Errorf("error listing applications: %w", err) | ||
} | ||
|
||
// Filter applications by name using nameMatchesPattern | ||
app, err := findApplicationByName(appList, appName) | ||
if err != nil { | ||
log.Errorf("error getting application: %v", err) | ||
return nil, fmt.Errorf("error getting application: %w", err) | ||
} | ||
|
||
// Retrieve the application in the specified namespace | ||
return client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(ctx, app.Name, 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(client.kubeClient.Namespace).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 { | ||
return nil, err | ||
return nil, fmt.Errorf("error listing applications: %w", 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) { | ||
var matchedApps []*v1alpha1.Application | ||
|
||
for _, app := range appList { | ||
log.Debugf("Found application: %s in namespace %s", app.Name, app.Namespace) | ||
if nameMatchesPattern(app.Name, []string{appName}) { | ||
log.Debugf("Application %s matches the pattern", app.Name) | ||
matchedApps = append(matchedApps, &app) | ||
} | ||
} | ||
|
||
if len(matchedApps) == 0 { | ||
return nil, fmt.Errorf("application %s not found", appName) | ||
} | ||
|
||
if len(matchedApps) > 1 { | ||
return nil, fmt.Errorf("multiple applications found matching %s", appName) | ||
} | ||
|
||
return matchedApps[0], nil | ||
} | ||
|
||
func (client *k8sClient) UpdateSpec(ctx context.Context, spec *application.ApplicationUpdateSpecRequest) (*v1alpha1.ApplicationSpec, error) { | ||
for { | ||
app, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(client.kubeClient.Namespace).Get(ctx, spec.GetName(), v1.GetOptions{}) | ||
const defaultMaxRetries = 7 | ||
const baseDelay = 100 * time.Millisecond // Initial delay before retrying | ||
|
||
// Allow overriding max retries for testing purposes | ||
maxRetries := defaultMaxRetries | ||
if overrideRetries, ok := os.LookupEnv("OVERRIDE_MAX_RETRIES"); ok { | ||
var retries int | ||
if _, err := fmt.Sscanf(overrideRetries, "%d", &retries); err == nil { | ||
maxRetries = retries | ||
} | ||
} | ||
Comment on lines
+89
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
for attempts := 0; attempts < maxRetries; attempts++ { | ||
app, err := client.GetApplication(ctx, spec.GetName()) | ||
if err != nil { | ||
return nil, err | ||
log.Errorf("could not get application: %s, error: %v", spec.GetName(), err) | ||
return nil, fmt.Errorf("error getting application: %w", err) | ||
} | ||
app.Spec = *spec.Spec | ||
|
||
updatedApp, err := client.kubeClient.ApplicationsClientset.ArgoprojV1alpha1().Applications(client.kubeClient.Namespace).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) { | ||
log.Warnf("conflict occurred while updating application: %s, retrying... (%d/%d)", spec.GetName(), attempts+1, maxRetries) | ||
time.Sleep(baseDelay * (1 << attempts)) // Exponential backoff, multiply baseDelay by 2^attempts | ||
continue | ||
} | ||
return nil, err | ||
log.Errorf("could not update application: %s, error: %v", spec.GetName(), err) | ||
return nil, fmt.Errorf("error updating application: %w", err) | ||
} | ||
return &updatedApp.Spec, nil | ||
} | ||
|
||
return nil, fmt.Errorf("max retries(%d) reached while updating application: %s", maxRetries, spec.GetName()) | ||
} | ||
|
||
// NewAPIClient creates a new API client for ArgoCD and connects to the ArgoCD | ||
// API server. | ||
// NewK8SClient creates a new kubernetes client to interact with kubernetes api-server. | ||
func NewK8SClient(kubeClient *kube.KubernetesClient) (ArgoCD, error) { | ||
return &k8sClient{kubeClient: kubeClient}, nil | ||
} | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to retrieve the application again, as it should be already retrieved as part of
appList, err := client.ListApplications("")
?