mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-10 18:38:46 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c279299281 | ||
|
|
24f8d82954 | ||
|
|
1ab570ad96 | ||
|
|
8612a99fe8 | ||
|
|
33fa128bad | ||
|
|
4e79aab03d | ||
|
|
7b89ae4424 | ||
|
|
2577d51796 | ||
|
|
2f8533efeb | ||
|
|
c698426a5c | ||
|
|
77556d9e64 | ||
|
|
1391ba7214 | ||
|
|
44e52c4ae7 | ||
|
|
4b55084a8f | ||
|
|
c689ea4957 | ||
|
|
ea9827791f |
@@ -58,10 +58,6 @@ const (
|
||||
// https://github.com/argoproj-labs/argocd-notifications/blob/33d345fa838829bb50fca5c08523aba380d2c12b/pkg/controller/state.go#L17
|
||||
NotifiedAnnotationKey = "notified.notifications.argoproj.io"
|
||||
ReconcileRequeueOnValidationError = time.Minute * 3
|
||||
|
||||
// LabelKeyAppSetInstance is the label key to use to uniquely identify the apps of an applicationset
|
||||
// The ArgoCD applicationset name is used as the instance name
|
||||
LabelKeyAppSetInstance = "argocd.argoproj.io/application-set-name"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -516,10 +512,6 @@ func (r *ApplicationSetReconciler) generateApplications(applicationSetInfo argov
|
||||
|
||||
for _, a := range t {
|
||||
tmplApplication := getTempApplication(a.Template)
|
||||
if tmplApplication.Labels == nil {
|
||||
tmplApplication.Labels = make(map[string]string)
|
||||
}
|
||||
tmplApplication.Labels[LabelKeyAppSetInstance] = applicationSetInfo.Name
|
||||
|
||||
for _, p := range a.Params {
|
||||
app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions)
|
||||
|
||||
@@ -165,9 +165,6 @@ func TestExtractApplications(t *testing.T) {
|
||||
if cc.generateParamsError == nil {
|
||||
for _, p := range cc.params {
|
||||
|
||||
tmpApplication := getTempApplication(cc.template)
|
||||
tmpApplication.Labels[LabelKeyAppSetInstance] = appSet.Name
|
||||
|
||||
if cc.rendererError != nil {
|
||||
rendererMock.On("RenderTemplateParams", getTempApplication(cc.template), p, false, []string(nil)).
|
||||
Return(nil, cc.rendererError)
|
||||
@@ -289,21 +286,7 @@ func TestMergeTemplateApplications(t *testing.T) {
|
||||
|
||||
rendererMock := rendererMock{}
|
||||
|
||||
appSet := &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Generators: []v1alpha1.ApplicationSetGenerator{generator},
|
||||
Template: cc.template,
|
||||
},
|
||||
}
|
||||
|
||||
tmpApplication := getTempApplication(cc.expectedMerged)
|
||||
tmpApplication.Labels[LabelKeyAppSetInstance] = appSet.Name
|
||||
|
||||
rendererMock.On("RenderTemplateParams", tmpApplication, cc.params[0], false, []string(nil)).
|
||||
rendererMock.On("RenderTemplateParams", getTempApplication(cc.expectedMerged), cc.params[0], false, []string(nil)).
|
||||
Return(&cc.expectedApps[0], nil)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
@@ -317,7 +300,17 @@ func TestMergeTemplateApplications(t *testing.T) {
|
||||
KubeClientset: kubefake.NewSimpleClientset(),
|
||||
}
|
||||
|
||||
got, _, _ := r.generateApplications(*appSet)
|
||||
got, _, _ := r.generateApplications(v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Generators: []v1alpha1.ApplicationSetGenerator{generator},
|
||||
Template: cc.template,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert.Equal(t, cc.expectedApps, got)
|
||||
})
|
||||
@@ -2169,7 +2162,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
|
||||
assert.Nil(t, err)
|
||||
|
||||
retrievedApplicationSet.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
retrievedApplicationSet.Spec.Template.Labels = map[string]string{"argocd.argoproj.io/application-set-name": "name", "label-key": "label-value"}
|
||||
retrievedApplicationSet.Spec.Template.Labels = map[string]string{"label-key": "label-value"}
|
||||
|
||||
retrievedApplicationSet.Spec.Template.Spec.Source.Helm = &v1alpha1.ApplicationSourceHelm{
|
||||
Values: "global.test: test",
|
||||
@@ -2197,7 +2190,6 @@ func TestUpdateNotPerformedWithSyncPolicyCreateOnly(t *testing.T) {
|
||||
|
||||
assert.Nil(t, app.Spec.Source.Helm)
|
||||
assert.Nil(t, app.ObjectMeta.Annotations)
|
||||
assert.Equal(t, map[string]string{"argocd.argoproj.io/application-set-name": "name"}, app.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func TestUpdateNotPerformedWithSyncPolicyCreateDelete(t *testing.T) {
|
||||
@@ -2208,7 +2200,6 @@ func TestUpdateNotPerformedWithSyncPolicyCreateDelete(t *testing.T) {
|
||||
|
||||
assert.Nil(t, app.Spec.Source.Helm)
|
||||
assert.Nil(t, app.ObjectMeta.Annotations)
|
||||
assert.Equal(t, map[string]string{"argocd.argoproj.io/application-set-name": "name"}, app.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func TestUpdatePerformedWithSyncPolicyCreateUpdate(t *testing.T) {
|
||||
@@ -2219,7 +2210,7 @@ func TestUpdatePerformedWithSyncPolicyCreateUpdate(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values)
|
||||
assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations)
|
||||
assert.Equal(t, map[string]string{"argocd.argoproj.io/application-set-name": "name", "label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func TestUpdatePerformedWithSyncPolicySync(t *testing.T) {
|
||||
@@ -2230,7 +2221,7 @@ func TestUpdatePerformedWithSyncPolicySync(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values)
|
||||
assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations)
|
||||
assert.Equal(t, map[string]string{"argocd.argoproj.io/application-set-name": "name", "label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) {
|
||||
@@ -2241,7 +2232,7 @@ func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t
|
||||
|
||||
assert.Equal(t, "global.test: test", app.Spec.Source.Helm.Values)
|
||||
assert.Equal(t, map[string]string{"annotation-key": "annotation-value"}, app.ObjectMeta.Annotations)
|
||||
assert.Equal(t, map[string]string{"argocd.argoproj.io/application-set-name": "name", "label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
assert.Equal(t, map[string]string{"label-key": "label-value"}, app.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.ApplicationList {
|
||||
@@ -2449,8 +2440,7 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "AppSet-branch1-1",
|
||||
Labels: map[string]string{
|
||||
"app1": "label1",
|
||||
LabelKeyAppSetInstance: "",
|
||||
"app1": "label1",
|
||||
},
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
|
||||
@@ -153,7 +153,7 @@ func InterpolateGenerator(requestedGenerator *argoprojiov1alpha1.ApplicationSetG
|
||||
interpolatedGenerator, err := render.RenderGeneratorParams(requestedGenerator, params, useGoTemplate, goTemplateOptions)
|
||||
if err != nil {
|
||||
log.WithError(err).WithField("interpolatedGenerator", interpolatedGenerator).Error("error interpolating generator with other generator's parameter")
|
||||
return *interpolatedGenerator, err
|
||||
return argoprojiov1alpha1.ApplicationSetGenerator{}, err
|
||||
}
|
||||
|
||||
return *interpolatedGenerator, nil
|
||||
|
||||
@@ -501,3 +501,60 @@ func TestInterpolateGenerator_go(t *testing.T) {
|
||||
assert.Equal(t, "production_01/west", interpolatedGenerator.Git.Files[0].Path)
|
||||
assert.Equal(t, "https://production-01.example.com", interpolatedGenerator.Git.Files[1].Path)
|
||||
}
|
||||
|
||||
func TestInterpolateGeneratorError(t *testing.T) {
|
||||
type args struct {
|
||||
requestedGenerator *argov1alpha1.ApplicationSetGenerator
|
||||
params map[string]interface{}
|
||||
useGoTemplate bool
|
||||
goTemplateOptions []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want argov1alpha1.ApplicationSetGenerator
|
||||
expectedErrStr string
|
||||
}{
|
||||
{name: "Empty Gen", args: args{
|
||||
requestedGenerator: nil,
|
||||
params: nil,
|
||||
useGoTemplate: false,
|
||||
goTemplateOptions: nil,
|
||||
}, want: argov1alpha1.ApplicationSetGenerator{}, expectedErrStr: "generator is empty"},
|
||||
{name: "No Params", args: args{
|
||||
requestedGenerator: &argov1alpha1.ApplicationSetGenerator{},
|
||||
params: map[string]interface{}{},
|
||||
useGoTemplate: false,
|
||||
goTemplateOptions: nil,
|
||||
}, want: argov1alpha1.ApplicationSetGenerator{}, expectedErrStr: ""},
|
||||
{name: "Error templating", args: args{
|
||||
requestedGenerator: &argov1alpha1.ApplicationSetGenerator{Git: &argov1alpha1.GitGenerator{
|
||||
RepoURL: "foo",
|
||||
Files: []argov1alpha1.GitFileGeneratorItem{{Path: "bar/"}},
|
||||
Revision: "main",
|
||||
Values: map[string]string{
|
||||
"git_test": "{{ toPrettyJson . }}",
|
||||
"selection": "{{ default .override .test }}",
|
||||
"resolved": "{{ index .rmap (default .override .test) }}",
|
||||
},
|
||||
}},
|
||||
params: map[string]interface{}{
|
||||
"name": "in-cluster",
|
||||
"override": "foo",
|
||||
},
|
||||
useGoTemplate: true,
|
||||
goTemplateOptions: []string{},
|
||||
}, want: argov1alpha1.ApplicationSetGenerator{}, expectedErrStr: "failed to replace parameters in generator: failed to execute go template {{ index .rmap (default .override .test) }}: template: :1:3: executing \"\" at <index .rmap (default .override .test)>: error calling index: index of untyped nil"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := InterpolateGenerator(tt.args.requestedGenerator, tt.args.params, tt.args.useGoTemplate, tt.args.goTemplateOptions)
|
||||
if tt.expectedErrStr != "" {
|
||||
assert.EqualError(t, err, tt.expectedErrStr)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "InterpolateGenerator(%v, %v, %v, %v)", tt.args.requestedGenerator, tt.args.params, tt.args.useGoTemplate, tt.args.goTemplateOptions)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ func NewGiteaService(ctx context.Context, token, url, owner, repo string, insecu
|
||||
if insecure {
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
httpClient = &http.Client{
|
||||
Jar: cookieJar,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}}
|
||||
Jar: cookieJar,
|
||||
Transport: tr,
|
||||
}
|
||||
}
|
||||
client, err := gitea.NewClient(url, gitea.SetToken(token), gitea.SetHTTPClient(httpClient))
|
||||
if err != nil {
|
||||
|
||||
@@ -32,9 +32,9 @@ func NewGitLabService(ctx context.Context, token, url, project string, labels []
|
||||
token = os.Getenv("GITLAB_TOKEN")
|
||||
}
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: utils.GetTlsConfig(scmRootCAPath, insecure),
|
||||
}
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure)
|
||||
|
||||
retryClient := retryablehttp.NewClient()
|
||||
retryClient.HTTPClient.Transport = tr
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@ func NewGiteaProvider(ctx context.Context, owner, token, url string, allBranches
|
||||
if insecure {
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
httpClient = &http.Client{
|
||||
Jar: cookieJar,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}}
|
||||
Jar: cookieJar,
|
||||
Transport: tr,
|
||||
}
|
||||
}
|
||||
client, err := gitea.NewClient(url, gitea.SetToken(token), gitea.SetHTTPClient(httpClient))
|
||||
if err != nil {
|
||||
|
||||
@@ -28,9 +28,9 @@ func NewGitlabProvider(ctx context.Context, organization string, token string, u
|
||||
}
|
||||
var client *gitlab.Client
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: utils.GetTlsConfig(scmRootCAPath, insecure),
|
||||
}
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure)
|
||||
|
||||
retryClient := retryablehttp.NewClient()
|
||||
retryClient.HTTPClient.Transport = tr
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ func NewCommand() *cobra.Command {
|
||||
allowOutOfBoundsSymlinks bool
|
||||
streamedManifestMaxTarSize string
|
||||
streamedManifestMaxExtractedSize string
|
||||
helmManifestMaxExtractedSize string
|
||||
disableManifestMaxExtractedSize bool
|
||||
)
|
||||
var command = cobra.Command{
|
||||
Use: cliName,
|
||||
@@ -120,6 +122,9 @@ func NewCommand() *cobra.Command {
|
||||
streamedManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(streamedManifestMaxExtractedSize)
|
||||
errors.CheckError(err)
|
||||
|
||||
helmManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(helmManifestMaxExtractedSize)
|
||||
errors.CheckError(err)
|
||||
|
||||
askPassServer := askpass.NewServer()
|
||||
metricsServer := metrics.NewMetricsServer()
|
||||
cacheutil.CollectMetrics(redisClient, metricsServer)
|
||||
@@ -134,6 +139,7 @@ func NewCommand() *cobra.Command {
|
||||
AllowOutOfBoundsSymlinks: allowOutOfBoundsSymlinks,
|
||||
StreamedManifestMaxExtractedSize: streamedManifestMaxExtractedSizeQuantity.ToDec().Value(),
|
||||
StreamedManifestMaxTarSize: streamedManifestMaxTarSizeQuantity.ToDec().Value(),
|
||||
HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(),
|
||||
}, askPassServer)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -216,6 +222,8 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().BoolVar(&allowOutOfBoundsSymlinks, "allow-oob-symlinks", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS", false), "Allow out-of-bounds symlinks in repositories (not recommended)")
|
||||
command.Flags().StringVar(&streamedManifestMaxTarSize, "streamed-manifest-max-tar-size", env.StringFromEnv("ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE", "100M"), "Maximum size of streamed manifest archives")
|
||||
command.Flags().StringVar(&streamedManifestMaxExtractedSize, "streamed-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of streamed manifest archives when extracted")
|
||||
command.Flags().StringVar(&helmManifestMaxExtractedSize, "helm-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of helm manifest archives when extracted")
|
||||
command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted")
|
||||
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
|
||||
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
|
||||
redisClient = client
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -335,6 +336,10 @@ func verifyGnuPGSignature(revision string, project *v1alpha1.AppProject, manifes
|
||||
return conditions
|
||||
}
|
||||
|
||||
func isManagedNamespace(ns *unstructured.Unstructured, app *v1alpha1.Application) bool {
|
||||
return ns != nil && ns.GetKind() == kubeutil.NamespaceKind && ns.GetName() == app.Spec.Destination.Namespace && app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.ManagedNamespaceMetadata != nil
|
||||
}
|
||||
|
||||
// CompareAppState compares application git state to the live app state, using the specified
|
||||
// revision and supplied source. If revision or overrides are empty, then compares against
|
||||
// revision and overrides in the app spec.
|
||||
@@ -494,6 +499,35 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
LastTransitionTime: &now,
|
||||
})
|
||||
}
|
||||
|
||||
// For the case when a namespace is managed with `managedNamespaceMetadata` AND it has resource tracking
|
||||
// enabled (e.g. someone manually adds resource tracking labels or annotations), we need to do some
|
||||
// bookkeeping in order to prevent the managed namespace from being pruned.
|
||||
//
|
||||
// Live namespaces which are managed namespaces (i.e. application namespaces which are managed with
|
||||
// CreateNamespace=true and has non-nil managedNamespaceMetadata) will (usually) not have a corresponding
|
||||
// entry in source control. In order for the namespace not to risk being pruned, we'll need to generate a
|
||||
// namespace which we can compare the live namespace with. For that, we'll do the same as is done in
|
||||
// gitops-engine, the difference here being that we create a managed namespace which is only used for comparison.
|
||||
if isManagedNamespace(liveObj, app) {
|
||||
nsSpec := &v1.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: kubeutil.NamespaceKind}, ObjectMeta: metav1.ObjectMeta{Name: liveObj.GetName()}}
|
||||
managedNs, err := kubeutil.ToUnstructured(nsSpec)
|
||||
|
||||
if err != nil {
|
||||
conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
|
||||
failedToLoadObjs = true
|
||||
continue
|
||||
}
|
||||
|
||||
// No need to care about the return value here, we just want the modified managedNs
|
||||
_, err = syncNamespace(m.resourceTracking, appLabelKey, trackingMethod, app.Name, app.Spec.SyncPolicy)(managedNs, liveObj)
|
||||
if err != nil {
|
||||
conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
|
||||
failedToLoadObjs = true
|
||||
} else {
|
||||
targetObjs = append(targetObjs, managedNs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,12 +622,22 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
} else {
|
||||
diffResult = diff.DiffResult{Modified: false, NormalizedLive: []byte("{}"), PredictedLive: []byte("{}")}
|
||||
}
|
||||
|
||||
// For the case when a namespace is managed with `managedNamespaceMetadata` AND it has resource tracking
|
||||
// enabled (e.g. someone manually adds resource tracking labels or annotations), we need to do some
|
||||
// bookkeeping in order to ensure that it's not considered `OutOfSync` (since it does not exist in source
|
||||
// control).
|
||||
//
|
||||
// This is in addition to the bookkeeping we do (see `isManagedNamespace` and its references) to prevent said
|
||||
// namespace from being pruned.
|
||||
isManagedNs := isManagedNamespace(targetObj, app) && liveObj == nil
|
||||
|
||||
if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) || !isSelfReferencedObj {
|
||||
// For resource hooks, skipped resources or objects that may have
|
||||
// been created by another controller with annotations copied from
|
||||
// the source object, don't store sync status, and do not affect
|
||||
// overall sync status
|
||||
} else if diffResult.Modified || targetObj == nil || liveObj == nil {
|
||||
} else if !isManagedNs && (diffResult.Modified || targetObj == nil || liveObj == nil) {
|
||||
// Set resource state to OutOfSync since one of the following is true:
|
||||
// * target and live resource are different
|
||||
// * target resource not defined and live resource is extra
|
||||
|
||||
@@ -433,6 +433,47 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) {
|
||||
assert.Equal(t, 4, len(compRes.resources))
|
||||
}
|
||||
|
||||
func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.SyncPolicy = &argoappv1.SyncPolicy{
|
||||
ManagedNamespaceMetadata: &argoappv1.ManagedNamespaceMetadata{
|
||||
Labels: nil,
|
||||
Annotations: nil,
|
||||
},
|
||||
}
|
||||
|
||||
ns := NewNamespace()
|
||||
ns.SetName(test.FakeDestNamespace)
|
||||
ns.SetNamespace(test.FakeDestNamespace)
|
||||
ns.SetAnnotations(map[string]string{"argocd.argoproj.io/sync-options": "ServerSideApply=true"})
|
||||
|
||||
data := fakeData{
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(ns): ns,
|
||||
},
|
||||
}
|
||||
ctrl := newFakeController(&data)
|
||||
compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, []string{}, app.Spec.Sources, false, false, nil, false)
|
||||
|
||||
assert.NotNil(t, compRes)
|
||||
assert.Equal(t, 0, len(app.Status.Conditions))
|
||||
assert.NotNil(t, compRes)
|
||||
assert.NotNil(t, compRes.syncStatus)
|
||||
// Ensure that ns does not get pruned
|
||||
assert.NotNil(t, compRes.reconciliationResult.Target[0])
|
||||
assert.Equal(t, compRes.reconciliationResult.Target[0].GetName(), ns.GetName())
|
||||
assert.Equal(t, compRes.reconciliationResult.Target[0].GetAnnotations(), ns.GetAnnotations())
|
||||
assert.Equal(t, compRes.reconciliationResult.Target[0].GetLabels(), ns.GetLabels())
|
||||
assert.Len(t, compRes.resources, 1)
|
||||
assert.Len(t, compRes.managedResources, 1)
|
||||
}
|
||||
|
||||
var defaultProj = argoappv1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default",
|
||||
|
||||
@@ -38,16 +38,16 @@ With the ApplicationSet v0.1.0 release, one could *only* specify `url` and `clus
|
||||
spec:
|
||||
generators:
|
||||
- list:
|
||||
elements:
|
||||
# v0.1.0 form - requires cluster/url keys:
|
||||
- cluster: engineering-dev
|
||||
url: https://kubernetes.default.svc
|
||||
values:
|
||||
additional: value
|
||||
# v0.2.0+ form - does not require cluster/URL keys
|
||||
# (but they are still supported).
|
||||
- staging: "true"
|
||||
gitRepo: https://kubernetes.default.svc
|
||||
elements:
|
||||
# v0.1.0 form - requires cluster/url keys:
|
||||
- cluster: engineering-dev
|
||||
url: https://kubernetes.default.svc
|
||||
values:
|
||||
additional: value
|
||||
# v0.2.0+ form - does not require cluster/URL keys
|
||||
# (but they are still supported).
|
||||
- staging: "true"
|
||||
gitRepo: https://kubernetes.default.svc
|
||||
# (...)
|
||||
```
|
||||
|
||||
@@ -74,7 +74,6 @@ spec:
|
||||
files:
|
||||
- path: applicationset/examples/list-generator/list-elementsYaml-example.yaml
|
||||
- list:
|
||||
elements: []
|
||||
elementsYaml: "{{ .key.components | toJson }}"
|
||||
template:
|
||||
metadata:
|
||||
|
||||
@@ -406,7 +406,7 @@ spec:
|
||||
* `sha`: The Git commit SHA for the branch.
|
||||
* `short_sha`: The abbreviated Git commit SHA for the branch (8 chars or the length of the `sha` if it's shorter).
|
||||
* `short_sha_7`: The abbreviated Git commit SHA for the branch (7 chars or the length of the `sha` if it's shorter).
|
||||
* `labels`: A comma-separated list of repository labels.
|
||||
* `labels`: A comma-separated list of repository labels in case of Gitea, repository topics in case of Gitlab and Github. Not supported by Bitbucket Cloud, Bitbucket Server, or Azure DevOps.
|
||||
* `branchNormalized`: The value of `branch` normalized to contain only lowercase alphanumeric characters, '-' or '.'.
|
||||
|
||||
## Pass additional key-value pairs via `values` field
|
||||
|
||||
@@ -103,6 +103,7 @@ generators' templating:
|
||||
- `{{ path.filename }}` becomes `{{ .path.filename }}`
|
||||
- `{{ path.filenameNormalized }}` becomes `{{ .path.filenameNormalized }}`
|
||||
- `{{ path[n] }}` becomes `{{ index .path.segments n }}`
|
||||
- `{{ values }}` if being used in the file generator becomes `{{ .values }}`
|
||||
|
||||
Here is an example:
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ argocd-repo-server [flags]
|
||||
--address string Listen on given address for incoming connections (default "0.0.0.0")
|
||||
--allow-oob-symlinks Allow out-of-bounds symlinks in repositories (not recommended)
|
||||
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
|
||||
--disable-helm-manifest-max-extracted-size Disable maximum size of helm manifest archives when extracted
|
||||
--disable-tls Disable TLS on the gRPC endpoint
|
||||
--helm-manifest-max-extracted-size string Maximum size of helm manifest archives when extracted (default "1G")
|
||||
-h, --help help for argocd-repo-server
|
||||
--logformat string Set the logging format. One of: text|json (default "text")
|
||||
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
|
||||
|
||||
2
go.mod
2
go.mod
@@ -20,7 +20,7 @@ require (
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.5.0
|
||||
github.com/casbin/casbin/v2 v2.71.1
|
||||
github.com/coreos/go-oidc/v3 v3.6.0
|
||||
github.com/cyphar/filepath-securejoin v0.2.3
|
||||
github.com/cyphar/filepath-securejoin v0.2.4
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
|
||||
3
go.sum
3
go.sum
@@ -275,8 +275,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.8.2
|
||||
newTag: v2.8.4
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -150,6 +150,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
|
||||
@@ -36,3 +36,15 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- create # supports triggering jobs from UI
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
verbs:
|
||||
- create # supports triggering workflows from UI
|
||||
|
||||
@@ -18880,7 +18880,7 @@ spec:
|
||||
key: applicationsetcontroller.allowed.scm.providers
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -19156,6 +19156,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -19168,7 +19180,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -19220,7 +19232,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -19439,7 +19451,7 @@ spec:
|
||||
key: controller.kubectl.parallelism.limit
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.8.2
|
||||
newTag: v2.8.4
|
||||
|
||||
@@ -12,7 +12,7 @@ patches:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.8.2
|
||||
newTag: v2.8.4
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -18763,6 +18763,18 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
verbs:
|
||||
- create
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -20117,7 +20129,7 @@ spec:
|
||||
key: applicationsetcontroller.allowed.scm.providers
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -20240,7 +20252,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -20310,7 +20322,7 @@ spec:
|
||||
key: notificationscontroller.log.level
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -20612,6 +20624,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -20624,7 +20648,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -20676,7 +20700,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -20965,7 +20989,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -21211,7 +21235,7 @@ spec:
|
||||
key: controller.kubectl.parallelism.limit
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -1635,7 +1635,7 @@ spec:
|
||||
key: applicationsetcontroller.allowed.scm.providers
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1758,7 +1758,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1828,7 +1828,7 @@ spec:
|
||||
key: notificationscontroller.log.level
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2130,6 +2130,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -2142,7 +2154,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2194,7 +2206,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2483,7 +2495,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2729,7 +2741,7 @@ spec:
|
||||
key: controller.kubectl.parallelism.limit
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -18722,6 +18722,18 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
verbs:
|
||||
- create
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -19218,7 +19230,7 @@ spec:
|
||||
key: applicationsetcontroller.allowed.scm.providers
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -19341,7 +19353,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -19411,7 +19423,7 @@ spec:
|
||||
key: notificationscontroller.log.level
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -19669,6 +19681,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -19681,7 +19705,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -19733,7 +19757,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -20020,7 +20044,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -20266,7 +20290,7 @@ spec:
|
||||
key: controller.kubectl.parallelism.limit
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -736,7 +736,7 @@ spec:
|
||||
key: applicationsetcontroller.allowed.scm.providers
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -859,7 +859,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -929,7 +929,7 @@ spec:
|
||||
key: notificationscontroller.log.level
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1187,6 +1187,18 @@ spec:
|
||||
key: reposerver.streamed.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_GIT_MODULES_ENABLED
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -1199,7 +1211,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1251,7 +1263,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1538,7 +1550,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1784,7 +1796,7 @@ spec:
|
||||
key: controller.kubectl.parallelism.limit
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.8.2
|
||||
image: quay.io/argoproj/argocd:v2.8.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -221,10 +221,6 @@ func NewClient(opts *ClientOptions) (Client, error) {
|
||||
if c.ServerAddr == "" {
|
||||
return nil, errors.New("Argo CD server address unspecified")
|
||||
}
|
||||
if parts := strings.Split(c.ServerAddr, ":"); len(parts) == 1 {
|
||||
// If port is unspecified, assume the most likely port
|
||||
c.ServerAddr += ":443"
|
||||
}
|
||||
// Override auth-token if specified in env variable or CLI flag
|
||||
c.AuthToken = env.StringFromEnv(EnvArgoCDAuthToken, c.AuthToken)
|
||||
if opts.AuthToken != "" {
|
||||
@@ -280,6 +276,10 @@ func NewClient(opts *ClientOptions) (Client, error) {
|
||||
}
|
||||
}
|
||||
if !c.GRPCWeb {
|
||||
if parts := strings.Split(c.ServerAddr, ":"); len(parts) == 1 {
|
||||
// If port is unspecified, assume the most likely port
|
||||
c.ServerAddr += ":443"
|
||||
}
|
||||
// test if we need to set it to true
|
||||
// if a call to grpc failed, then try again with GRPCWeb
|
||||
conn, versionIf, err := c.NewVersionClient()
|
||||
|
||||
@@ -107,6 +107,8 @@ type RepoServerInitConstants struct {
|
||||
AllowOutOfBoundsSymlinks bool
|
||||
StreamedManifestMaxExtractedSize int64
|
||||
StreamedManifestMaxTarSize int64
|
||||
HelmManifestMaxExtractedSize int64
|
||||
DisableHelmManifestMaxExtractedSize bool
|
||||
}
|
||||
|
||||
// NewService returns a new instance of the Manifest service
|
||||
@@ -346,7 +348,7 @@ func (s *Service) runRepoOperation(
|
||||
if source.Helm != nil {
|
||||
helmPassCredentials = source.Helm.PassCredentials
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials)
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2233,7 +2235,7 @@ func (s *Service) GetRevisionChartDetails(ctx context.Context, q *apiclient.Repo
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("helm client error: %v", err)
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false)
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting chart: %v", err)
|
||||
}
|
||||
|
||||
@@ -9,25 +9,28 @@ import (
|
||||
|
||||
healthutil "github.com/argoproj/gitops-engine/pkg/health"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
validation "k8s.io/apimachinery/pkg/api/validation"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
"github.com/argoproj/argo-cd/v2/util/assets"
|
||||
"github.com/argoproj/argo-cd/v2/util/security"
|
||||
"github.com/argoproj/argo-cd/v2/util/settings"
|
||||
)
|
||||
|
||||
//NewHandler creates handler serving to do api/badge endpoint
|
||||
func NewHandler(appClientset versioned.Interface, settingsMrg *settings.SettingsManager, namespace string) http.Handler {
|
||||
return &Handler{appClientset: appClientset, namespace: namespace, settingsMgr: settingsMrg}
|
||||
// NewHandler creates handler serving to do api/badge endpoint
|
||||
func NewHandler(appClientset versioned.Interface, settingsMrg *settings.SettingsManager, namespace string, enabledNamespaces []string) http.Handler {
|
||||
return &Handler{appClientset: appClientset, namespace: namespace, settingsMgr: settingsMrg, enabledNamespaces: enabledNamespaces}
|
||||
}
|
||||
|
||||
//Handler used to get application in order to access health/sync
|
||||
// Handler used to get application in order to access health/sync
|
||||
type Handler struct {
|
||||
namespace string
|
||||
appClientset versioned.Interface
|
||||
settingsMgr *settings.SettingsManager
|
||||
namespace string
|
||||
appClientset versioned.Interface
|
||||
settingsMgr *settings.SettingsManager
|
||||
enabledNamespaces []string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -62,8 +65,8 @@ func replaceFirstGroupSubMatch(re *regexp.Regexp, str string, repl string) strin
|
||||
return result + str[lastIndex:]
|
||||
}
|
||||
|
||||
//ServeHTTP returns badge with health and sync status for application
|
||||
//(or an error badge if wrong query or application name is given)
|
||||
// ServeHTTP returns badge with health and sync status for application
|
||||
// (or an error badge if wrong query or application name is given)
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
health := healthutil.HealthStatusUnknown
|
||||
status := appv1.SyncStatusCodeUnknown
|
||||
@@ -75,21 +78,50 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
enabled = sets.StatusBadgeEnabled
|
||||
}
|
||||
|
||||
//Sample url: http://localhost:8080/api/badge?name=123
|
||||
if name, ok := r.URL.Query()["name"]; ok && enabled {
|
||||
if app, err := h.appClientset.ArgoprojV1alpha1().Applications(h.namespace).Get(context.Background(), name[0], v1.GetOptions{}); err == nil {
|
||||
health = app.Status.Health.Status
|
||||
status = app.Status.Sync.Status
|
||||
if app.Status.OperationState != nil && app.Status.OperationState.SyncResult != nil {
|
||||
revision = app.Status.OperationState.SyncResult.Revision
|
||||
reqNs := ""
|
||||
if ns, ok := r.URL.Query()["namespace"]; ok && enabled {
|
||||
if errs := validation.NameIsDNSSubdomain(strings.ToLower(ns[0]), false); len(errs) == 0 {
|
||||
if security.IsNamespaceEnabled(ns[0], h.namespace, h.enabledNamespaces) {
|
||||
reqNs = ns[0]
|
||||
} else {
|
||||
notFound = true
|
||||
}
|
||||
} else if errors.IsNotFound(err) {
|
||||
notFound = true
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
reqNs = h.namespace
|
||||
}
|
||||
|
||||
//Sample url: http://localhost:8080/api/badge?name=123
|
||||
if name, ok := r.URL.Query()["name"]; ok && enabled && !notFound {
|
||||
if errs := validation.NameIsDNSLabel(strings.ToLower(name[0]), false); len(errs) == 0 {
|
||||
if app, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).Get(context.Background(), name[0], v1.GetOptions{}); err == nil {
|
||||
health = app.Status.Health.Status
|
||||
status = app.Status.Sync.Status
|
||||
if app.Status.OperationState != nil && app.Status.OperationState.SyncResult != nil {
|
||||
revision = app.Status.OperationState.SyncResult.Revision
|
||||
}
|
||||
} else {
|
||||
if errors.IsNotFound(err) {
|
||||
notFound = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
//Sample url: http://localhost:8080/api/badge?project=default
|
||||
if projects, ok := r.URL.Query()["project"]; ok && enabled {
|
||||
if apps, err := h.appClientset.ArgoprojV1alpha1().Applications(h.namespace).List(context.Background(), v1.ListOptions{}); err == nil {
|
||||
if projects, ok := r.URL.Query()["project"]; ok && enabled && !notFound {
|
||||
for _, p := range projects {
|
||||
if errs := validation.NameIsDNSLabel(strings.ToLower(p), false); len(p) > 0 && len(errs) != 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
if apps, err := h.appClientset.ArgoprojV1alpha1().Applications(reqNs).List(context.Background(), v1.ListOptions{}); err == nil {
|
||||
applicationSet := argo.FilterByProjects(apps.Items, projects)
|
||||
for _, a := range applicationSet {
|
||||
if a.Status.Sync.Status != appv1.SyncStatusCodeSynced {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
@@ -41,7 +42,19 @@ var (
|
||||
},
|
||||
}
|
||||
testApp = v1alpha1.Application{
|
||||
ObjectMeta: v1.ObjectMeta{Name: "testApp", Namespace: "default"},
|
||||
ObjectMeta: v1.ObjectMeta{Name: "test-app", Namespace: "default"},
|
||||
Status: v1alpha1.ApplicationStatus{
|
||||
Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeSynced},
|
||||
Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy},
|
||||
OperationState: &v1alpha1.OperationState{
|
||||
SyncResult: &v1alpha1.SyncOperationResult{
|
||||
Revision: "aa29b85",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
testApp2 = v1alpha1.Application{
|
||||
ObjectMeta: v1.ObjectMeta{Name: "test-app", Namespace: "argocd-test"},
|
||||
Status: v1alpha1.ApplicationStatus{
|
||||
Sync: v1alpha1.SyncStatus{Status: v1alpha1.SyncStatusCodeSynced},
|
||||
Health: v1alpha1.HealthStatus{Status: health.HealthStatusHealthy},
|
||||
@@ -53,15 +66,15 @@ var (
|
||||
},
|
||||
}
|
||||
testProject = v1alpha1.AppProject{
|
||||
ObjectMeta: v1.ObjectMeta{Name: "testProject", Namespace: "default"},
|
||||
ObjectMeta: v1.ObjectMeta{Name: "test-project", Namespace: "default"},
|
||||
Spec: v1alpha1.AppProjectSpec{},
|
||||
}
|
||||
)
|
||||
|
||||
func TestHandlerFeatureIsEnabled(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default")
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=testApp", nil)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default", []string{})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -81,6 +94,7 @@ func TestHandlerFeatureIsEnabled(t *testing.T) {
|
||||
func TestHandlerFeatureProjectIsEnabled(t *testing.T) {
|
||||
projectTests := []struct {
|
||||
testApp []*v1alpha1.Application
|
||||
response int
|
||||
apiEndPoint string
|
||||
namespace string
|
||||
health string
|
||||
@@ -89,42 +103,105 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) {
|
||||
statusColor color.RGBA
|
||||
}{
|
||||
{createApplications([]string{"Healthy:Synced", "Healthy:Synced"}, []string{"default", "default"}, "test"),
|
||||
"/api/badge?project=default", "test", "Healthy", "Synced", Green, Green},
|
||||
{createApplications([]string{"Healthy:Synced", "Healthy:OutOfSync"}, []string{"testProject", "testProject"}, "default"),
|
||||
"/api/badge?project=testProject", "default", "Healthy", "OutOfSync", Green, Orange},
|
||||
http.StatusOK, "/api/badge?project=default", "test", "Healthy", "Synced", Green, Green},
|
||||
{createApplications([]string{"Healthy:Synced", "Healthy:OutOfSync"}, []string{"test-project", "test-project"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=test-project", "default", "Healthy", "OutOfSync", Green, Orange},
|
||||
{createApplications([]string{"Healthy:Synced", "Degraded:Synced"}, []string{"default", "default"}, "test"),
|
||||
"/api/badge?project=default", "test", "Degraded", "Synced", Red, Green},
|
||||
{createApplications([]string{"Healthy:Synced", "Degraded:OutOfSync"}, []string{"testProject", "testProject"}, "default"),
|
||||
"/api/badge?project=testProject", "default", "Degraded", "OutOfSync", Red, Orange},
|
||||
{createApplications([]string{"Healthy:Synced", "Healthy:Synced"}, []string{"testProject", "default"}, "test"),
|
||||
"/api/badge?project=default&project=testProject", "test", "Healthy", "Synced", Green, Green},
|
||||
{createApplications([]string{"Healthy:OutOfSync", "Healthy:Synced"}, []string{"testProject", "default"}, "default"),
|
||||
"/api/badge?project=default&project=testProject", "default", "Healthy", "OutOfSync", Green, Orange},
|
||||
{createApplications([]string{"Degraded:Synced", "Healthy:Synced"}, []string{"testProject", "default"}, "test"),
|
||||
"/api/badge?project=default&project=testProject", "test", "Degraded", "Synced", Red, Green},
|
||||
{createApplications([]string{"Degraded:OutOfSync", "Healthy:OutOfSync"}, []string{"testProject", "default"}, "default"),
|
||||
"/api/badge?project=default&project=testProject", "default", "Degraded", "OutOfSync", Red, Orange},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"testProject", "default"}, "default"),
|
||||
"/api/badge?project=", "default", "Unknown", "Unknown", Purple, Purple},
|
||||
http.StatusOK, "/api/badge?project=default", "test", "Degraded", "Synced", Red, Green},
|
||||
{createApplications([]string{"Healthy:Synced", "Degraded:OutOfSync"}, []string{"test-project", "test-project"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=test-project", "default", "Degraded", "OutOfSync", Red, Orange},
|
||||
{createApplications([]string{"Healthy:Synced", "Healthy:Synced"}, []string{"test-project", "default"}, "test"),
|
||||
http.StatusOK, "/api/badge?project=default&project=test-project", "test", "Healthy", "Synced", Green, Green},
|
||||
{createApplications([]string{"Healthy:OutOfSync", "Healthy:Synced"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=default&project=test-project", "default", "Healthy", "OutOfSync", Green, Orange},
|
||||
{createApplications([]string{"Degraded:Synced", "Healthy:Synced"}, []string{"test-project", "default"}, "test"),
|
||||
http.StatusOK, "/api/badge?project=default&project=test-project", "test", "Degraded", "Synced", Red, Green},
|
||||
{createApplications([]string{"Degraded:OutOfSync", "Healthy:OutOfSync"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=default&project=test-project", "default", "Degraded", "OutOfSync", Red, Orange},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=", "default", "Unknown", "Unknown", Purple, Purple},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusBadRequest, "/api/badge?project=test$project", "default", "Unknown", "Unknown", Purple, Purple},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusOK, "/api/badge?project=unknown", "default", "Unknown", "Unknown", Purple, Purple},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusBadRequest, "/api/badge?name=foo_bar", "default", "Unknown", "Unknown", Purple, Purple},
|
||||
{createApplications([]string{"Unknown:Unknown", "Unknown:Unknown"}, []string{"test-project", "default"}, "default"),
|
||||
http.StatusOK, "/api/badge?name=foobar", "default", "Not Found", "", Purple, Purple},
|
||||
}
|
||||
for _, tt := range projectTests {
|
||||
argoCDCm.ObjectMeta.Namespace = tt.namespace
|
||||
argoCDSecret.ObjectMeta.Namespace = tt.namespace
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), tt.namespace)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testProject, tt.testApp[0], tt.testApp[1]), settingsMgr, tt.namespace)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testProject, tt.testApp[0], tt.testApp[1]), settingsMgr, tt.namespace, []string{})
|
||||
rr := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(http.MethodGet, tt.apiEndPoint, nil)
|
||||
assert.NoError(t, err)
|
||||
handler.ServeHTTP(rr, req)
|
||||
require.Equal(t, tt.response, rr.Result().StatusCode)
|
||||
if rr.Result().StatusCode != 400 {
|
||||
assert.Equal(t, "private, no-store", rr.Header().Get("Cache-Control"))
|
||||
assert.Equal(t, "*", rr.Header().Get("Access-Control-Allow-Origin"))
|
||||
response := rr.Body.String()
|
||||
require.Greater(t, len(response), 2)
|
||||
assert.Equal(t, toRGBString(tt.healthColor), leftRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, toRGBString(tt.statusColor), rightRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, tt.health, leftTextPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, tt.status, rightTextPattern.FindStringSubmatch(response)[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlerNamespacesIsEnabled(t *testing.T) {
|
||||
t.Run("Application in allowed namespace", func(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp2), settingsMgr, "default", []string{"argocd-test"})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=argocd-test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, "private, no-store", rr.Header().Get("Cache-Control"))
|
||||
assert.Equal(t, "*", rr.Header().Get("Access-Control-Allow-Origin"))
|
||||
response := rr.Body.String()
|
||||
assert.Equal(t, toRGBString(tt.healthColor), leftRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, toRGBString(tt.statusColor), rightRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, tt.health, leftTextPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, tt.status, rightTextPattern.FindStringSubmatch(response)[1])
|
||||
|
||||
}
|
||||
response := rr.Body.String()
|
||||
assert.Equal(t, toRGBString(Green), leftRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, toRGBString(Green), rightRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, "Healthy", leftTextPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, "Synced", rightTextPattern.FindStringSubmatch(response)[1])
|
||||
assert.NotContains(t, response, "(aa29b85)")
|
||||
})
|
||||
|
||||
t.Run("Application in disallowed namespace", func(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp2), settingsMgr, "default", []string{"argocd-test"})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube-system", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Result().StatusCode)
|
||||
response := rr.Body.String()
|
||||
assert.Equal(t, toRGBString(Purple), leftRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, toRGBString(Purple), rightRectColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, "Not Found", leftTextPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, "", rightTextPattern.FindStringSubmatch(response)[1])
|
||||
|
||||
})
|
||||
|
||||
t.Run("Request with illegal namespace", func(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp2), settingsMgr, "default", []string{"argocd-test"})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube()system", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Result().StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
func createApplicationFeatureProjectIsEnabled(healthStatus health.HealthStatusCode, syncStatus v1alpha1.SyncStatusCode, appName, projectName, namespace string) *v1alpha1.Application {
|
||||
@@ -176,8 +253,8 @@ func createApplications(appCombo, projectName []string, namespace string) []*v1a
|
||||
}
|
||||
func TestHandlerFeatureIsEnabledRevisionIsEnabled(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default")
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=testApp&revision=true", nil)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default", []string{})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -199,8 +276,8 @@ func TestHandlerRevisionIsEnabledNoOperationState(t *testing.T) {
|
||||
app.Status.OperationState = nil
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default")
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=testApp&revision=true", nil)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -222,8 +299,8 @@ func TestHandlerRevisionIsEnabledShortCommitSHA(t *testing.T) {
|
||||
app.Status.OperationState.SyncResult.Revision = "abc"
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default")
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=testApp&revision=true", nil)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -239,8 +316,8 @@ func TestHandlerFeatureIsDisabled(t *testing.T) {
|
||||
delete(argoCDCmDisabled.Data, "statusbadge.enabled")
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCmDisabled, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default")
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=testApp", nil)
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(&testApp), settingsMgr, "default", []string{})
|
||||
req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
@@ -951,7 +951,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
Handler: &handlerSwitcher{
|
||||
handler: mux,
|
||||
urlToHandler: map[string]http.Handler{
|
||||
"/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace),
|
||||
"/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace, a.ApplicationNamespaces),
|
||||
common.LogoutEndpoint: logout.NewHandler(a.AppClientset, a.settingsMgr, a.sessionMgr, a.ArgoCDServerOpts.RootPath, a.ArgoCDServerOpts.BaseHRef, a.Namespace),
|
||||
},
|
||||
contentTypeToHandler: map[string]http.Handler{
|
||||
|
||||
@@ -1754,6 +1754,40 @@ func TestCompareOptionIgnoreExtraneous(t *testing.T) {
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced))
|
||||
}
|
||||
|
||||
func TestSourceNamespaceCanBeMigratedToManagedNamespaceWithoutBeingPrunedOrOutOfSync(t *testing.T) {
|
||||
Given(t).
|
||||
Prune(true).
|
||||
Path("guestbook-with-plain-namespace-manifest").
|
||||
When().
|
||||
PatchFile("guestbook-ui-namespace.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/name", "value": "%s"}]`, DeploymentNamespace())).
|
||||
CreateApp().
|
||||
Sync().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
When().
|
||||
PatchApp(`[{
|
||||
"op": "add",
|
||||
"path": "/spec/syncPolicy",
|
||||
"value": { "prune": true, "syncOptions": ["PrunePropagationPolicy=foreground"], "managedNamespaceMetadata": { "labels": { "foo": "bar" } } }
|
||||
}]`).
|
||||
Sync().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
assert.Equal(t, &ManagedNamespaceMetadata{Labels: map[string]string{"foo": "bar"}}, app.Spec.SyncPolicy.ManagedNamespaceMetadata)
|
||||
}).
|
||||
When().
|
||||
DeleteFile("guestbook-ui-namespace.yaml").
|
||||
Refresh(RefreshTypeHard).
|
||||
Sync().
|
||||
Wait().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced))
|
||||
}
|
||||
|
||||
func TestSelfManagedApps(t *testing.T) {
|
||||
|
||||
Given(t).
|
||||
|
||||
@@ -48,7 +48,6 @@ var (
|
||||
Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate,
|
||||
},
|
||||
}
|
||||
LabelKeyAppSetInstance = "argocd.argoproj.io/application-set-name"
|
||||
)
|
||||
|
||||
func TestSimpleListGeneratorExternalNamespace(t *testing.T) {
|
||||
@@ -59,11 +58,8 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) {
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator-external",
|
||||
},
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -135,15 +131,13 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-list-generator-external",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
appset.Spec.Template.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-list-generator-external",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})).
|
||||
|
||||
@@ -164,11 +158,8 @@ func TestSimpleListGenerator(t *testing.T) {
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
},
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -235,10 +226,7 @@ func TestSimpleListGenerator(t *testing.T) {
|
||||
And(func() {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
@@ -265,9 +253,6 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) {
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -334,10 +319,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) {
|
||||
And(func() {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
@@ -364,9 +346,6 @@ func TestRenderHelmValuesObject(t *testing.T) {
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "test-values-object",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -443,9 +422,6 @@ func TestSyncPolicyCreateUpdate(t *testing.T) {
|
||||
Name: "my-cluster-guestbook-sync-policy-create-update",
|
||||
Namespace: utils.ArgoCDNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "sync-policy-create-update",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -515,15 +491,13 @@ func TestSyncPolicyCreateUpdate(t *testing.T) {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "sync-policy-create-update",
|
||||
"label-key": "label-value",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
appset.Spec.Template.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "sync-policy-create-update",
|
||||
"label-key": "label-value",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
applicationsSyncPolicy := argov1alpha1.ApplicationsSyncPolicyCreateUpdate
|
||||
appset.Spec.SyncPolicy = &argov1alpha1.ApplicationSetSyncPolicy{
|
||||
@@ -558,9 +532,6 @@ func TestSyncPolicyCreateDelete(t *testing.T) {
|
||||
Name: "my-cluster-guestbook-sync-policy-create-delete",
|
||||
Namespace: utils.ArgoCDNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "sync-policy-create-delete",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -661,9 +632,6 @@ func TestSyncPolicyCreateOnly(t *testing.T) {
|
||||
Name: "my-cluster-guestbook-sync-policy-create-only",
|
||||
Namespace: utils.ArgoCDNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "sync-policy-create-only",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -764,9 +732,6 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -848,10 +813,7 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -879,9 +841,6 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -964,10 +923,7 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -996,9 +952,6 @@ func TestSimpleGitFilesGenerator(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1079,10 +1032,7 @@ func TestSimpleGitFilesGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -1111,9 +1061,6 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1195,10 +1142,7 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -1557,9 +1501,6 @@ func TestSimpleSCMProviderGenerator(t *testing.T) {
|
||||
Name: "argo-cd-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-scm-provider-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1634,9 +1575,6 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) {
|
||||
Name: "argo-cd-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-scm-provider-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1706,9 +1644,6 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) {
|
||||
Name: "argo-cd-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-scm-provider-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1784,9 +1719,6 @@ func TestCustomApplicationFinalizers(t *testing.T) {
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1853,9 +1785,6 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) {
|
||||
Name: "my-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io/background"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-list-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -1963,9 +1892,6 @@ func TestSimplePullRequestGenerator(t *testing.T) {
|
||||
Name: "guestbook-1",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-pull-request-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -2043,10 +1969,7 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) {
|
||||
Name: "guestbook-1",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
"app": "preview",
|
||||
LabelKeyAppSetInstance: "simple-pull-request-generator",
|
||||
},
|
||||
Labels: map[string]string{"app": "preview"},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -2122,8 +2045,7 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) {
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
"app": "preview",
|
||||
LabelKeyAppSetInstance: "simple-pull-request-generator",
|
||||
"app": "preview",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -2206,9 +2128,6 @@ func TestGitGeneratorPrivateRepo(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator-private",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -2284,9 +2203,6 @@ func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) {
|
||||
Name: name,
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-git-generator-private",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
|
||||
@@ -24,11 +24,8 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) {
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -104,15 +101,13 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
appset.Spec.Template.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})).
|
||||
|
||||
@@ -132,9 +127,6 @@ func TestSimpleClusterGenerator(t *testing.T) {
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -206,10 +198,7 @@ func TestSimpleClusterGenerator(t *testing.T) {
|
||||
And(func() {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
@@ -231,9 +220,6 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) {
|
||||
Name: "in-cluster-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "in-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -326,10 +312,7 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) {
|
||||
And(func() {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "in-cluster-generator",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
@@ -354,9 +337,6 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) {
|
||||
Name: "{{name}}-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -439,9 +419,6 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) {
|
||||
Name: "{{name}}-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
|
||||
@@ -25,11 +25,8 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) {
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: utils.ArgoCDExternalNamespace,
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -113,15 +110,13 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
appset.Spec.Template.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
}).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})).
|
||||
|
||||
@@ -141,9 +136,6 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) {
|
||||
Name: "cluster1-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -223,10 +215,7 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) {
|
||||
And(func() {
|
||||
expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
"label-key": "label-value",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
}).
|
||||
Update(func(appset *v1alpha1.ApplicationSet) {
|
||||
appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
@@ -249,9 +238,6 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) {
|
||||
Name: "{{name}}-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -347,9 +333,6 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing.
|
||||
Name: "{{name}}-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -447,9 +430,6 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te
|
||||
Name: "{{name}}-guestbook",
|
||||
Namespace: fixture.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "simple-cluster-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
|
||||
@@ -26,9 +26,6 @@ func TestListMatrixGenerator(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", cluster, name),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "matrix-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -128,10 +125,7 @@ func TestListMatrixGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "matrix-generator",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -156,9 +150,6 @@ func TestClusterMatrixGenerator(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", cluster, name),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "matrix-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -261,10 +252,7 @@ func TestClusterMatrixGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "matrix-generator",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -289,9 +277,6 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", cluster, name),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "matrix-generator-nested-matrix",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -443,9 +428,6 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", name, nameSuffix),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "matrix-generator-nested-merge",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
|
||||
@@ -27,9 +27,6 @@ func TestListMergeGenerator(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", name, nameSuffix),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "merge-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -125,10 +122,7 @@ func TestListMergeGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "merge-generator",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -153,9 +147,6 @@ func TestClusterMergeGenerator(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s-%s", cluster, name, nameSuffix),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "merge-generator",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
@@ -276,10 +267,7 @@ func TestClusterMergeGenerator(t *testing.T) {
|
||||
for _, expectedApp := range expectedAppsNewNamespace {
|
||||
expectedAppNewMetadata := expectedApp.DeepCopy()
|
||||
expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
|
||||
"label-key": "label-value",
|
||||
LabelKeyAppSetInstance: "merge-generator",
|
||||
}
|
||||
expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
|
||||
expectedAppsNewMetadata = append(expectedAppsNewMetadata, *expectedAppNewMetadata)
|
||||
}
|
||||
}).
|
||||
@@ -304,9 +292,6 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) {
|
||||
Name: fmt.Sprintf("%s-%s", name, nameSuffix),
|
||||
Namespace: utils.TestNamespace(),
|
||||
Finalizers: []string{"resources-finalizer.argocd.argoproj.io"},
|
||||
Labels: map[string]string{
|
||||
LabelKeyAppSetInstance: "merge-generator-nested-merge",
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
Project: "default",
|
||||
|
||||
23
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-deployment.yaml
vendored
Normal file
23
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-deployment.yaml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: guestbook-ui
|
||||
labels:
|
||||
test: "true"
|
||||
spec:
|
||||
replicas: 0
|
||||
revisionHistoryLimit: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook-ui
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
9
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-namespace.yaml
vendored
Normal file
9
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-namespace.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: guestbook-ui-with-namespace-manifest
|
||||
labels:
|
||||
test: "true"
|
||||
annotations:
|
||||
foo: bar
|
||||
something: else
|
||||
10
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-svc.yaml
vendored
Normal file
10
test/e2e/testdata/guestbook-with-plain-namespace-manifest/guestbook-ui-svc.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: guestbook-ui
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
selector:
|
||||
app: guestbook-ui
|
||||
@@ -32,7 +32,7 @@ export const RevisionMetadataRows = (props: {applicationName: string; applicatio
|
||||
<div className='columns small-9'>{m.description}</div>
|
||||
</div>
|
||||
)}
|
||||
{m.maintainers.length > 0 && (
|
||||
{m.maintainers && m.maintainers.length > 0 && (
|
||||
<div className='row'>
|
||||
<div className='columns small-3'>Maintainers:</div>
|
||||
<div className='columns small-9'>{m.maintainers.join(', ')}</div>
|
||||
|
||||
@@ -669,7 +669,7 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
|
||||
<div className='columns small-9'>{m.description}</div>
|
||||
</div>
|
||||
)}
|
||||
{m.maintainers.length > 0 && (
|
||||
{m.maintainers && m.maintainers.length > 0 && (
|
||||
<div className='row white-box__details-row'>
|
||||
<div className='columns small-3'>Maintainers:</div>
|
||||
<div className='columns small-9'>{m.maintainers.join(', ')}</div>
|
||||
|
||||
@@ -165,7 +165,7 @@ func (rt *resourceTracking) BuildAppInstanceValue(value AppInstanceValue) string
|
||||
//ParseAppInstanceValue parse resource tracking id from format <application-name>:<group>/<kind>:<namespace>/<name> to struct
|
||||
func (rt *resourceTracking) ParseAppInstanceValue(value string) (*AppInstanceValue, error) {
|
||||
var appInstanceValue AppInstanceValue
|
||||
parts := strings.Split(value, ":")
|
||||
parts := strings.SplitN(value, ":", 3)
|
||||
appInstanceValue.ApplicationName = parts[0]
|
||||
if len(parts) != 3 {
|
||||
return nil, WrongResourceTrackingFormat
|
||||
|
||||
@@ -89,6 +89,19 @@ func TestParseAppInstanceValue(t *testing.T) {
|
||||
assert.Equal(t, appInstanceValue.Name, "<name>")
|
||||
}
|
||||
|
||||
func TestParseAppInstanceValueColon(t *testing.T) {
|
||||
resourceTracking := NewResourceTracking()
|
||||
appInstanceValue, err := resourceTracking.ParseAppInstanceValue("app:<group>/<kind>:<namespace>/<name>:<colon>")
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
assert.Equal(t, appInstanceValue.ApplicationName, "app")
|
||||
assert.Equal(t, appInstanceValue.Group, "<group>")
|
||||
assert.Equal(t, appInstanceValue.Kind, "<kind>")
|
||||
assert.Equal(t, appInstanceValue.Namespace, "<namespace>")
|
||||
assert.Equal(t, appInstanceValue.Name, "<name>:<colon>")
|
||||
}
|
||||
|
||||
func TestParseAppInstanceValueWrongFormat1(t *testing.T) {
|
||||
resourceTracking := NewResourceTracking()
|
||||
_, err := resourceTracking.ParseAppInstanceValue("app")
|
||||
|
||||
@@ -345,6 +345,9 @@ func clusterToSecret(c *appv1.Cluster, secret *apiv1.Secret) error {
|
||||
secret.Data = data
|
||||
|
||||
secret.Labels = c.Labels
|
||||
if c.Annotations != nil && c.Annotations[apiv1.LastAppliedConfigAnnotation] != "" {
|
||||
return status.Errorf(codes.InvalidArgument, "annotation %s cannot be set", apiv1.LastAppliedConfigAnnotation)
|
||||
}
|
||||
secret.Annotations = c.Annotations
|
||||
|
||||
if secret.Annotations == nil {
|
||||
@@ -403,6 +406,8 @@ func SecretToCluster(s *apiv1.Secret) (*appv1.Cluster, error) {
|
||||
annotations := map[string]string{}
|
||||
if s.Annotations != nil {
|
||||
annotations = collections.CopyStringMap(s.Annotations)
|
||||
// delete system annotations
|
||||
delete(annotations, apiv1.LastAppliedConfigAnnotation)
|
||||
delete(annotations, common.AnnotationKeyManagedBy)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
@@ -56,6 +58,24 @@ func Test_secretToCluster(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_secretToCluster_LastAppliedConfigurationDropped(t *testing.T) {
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mycluster",
|
||||
Namespace: fakeNamespace,
|
||||
Annotations: map[string]string{v1.LastAppliedConfigAnnotation: "val2"},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"name": []byte("test"),
|
||||
"server": []byte("http://mycluster"),
|
||||
"config": []byte("{\"username\":\"foo\"}"),
|
||||
},
|
||||
}
|
||||
cluster, err := SecretToCluster(secret)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, cluster.Annotations, 0)
|
||||
}
|
||||
|
||||
func TestClusterToSecret(t *testing.T) {
|
||||
cluster := &appv1.Cluster{
|
||||
Server: "server",
|
||||
@@ -78,6 +98,21 @@ func TestClusterToSecret(t *testing.T) {
|
||||
assert.Equal(t, cluster.Labels, s.Labels)
|
||||
}
|
||||
|
||||
func TestClusterToSecret_LastAppliedConfigurationRejected(t *testing.T) {
|
||||
cluster := &appv1.Cluster{
|
||||
Server: "server",
|
||||
Annotations: map[string]string{v1.LastAppliedConfigAnnotation: "val2"},
|
||||
Name: "test",
|
||||
Config: v1alpha1.ClusterConfig{},
|
||||
Project: "project",
|
||||
Namespaces: []string{"default"},
|
||||
}
|
||||
s := &v1.Secret{}
|
||||
err := clusterToSecret(cluster, s)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, codes.InvalidArgument, status.Code(err))
|
||||
}
|
||||
|
||||
func Test_secretToCluster_NoConfig(t *testing.T) {
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
executil "github.com/argoproj/argo-cd/v2/util/exec"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -25,7 +26,6 @@ import (
|
||||
"oras.land/oras-go/v2/registry/remote/auth"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/cache"
|
||||
executil "github.com/argoproj/argo-cd/v2/util/exec"
|
||||
argoio "github.com/argoproj/argo-cd/v2/util/io"
|
||||
"github.com/argoproj/argo-cd/v2/util/io/files"
|
||||
"github.com/argoproj/argo-cd/v2/util/proxy"
|
||||
@@ -52,7 +52,7 @@ type indexCache interface {
|
||||
|
||||
type Client interface {
|
||||
CleanChartCache(chart string, version string) error
|
||||
ExtractChart(chart string, version string, passCredentials bool) (string, argoio.Closer, error)
|
||||
ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error)
|
||||
GetIndex(noCache bool) (*Index, error)
|
||||
GetTags(chart string, noCache bool) (*TagsList, error)
|
||||
TestHelmOCI() (bool, error)
|
||||
@@ -122,7 +122,21 @@ func (c *nativeHelmChart) CleanChartCache(chart string, version string) error {
|
||||
return os.RemoveAll(cachePath)
|
||||
}
|
||||
|
||||
func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool) (string, argoio.Closer, error) {
|
||||
func untarChart(tempDir string, cachedChartPath string, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) error {
|
||||
if disableManifestMaxExtractedSize {
|
||||
cmd := exec.Command("tar", "-zxvf", cachedChartPath)
|
||||
cmd.Dir = tempDir
|
||||
_, err := executil.Run(cmd)
|
||||
return err
|
||||
}
|
||||
reader, err := os.Open(cachedChartPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return files.Untgz(tempDir, reader, manifestMaxExtractedSize, false)
|
||||
}
|
||||
|
||||
func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) {
|
||||
// always use Helm V3 since we don't have chart content to determine correct Helm version
|
||||
helmCmd, err := NewCmdWithVersion("", HelmV3, c.enableOci, c.proxy)
|
||||
|
||||
@@ -196,15 +210,14 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredent
|
||||
if len(infos) != 1 {
|
||||
return "", nil, fmt.Errorf("expected 1 file, found %v", len(infos))
|
||||
}
|
||||
|
||||
err = os.Rename(filepath.Join(tempDest, infos[0].Name()), cachedChartPath)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command("tar", "-zxvf", cachedChartPath)
|
||||
cmd.Dir = tempDir
|
||||
_, err = executil.Run(cmd)
|
||||
err = untarChart(tempDir, cachedChartPath, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(tempDir)
|
||||
return "", nil, err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -71,7 +72,7 @@ func TestIndex(t *testing.T) {
|
||||
|
||||
func Test_nativeHelmChart_ExtractChart(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "")
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false)
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
|
||||
assert.NoError(t, err)
|
||||
defer io.Close(closer)
|
||||
info, err := os.Stat(path)
|
||||
@@ -79,9 +80,15 @@ func Test_nativeHelmChart_ExtractChart(t *testing.T) {
|
||||
assert.True(t, info.IsDir())
|
||||
}
|
||||
|
||||
func Test_nativeHelmChart_ExtractChartWithLimiter(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "")
|
||||
_, _, err := client.ExtractChart("argo-cd", "0.7.1", false, 100, false)
|
||||
assert.Error(t, err, "error while iterating on tar reader: unexpected EOF")
|
||||
}
|
||||
|
||||
func Test_nativeHelmChart_ExtractChart_insecure(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{InsecureSkipVerify: true}, false, "")
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false)
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
|
||||
assert.NoError(t, err)
|
||||
defer io.Close(closer)
|
||||
info, err := os.Stat(path)
|
||||
|
||||
@@ -29,7 +29,7 @@ func (_m *Client) CleanChartCache(chart string, version string) error {
|
||||
}
|
||||
|
||||
// ExtractChart provides a mock function with given fields: chart, version
|
||||
func (_m *Client) ExtractChart(chart string, version string, passCredentials bool) (string, io.Closer, error) {
|
||||
func (_m *Client) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error) {
|
||||
ret := _m.Called(chart, version)
|
||||
|
||||
var r0 string
|
||||
|
||||
Reference in New Issue
Block a user