mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-15 12:58:48 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5a65cdfe7 | ||
|
|
219fae8380 | ||
|
|
ba04a028c1 | ||
|
|
634e0d6323 | ||
|
|
962fb84fba | ||
|
|
0a8507ac6e | ||
|
|
3026882f17 | ||
|
|
e84c56b279 | ||
|
|
25a1b4ccc6 | ||
|
|
90bc83d1f7 | ||
|
|
130b1e6218 | ||
|
|
af5f1a7e69 | ||
|
|
be93e7918b | ||
|
|
4ea88b621d | ||
|
|
e1336f1f23 | ||
|
|
0af64eaf9a |
@@ -177,7 +177,6 @@ jobs:
|
||||
command: PATH=dist:$PATH make test-e2e
|
||||
environment:
|
||||
ARGOCD_OPTS: "--server localhost:8080 --plaintext"
|
||||
ARGOCD_E2E_EXPECT_TIMEOUT: "30"
|
||||
ARGOCD_E2E_K3S: "true"
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
|
||||
@@ -1297,7 +1297,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Server: app.Spec.Destination.Server})
|
||||
errors.CheckError(err)
|
||||
util.Close(conn)
|
||||
localObjsStrings = getLocalObjectsString(app, local, cluster.ServerVersion, argoSettings.AppLabelKey, argoSettings.KustomizeOptions)
|
||||
localObjsStrings = getLocalObjectsString(app, local, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions)
|
||||
}
|
||||
|
||||
syncReq := applicationpkg.ApplicationSyncRequest{
|
||||
|
||||
@@ -136,7 +136,8 @@ func NewApplicationController(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, cache.Indexers{})
|
||||
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
||||
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, indexers)
|
||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort)
|
||||
ctrl.metricsServer = metrics.NewMetricsServer(metricsAddr, appLister, func() error {
|
||||
_, err := kubeClientset.Discovery().ServerVersion()
|
||||
|
||||
@@ -56,6 +56,8 @@ Ensure dependencies are up to date first:
|
||||
dep ensure
|
||||
make dev-builder-image
|
||||
make install-lint-tools
|
||||
go get github.com/mattn/goreman
|
||||
go get github.com/jstemmer/go-junit-report
|
||||
```
|
||||
|
||||
Common make targets:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -eux -o pipefail
|
||||
|
||||
"$(dirname $0)/../install.sh" helm-linux jq-linux kustomize-linux protoc-linux swagger-linux
|
||||
KUSTOMIZE_VERSION=2.0.3 "$(dirname $0)/../install.sh" helm-linux jq-linux kustomize-linux protoc-linux swagger-linux
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -eux -o pipefail
|
||||
|
||||
# TODO we use v2 for generating manifests, v3 for production - we should always use v3
|
||||
KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION:-3.2.1}
|
||||
DL=$DOWNLOADS/kustomize-${KUSTOMIZE_VERSION}
|
||||
|
||||
@@ -11,7 +10,16 @@ DL=$DOWNLOADS/kustomize-${KUSTOMIZE_VERSION}
|
||||
# v3.2.0 = https://github.com/kubernetes-sigs/kustomize/releases/download/v3.2.0/kustomize_3.2.0_linux_amd64
|
||||
# v3.2.1 = https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.2.1/kustomize_kustomize.v3.2.1_linux_amd64
|
||||
# v3.3.0 = https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.3.0/kustomize_v3.3.0_linux_amd64.tar.gz
|
||||
[ -e $DL ] || curl -sLf --retry 3 -o $DL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v${KUSTOMIZE_VERSION}/kustomize_kustomize.v${KUSTOMIZE_VERSION}_linux_amd64
|
||||
case $KUSTOMIZE_VERSION in
|
||||
2.*)
|
||||
URL=https://github.com/kubernetes-sigs/kustomize/releases/download/v${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64
|
||||
;;
|
||||
*)
|
||||
URL=https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v${KUSTOMIZE_VERSION}/kustomize_kustomize.v${KUSTOMIZE_VERSION}_linux_amd64
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -e $DL ] || curl -sLf --retry 3 -o $DL $URL
|
||||
cp $DL $BIN/kustomize
|
||||
chmod +x $BIN/kustomize
|
||||
kustomize version
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: v1.3.0
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.3.0
|
||||
resources:
|
||||
bases:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
- ./repo-server
|
||||
- ./server
|
||||
- ./config
|
||||
- ./redis
|
||||
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: v1.3.2
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.3.2
|
||||
|
||||
@@ -7,18 +7,18 @@ patchesStrategicMerge:
|
||||
- overlays/argocd-server-deployment.yaml
|
||||
- overlays/argocd-application-controller-deployment.yaml
|
||||
|
||||
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: v1.3.0
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.3.0
|
||||
resources:
|
||||
bases:
|
||||
- ../../base/application-controller
|
||||
- ../../base/dex
|
||||
- ../../base/repo-server
|
||||
- ../../base/server
|
||||
- ../../base/config
|
||||
- ./redis-ha
|
||||
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: v1.3.2
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.3.2
|
||||
|
||||
@@ -2789,30 +2789,6 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: null
|
||||
labels:
|
||||
app.kubernetes.io/component: redis
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-redis-ha
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: server
|
||||
port: 6379
|
||||
protocol: TCP
|
||||
targetPort: redis
|
||||
- name: sentinel
|
||||
port: 26379
|
||||
protocol: TCP
|
||||
targetPort: sentinel
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||
@@ -2891,6 +2867,30 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: null
|
||||
labels:
|
||||
app.kubernetes.io/component: redis
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-redis-ha
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: server
|
||||
port: 6379
|
||||
protocol: TCP
|
||||
targetPort: redis
|
||||
- name: sentinel
|
||||
port: 26379
|
||||
protocol: TCP
|
||||
targetPort: sentinel
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: repo-server
|
||||
@@ -2912,6 +2912,23 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
@@ -2931,23 +2948,6 @@ spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -2982,7 +2982,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3036,7 +3036,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3092,7 +3092,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3166,7 +3166,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2704,30 +2704,6 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: null
|
||||
labels:
|
||||
app.kubernetes.io/component: redis
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-redis-ha
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: server
|
||||
port: 6379
|
||||
protocol: TCP
|
||||
targetPort: redis
|
||||
- name: sentinel
|
||||
port: 26379
|
||||
protocol: TCP
|
||||
targetPort: sentinel
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||
@@ -2806,6 +2782,30 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: null
|
||||
labels:
|
||||
app.kubernetes.io/component: redis
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-redis-ha
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: server
|
||||
port: 6379
|
||||
protocol: TCP
|
||||
targetPort: redis
|
||||
- name: sentinel
|
||||
port: 26379
|
||||
protocol: TCP
|
||||
targetPort: sentinel
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-redis-ha
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: repo-server
|
||||
@@ -2827,6 +2827,23 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
@@ -2846,23 +2863,6 @@ spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -2897,7 +2897,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2951,7 +2951,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3007,7 +3007,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3081,7 +3081,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2684,6 +2684,23 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
@@ -2703,23 +2720,6 @@ spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -2746,7 +2746,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2800,7 +2800,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2864,7 +2864,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2915,7 +2915,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2599,6 +2599,23 @@ spec:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
@@ -2618,23 +2635,6 @@ spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: server
|
||||
app.kubernetes.io/name: argocd-server-metrics
|
||||
app.kubernetes.io/part-of: argocd
|
||||
name: argocd-server-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 8083
|
||||
protocol: TCP
|
||||
targetPort: 8083
|
||||
selector:
|
||||
app.kubernetes.io/name: argocd-server
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -2661,7 +2661,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2715,7 +2715,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2779,7 +2779,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2830,7 +2830,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:v1.3.0
|
||||
image: argoproj/argocd:v1.3.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1291,7 +1291,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-.]+$`, 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)
|
||||
}
|
||||
|
||||
@@ -303,6 +303,7 @@ func TestAppProject_ValidPolicyRules(t *testing.T) {
|
||||
"p, proj:my-proj:my-role, applications, get, my-proj/*-foo, allow",
|
||||
"p, proj:my-proj:my-role, applications, get, my-proj/foo-*, allow",
|
||||
"p, proj:my-proj:my-role, applications, get, my-proj/*-*, allow",
|
||||
"p, proj:my-proj:my-role, applications, get, my-proj/*.*, allow",
|
||||
"p, proj:my-proj:my-role, applications, *, my-proj/foo, allow",
|
||||
"p, proj:my-proj:my-role, applications, create, my-proj/foo, allow",
|
||||
"p, proj:my-proj:my-role, applications, update, my-proj/foo, allow",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"time"
|
||||
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
@@ -28,13 +29,16 @@ func (c *clientSet) NewRepoServerClient() (util.Closer, RepoServerServiceClient,
|
||||
grpc_retry.WithMax(3),
|
||||
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)),
|
||||
}
|
||||
unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)}
|
||||
if c.timeoutSeconds > 0 {
|
||||
unaryInterceptors = append(unaryInterceptors, argogrpc.WithTimeout(time.Duration(c.timeoutSeconds)*time.Second))
|
||||
}
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})),
|
||||
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)),
|
||||
grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(retryOpts...))}
|
||||
if c.timeoutSeconds > 0 {
|
||||
opts = append(opts, grpc.WithUnaryInterceptor(argogrpc.WithTimeout(time.Duration(c.timeoutSeconds)*time.Second)))
|
||||
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)),
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(c.address, opts...)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to connect to repository service with address %s", c.address)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/util/ksonnet"
|
||||
"github.com/argoproj/argo-cd/util/kube"
|
||||
"github.com/argoproj/argo-cd/util/kustomize"
|
||||
"github.com/argoproj/argo-cd/util/security"
|
||||
"github.com/argoproj/argo-cd/util/text"
|
||||
)
|
||||
|
||||
@@ -110,7 +112,7 @@ type operationSettings struct {
|
||||
|
||||
// runRepoOperation downloads either git folder or helm chart and executes specified operation
|
||||
func (s *Service) runRepoOperation(
|
||||
c context.Context,
|
||||
ctx context.Context,
|
||||
revision string,
|
||||
repo *v1alpha1.Repository,
|
||||
source *v1alpha1.ApplicationSource,
|
||||
@@ -136,7 +138,7 @@ func (s *Service) runRepoOperation(
|
||||
defer s.metricsServer.DecPendingRepoRequest(repo.Repo)
|
||||
|
||||
if settings.sem != nil {
|
||||
err = settings.sem.Acquire(c, 1)
|
||||
err = settings.sem.Acquire(ctx, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -157,27 +159,27 @@ func (s *Service) runRepoOperation(
|
||||
}
|
||||
defer util.Close(closer)
|
||||
return operation(chartPath, revision)
|
||||
} else {
|
||||
s.repoLock.Lock(gitClient.Root())
|
||||
defer s.repoLock.Unlock(gitClient.Root())
|
||||
// double-check locking
|
||||
if !settings.noCache && getCached(revision) {
|
||||
return nil
|
||||
}
|
||||
revision, err = checkoutRevision(gitClient, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appPath, err := argopath.Path(gitClient.Root(), source.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return operation(appPath, revision)
|
||||
}
|
||||
s.repoLock.Lock(gitClient.Root())
|
||||
defer s.repoLock.Unlock(gitClient.Root())
|
||||
|
||||
if !settings.noCache && getCached(revision) {
|
||||
return nil
|
||||
}
|
||||
|
||||
revision, err = checkoutRevision(gitClient, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appPath, err := argopath.Path(gitClient.Root(), source.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return operation(appPath, revision)
|
||||
}
|
||||
|
||||
func (s *Service) GenerateManifest(c context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) {
|
||||
var res *apiclient.ManifestResponse
|
||||
func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) {
|
||||
res := &apiclient.ManifestResponse{}
|
||||
|
||||
getCached := func(revision string) bool {
|
||||
err := s.cache.GetManifests(revision, q.ApplicationSource, q.Namespace, q.AppLabelKey, q.AppLabelValue, &res)
|
||||
@@ -192,7 +194,7 @@ func (s *Service) GenerateManifest(c context.Context, q *apiclient.ManifestReque
|
||||
}
|
||||
return false
|
||||
}
|
||||
err := s.runRepoOperation(c, q.Revision, q.Repo, q.ApplicationSource, getCached, func(appPath string, revision string) error {
|
||||
err := s.runRepoOperation(ctx, q.Revision, q.Repo, q.ApplicationSource, getCached, func(appPath string, revision string) error {
|
||||
var err error
|
||||
res, err = GenerateManifests(appPath, q)
|
||||
if err != nil {
|
||||
@@ -224,14 +226,41 @@ func helmTemplate(appPath string, q *apiclient.ManifestRequest) ([]*unstructured
|
||||
Set: map[string]string{},
|
||||
SetString: map[string]string{},
|
||||
}
|
||||
|
||||
appHelm := q.ApplicationSource.Helm
|
||||
if appHelm != nil {
|
||||
if appHelm.ReleaseName != "" {
|
||||
templateOpts.Name = appHelm.ReleaseName
|
||||
}
|
||||
templateOpts.Values = appHelm.ValueFiles
|
||||
|
||||
for _, val := range appHelm.ValueFiles {
|
||||
// If val is not a URL, run it against the directory enforcer. If it is a URL, use it without checking
|
||||
if _, err := url.ParseRequestURI(val); err != nil {
|
||||
baseDirectoryPath, err := security.SubtractRelativeFromAbsolutePath(appPath, q.ApplicationSource.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
absBaseDir, err := filepath.Abs(baseDirectoryPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !filepath.IsAbs(val) {
|
||||
absWorkDir, err := filepath.Abs(appPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
val = filepath.Join(absWorkDir, val)
|
||||
}
|
||||
_, err = security.EnforceToCurrentRoot(absBaseDir, val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
templateOpts.Values = append(templateOpts.Values, val)
|
||||
}
|
||||
|
||||
if appHelm.Values != "" {
|
||||
file, err := ioutil.TempFile(appPath, "values-*.yaml")
|
||||
file, err := ioutil.TempFile("", "values-*.yaml")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -243,6 +272,7 @@ func helmTemplate(appPath string, q *apiclient.ManifestRequest) ([]*unstructured
|
||||
}
|
||||
templateOpts.Values = append(templateOpts.Values, p)
|
||||
}
|
||||
|
||||
for _, p := range appHelm.Parameters {
|
||||
if p.ForceString {
|
||||
templateOpts.SetString[p.Name] = p.Value
|
||||
@@ -572,17 +602,17 @@ func runConfigManagementPlugin(appPath string, q *apiclient.ManifestRequest, cre
|
||||
}
|
||||
|
||||
func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppDetailsQuery) (*apiclient.RepoAppDetailsResponse, error) {
|
||||
var res apiclient.RepoAppDetailsResponse
|
||||
res := &apiclient.RepoAppDetailsResponse{}
|
||||
getCached := func(revision string) bool {
|
||||
err := s.cache.GetAppDetails(revision, q.Source, &res)
|
||||
if err == nil {
|
||||
log.Infof("manifest cache hit: %s/%s", revision, q.Source.Path)
|
||||
log.Infof("app details cache hit: %s/%s", revision, q.Source.Path)
|
||||
return true
|
||||
} else {
|
||||
if err != cache.ErrCacheMiss {
|
||||
log.Warnf("manifest cache error %s: %v", revision, q.Source)
|
||||
log.Warnf("app details cache error %s: %v", revision, q.Source)
|
||||
} else {
|
||||
log.Infof("manifest cache miss: %s/%s", revision, q.Source)
|
||||
log.Infof("app details cache miss: %s/%s", revision, q.Source)
|
||||
}
|
||||
}
|
||||
return false
|
||||
@@ -677,32 +707,33 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
||||
return nil
|
||||
}, operationSettings{})
|
||||
|
||||
return &res, err
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (s *Service) GetRevisionMetadata(ctx context.Context, q *apiclient.RepoServerRevisionMetadataRequest) (*v1alpha1.RevisionMetadata, error) {
|
||||
gitClient, commitSHA, err := s.newClientResolveRevision(q.Repo, q.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !git.IsCommitSHA(q.Revision) {
|
||||
return nil, fmt.Errorf("revision %s must be resolved", q.Revision)
|
||||
}
|
||||
|
||||
metadata, err := s.cache.GetRevisionMetadata(q.Repo.Repo, commitSHA)
|
||||
metadata, err := s.cache.GetRevisionMetadata(q.Repo.Repo, q.Revision)
|
||||
if err == nil {
|
||||
log.Infof("manifest cache hit: %s/%s", q.Repo.Repo, commitSHA)
|
||||
log.Infof("revision metadata cache hit: %s/%s", q.Repo.Repo, q.Revision)
|
||||
return metadata, nil
|
||||
} else {
|
||||
if err != cache.ErrCacheMiss {
|
||||
log.Warnf("manifest cache error %s/%s: %v", q.Repo.Repo, commitSHA, err)
|
||||
log.Warnf("revision metadata cache error %s/%s: %v", q.Repo.Repo, q.Revision, err)
|
||||
} else {
|
||||
log.Infof("manifest cache miss: %s/%s", q.Repo.Repo, commitSHA)
|
||||
log.Infof("revision metadata cache miss: %s/%s", q.Repo.Repo, q.Revision)
|
||||
}
|
||||
}
|
||||
|
||||
commitSHA, err = checkoutRevision(gitClient, commitSHA)
|
||||
gitClient, _, err := s.newClientResolveRevision(q.Repo, q.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := gitClient.RevisionMetadata(commitSHA)
|
||||
_, err = checkoutRevision(gitClient, q.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := gitClient.RevisionMetadata(q.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -206,8 +206,8 @@ func TestGenerateHelmWithValues(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
// This tests against a path traversal attack. The requested value file (`../minio/values.yaml`) is outside the
|
||||
// app path (`./util/helm/testdata/redis`)
|
||||
// The requested value file (`../minio/values.yaml`) is outside the app path (`./util/helm/testdata/redis`), however
|
||||
// since the requested value is sill under the repo directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed
|
||||
func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) {
|
||||
service := newService("../..")
|
||||
|
||||
@@ -222,7 +222,42 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGenerateHelmWithURL(t *testing.T) {
|
||||
service := newService("../..")
|
||||
|
||||
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
AppLabelValue: "test",
|
||||
ApplicationSource: &argoappv1.ApplicationSource{
|
||||
Path: "./util/helm/testdata/redis",
|
||||
Helm: &argoappv1.ApplicationSourceHelm{
|
||||
ValueFiles: []string{"https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/helm-guestbook/values.yaml"},
|
||||
Values: `cluster: {slaveCount: 2}`,
|
||||
},
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// The requested value file (`../../../../../minio/values.yaml`) is outside the repo directory
|
||||
// (`~/go/src/github.com/argoproj/argo-cd`), so it is blocked
|
||||
func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) {
|
||||
service := newService("../..")
|
||||
|
||||
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
AppLabelValue: "test",
|
||||
ApplicationSource: &argoappv1.ApplicationSource{
|
||||
Path: "./util/helm/testdata/redis",
|
||||
Helm: &argoappv1.ApplicationSourceHelm{
|
||||
ValueFiles: []string{"../../../../../minio/values.yaml"},
|
||||
Values: `cluster: {slaveCount: 2}`,
|
||||
},
|
||||
},
|
||||
})
|
||||
assert.Error(t, err, "should be on or under current directory")
|
||||
}
|
||||
|
||||
@@ -408,7 +443,7 @@ func TestGetRevisionMetadata(t *testing.T) {
|
||||
|
||||
res, err := service.GetRevisionMetadata(context.Background(), &apiclient.RepoServerRevisionMetadataRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
Revision: "123",
|
||||
Revision: "c0b400fc458875d925171398f9ba9eabd5529923",
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -1037,24 +1037,29 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
|
||||
if ambiguousRevision == "" {
|
||||
ambiguousRevision = app.Spec.Source.TargetRevision
|
||||
}
|
||||
if git.IsCommitSHA(ambiguousRevision) {
|
||||
// If it's already a commit SHA, then no need to look it up
|
||||
|
||||
if app.Spec.Source.IsHelm() {
|
||||
return ambiguousRevision, ambiguousRevision, nil
|
||||
} else {
|
||||
if git.IsCommitSHA(ambiguousRevision) {
|
||||
// If it's already a commit SHA, then no need to look it up
|
||||
return ambiguousRevision, ambiguousRevision, nil
|
||||
}
|
||||
repo, err := s.db.GetRepository(ctx, app.Spec.Source.RepoURL)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(), repo.IsInsecure(), repo.IsLFSEnabled())
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
commitSHA, err := gitClient.LsRemote(ambiguousRevision)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
displayRevision := fmt.Sprintf("%s (%s)", ambiguousRevision, commitSHA)
|
||||
return commitSHA, displayRevision, nil
|
||||
}
|
||||
repo, err := s.db.GetRepository(ctx, app.Spec.Source.RepoURL)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(), repo.IsInsecure(), repo.IsLFSEnabled())
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
commitSHA, err := gitClient.LsRemote(ambiguousRevision)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
displayRevision := fmt.Sprintf("%s (%s)", ambiguousRevision, commitSHA)
|
||||
return commitSHA, displayRevision, nil
|
||||
}
|
||||
|
||||
func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application.OperationTerminateRequest) (*application.OperationTerminateResponse, error) {
|
||||
|
||||
@@ -552,6 +552,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
mustRegisterGWHandler(sessionpkg.RegisterSessionServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(settingspkg.RegisterSettingsServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(projectpkg.RegisterProjectServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(accountpkg.RegisterAccountServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(certificatepkg.RegisterCertificateServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
|
||||
// Swagger UI
|
||||
|
||||
@@ -567,6 +567,18 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestLocalSync(t *testing.T) {
|
||||
Given(t).
|
||||
// we've got to use Helm as this uses kubeVersion
|
||||
Path("helm").
|
||||
When().
|
||||
Create().
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
FailOnErr(RunCli("app", "sync", app.Name, "--local", "testdata/helm"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestNoLocalSyncWithAutosyncEnabled(t *testing.T) {
|
||||
Given(t).
|
||||
Path(guestbookPath).
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -24,7 +22,7 @@ func (c *Consequences) Expect(e Expectation) *Consequences {
|
||||
c.context.t.Helper()
|
||||
var message string
|
||||
var state state
|
||||
timeout := c.timeout()
|
||||
timeout := time.Duration(15) * time.Second
|
||||
for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) {
|
||||
state, message = e(c)
|
||||
switch state {
|
||||
@@ -78,12 +76,3 @@ func (c *Consequences) resource(kind, name string) ResourceStatus {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Consequences) timeout() time.Duration {
|
||||
value := os.Getenv("ARGOCD_E2E_EXPECT_TIMEOUT")
|
||||
timeout, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
timeout = 15
|
||||
}
|
||||
return time.Duration(timeout) * time.Second
|
||||
}
|
||||
|
||||
@@ -193,7 +193,10 @@ func TestHelmWithDependenciesLegacyRepo(t *testing.T) {
|
||||
}
|
||||
|
||||
func testHelmWithDependencies(t *testing.T, legacyRepo bool) {
|
||||
ctx := Given(t).CustomCACertAdded()
|
||||
ctx := Given(t).
|
||||
CustomCACertAdded().
|
||||
// these are slow tests
|
||||
Timeout(30)
|
||||
if legacyRepo {
|
||||
ctx.And(func() {
|
||||
errors.FailOnErr(fixture.Run("", "kubectl", "create", "secret", "generic", "helm-repo",
|
||||
|
||||
@@ -4,21 +4,24 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
. "strings"
|
||||
"testing"
|
||||
|
||||
argoexec "github.com/argoproj/pkg/exec"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/argo-cd/test/fixture/test"
|
||||
)
|
||||
|
||||
func TestKustomizeVersion(t *testing.T) {
|
||||
test.CIOnly(t)
|
||||
out, err := argoexec.RunCommand("kustomize", argoexec.CmdOpts{}, "version")
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, out, "Version:kustomize/v3", "kustomize should be version 3")
|
||||
}
|
||||
|
||||
// TestBuildManifests makes sure we are consistent in naming, and all kustomization.yamls are buildable
|
||||
func TestBuildManifests(t *testing.T) {
|
||||
|
||||
out, err := argoexec.RunCommand("kustomize", argoexec.CmdOpts{}, "version")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, Contains(out, "Version:kustomize/v3"), "kustomize should be version 3")
|
||||
|
||||
err = filepath.Walk("../manifests", func(path string, f os.FileInfo, err error) error {
|
||||
err := filepath.Walk("../manifests", func(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { DropDownMenu, Tooltip } from 'argo-ui';
|
||||
import {DropDownMenu} from 'argo-ui';
|
||||
import * as React from 'react';
|
||||
const GitUrlParse = require('git-url-parse');
|
||||
|
||||
import { Cluster } from '../../../shared/components';
|
||||
import { Consumer } from '../../../shared/context';
|
||||
import * as models from '../../../shared/models';
|
||||
@@ -10,11 +8,6 @@ import * as AppUtils from '../utils';
|
||||
|
||||
require('./applications-table.scss');
|
||||
|
||||
function shortRepo(repo: string) {
|
||||
const url = GitUrlParse(repo);
|
||||
return <Tooltip content={repo}><span>{url.pathname.slice(1)}</span></Tooltip>;
|
||||
}
|
||||
|
||||
export const ApplicationsTable = (props: {
|
||||
applications: models.Application[];
|
||||
syncApplication: (appName: string) => any;
|
||||
@@ -44,7 +37,7 @@ export const ApplicationsTable = (props: {
|
||||
<div className='row'>
|
||||
<div className='show-for-xxlarge columns small-2'>Source:</div>
|
||||
<div className='columns small-12 xxlarge-10' style={{position: 'relative'}}>
|
||||
{shortRepo(app.spec.source.repoURL)}/{app.spec.source.path}
|
||||
{app.spec.source.repoURL}/{app.spec.source.path || app.spec.source.chart}
|
||||
<div className='applications-table__meta'>
|
||||
<span>{app.spec.source.targetRevision || 'HEAD'}</span>
|
||||
{Object.keys(app.metadata.labels || {}).map((label) => <span key={label}>{`${label}=${app.metadata.labels[label]}`}</span>)}
|
||||
|
||||
@@ -71,10 +71,18 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
|
||||
<div className='columns small-3'>Target Revision:</div>
|
||||
<div className='columns small-9'>{app.spec.source.targetRevision || 'latest'}</div>
|
||||
</div>
|
||||
{app.spec.source.path && (
|
||||
<div className='row'>
|
||||
<div className='columns small-3'>Path:</div>
|
||||
<div className='columns small-9'>{app.spec.source.path}</div>
|
||||
</div>
|
||||
)}
|
||||
{app.spec.source.chart && (
|
||||
<div className='row'>
|
||||
<div className='columns small-3'>Chart:</div>
|
||||
<div className='columns small-9'>{app.spec.source.chart}</div>
|
||||
</div>
|
||||
)}
|
||||
<div className='row'>
|
||||
<div className='columns small-3'>Destination:</div>
|
||||
<div className='columns small-9'>{app.spec.destination.server}</div>
|
||||
|
||||
@@ -48,7 +48,8 @@ func TestGetAppProjectWithNoProjDefined(t *testing.T) {
|
||||
appClientset := appclientset.NewSimpleClientset(testProj)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
informer := v1alpha1.NewAppProjectInformer(appClientset, namespace, 0, cache.Indexers{})
|
||||
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
||||
informer := v1alpha1.NewAppProjectInformer(appClientset, namespace, 0, indexers)
|
||||
go informer.Run(ctx.Done())
|
||||
cache.WaitForCacheSync(ctx.Done(), informer.HasSynced)
|
||||
proj, err := GetAppProject(&testApp.Spec, applisters.NewAppProjectLister(informer.GetIndexer()), namespace)
|
||||
|
||||
@@ -6,14 +6,12 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
argoexec "github.com/argoproj/pkg/exec"
|
||||
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
"github.com/argoproj/argo-cd/util/config"
|
||||
"github.com/argoproj/argo-cd/util/security"
|
||||
)
|
||||
|
||||
// A thin wrapper around the "helm" command, adding logging and error translation.
|
||||
@@ -196,18 +194,7 @@ func (c *Cmd) template(chart string, opts *TemplateOpts) (string, error) {
|
||||
args = append(args, "--set-string", key+"="+cleanSetParameters(val))
|
||||
}
|
||||
for _, val := range opts.Values {
|
||||
absWorkDir, err := filepath.Abs(c.WorkDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !filepath.IsAbs(val) {
|
||||
val = filepath.Join(absWorkDir, val)
|
||||
}
|
||||
cleanVal, err := security.EnforceToCurrentRoot(absWorkDir, val)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
args = append(args, "--values", cleanVal)
|
||||
args = append(args, "--values", val)
|
||||
}
|
||||
|
||||
return c.run(args...)
|
||||
|
||||
@@ -21,27 +21,3 @@ func TestCmd_template_kubeVersion(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, s)
|
||||
}
|
||||
|
||||
func TestCmd_template_PathTraversal(t *testing.T) {
|
||||
cmd, err := NewCmd("./testdata/redis")
|
||||
assert.NoError(t, err)
|
||||
s, err := cmd.template(".", &TemplateOpts{
|
||||
KubeVersion: "1.14",
|
||||
Values: []string{"values.yaml"},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, s)
|
||||
|
||||
_, err = cmd.template(".", &TemplateOpts{
|
||||
KubeVersion: "1.14",
|
||||
Values: []string{"../minio/values.yaml"},
|
||||
})
|
||||
assert.Error(t, err)
|
||||
|
||||
s, err = cmd.template(".", &TemplateOpts{
|
||||
KubeVersion: "1.14",
|
||||
Values: []string{"../minio/../redis/values.yaml"},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, s)
|
||||
}
|
||||
|
||||
8
util/helm/version.go
Normal file
8
util/helm/version.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package helm
|
||||
|
||||
import "github.com/Masterminds/semver"
|
||||
|
||||
func IsVersion(text string) bool {
|
||||
_, err := semver.NewVersion(text)
|
||||
return err == nil
|
||||
}
|
||||
14
util/helm/version_test.go
Normal file
14
util/helm/version_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package helm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsVersion(t *testing.T) {
|
||||
assert.False(t, IsVersion("*"))
|
||||
assert.False(t, IsVersion("1.*"))
|
||||
assert.False(t, IsVersion("1.0.*"))
|
||||
assert.True(t, IsVersion("1.0.0"))
|
||||
}
|
||||
@@ -20,5 +20,8 @@ func DeletePolicies(obj *unstructured.Unstructured) []v1alpha1.HookDeletePolicy
|
||||
for _, p := range helmhook.DeletePolicies(obj) {
|
||||
policies = append(policies, p.DeletePolicy())
|
||||
}
|
||||
if len(policies) == 0 {
|
||||
policies = append(policies, v1alpha1.HookDeletePolicyBeforeHookCreation)
|
||||
}
|
||||
return policies
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
func TestDeletePolicies(t *testing.T) {
|
||||
assert.Nil(t, DeletePolicies(NewPod()))
|
||||
assert.Nil(t, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "garbage")))
|
||||
assert.Equal(t, []HookDeletePolicy{HookDeletePolicyBeforeHookCreation}, DeletePolicies(NewPod()))
|
||||
assert.Equal(t, []HookDeletePolicy{HookDeletePolicyBeforeHookCreation}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "garbage")))
|
||||
assert.Equal(t, []HookDeletePolicy{HookDeletePolicyBeforeHookCreation}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")))
|
||||
assert.Equal(t, []HookDeletePolicy{HookDeletePolicyHookSucceeded}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded")))
|
||||
assert.Equal(t, []HookDeletePolicy{HookDeletePolicyHookFailed}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookFailed")))
|
||||
|
||||
@@ -168,7 +168,8 @@ func (e *Enforcer) newInformer() cache.SharedIndexInformer {
|
||||
cmFieldSelector := fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", e.configmap))
|
||||
options.FieldSelector = cmFieldSelector.String()
|
||||
}
|
||||
return v1.NewFilteredConfigMapInformer(e.clientset, e.namespace, defaultRBACSyncPeriod, cache.Indexers{}, tweakConfigMap)
|
||||
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
||||
return v1.NewFilteredConfigMapInformer(e.clientset, e.namespace, defaultRBACSyncPeriod, indexers, tweakConfigMap)
|
||||
}
|
||||
|
||||
// RunPolicyLoader runs the policy loader which watches policy updates from the configmap and reloads them
|
||||
|
||||
@@ -17,6 +17,29 @@ func EnforceToCurrentRoot(currentRoot, requestedPath string) (string, error) {
|
||||
return requestedDir + string(filepath.Separator) + requestedFile, nil
|
||||
}
|
||||
|
||||
func SubtractRelativeFromAbsolutePath(abs, rel string) (string, error) {
|
||||
if len(rel) == 0 {
|
||||
return abs, nil
|
||||
}
|
||||
if rel[0] == '.' {
|
||||
return SubtractRelativeFromAbsolutePath(abs, rel[1:])
|
||||
}
|
||||
if rel[0] != '/' {
|
||||
return SubtractRelativeFromAbsolutePath(abs, "/"+rel)
|
||||
}
|
||||
if rel[len(rel)-1] == '/' {
|
||||
return SubtractRelativeFromAbsolutePath(abs, rel[:len(rel)-1])
|
||||
}
|
||||
rel = filepath.Clean(rel)
|
||||
lastIndex := strings.LastIndex(abs, rel)
|
||||
if lastIndex < 0 {
|
||||
// This should be unreachable, because by this point the App Path will have already been validated by Path in
|
||||
// util/app/path/path.go
|
||||
return "", fmt.Errorf("app path is not under repo path (unreachable and most likely a bug)")
|
||||
}
|
||||
return abs[:lastIndex], nil
|
||||
}
|
||||
|
||||
func isRequestedDirUnderCurrentRoot(currentRoot, requestedDir string) bool {
|
||||
if currentRoot == string(filepath.Separator) {
|
||||
return true
|
||||
|
||||
@@ -24,3 +24,32 @@ func TestEnforceToCurrentRoot(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/home/argo/helmapp/values.yaml", cleanDir)
|
||||
}
|
||||
|
||||
func TestSubtractRelativeFromAbsolutePath(t *testing.T) {
|
||||
for _, test := range []string{"env", "/env", "env/", "/env/", "./env"} {
|
||||
subtracted, err := SubtractRelativeFromAbsolutePath("/argocd-example-apps/helm-guestbook/env/guestbook/env", test)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/argocd-example-apps/helm-guestbook/env/guestbook", subtracted)
|
||||
}
|
||||
for _, test := range []string{"guestbook/env", "/guestbook/env", "guestbook/env/", "/guestbook/env/", "./guestbook/env"} {
|
||||
subtracted, err := SubtractRelativeFromAbsolutePath("/argocd-example-apps/helm-guestbook/env/guestbook/env", test)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/argocd-example-apps/helm-guestbook/env", subtracted)
|
||||
}
|
||||
for _, test := range []string{"", ".", "/", "./"} {
|
||||
subtracted, err := SubtractRelativeFromAbsolutePath("/argocd-example-apps/helm-guestbook/env/guestbook/env", test)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/argocd-example-apps/helm-guestbook/env/guestbook/env", subtracted)
|
||||
}
|
||||
// "Dirty" strings
|
||||
for _, test := range []string{"guestbook/foo/../env", "/guestbook//env", "../guestbook/env/", "/../guestbook/env/", "./guestbook/env///"} {
|
||||
subtracted, err := SubtractRelativeFromAbsolutePath("/argocd-example-apps/helm-guestbook/env/guestbook/env", test)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/argocd-example-apps/helm-guestbook/env", subtracted)
|
||||
}
|
||||
// Invalid strings
|
||||
for _, test := range []string{"/not/in/path", "../not/in/path", "not/in/path"} {
|
||||
_, err := SubtractRelativeFromAbsolutePath("/argocd-example-apps/helm-guestbook/env/guestbook/env", test)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ type ArgoCDSettings struct {
|
||||
// Secrets holds all secrets in argocd-secret as a map[string]string
|
||||
Secrets map[string]string `json:"secrets,omitempty"`
|
||||
// KustomizeBuildOptions is a string of kustomize build parameters
|
||||
KustomizeBuildOptions string
|
||||
KustomizeBuildOptions string `json:"kustomizeBuildOptions,omitempty"`
|
||||
// Indicates if anonymous user is enabled or not
|
||||
AnonymousUserEnabled bool
|
||||
AnonymousUserEnabled bool `json:"anonymousUserEnabled,omitempty"`
|
||||
}
|
||||
|
||||
type GoogleAnalytics struct {
|
||||
@@ -325,7 +325,10 @@ func (mgr *SettingsManager) GetKustomizeBuildOptions() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return argoCDCM.Data[kustomizeBuildOptions], nil
|
||||
if value, ok := argoCDCM.Data[kustomizeBuildOptions]; ok {
|
||||
return value, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// DEPRECATED. Helm repository credentials are now managed using RepoCredentials
|
||||
@@ -455,8 +458,9 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error {
|
||||
options.LabelSelector = cmLabelSelector.String()
|
||||
}
|
||||
|
||||
cmInformer := v1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, cache.Indexers{}, tweakConfigMap)
|
||||
secretsInformer := v1.NewSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, cache.Indexers{})
|
||||
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
||||
cmInformer := v1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers, tweakConfigMap)
|
||||
secretsInformer := v1.NewSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers)
|
||||
|
||||
log.Info("Starting configmap/secret informers")
|
||||
go func() {
|
||||
|
||||
Reference in New Issue
Block a user