mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-06 08:28:50 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d9e9f2f95 | ||
|
|
ca7d83f645 | ||
|
|
e59f4889a4 | ||
|
|
fea6197af4 | ||
|
|
5b576acf5d | ||
|
|
2ccc17afcb | ||
|
|
e7521ed7b8 | ||
|
|
f83bed0d4b | ||
|
|
88274b6870 | ||
|
|
431ee12282 | ||
|
|
3b17121d44 | ||
|
|
f071b29b5f | ||
|
|
5ed749e827 |
@@ -19,8 +19,9 @@ type RepositoryDB interface {
|
||||
}
|
||||
|
||||
type argoCDService struct {
|
||||
repositoriesDB RepositoryDB
|
||||
storecreds git.CredsStore
|
||||
repositoriesDB RepositoryDB
|
||||
storecreds git.CredsStore
|
||||
submoduleEnabled bool
|
||||
}
|
||||
|
||||
type Repos interface {
|
||||
@@ -32,11 +33,12 @@ type Repos interface {
|
||||
GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error)
|
||||
}
|
||||
|
||||
func NewArgoCDService(db db.ArgoDB, gitCredStore git.CredsStore, repoServerAddress string) Repos {
|
||||
func NewArgoCDService(db db.ArgoDB, gitCredStore git.CredsStore, submoduleEnabled bool) Repos {
|
||||
|
||||
return &argoCDService{
|
||||
repositoriesDB: db.(RepositoryDB),
|
||||
storecreds: gitCredStore,
|
||||
repositoriesDB: db.(RepositoryDB),
|
||||
storecreds: gitCredStore,
|
||||
submoduleEnabled: submoduleEnabled,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +54,7 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = checkoutRepo(gitRepoClient, revision)
|
||||
err = checkoutRepo(gitRepoClient, revision, a.submoduleEnabled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -86,7 +88,7 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = checkoutRepo(gitRepoClient, revision)
|
||||
err = checkoutRepo(gitRepoClient, revision, a.submoduleEnabled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,7 +130,7 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revi
|
||||
|
||||
}
|
||||
|
||||
func checkoutRepo(gitRepoClient git.Client, revision string) error {
|
||||
func checkoutRepo(gitRepoClient git.Client, revision string, submoduleEnabled bool) error {
|
||||
err := gitRepoClient.Init()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error during initializing repo: %w", err)
|
||||
@@ -143,7 +145,7 @@ func checkoutRepo(gitRepoClient git.Client, revision string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error during fetching commitSHA: %w", err)
|
||||
}
|
||||
err = gitRepoClient.Checkout(commitSHA, true)
|
||||
err = gitRepoClient.Checkout(commitSHA, submoduleEnabled)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error during repo checkout: %w", err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/utils"
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/askpass"
|
||||
"github.com/argoproj/argo-cd/v2/util/env"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -37,6 +38,11 @@ import (
|
||||
argosettings "github.com/argoproj/argo-cd/v2/util/settings"
|
||||
)
|
||||
|
||||
// TODO: load this using Cobra. https://github.com/argoproj/argo-cd/issues/10157
|
||||
func getSubmoduleEnabled() bool {
|
||||
return env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true)
|
||||
}
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
var (
|
||||
clientConfig clientcmd.ClientConfig
|
||||
@@ -136,7 +142,7 @@ func NewCommand() *cobra.Command {
|
||||
terminalGenerators := map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
"Clusters": generators.NewClusterGenerator(mgr.GetClient(), context.Background(), k8sClient, namespace),
|
||||
"Git": generators.NewGitGenerator(services.NewArgoCDService(argoCDDB, askPassServer, argocdRepoServer)),
|
||||
"Git": generators.NewGitGenerator(services.NewArgoCDService(argoCDDB, askPassServer, getSubmoduleEnabled())),
|
||||
"SCMProvider": generators.NewSCMProviderGenerator(mgr.GetClient()),
|
||||
"ClusterDecisionResource": generators.NewDuckTypeGenerator(context.Background(), dynamicClient, k8sClient, namespace),
|
||||
"PullRequest": generators.NewPullRequestGenerator(mgr.GetClient()),
|
||||
|
||||
@@ -691,10 +691,11 @@ func (m *appStateManager) isSelfReferencedObj(obj *unstructured.Unstructured, ap
|
||||
|
||||
// In order for us to assume obj to be managed by this application, the
|
||||
// values from the annotation have to match the properties from the live
|
||||
// object.
|
||||
// object. Cluster scoped objects carry the app's destination namespace
|
||||
// in the tracking annotation, but are unique in GVK + name combination.
|
||||
appInstance := m.resourceTracking.GetAppInstance(obj, appLabelKey, trackingMethod)
|
||||
if appInstance != nil {
|
||||
return obj.GetNamespace() == appInstance.Namespace &&
|
||||
return (obj.GetNamespace() == appInstance.Namespace || obj.GetNamespace() == "") &&
|
||||
obj.GetName() == appInstance.Name &&
|
||||
obj.GetObjectKind().GroupVersionKind().Group == appInstance.Group &&
|
||||
obj.GetObjectKind().GroupVersionKind().Kind == appInstance.Kind
|
||||
|
||||
@@ -489,6 +489,7 @@ The secret data must include following fields:
|
||||
* `name` - cluster name
|
||||
* `server` - cluster api server url
|
||||
* `namespaces` - optional comma-separated list of namespaces which are accessible in that cluster. Cluster level resources would be ignored if namespace list is not empty.
|
||||
* `clusterResources` - optional boolean string (`"true"` or `"false"`) determining whether Argo CD can manage cluster-level resources on this cluster. This setting is used only if the list of managed namespaces is not empty.
|
||||
* `config` - JSON representation of following data structure:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -119,7 +119,7 @@ If the manifest generation has no side effects then requests are processed in pa
|
||||
* **Multiple Helm based applications pointing to the same directory in one Git repository:** ensure that your Helm chart don't have conditional
|
||||
[dependencies](https://helm.sh/docs/chart_best_practices/dependencies/#conditions-and-tags) and create `.argocd-allow-concurrency` file in chart directory.
|
||||
|
||||
* **Multiple Custom plugin based applications:** avoid creating temporal files during manifest generation and create `.argocd-allow-concurrency` file in app directory.
|
||||
* **Multiple Custom plugin based applications:** avoid creating temporal files during manifest generation and create `.argocd-allow-concurrency` file in app directory, or use the sidecar plugin option, which processes each application using a temporary copy of the repository.
|
||||
|
||||
* **Multiple Kustomize applications in same repository with [parameter overrides](../user-guide/parameters.md):** sorry, no workaround for now.
|
||||
|
||||
|
||||
@@ -107,13 +107,13 @@ p, role:org-admin, *, create, my-proj/*, allow
|
||||
New:
|
||||
|
||||
```csv
|
||||
p, role: org-admin, clusters, create, my-proj/*, allow
|
||||
p, role: org-admin, projects, create, my-proj/*, allow
|
||||
p, role: org-admin, applications, create, my-proj/*, allow
|
||||
p, role: org-admin, repositories, create, my-proj/*, allow
|
||||
p, role: org-admin, certificates, create, my-proj/*, allow
|
||||
p, role: org-admin, accounts, create, my-proj/*, allow
|
||||
p, role: org-admin, gpgkeys, create, my-proj/*, allow
|
||||
p, role:org-admin, clusters, create, my-proj/*, allow
|
||||
p, role:org-admin, projects, create, my-proj/*, allow
|
||||
p, role:org-admin, applications, create, my-proj/*, allow
|
||||
p, role:org-admin, repositories, create, my-proj/*, allow
|
||||
p, role:org-admin, certificates, create, my-proj/*, allow
|
||||
p, role:org-admin, accounts, create, my-proj/*, allow
|
||||
p, role:org-admin, gpgkeys, create, my-proj/*, allow
|
||||
```
|
||||
|
||||
## Enable logs RBAC enforcement
|
||||
|
||||
@@ -14,7 +14,7 @@ There are two ways to install a Config Management Plugin (CMP):
|
||||
1. Add the plugin config to the Argo CD ConfigMap. The repo-server container will run your plugin's commands.
|
||||
This is a good option for a simple plugin that requires only a few lines of code that fit nicely in the Argo CD ConfigMap.
|
||||
2. Add the plugin as a sidecar to the repo-server Pod.
|
||||
This is a good option for a more complex plugin that would clutter the Argo CD ConfigMap.
|
||||
This is a good option for a more complex plugin that would clutter the Argo CD ConfigMap. A copy of the repository is sent to the sidecar container as a tarball and processed individually per application, which makes it a good option for [concurrent processing of monorepos](../operator-manual/high_availability.md#enable-concurrent-processing).
|
||||
|
||||
### Option 1: Configure plugins via Argo CD configmap
|
||||
|
||||
|
||||
@@ -187,3 +187,17 @@ spec:
|
||||
```
|
||||
|
||||
The example above shows how an ArgoCD Application can be configured so it will ignore the `spec.replicas` field from the desired state (git) during the sync stage. This is achieve by calculating and pre-patching the desired state before applying it in the cluster. Note that the `RespectIgnoreDifferences` sync option is only effective when the resource is already created in the cluster. If the Application is being created and no live state exists, the desired state is applied as-is.
|
||||
|
||||
## Create Namespace
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
namespace: test
|
||||
spec:
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
The example above shows how an Argo CD Application can be configured so it will create namespaces for the Application resources if the namespaces don't exist already. Without this either declared in the Application manifest or passed in the cli via `--sync-option CreateNamespace=true`, the Application will fail to sync if the resources' namespaces do not exist.
|
||||
|
||||
2
go.mod
2
go.mod
@@ -9,7 +9,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.7.1
|
||||
github.com/argoproj/gitops-engine v0.7.3
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
|
||||
github.com/aws/aws-sdk-go v1.38.49
|
||||
|
||||
4
go.sum
4
go.sum
@@ -146,8 +146,8 @@ github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH
|
||||
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/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc=
|
||||
github.com/argoproj/gitops-engine v0.7.1 h1:aqRcIyW+Fu2wGplPOwGjABTESzQs3VBvl9A4aj5JV1c=
|
||||
github.com/argoproj/gitops-engine v0.7.1/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
|
||||
github.com/argoproj/gitops-engine v0.7.3 h1:0ZlRTReAJG5Y1PviQ8ZIJq/+VowxWe2uFwoXqYcbtXU=
|
||||
github.com/argoproj/gitops-engine v0.7.3/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320 h1:XDjtTfccs4rSOT1n+i1zV9RpxQdKky1b4YBic16E0qY=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320/go.mod h1:R3zlopt+/juYlebQc9Jarn9vBQ2xZruWOWjUNkfGY9M=
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.9
|
||||
newTag: v2.4.11
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -9385,7 +9385,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9615,7 +9615,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -9664,7 +9664,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -9851,7 +9851,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.9
|
||||
newTag: v2.4.11
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.9
|
||||
newTag: v2.4.11
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -10320,7 +10320,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -10417,7 +10417,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -10457,7 +10457,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10714,7 +10714,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10763,7 +10763,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -11010,7 +11010,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -11218,7 +11218,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1244,7 +1244,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1341,7 +1341,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1381,7 +1381,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1638,7 +1638,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1687,7 +1687,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1934,7 +1934,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2142,7 +2142,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -9692,7 +9692,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9789,7 +9789,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -9829,7 +9829,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10054,7 +10054,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10103,7 +10103,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -10346,7 +10346,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -10548,7 +10548,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -616,7 +616,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -713,7 +713,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -753,7 +753,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -978,7 +978,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1027,7 +1027,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1270,7 +1270,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1472,7 +1472,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.9
|
||||
image: quay.io/argoproj/argocd:v2.4.11
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -195,30 +195,40 @@ func (repo *Repository) GetHelmCreds() helm.Creds {
|
||||
}
|
||||
|
||||
func getCAPath(repoURL string) string {
|
||||
hostname := ""
|
||||
// For git ssh protocol url without ssh://, url.Parse() will fail to parse.
|
||||
// However, no warn log is output since ssh scheme url is a possible format.
|
||||
if ok, _ := git.IsSSHURL(repoURL); ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
hostname := ""
|
||||
// url.Parse() will happily parse most things thrown at it. When the URL
|
||||
// is either https or oci, we use the parsed hostname to receive the cert,
|
||||
// otherwise we'll use the parsed path (OCI repos are often specified as
|
||||
// hostname, without protocol).
|
||||
if parsedURL, err := url.Parse(repoURL); err == nil {
|
||||
if parsedURL.Scheme == "https" || parsedURL.Scheme == "oci" {
|
||||
hostname = parsedURL.Host
|
||||
} else if parsedURL.Scheme == "" {
|
||||
hostname = parsedURL.Path
|
||||
}
|
||||
} else {
|
||||
parsedURL, err := url.Parse(repoURL)
|
||||
if err != nil {
|
||||
log.Warnf("Could not parse repo URL '%s': %v", repoURL, err)
|
||||
return ""
|
||||
}
|
||||
if parsedURL.Scheme == "https" || parsedURL.Scheme == "oci" {
|
||||
hostname = parsedURL.Host
|
||||
} else if parsedURL.Scheme == "" {
|
||||
hostname = parsedURL.Path
|
||||
}
|
||||
|
||||
if hostname != "" {
|
||||
if caPath, err := cert.GetCertBundlePathForRepository(hostname); err == nil {
|
||||
return caPath
|
||||
} else {
|
||||
log.Warnf("Could not get cert bundle path for repository '%s': %v", repoURL, err)
|
||||
}
|
||||
if hostname == "" {
|
||||
log.Warnf("Could not get hostname for repository '%s'", repoURL)
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
|
||||
caPath, err := cert.GetCertBundlePathForRepository(hostname)
|
||||
if err != nil {
|
||||
log.Warnf("Could not get cert bundle path for repository '%s': %v", repoURL, err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return caPath
|
||||
}
|
||||
|
||||
// CopySettingsFrom copies all repository settings from source to receiver
|
||||
|
||||
@@ -2628,6 +2628,7 @@ func TestGetCAPath(t *testing.T) {
|
||||
"oci://bar.example.com",
|
||||
"bar.example.com",
|
||||
"ssh://foo.example.com",
|
||||
"git@example.com:organization/reponame.git",
|
||||
"/some/invalid/thing",
|
||||
"../another/invalid/thing",
|
||||
"./also/invalid",
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -1600,9 +1601,11 @@ func TestSyncWithInfos(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource console which does not require namespace
|
||||
//Expect: no app.Status.Conditions
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource console which does not require namespace
|
||||
//
|
||||
// Expect: no app.Status.Conditions
|
||||
func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) {
|
||||
Given(t).
|
||||
Path(globalWithNoNameSpace).
|
||||
@@ -1617,10 +1620,12 @@ func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Deployment and service do not have namespace in manifest
|
||||
//Expect: app.Status.Conditions for deployment ans service which does not have namespace in manifest
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Deployment and service do not have namespace in manifest
|
||||
//
|
||||
// Expect: app.Status.Conditions for deployment ans service which does not have namespace in manifest
|
||||
func TestCreateAppWithNoNameSpaceWhenRequired(t *testing.T) {
|
||||
Given(t).
|
||||
Path(guestbookPath).
|
||||
@@ -1638,11 +1643,13 @@ func TestCreateAppWithNoNameSpaceWhenRequired(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Some deployment and service has namespace in manifest
|
||||
// Some deployment and service does not have namespace in manifest
|
||||
//Expect: app.Status.Conditions for deployment and service which does not have namespace in manifest
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Some deployment and service has namespace in manifest
|
||||
// Some deployment and service does not have namespace in manifest
|
||||
//
|
||||
// Expect: app.Status.Conditions for deployment and service which does not have namespace in manifest
|
||||
func TestCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) {
|
||||
Given(t).
|
||||
Path(guestbookWithNamespace).
|
||||
@@ -1718,10 +1725,13 @@ func TestListResource(t *testing.T) {
|
||||
}
|
||||
|
||||
// Given application is set with --sync-option CreateNamespace=true
|
||||
// application --dest-namespace does not exist
|
||||
//
|
||||
// application --dest-namespace does not exist
|
||||
//
|
||||
// Verity application --dest-namespace is created
|
||||
// application sync successful
|
||||
// when application is deleted, --dest-namespace is not deleted
|
||||
//
|
||||
// application sync successful
|
||||
// when application is deleted, --dest-namespace is not deleted
|
||||
func TestNamespaceAutoCreation(t *testing.T) {
|
||||
SkipOnEnv(t, "OPENSHIFT")
|
||||
updatedNamespace := getNewNamespace(t)
|
||||
@@ -2320,5 +2330,58 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a cluster-scoped resource that is not referencing itself
|
||||
FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "e2e-test-clusterrole",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
fixture.TestingLabel: "true",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a cluster-scoped resource that is referencing itself
|
||||
FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "e2e-other-clusterrole",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
fixture.TestingLabel: "true",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
Sync("--prune").
|
||||
And(func() {
|
||||
// The extra configmap must be pruned now, because it's tracked and does not exist in git
|
||||
cr, err := KubeClientset.RbacV1().ClusterRoles().Get(context.Background(), "e2e-other-clusterrole", metav1.GetOptions{})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "", cr.Name)
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy))
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ const (
|
||||
defaultAdminPassword = "password"
|
||||
defaultAdminUsername = "admin"
|
||||
DefaultTestUserPassword = "password"
|
||||
testingLabel = "e2e.argoproj.io"
|
||||
TestingLabel = "e2e.argoproj.io"
|
||||
ArgoCDNamespace = "argocd-e2e"
|
||||
|
||||
// ensure all repos are in one directory tree, so we can easily clean them up
|
||||
@@ -299,7 +299,7 @@ func CreateSecret(username, password string) string {
|
||||
"--from-literal=username="+username,
|
||||
"--from-literal=password="+password,
|
||||
"-n", TestNamespace()))
|
||||
FailOnErr(Run("", "kubectl", "label", "secret", secretName, testingLabel+"=true", "-n", TestNamespace()))
|
||||
FailOnErr(Run("", "kubectl", "label", "secret", secretName, TestingLabel+"=true", "-n", TestNamespace()))
|
||||
return secretName
|
||||
}
|
||||
|
||||
@@ -521,10 +521,11 @@ func EnsureCleanState(t *testing.T) {
|
||||
v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster}))
|
||||
// kubectl delete secrets -l e2e.argoproj.io=true
|
||||
CheckError(KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(),
|
||||
v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: testingLabel + "=true"}))
|
||||
v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: TestingLabel + "=true"}))
|
||||
|
||||
FailOnErr(Run("", "kubectl", "delete", "ns", "-l", testingLabel+"=true", "--field-selector", "status.phase=Active", "--wait=false"))
|
||||
FailOnErr(Run("", "kubectl", "delete", "crd", "-l", testingLabel+"=true", "--wait=false"))
|
||||
FailOnErr(Run("", "kubectl", "delete", "ns", "-l", TestingLabel+"=true", "--field-selector", "status.phase=Active", "--wait=false"))
|
||||
FailOnErr(Run("", "kubectl", "delete", "crd", "-l", TestingLabel+"=true", "--wait=false"))
|
||||
FailOnErr(Run("", "kubectl", "delete", "clusterroles", "-l", TestingLabel+"=true", "--wait=false"))
|
||||
|
||||
// reset settings
|
||||
updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
|
||||
@@ -615,7 +616,7 @@ func EnsureCleanState(t *testing.T) {
|
||||
|
||||
// create namespace
|
||||
FailOnErr(Run("", "kubectl", "create", "ns", DeploymentNamespace()))
|
||||
FailOnErr(Run("", "kubectl", "label", "ns", DeploymentNamespace(), testingLabel+"=true"))
|
||||
FailOnErr(Run("", "kubectl", "label", "ns", DeploymentNamespace(), TestingLabel+"=true"))
|
||||
|
||||
log.WithFields(log.Fields{"duration": time.Since(start), "name": t.Name(), "id": id, "username": "admin", "password": "password"}).Info("clean state")
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import * as React from 'react';
|
||||
import * as ReactForm from 'react-form';
|
||||
import {Text} from 'react-form';
|
||||
import * as moment from 'moment';
|
||||
import {BehaviorSubject, from, fromEvent, merge, Observable, Observer, Subscription} from 'rxjs';
|
||||
import {debounceTime} from 'rxjs/operators';
|
||||
import {BehaviorSubject, combineLatest, concat, from, fromEvent, Observable, Observer, Subscription} from 'rxjs';
|
||||
import {debounceTime, map} from 'rxjs/operators';
|
||||
import {AppContext, Context, ContextApis} from '../../shared/context';
|
||||
import {ResourceTreeNode} from './application-resource-tree/application-resource-tree';
|
||||
|
||||
@@ -321,7 +321,6 @@ function getActionItems(
|
||||
appChanged: BehaviorSubject<appModels.Application>,
|
||||
isQuickStart: boolean
|
||||
): Observable<ActionMenuItem[]> {
|
||||
let menuItems: Observable<ActionMenuItem[]>;
|
||||
const isRoot = resource.root && nodeKey(resource.root) === nodeKey(resource);
|
||||
const items: MenuItem[] = [
|
||||
...((isRoot && [
|
||||
@@ -365,44 +364,51 @@ function getActionItems(
|
||||
.then(async settings => {
|
||||
const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name);
|
||||
if (resource.kind === 'Pod' && settings.execEnabled && execAllowed) {
|
||||
return items.concat([
|
||||
return [
|
||||
{
|
||||
title: 'Exec',
|
||||
iconClassName: 'fa fa-terminal',
|
||||
action: async () => appContext.apis.navigation.goto('.', {node: nodeKey(resource), tab: 'exec'}, {replace: true})
|
||||
}
|
||||
]);
|
||||
} as MenuItem
|
||||
];
|
||||
}
|
||||
return items;
|
||||
return [] as MenuItem[];
|
||||
})
|
||||
.catch(() => items);
|
||||
.catch(() => [] as MenuItem[]);
|
||||
|
||||
const resourceActions = services.applications
|
||||
.getResourceActions(application.metadata.name, resource)
|
||||
.then(actions => {
|
||||
return items.concat(
|
||||
actions.map(action => ({
|
||||
title: action.name,
|
||||
disabled: !!action.disabled,
|
||||
action: async () => {
|
||||
try {
|
||||
const confirmed = await appContext.apis.popup.confirm(`Execute '${action.name}' action?`, `Are you sure you want to execute '${action.name}' action?`);
|
||||
if (confirmed) {
|
||||
await services.applications.runResourceAction(application.metadata.name, resource, action.name);
|
||||
return actions.map(
|
||||
action =>
|
||||
({
|
||||
title: action.name,
|
||||
disabled: !!action.disabled,
|
||||
action: async () => {
|
||||
try {
|
||||
const confirmed = await appContext.apis.popup.confirm(
|
||||
`Execute '${action.name}' action?`,
|
||||
`Are you sure you want to execute '${action.name}' action?`
|
||||
);
|
||||
if (confirmed) {
|
||||
await services.applications.runResourceAction(application.metadata.name, resource, action.name);
|
||||
}
|
||||
} catch (e) {
|
||||
appContext.apis.notifications.show({
|
||||
content: <ErrorNotification title='Unable to execute resource action' e={e} />,
|
||||
type: NotificationType.Error
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
appContext.apis.notifications.show({
|
||||
content: <ErrorNotification title='Unable to execute resource action' e={e} />,
|
||||
type: NotificationType.Error
|
||||
});
|
||||
}
|
||||
}
|
||||
}))
|
||||
} as MenuItem)
|
||||
);
|
||||
})
|
||||
.catch(() => items);
|
||||
menuItems = merge(from([items]), from(resourceActions), from(execAction));
|
||||
return menuItems;
|
||||
.catch(() => [] as MenuItem[]);
|
||||
return combineLatest(
|
||||
from([items]), // this resolves immediately
|
||||
concat([[] as MenuItem[]], resourceActions), // this resolves at first to [] and then whatever the API returns
|
||||
concat([[] as MenuItem[]], execAction) // this resolves at first to [] and then whatever the API returns
|
||||
).pipe(map(res => ([] as MenuItem[]).concat(...res)));
|
||||
}
|
||||
|
||||
export function renderResourceMenu(
|
||||
|
||||
Reference in New Issue
Block a user