mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-21 01:58:46 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03b17e0233 | ||
|
|
d5909f7168 | ||
|
|
7d0d665747 | ||
|
|
834a102c09 | ||
|
|
4bcd8cf733 | ||
|
|
a069c602dc | ||
|
|
e309ceebac | ||
|
|
4a7f0bbfd8 | ||
|
|
28a54bf2a2 | ||
|
|
e209426a7e | ||
|
|
06a95f86ce | ||
|
|
122ecefc3a | ||
|
|
004d73ce92 | ||
|
|
81e1a58328 | ||
|
|
84f949ff17 | ||
|
|
a7e7f32a0f |
@@ -27,6 +27,8 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/cli"
|
||||
"github.com/argoproj/argo-cd/v2/util/io"
|
||||
"github.com/argoproj/argo-cd/v2/util/localconfig"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func testAPI(clientOpts *argoapi.ClientOptions) error {
|
||||
@@ -43,6 +45,13 @@ func testAPI(clientOpts *argoapi.ClientOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func retrieveContextIfChanged(contextFlag *flag.Flag) string {
|
||||
if contextFlag != nil && contextFlag.Changed {
|
||||
return contextFlag.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InitCommand allows executing command in a headless mode: on the fly starts Argo CD API server and
|
||||
// changes provided client options to use started API server port
|
||||
func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *int) *cobra.Command {
|
||||
@@ -108,10 +117,7 @@ func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *in
|
||||
return err
|
||||
}
|
||||
|
||||
var context string
|
||||
if cmd.Flag("context").Changed {
|
||||
context = cmd.Flag("context").Value.String()
|
||||
}
|
||||
context := retrieveContextIfChanged(cmd.Flag("context"))
|
||||
|
||||
mr, err := miniredis.Run()
|
||||
if err != nil {
|
||||
|
||||
80
cmd/argocd/commands/headless/headless_test.go
Normal file
80
cmd/argocd/commands/headless/headless_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package headless
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type StringFlag struct {
|
||||
// The exact value provided on the flag
|
||||
value string
|
||||
}
|
||||
|
||||
func (f StringFlag) String() string {
|
||||
return f.value
|
||||
}
|
||||
|
||||
func (f *StringFlag) Set(value string) error {
|
||||
f.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *StringFlag) Type() string {
|
||||
return "string"
|
||||
}
|
||||
|
||||
func Test_FlagContextNotChanged(t *testing.T) {
|
||||
res := retrieveContextIfChanged(&flag.Flag{
|
||||
Name: "",
|
||||
Shorthand: "",
|
||||
Usage: "",
|
||||
Value: &StringFlag{value: "test"},
|
||||
DefValue: "",
|
||||
Changed: false,
|
||||
NoOptDefVal: "",
|
||||
Deprecated: "",
|
||||
Hidden: false,
|
||||
ShorthandDeprecated: "",
|
||||
Annotations: nil,
|
||||
})
|
||||
|
||||
assert.Equal(t, "", res)
|
||||
}
|
||||
|
||||
func Test_FlagContextChanged(t *testing.T) {
|
||||
res := retrieveContextIfChanged(&flag.Flag{
|
||||
Name: "",
|
||||
Shorthand: "",
|
||||
Usage: "",
|
||||
Value: &StringFlag{value: "test"},
|
||||
DefValue: "",
|
||||
Changed: true,
|
||||
NoOptDefVal: "",
|
||||
Deprecated: "",
|
||||
Hidden: false,
|
||||
ShorthandDeprecated: "",
|
||||
Annotations: nil,
|
||||
})
|
||||
|
||||
assert.Equal(t, "test", res)
|
||||
}
|
||||
|
||||
func Test_FlagContextNil(t *testing.T) {
|
||||
res := retrieveContextIfChanged(&flag.Flag{
|
||||
Name: "",
|
||||
Shorthand: "",
|
||||
Usage: "",
|
||||
Value: nil,
|
||||
DefValue: "",
|
||||
Changed: false,
|
||||
NoOptDefVal: "",
|
||||
Deprecated: "",
|
||||
Hidden: false,
|
||||
ShorthandDeprecated: "",
|
||||
Annotations: nil,
|
||||
})
|
||||
|
||||
assert.Equal(t, "", res)
|
||||
}
|
||||
@@ -1102,7 +1102,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
||||
}
|
||||
|
||||
ctrl.setOperationState(app, state)
|
||||
if state.Phase.Completed() && !app.Operation.Sync.DryRun {
|
||||
if state.Phase.Completed() && (app.Operation.Sync != nil && !app.Operation.Sync.DryRun) {
|
||||
// if we just completed an operation, force a refresh so that UI will report up-to-date
|
||||
// sync/health information
|
||||
if _, err := cache.MetaNamespaceKeyFunc(app); err == nil {
|
||||
|
||||
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible
|
||||
github.com/alicebob/miniredis/v2 v2.14.2
|
||||
github.com/argoproj/gitops-engine v0.5.1
|
||||
github.com/argoproj/gitops-engine v0.5.2
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
|
||||
github.com/bombsimon/logrusr v1.0.0
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.0.2
|
||||
|
||||
4
go.sum
4
go.sum
@@ -103,8 +103,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/argoproj/gitops-engine v0.5.1 h1:kIPvoYFRvDA+3Tz2aEjwRBVGIgcuZ+HIzuHcRmvxo54=
|
||||
github.com/argoproj/gitops-engine v0.5.1/go.mod h1:K2RYpGXh11VdFwDksS23SyFTOJaPcsF+MVJ/FHlqEOE=
|
||||
github.com/argoproj/gitops-engine v0.5.2 h1:UQ2ajVyUPCSgFyqidzlTXddh/Xf6cE3I0s9uu92BoJg=
|
||||
github.com/argoproj/gitops-engine v0.5.2/go.mod h1:K2RYpGXh11VdFwDksS23SyFTOJaPcsF+MVJ/FHlqEOE=
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.2.0
|
||||
newTag: v2.2.2
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -3018,7 +3018,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -3067,7 +3067,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/argocd
|
||||
@@ -3232,7 +3232,7 @@ spec:
|
||||
key: controller.default.cache.expiration
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -11,4 +11,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.2.0
|
||||
newTag: v2.2.2
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.2.0
|
||||
newTag: v2.2.2
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/dex
|
||||
|
||||
@@ -3709,7 +3709,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3926,7 +3926,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -3975,7 +3975,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/argocd
|
||||
@@ -4202,7 +4202,7 @@ spec:
|
||||
key: server.http.cookie.maxnumber
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -4398,7 +4398,7 @@ spec:
|
||||
key: controller.default.cache.expiration
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1068,7 +1068,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -1285,7 +1285,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1334,7 +1334,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/argocd
|
||||
@@ -1561,7 +1561,7 @@ spec:
|
||||
key: server.http.cookie.maxnumber
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1757,7 +1757,7 @@ spec:
|
||||
key: controller.default.cache.expiration
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -3079,7 +3079,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3260,7 +3260,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -3309,7 +3309,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/argocd
|
||||
@@ -3532,7 +3532,7 @@ spec:
|
||||
key: server.http.cookie.maxnumber
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3722,7 +3722,7 @@ spec:
|
||||
key: controller.default.cache.expiration
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -438,7 +438,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -619,7 +619,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -668,7 +668,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/argocd
|
||||
@@ -891,7 +891,7 @@ spec:
|
||||
key: server.http.cookie.maxnumber
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1081,7 +1081,7 @@ spec:
|
||||
key: controller.default.cache.expiration
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.2.0
|
||||
image: quay.io/argoproj/argocd:v2.2.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1569,8 +1569,8 @@ func validatePolicy(proj string, role string, policy string) error {
|
||||
}
|
||||
// resource
|
||||
resource := strings.Trim(policyComponents[2], " ")
|
||||
if resource != "applications" {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', not '%s'", policy, resource)
|
||||
if resource != "applications" && resource != "repositories" && resource != "clusters" {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', 'repositories' or 'clusters', not '%s'", policy, resource)
|
||||
}
|
||||
// action
|
||||
action := strings.Trim(policyComponents[3], " ")
|
||||
@@ -1579,7 +1579,7 @@ func validatePolicy(proj string, role string, policy string) error {
|
||||
}
|
||||
// object
|
||||
object := strings.Trim(policyComponents[4], " ")
|
||||
objectRegexp, err := regexp.Compile(fmt.Sprintf(`^%s/[*\w-.]+$`, proj))
|
||||
objectRegexp, err := regexp.Compile(fmt.Sprintf(`^%s/[*\w-.]+$`, regexp.QuoteMeta(proj)))
|
||||
if err != nil || !objectRegexp.MatchString(object) {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': object must be of form '%s/*' or '%s/<APPNAME>', not '%s'", policy, proj, proj, object)
|
||||
}
|
||||
|
||||
@@ -2561,3 +2561,22 @@ func TestOrphanedResourcesMonitorSettings_IsWarn(t *testing.T) {
|
||||
settings.Warn = pointer.BoolPtr(true)
|
||||
assert.True(t, settings.IsWarn())
|
||||
}
|
||||
|
||||
func Test_validatePolicy_projIsNotRegex(t *testing.T) {
|
||||
// Make sure the "." in "some.project" isn't treated as the regex wildcard.
|
||||
err := validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some-project/*, allow")
|
||||
assert.Error(t, err)
|
||||
|
||||
err = validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some.project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_validatePolicy_ValidResource(t *testing.T) {
|
||||
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ package cluster
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
|
||||
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
servercache "github.com/argoproj/argo-cd/v2/server/cache"
|
||||
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
"github.com/argoproj/argo-cd/v2/util/clusterauth"
|
||||
"github.com/argoproj/argo-cd/v2/util/db"
|
||||
"github.com/argoproj/argo-cd/v2/util/rbac"
|
||||
@@ -181,6 +181,15 @@ var clusterFieldsByPath = map[string]func(updated *appv1.Cluster, existing *appv
|
||||
"clusterResources": func(updated *appv1.Cluster, existing *appv1.Cluster) {
|
||||
updated.ClusterResources = existing.ClusterResources
|
||||
},
|
||||
"labels": func(updated *appv1.Cluster, existing *appv1.Cluster) {
|
||||
updated.Labels = existing.Labels
|
||||
},
|
||||
"annotations": func(updated *appv1.Cluster, existing *appv1.Cluster) {
|
||||
updated.Annotations = existing.Annotations
|
||||
},
|
||||
"project": func(updated *appv1.Cluster, existing *appv1.Cluster) {
|
||||
updated.Project = existing.Project
|
||||
},
|
||||
}
|
||||
|
||||
// Update updates a cluster
|
||||
@@ -197,9 +206,12 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (*
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(c.Project, q.Cluster.Server)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// verify that user can do update inside project where cluster will be located
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(q.Cluster.Project, q.Cluster.Server)); err != nil {
|
||||
return nil, err
|
||||
|
||||
if len(q.UpdatedFields) == 0 || sets.NewString(q.UpdatedFields...).Has("project") {
|
||||
// verify that user can do update inside project where cluster will be located
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(q.Cluster.Project, q.Cluster.Server)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(q.UpdatedFields) != 0 {
|
||||
|
||||
@@ -109,4 +109,52 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) {
|
||||
assert.Equal(t, updated.Name, "minikube")
|
||||
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
|
||||
assert.Equal(t, *updated.Shard, int64(1))
|
||||
|
||||
labelEnv := map[string]string{
|
||||
"env": "qa",
|
||||
}
|
||||
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
|
||||
Cluster: &v1alpha1.Cluster{
|
||||
Server: "https://127.0.0.1",
|
||||
Labels: labelEnv,
|
||||
},
|
||||
UpdatedFields: []string{"labels"},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, updated.Name, "minikube")
|
||||
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
|
||||
assert.Equal(t, updated.Labels, labelEnv)
|
||||
|
||||
annotationEnv := map[string]string{
|
||||
"env": "qa",
|
||||
}
|
||||
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
|
||||
Cluster: &v1alpha1.Cluster{
|
||||
Server: "https://127.0.0.1",
|
||||
Annotations: annotationEnv,
|
||||
},
|
||||
UpdatedFields: []string{"annotations"},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, updated.Name, "minikube")
|
||||
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
|
||||
assert.Equal(t, updated.Annotations, annotationEnv)
|
||||
|
||||
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
|
||||
Cluster: &v1alpha1.Cluster{
|
||||
Server: "https://127.0.0.1",
|
||||
Project: "new-project",
|
||||
},
|
||||
UpdatedFields: []string{"project"},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, updated.Name, "minikube")
|
||||
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
|
||||
assert.Equal(t, updated.Project, "new-project")
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...interface{}) *v1alph
|
||||
if res, ok := rvals[1].(string); ok {
|
||||
if obj, ok := rvals[3].(string); ok {
|
||||
switch res {
|
||||
case ResourceApplications:
|
||||
if objSplit := strings.Split(obj, "/"); len(objSplit) == 2 {
|
||||
case ResourceApplications, ResourceRepositories, ResourceClusters:
|
||||
if objSplit := strings.Split(obj, "/"); len(objSplit) >= 2 {
|
||||
return getProjectByName(objSplit[0])
|
||||
}
|
||||
case ResourceProjects:
|
||||
|
||||
@@ -149,3 +149,13 @@ func TestGetScopes_CustomScopes(t *testing.T) {
|
||||
scopes := rbacEnforcer.GetScopes()
|
||||
assert.Equal(t, scopes, customScopes)
|
||||
}
|
||||
|
||||
func Test_getProjectFromRequest(t *testing.T) {
|
||||
fp := newFakeProj()
|
||||
projLister := test.NewFakeProjLister(fp)
|
||||
|
||||
rbacEnforcer := NewRBACPolicyEnforcer(nil, projLister)
|
||||
project := rbacEnforcer.getProjectFromRequest("", "repositories", "create", fp.Name+"/https://github.com/argoproj/argocd-example-apps")
|
||||
|
||||
assert.Equal(t, project.Name, fp.Name)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ export const ApplicationNodeInfo = (props: {
|
||||
<DataLoader load={() => services.viewPreferences.getPreferences()}>
|
||||
{pref => {
|
||||
const live = deepMerge(props.live, {}) as any;
|
||||
if (live && pref.appDetails.hideManagedFields) {
|
||||
if (live?.metadata?.managedFields && pref.appDetails.hideManagedFields) {
|
||||
delete live.metadata.managedFields;
|
||||
}
|
||||
return (
|
||||
|
||||
@@ -27,11 +27,11 @@ const retryOptions: Array<(formApi: FormApi) => React.ReactNode> = [
|
||||
];
|
||||
|
||||
const defaultInitialValues = {
|
||||
limit: '',
|
||||
limit: 2,
|
||||
backoff: {
|
||||
duration: '',
|
||||
maxDuration: '',
|
||||
factor: ''
|
||||
duration: '5s',
|
||||
maxDuration: '3m0s',
|
||||
factor: 2
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ const retryOptionsView: Array<(initData: models.RetryStrategy) => React.ReactNod
|
||||
initData => buildRetryOptionView('Limit', initData?.limit),
|
||||
initData => buildRetryOptionView('Duration', initData?.backoff?.duration),
|
||||
initData => buildRetryOptionView('Max Duration', initData?.backoff?.maxDuration),
|
||||
initData => buildRetryOptionView('Factor', initData?.backoff.factor)
|
||||
initData => buildRetryOptionView('Factor', initData?.backoff?.factor)
|
||||
];
|
||||
|
||||
export const ApplicationRetryView = ({initValues}: {initValues?: models.RetryStrategy}) => {
|
||||
const result = !initValues ? 'Retry not installed' : retryOptionsView.map((render, i) => render(initValues));
|
||||
const result = !initValues ? 'Retry disabled' : retryOptionsView.map((render, i) => render(initValues));
|
||||
return <div className='application-retry-option-view-list'>{result}</div>;
|
||||
};
|
||||
|
||||
@@ -176,8 +176,10 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app
|
||||
let contentEnd = resKey.substr(-Math.floor(resKey.length / 2));
|
||||
// We want the ellipsis to be in the middle of our text, so we use RTL layout to put it there.
|
||||
// Unfortunately, strong LTR characters get jumbled around, so make sure that the last character isn't strong.
|
||||
const indexOfFirstLetter = /[a-z]/i.exec(contentEnd).index;
|
||||
contentEnd = contentEnd.slice(indexOfFirstLetter);
|
||||
const firstLetter = /[a-z]/i.exec(contentEnd);
|
||||
if (firstLetter) {
|
||||
contentEnd = contentEnd.slice(firstLetter.index);
|
||||
}
|
||||
const isLongLabel = resKey.length > 68;
|
||||
return (
|
||||
<div key={resKey} className='application-sync-panel__resource'>
|
||||
|
||||
Reference in New Issue
Block a user