Compare commits

...

32 Commits

Author SHA1 Message Date
argo-bot
1ba9008536 Bump version to 2.4.9 2022-08-11 15:08:32 +00:00
argo-bot
2b873f0b3a Bump version to 2.4.9 2022-08-11 15:08:25 +00:00
Michael Crenshaw
3fdb6ae960 docs: fix version reference for logs UI fix (#10245)
Signed-off-by: CI <michael@crenshaw.dev>
2022-08-09 17:27:27 -04:00
Brandon High
d40ebce7b3 docs: Document ignoreAggregatedRoles setting (#10206)
Signed-off-by: Brandon High <highb@users.noreply.github.com>
2022-08-09 12:05:01 -04:00
César M. Cristóbal
d945e9f256 docs: fix microsoft user management mapping role (#10251)
Signed-off-by: CI <michael@crenshaw.dev>
2022-08-09 10:17:18 -04:00
Sverre Boschman
fb75ada4c2 docs(applicationset): fix layout matrix/merge generator restrictions (#10246)
Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>

Signed-off-by: Sverre Boschman <1142569+sboschman@users.noreply.github.com>
2022-08-09 10:08:15 -04:00
Kerwood
05c9ba27e3 fix: Drop all references to exec unless the feature is enabled (#9920) (#10187)
* fix:  Drop all references to exec unless the feature is enabled #9920

Signed-off-by: Patrick Kerwood <patrick@kerwood.dk>

* fixed tslint issues

Signed-off-by: Patrick Kerwood <patrick@kerwood.dk>
2022-08-08 16:33:10 -04:00
reggie-k
77c972d27e fix: UI part for logs RBAC - do not display the logs tab when no RBAC in place (#7211) (#9828)
* show logs tab only upon explicit rbac allow policy

Signed-off-by: reggie-k <reginakagan@gmail.com>

* 2.4.7 docs edit

Signed-off-by: reggie-k <reginakagan@gmail.com>
2022-08-08 16:31:11 -04:00
jannfis
7e0ee5c449 fix: Ignore non-self-referencing resources while pruning (#10198)
* fix: Ignore non-self-referencing resources while pruning

Signed-off-by: jannfis <jann@mistrust.net>
2022-08-08 17:44:12 +00:00
Sahdev Zala
164284e329 docs: correct the api field description for the GitLab example (#10081)
The api field description for the GitLab example seems mistakenly
copied from the GitHub example.

Signed-off-by: Sahdev Zala <spzala@us.ibm.com>
2022-08-05 15:24:53 -04:00
Renaud Guérin
ac2c1618b2 docs: Use ConfigMap to disable TLS (#10106)
* docs: Use ConfigMap to disable TLS

Signed-off-by: Renaud Guerin <renaud@renaudguerin.net>

* Fix typo

Signed-off-by: Renaud Guerin <renaud@renaudguerin.net>
2022-08-04 17:00:15 -04:00
my-git9
4ee796604a docs: improve Installation.md (#10173)
Signed-off-by: xin.li <xin.li@daocloud.io>
2022-08-04 10:23:20 -04:00
Yves Richard
118d4d3c58 docs: fix kustomize namePrefix misconception in application.yaml (#10162)
* Update docs/operator-manual/application.yaml

- Removed comment about what namePrefix does. (i.e. it does not add a prefix to the image)
- Added examples of other supported transformers. (based on looking at the source code)
- Added link to the kustomize docs where the transormers are described in more detail.

* Update kustomize casing to be consistent

Signed-off-by: whyvez <yves@premise.com>
2022-08-03 14:40:10 -04:00
Mohamed Iflan
912fe33009 docs: Fixed indentation Error (#10123)
* Fixed indentation Error

Signed-off-by: iflan7744 <iflan_mohamed@yahoo.com>

* Fixed indentation Error for top-level data key

Signed-off-by: iflan7744 <iflan_mohamed@yahoo.com>

Co-authored-by: iflan7744 <iflan_mohamed@yahoo.com>
Signed-off-by: CI <michael@crenshaw.dev>
2022-08-01 10:40:08 -04:00
argo-bot
844f79eb9d Bump version to 2.4.8 2022-07-29 16:47:18 +00:00
argo-bot
ecfa0da491 Bump version to 2.4.8 2022-07-29 16:47:13 +00:00
Alexander Matyushentsev
fac8466e86 fix: extensions is not loading for ConfigMap/Pods (#10010)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-07-28 12:50:06 -07:00
Alexander Matyushentsev
ac34ff23c4 feat: support application level extensions (#9923)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-07-28 12:50:03 -07:00
Alexander Matyushentsev
a85d88d479 feat: support multiple extensions per resource group/kind (#9834)
* feat: support multiple extensions per resource group/kind

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* apply reviewers suggestions

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* apply reviewer notes: stream extension files one by one

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* wrap errors

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* skip symlinks

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-07-28 12:50:00 -07:00
dependabot[bot]
40075da70c chore(deps): bump moment from 2.29.3 to 2.29.4 in /ui (#9897)
Bumps [moment](https://github.com/moment/moment) from 2.29.3 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.3...2.29.4)

Signed-off-by: CI <michael@crenshaw.dev>
---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-28 15:37:25 -04:00
Snyk bot
779e383f64 fix: upgrade moment from 2.29.2 to 2.29.3 (#9330)
Snyk has created this PR to upgrade moment from 2.29.2 to 2.29.3.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/argoproj/project/d2931792-eef9-4d7c-b9d6-c0cbd2bd4dbe?utm_source=github&utm_medium=referral&page=upgrade-pr
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-28 15:36:47 -04:00
Michael Crenshaw
3e523dbab7 fix: skip redirect url validation when it's the base href (#10058) (#10116)
* fix: skip redirect url validation when it's the base href (#10058)

Signed-off-by: CI <michael@crenshaw.dev>

nicer way of doing it

Signed-off-by: CI <michael@crenshaw.dev>

* fix missin arg

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 16:38:05 -04:00
Michael Crenshaw
4df892fecf docs: add OpenSSH breaking change notes (#10104)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 15:26:49 -04:00
Michael Crenshaw
670a1756d7 fix: avoid CVE-2022-28948 (#10093)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 15:03:09 -04:00
Michael Crenshaw
5721f559f0 chore: update parse-url (#10101)
* chore: upgrade parse-url

Signed-off-by: CI <michael@crenshaw.dev>

* edit a generated file, because that's smart

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 14:57:06 -04:00
Sahdev Zala
e23178a8d1 docs: add api field example in the appset security doc (#10087)
It seems like most of the work for the mentioned issue below is done
under the PR #9466 but from the issue description, it's probably
worth to mention the example as added here.

Related #9352

Signed-off-by: Sahdev Zala <spzala@us.ibm.com>
2022-07-26 09:15:31 -04:00
Hyeonmin Park
918e5eadf4 fix: Set HOST_ARCH for yarn build from platform (#10018)
Signed-off-by: Hyeonmin Park <hyeonmin.park@kennysoft.kr>
2022-07-25 12:27:29 -04:00
34FathomBelow
55de2b9dab chore: update redis to 7.0.4 avoid CVE-2022-30065 (#10059)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-07-20 17:11:44 -04:00
Ashutosh
c48004f944 docs: add argocd-server grpc metric usage (#10007)
Signed-off-by: Ashutosh <mail.ashutosh8@gmail.com>

Co-authored-by: Ashutosh <mail.ashutosh8@gmail.com>
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-20 14:58:32 -04:00
Michael Crenshaw
f7b6a38041 chore: upgrade Dex to 2.32.0 (#10036) (#10042)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-20 10:45:24 -04:00
Michael Crenshaw
91eb9925ef chore: update redis to avoid CVE-2022-2097 (#10031)
* chore: update redis to avoid CVE-2022-2097

Signed-off-by: CI <michael@crenshaw.dev>

* codegen

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-20 10:38:36 -04:00
34FathomBelow
6190964899 chore: update haproxy to 2.0.29 for redis-ha (#10045)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-07-19 15:05:40 -04:00
49 changed files with 680 additions and 315 deletions

View File

@@ -407,7 +407,7 @@ jobs:
run: |
docker pull quay.io/dexidp/dex:v2.25.0
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:7.0.0-alpine
docker pull redis:7.0.4-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist

View File

@@ -13,9 +13,13 @@ commands, and helps to troubleshoot the application state.
Argo CD is used to manage the critical infrastructure of multiple organizations, which makes security the top priority of the project. We've listened to
your feedback and introduced additional access control settings that control access to Kubernetes Pod logs and the new Web Terminal feature.
#### Known UI Issue for Pod Logs Access
#### Pod Logs UI
Currently, upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
Since 2.4.9, the LOGS tab in pod view is visible in the UI only for users with explicit allow get logs policy.
#### Known pod logs UI issue prior to 2.4.9
Upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
### OpenTelemetry Tracing Integration

View File

@@ -92,12 +92,13 @@ COPY ["ui/", "."]
ARG ARGO_VERSION=latest
ENV ARGO_VERSION=$ARGO_VERSION
RUN HOST_ARCH='amd64' NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OPTIONS=--max_old_space_size=8192 yarn build
ARG TARGETARCH
RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OPTIONS=--max_old_space_size=8192 yarn build
####################################################################################################
# Argo CD Build stage which performs the actual build of Argo CD binaries
####################################################################################################
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.18 AS argocd-build
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.18 AS argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd

View File

@@ -1 +1 @@
2.4.7
2.4.9

View File

@@ -205,6 +205,13 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
reconciliationResult.Target = patchedTargets
}
appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey()
if err != nil {
log.Errorf("Could not get appInstanceLabelKey: %v", err)
return
}
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
syncCtx, cleanup, err := sync.NewSyncContext(
compareResult.syncStatus.Revision,
reconciliationResult,
@@ -217,7 +224,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
sync.WithHealthOverride(lua.ResourceHealthOverrides(resourceOverrides)),
sync.WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error {
if !proj.IsGroupKindPermitted(un.GroupVersionKind().GroupKind(), res.Namespaced) {
return fmt.Errorf("Resource %s:%s is not permitted in project %s.", un.GroupVersionKind().Group, un.GroupVersionKind().Kind, proj.Name)
return fmt.Errorf("resource %s:%s is not permitted in project %s", un.GroupVersionKind().Group, un.GroupVersionKind().Kind, proj.Name)
}
if res.Namespaced && !proj.IsDestinationPermitted(v1alpha1.ApplicationDestination{Namespace: un.GetNamespace(), Server: app.Spec.Destination.Server, Name: app.Spec.Destination.Name}) {
return fmt.Errorf("namespace %v is not permitted in project '%s'", un.GetNamespace(), proj.Name)
@@ -227,7 +234,9 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
sync.WithOperationSettings(syncOp.DryRun, syncOp.Prune, syncOp.SyncStrategy.Force(), syncOp.IsApplyStrategy() || len(syncOp.Resources) > 0),
sync.WithInitialState(state.Phase, state.Message, initialResourcesRes, state.StartedAt),
sync.WithResourcesFilter(func(key kube.ResourceKey, target *unstructured.Unstructured, live *unstructured.Unstructured) bool {
return len(syncOp.Resources) == 0 || argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)
return (len(syncOp.Resources) == 0 ||
argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) &&
m.isSelfReferencedObj(live, appLabelKey, trackingMethod)
}),
sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)),
sync.WithNamespaceCreation(syncOp.SyncOptions.HasOption("CreateNamespace=true"), func(un *unstructured.Unstructured) bool {

View File

@@ -0,0 +1,64 @@
# UI Extensions
Argo CD web user interface can be extended with additional UI elements. Extensions should be delivered as a javascript file
in the `argocd-server` Pods that are placed in the `/tmp/extensions` directory and starts with `extension` prefix ( matches to `^extension(.*)\.js$` regex ).
```
/tmp/extensions
├── example1
│   └── extension-1.js
└── example2
└── extension-2.js
```
Extensions are loaded during initial page rendering and should register themselves using API exposed in the `extensionsAPI` global variable. (See
corresponding extension type details for additional information).
The extension should provide a React component that is responsible for rendering the UI element. Extension should not bundle the React library.
Instead extension should use the `react` global variable. You can leverage `externals` setting if you are using webpack:
```js
externals: {
react: 'React'
}
```
## Resource Tab Extensions
Resource Tab extensions is an extension that provides an additional tab for the resource sliding panel at the Argo CD Application details page.
The resource tab extension should be registered using the `extensionsAPI.registerResourceExtension` method:
```typescript
registerResourceExtension(component: ExtensionComponent, group: string, kind: string, tabTitle: string)
```
* `component: ExtensionComponent` is a React component that receives the following properties:
* application: Application - Argo CD Application resource;
* resource: State - the kubernetes resource object;
* tree: ApplicationTree - includes list of all resources that comprise the application;
See properties interfaces in [models.ts](https://github.com/argoproj/argo-cd/blob/master/ui/src/app/shared/models.ts)
* `group: string` - the glob expression that matches the group of the resource; note: use globstar (`**`) to match all groups including empty string;
* `kind: string` - the glob expression that matches the kind of the resource;
* `tabTitle: string` - the extension tab title.
* `opts: Object` - additional options:
* `icon: string` - the class name the represents the icon from the [https://fontawesome.com/](https://fontawesome.com/) library (e.g. 'fa-calendar-alt');
Below is an example of a resource tab extension:
```javascript
((window) => {
const component = () => {
return React.createElement( 'div', {}, 'Hello World' );
};
window.extensionsAPI.registerResourceExtension(component, '*', '*', 'Nice extension');
})(window)
```
## Application Tab Extensions
Since the Argo CD Application is a Kubernetes resource, application tabs can be the same as any other resource tab.
Make sure to use 'argoproj.io'/'Application' as group/kind and an extension will be used to render the application-level tab.

View File

@@ -69,11 +69,16 @@ spec:
kustomize:
# Optional kustomize version. Note: version must be configured in argocd-cm ConfigMap
version: v3.5.4
# Optional image name prefix
# Supported kustomize transformers. https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/
namePrefix: prod-
# Optional images passed to "kustomize edit set image".
nameSuffix: -some-suffix
commonLabels:
foo: bar
commonAnnotations:
beep: boop
images:
- gcr.io/heptio-images/ks-guestbook-demo:0.2
- my-app=gcr.io/my-repo/my-app:0.1
# directory
directory:

View File

@@ -107,32 +107,33 @@ Finally, the Matrix generator will combine both sets of outputs, and produce:
## Restrictions
1. The Matrix generator currently only supports combining the outputs of only two child generators (eg does not support generating combinations for 3 or more).
1. You should specify only a single generator per array entry, eg this is not valid:
```yaml
- matrix:
generators:
- list: # (...)
git: # (...)
```
- matrix:
generators:
- list: # (...)
git: # (...)
- While this *will* be accepted by Kubernetes API validation, the controller will report an error on generation. Each generator should be specified in a separate array element, as in the examples above.
1. The Matrix generator does not currently support [`template` overrides](Template.md#generator-templates) specified on child generators, eg this `template` will not be processed:
```yaml
- matrix:
generators:
- list:
elements:
- # (...)
template: { } # Not processed
```
- matrix:
generators:
- list:
elements:
- # (...)
template: { } # Not processed
1. Combination-type generators (matrix or merge) can only be nested once. For example, this will not work:
```yaml
- matrix:
generators:
- matrix:
generators:
- matrix: # This third level is invalid.
generators:
- list:
elements:
- # (...)
```
- matrix:
generators:
- matrix:
generators:
- matrix: # This third level is invalid.
generators:
- list:
elements:
- # (...)

View File

@@ -114,31 +114,31 @@ When merged with the updated base parameters, the `values.redis` value for the p
## Restrictions
1. You should specify only a single generator per array entry. This is not valid:
```yaml
- merge:
generators:
- list: # (...)
git: # (...)
```
- merge:
generators:
- list: # (...)
git: # (...)
- While this *will* be accepted by Kubernetes API validation, the controller will report an error on generation. Each generator should be specified in a separate array element, as in the examples above.
1. The Merge generator does not support [`template` overrides](Template.md#generator-templates) specified on child generators. This `template` will not be processed:
```yaml
- merge:
generators:
- list:
elements:
- # (...)
template: { } # Not processed
```
- merge:
generators:
- list:
elements:
- # (...)
template: { } # Not processed
1. Combination-type generators (Matrix or Merge) can only be nested once. For example, this will not work:
```yaml
- merge:
generators:
- merge:
generators:
- merge: # This third level is invalid.
generators:
- list:
elements:
- # (...)
```
- merge:
generators:
- merge:
generators:
- merge: # This third level is invalid.
generators:
- list:
elements:
- # (...)

View File

@@ -76,7 +76,7 @@ spec:
gitlab:
# The base GitLab group to scan. You can either use the group id or the full namespaced path.
group: "8675309"
# For GitLab Enterprise:
# For self-hosted GitLab:
api: https://gitlab.example.com/
# If true, scan every branch of every repository. If false, scan only the default branch. Defaults to false.
allBranches: true
@@ -91,7 +91,7 @@ spec:
```
* `group`: Required name of the base GitLab group to scan. If you have multiple base groups, use multiple generators.
* `api`: If using GitHub Enterprise, the URL to access it.
* `api`: If using self-hosted GitLab, the URL to access it.
* `allBranches`: By default (false) the template will only be evaluated for the default branch of each repo. If this is true, every branch of every repository will be passed to the filters. If using this flag, you likely want to use a `branchMatch` filter.
* `includeSubgroups`: By default (false) the controller will only search for repos directly in the base group. If this is true, it will recurse through all the subgroups searching for repos to scan.
* `tokenRef`: A `Secret` name and key containing the GitLab access token to use for requests. If not specified, will make anonymous requests which have a lower rate limit and can only see public repositories.

View File

@@ -4,7 +4,7 @@ Generators are responsible for generating *parameters*, which are then rendered
Generators are primarily based on the data source that they use to generate the template parameters. For example: the List generator provides a set of parameters from a *literal list*, the Cluster generator uses the *Argo CD cluster list* as a source, the Git generator uses files/directories from a *Git repository*, and so.
As of this writing there are seven generators:
As of this writing there are eight generators:
- [List generator](Generators-List.md): The List generator allows you to target Argo CD Applications to clusters based on a fixed list of cluster name/URL values.
- [Cluster generator](Generators-Cluster.md): The Cluster generator allows you to target Argo CD Applications to clusters, based on the list of clusters defined within (and managed by) Argo CD (which includes automatically responding to cluster addition/removal events from Argo CD).

View File

@@ -11,8 +11,8 @@ resources of Argo CD itself (like the RBAC ConfigMap).
ApplicationSets can also quickly create an arbitrary number of Applications and just as quickly delete them.
Finally, ApplicationSets can reveal privileged information. For example, the [git generator](./Generators-Git.md) can
read Secrets in the Argo CD namespace and send them to arbitrary URLs as auth headers. (This functionality is intended
for authorizing requests to SCM providers like GitHub, but it could be abused by a malicious user.)
read Secrets in the Argo CD namespace and send them to arbitrary URLs (e.g. URL provided for the `api` field) as auth headers.
(This functionality is intended for authorizing requests to SCM providers like GitHub, but it could be abused by a malicious user.)
For these reasons, **only admins** may be given permission (via Kubernetes RBAC or any other mechanism) to create,
update, or delete ApplicationSets.

View File

@@ -36,8 +36,9 @@ data:
help.chatUrl: "https://mycorp.slack.com/argo-cd"
# the text for getting chat help, defaults to "Chat now!"
help.chatText: "Chat now!"
# The URLs to download additional ArgoCD binaries (besides the Linux amd64 binary included by default)
# The URLs to download additional ArgoCD binaries (besides the Linux with current platform binary included by default)
# for different OS architectures. If provided, additional download buttons will be displayed on the help page.
help.download.linux-amd64: "path-or-url-to-download"
help.download.linux-arm64: "path-or-url-to-download"
help.download.linux-ppc64le: "path-or-url-to-download"
help.download.linux-s390x: "path-or-url-to-download"

View File

@@ -12,7 +12,7 @@ There are several ways how Ingress can be configured.
The Ambassador Edge Stack can be used as a Kubernetes ingress controller with [automatic TLS termination](https://www.getambassador.io/docs/latest/topics/running/tls/#host) and routing capabilities for both the CLI and the UI.
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command. Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required.
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required.
### Option 1: Mapping CRD for Host-based Routing
```yaml
@@ -72,7 +72,7 @@ argocd login <host>:<port> --grpc-web-root-path /argo-cd
## [Contour](https://projectcontour.io/)
The Contour ingress controller can terminate TLS ingress traffic at the edge.
The Argo CD API server should be run with TLS disabled. Edit the `argocd-server` Deployment to add the `--insecure` flag to the argocd-server container command.
The Argo CD API server should be run with TLS disabled. Edit the `argocd-server` Deployment to add the `--insecure` flag to the argocd-server container command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
It is also possible to provide an internal-only ingress path and an external-only ingress path by deploying two instances of Contour: one behind a private-subnet LoadBalancer service and one behind a public-subnet LoadBalancer service. The private Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-internal` and the public Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-external`.
@@ -164,20 +164,7 @@ spec:
The argocd-server Service needs to be annotated with `projectcontour.io/upstream-protocol.h2c: "https,443"` to wire up the gRPC protocol proxying.
The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the
`--insecure` flag to the argocd-server command:
```yaml
spec:
template:
spec:
containers:
- name: argocd-server
command:
- /argocd-server
- --repo-server
- argocd-repo-server:8081
- --insecure
```
`--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
## [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx)
@@ -319,20 +306,7 @@ spec:
```
The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the
`--insecure` flag to the argocd-server command:
```yaml
spec:
template:
spec:
containers:
- name: argocd-server
command:
- argocd-server
- --repo-server
- argocd-repo-server:8081
- --insecure
```
`--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
The obvious disadvantage to this approach is that this technique requires two separate hostnames for
the API server -- one for gRPC and the other for HTTP/HTTPS. However it allows TLS termination to
@@ -345,7 +319,7 @@ Traefik can be used as an edge router and provide [TLS](https://docs.traefik.io/
It currently has an advantage over NGINX in that it can terminate both TCP and HTTP connections _on the same port_ meaning you do not require multiple hosts or paths.
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command.
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command or set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
### IngressRoute CRD
```yaml
@@ -455,26 +429,9 @@ If you need detail for all the options available for these Google integrations,
### Disable internal TLS
First, to avoid internal redirection loops from HTTP to HTTPS, the API server should be run with TLS disabled. Edit the argocd-server deployment to add the --insecure flag to the argocd-server command. For this you can edit your resource live with `kubectl -n argocd edit deployments.apps argocd-server` or use a kustomize patch before installing Argo CD.
First, to avoid internal redirection loops from HTTP to HTTPS, the API server should be run with TLS disabled.
The container command should change from:
```yaml
containers:
- command:
- argocd-server
- --staticassets
- /shared/app
```
To:
```yaml
containers:
- command:
- argocd-server
- --insecure
- --staticassets
- /shared/app
```
Edit the `--insecure` flag in the `argocd-server` command of the argocd-server deployment, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
### Creating a service

View File

@@ -32,7 +32,7 @@ Not recommended for production use. This type of installation is typically used
> Note: Argo CD CRDs are not included into [namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml).
> and have to be installed separately. The CRD manifests are located in the [manifests/crds](https://github.com/argoproj/argo-cd/blob/master/manifests/crds) directory.
> Use the following command to install them:
> ```bash
> ```
> kubectl apply -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable
> ```

View File

@@ -67,8 +67,10 @@ Scraped at the `argocd-server-metrics:8083/metrics` endpoint.
| Metric | Type | Description |
|--------|:----:|-------------|
| `argocd_redis_request_duration` | histogram | Redis requests duration. |
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. |
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application
reconciliation. |
| `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. |
| `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. |
## Repo Server Metrics
Metrics about the Repo Server.
Scraped at the `argocd-repo-server:8084/metrics` endpoint.

View File

@@ -14,3 +14,76 @@ Note that bundled Helm has been upgraded from 3.6.0 to v3.7+. This includes foll
- Experimental OCI support has been rewritten.
More information in the [Helm v3.7.0 release notes](https://github.com/helm/helm/releases/tag/v3.7.0).
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed in 2.2.12
Argo CD 2.2.12 upgraded its base image from Ubuntu 21.10 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
The signature algorithm is _not_ the same as the algorithm used when generating the key. There is no need to update
keys.
The signature algorithm is negotiated with the SSH server when the connection is being set up. The client offers its
list of accepted signature algorithms, and if the server has a match, the connection proceeds. For most SSH servers on
up-to-date git providers, acceptable algorithms other than `ssh-rsa` should be available.
Before upgrading to Argo CD 2.2.12, check whether your git provider(s) using SSH authentication support algorithms newer
than `rsa-ssh`.
1. Make sure your version of SSH >= 8.9 (the version used by Argo CD). If not, upgrade it before proceeding.
```shell
ssh -V
```
Example output: `OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022`
2. Once you have a recent version of OpenSSH, follow the directions from the [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.7):
> To check whether a server is using the weak ssh-rsa public key
> algorithm, for host authentication, try to connect to it after
> removing the ssh-rsa algorithm from ssh(1)'s allowed list:
>
> ```shell
> ssh -oHostKeyAlgorithms=-ssh-rsa user@host
> ```
>
> If the host key verification fails and no other supported host key
> types are available, the server software on that host should be
> upgraded.
If the server does not support an acceptable version, you will get an error similar to this;
```
$ ssh -oHostKeyAlgorithms=-ssh-rsa vs-ssh.visualstudio.com
Unable to negotiate with 20.42.134.1 port 22: no matching host key type found. Their offer: ssh-rsa
```
This indicates that the server needs to update its supported key signature algorithms, and Argo CD will not connect
to it.
### Workaround
The [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.8) describe a workaround if you cannot change the
server's key signature algorithms configuration.
> Incompatibility is more likely when connecting to older SSH
> implementations that have not been upgraded or have not closely tracked
> improvements in the SSH protocol. For these cases, it may be necessary
> to selectively re-enable RSA/SHA1 to allow connection and/or user
> authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
> options. For example, the following stanza in ~/.ssh/config will enable
> RSA/SHA1 for host and user authentication for a single destination host:
>
> ```
> Host old-host
> HostkeyAlgorithms +ssh-rsa
> PubkeyAcceptedAlgorithms +ssh-rsa
> ```
>
> We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
> implementations can be upgraded or reconfigured with another key type
> (such as ECDSA or Ed25519).
To apply this to Argo CD, you could create a ConfigMap with the desired ssh config file and then mount it at
`/home/argocd/.ssh/config`.

View File

@@ -46,3 +46,77 @@ Note that bundled Kustomize version has been upgraded from 4.2.0 to 4.4.1.
## Upgraded Helm Version
Note that bundled Helm version has been upgraded from 3.7.1 to 3.8.0.
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed in 2.3.7
Argo CD 2.3.7 upgraded its base image from Ubuntu 21.04 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
The signature algorithm is _not_ the same as the algorithm used when generating the key. There is no need to update
keys.
The signature algorithm is negotiated with the SSH server when the connection is being set up. The client offers its
list of accepted signature algorithms, and if the server has a match, the connection proceeds. For most SSH servers on
up-to-date git providers, acceptable algorithms other than `ssh-rsa` should be available.
Before upgrading to Argo CD 2.3.7, check whether your git provider(s) using SSH authentication support algorithms newer
than `rsa-ssh`.
1. Make sure your version of SSH >= 8.9 (the version used by Argo CD). If not, upgrade it before proceeding.
```shell
ssh -V
```
Example output: `OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022`
2. Once you have a recent version of OpenSSH, follow the directions from the [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.7):
> To check whether a server is using the weak ssh-rsa public key
> algorithm, for host authentication, try to connect to it after
> removing the ssh-rsa algorithm from ssh(1)'s allowed list:
>
> ```shell
> ssh -oHostKeyAlgorithms=-ssh-rsa user@host
> ```
>
> If the host key verification fails and no other supported host key
> types are available, the server software on that host should be
> upgraded.
If the server does not support an acceptable version, you will get an error similar to this;
```
$ ssh -oHostKeyAlgorithms=-ssh-rsa vs-ssh.visualstudio.com
Unable to negotiate with 20.42.134.1 port 22: no matching host key type found. Their offer: ssh-rsa
```
This indicates that the server needs to update its supported key signature algorithms, and Argo CD will not connect
to it.
### Workaround
The [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.8) describe a workaround if you cannot change the
server's key signature algorithms configuration.
> Incompatibility is more likely when connecting to older SSH
> implementations that have not been upgraded or have not closely tracked
> improvements in the SSH protocol. For these cases, it may be necessary
> to selectively re-enable RSA/SHA1 to allow connection and/or user
> authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
> options. For example, the following stanza in ~/.ssh/config will enable
> RSA/SHA1 for host and user authentication for a single destination host:
>
> ```
> Host old-host
> HostkeyAlgorithms +ssh-rsa
> PubkeyAcceptedAlgorithms +ssh-rsa
> ```
>
> We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
> implementations can be upgraded or reconfigured with another key type
> (such as ECDSA or Ed25519).
To apply this to Argo CD, you could create a ConfigMap with the desired ssh config file and then mount it at
`/home/argocd/.ssh/config`.

View File

@@ -12,6 +12,8 @@ Helm 2 support was preserved in the Argo CD. We feel that Helm 3 is stable, and
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed
Note: this change was back-ported to 2.3.7 and 2.2.12.
Argo CD 2.4 upgraded its base image from Ubuntu 20.04 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
@@ -149,9 +151,13 @@ p, role:test-db-admins, applications, *, staging-db-admins/*, allow
p, role:test-db-admins, logs, get, staging-db-admins/*, allow
```
## Known UI issue
### Pod Logs UI
Currently, upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
Since 2.4.9, the LOGS tab in pod view is visible in the UI only for users with explicit allow get logs policy.
### Known pod logs UI issue prior to 2.4.9
Upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
## Test repo-server with its new dedicated Service Account

View File

@@ -36,24 +36,24 @@
1. Edit `argocd-cm` and add the following `dex.config` to the data section, replacing the `caData`, `my-argo-cd-url` and `my-login-url` your values from the Azure AD App:
data:
url: https://my-argo-cd-url
dex.config: |
logger:
url: https://my-argo-cd-url
dex.config: |
logger:
level: debug
format: json
connectors:
- type: saml
connectors:
- type: saml
id: saml
name: saml
config:
entityIssuer: https://my-argo-cd-url/api/dex/callback
ssoURL: https://my-login-url (e.g. https://login.microsoftonline.com/xxxxx/a/saml2)
caData: |
MY-BASE64-ENCODED-CERTIFICATE-DATA
redirectURI: https://my-argo-cd-url/api/dex/callback
usernameAttr: email
emailAttr: email
groupsAttr: Group
entityIssuer: https://my-argo-cd-url/api/dex/callback
ssoURL: https://my-login-url (e.g. https://login.microsoftonline.com/xxxxx/a/saml2)
caData: |
MY-BASE64-ENCODED-CERTIFICATE-DATA
redirectURI: https://my-argo-cd-url/api/dex/callback
usernameAttr: email
emailAttr: email
groupsAttr: Group
2. Edit `argocd-rbac-cm` to configure permissions, similar to example below.
- Use Azure AD `Group IDs` for assigning roles.
@@ -169,7 +169,7 @@
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin
scopes: '[roles, email]'
scopes: '[groups, email]'
Refer to [operator-manual/argocd-rbac-cm.yaml](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml) for all of the available variables.

View File

@@ -81,7 +81,7 @@ data:
- '.webhooks[]?.clientConfig.caBundle'
```
Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example bellow shows how to configure ArgoCD to ignore changes made by `kube-controller-manager` in `Deployment` resources.
Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example bellow shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources.
```yaml
data:
@@ -90,7 +90,7 @@ data:
- kube-controller-manager
```
It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an ArgoCD instance. In order to do so, resource customizations can be configured like in the example bellow:
It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example bellow:
```yaml
data:
@@ -116,11 +116,26 @@ data:
By default `status` field is ignored during diffing for `CustomResourceDefinition` resource. The behavior can be extended to all resources using `all` value or disabled using `none`.
### Ignoring RBAC changes made by AggregateRoles
If you are using [Aggregated ClusterRoles](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles) and don't want Argo CD to detect the `rules` changes as drift, you can set `resource.compareoptions.ignoreAggregatedRoles: true`. Then Argo CD will no longer detect these changes as an event that requires syncing.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
resource.compareoptions: |
# disables status field diffing in specified resource types
ignoreAggregatedRoles: true
```
## Known Kubernetes types in CRDs (Resource limits, Volume mounts etc)
Some CRDs are re-using data structures defined in the Kubernetes source base and therefore inheriting custom
JSON/YAML marshaling. Custom marshalers might serialize CRDs in a slightly different format that causes false
positives during drift detection.
positives during drift detection.
A typical example is the `argoproj.io/Rollout` CRD that re-using `core/v1/PodSpec` data structure. Pod resource requests
might be reformatted by the custom marshaller of `IntOrString` data type:
@@ -140,7 +155,7 @@ resources:
```
The solution is to specify which CRDs fields are using built-in Kubernetes types in the `resource.customizations`
section of `argocd-cm` ConfigMap:
section of `argocd-cm` ConfigMap:
```yaml
apiVersion: v1

5
go.mod
View File

@@ -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.0
github.com/argoproj/gitops-engine v0.7.1
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
@@ -257,6 +257,9 @@ replace (
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/improbable-eng/grpc-web => github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
// Avoid CVE-2022-28948
gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
// https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280
k8s.io/api => k8s.io/api v0.23.1
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.1

10
go.sum
View File

@@ -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.0 h1:X6W8VP9bWTe74wWxAV3i8KZ0yBmre5DU8g+GWH09FCo=
github.com/argoproj/gitops-engine v0.7.0/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
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/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=
@@ -1814,10 +1814,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=

View File

@@ -35,7 +35,7 @@ spec:
runAsNonRoot: true
containers:
- name: dex
image: ghcr.io/dexidp/dex:v2.30.2
image: ghcr.io/dexidp/dex:v2.32.0
imagePullPolicy: Always
command: [/shared/argocd-dex, rundex]
securityContext:

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.4.7
newTag: v2.4.9
resources:
- ./application-controller
- ./dex

View File

@@ -21,7 +21,7 @@ spec:
serviceAccountName: argocd-redis
containers:
- name: redis
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: Always
args:
- "--save"

View File

@@ -9385,7 +9385,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9465,7 +9465,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: Always
name: redis
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.4.7
newTag: v2.4.9

View File

@@ -11,7 +11,7 @@ patchesStrategicMerge:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.4.7
newTag: v2.4.9
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -770,7 +770,7 @@ spec:
topologyKey: kubernetes.io/hostname
initContainers:
- name: config-init
image: haproxy:2.0.25-alpine
image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -790,7 +790,7 @@ spec:
runAsUser: 1000
containers:
- name: haproxy
image: haproxy:2.0.25-alpine
image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
@@ -878,7 +878,7 @@ spec:
automountServiceAccountToken: false
initContainers:
- name: config-init
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -906,7 +906,7 @@ spec:
containers:
- name: redis
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
@@ -947,7 +947,7 @@ spec:
lifecycle:
{}
- name: sentinel
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
command:
- redis-sentinel

View File

@@ -9,12 +9,12 @@ redis-ha:
haproxy:
enabled: true
image:
tag: 2.0.25-alpine
tag: 2.0.29-alpine
timeout:
server: 6m
client: 6m
checkInterval: 3s
image:
tag: 7.0.0-alpine
tag: 7.0.4-alpine
sentinel:
bind: "0.0.0.0"

View File

@@ -10320,7 +10320,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -10392,7 +10392,7 @@ spec:
- command:
- /shared/argocd-dex
- rundex
image: ghcr.io/dexidp/dex:v2.30.2
image: ghcr.io/dexidp/dex:v2.32.0
imagePullPolicy: Always
name: dex
ports:
@@ -10417,7 +10417,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -10457,7 +10457,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -10526,7 +10526,7 @@ spec:
app.kubernetes.io/name: argocd-redis-ha-haproxy
topologyKey: kubernetes.io/hostname
containers:
- image: haproxy:2.0.25-alpine
- image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -10555,7 +10555,7 @@ spec:
- /readonly/haproxy_init.sh
command:
- sh
image: haproxy:2.0.25-alpine
image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:
@@ -10714,7 +10714,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -11299,7 +11299,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -11337,7 +11337,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -11383,7 +11383,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:

View File

@@ -1244,7 +1244,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1316,7 +1316,7 @@ spec:
- command:
- /shared/argocd-dex
- rundex
image: ghcr.io/dexidp/dex:v2.30.2
image: ghcr.io/dexidp/dex:v2.32.0
imagePullPolicy: Always
name: dex
ports:
@@ -1341,7 +1341,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1381,7 +1381,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1450,7 +1450,7 @@ spec:
app.kubernetes.io/name: argocd-redis-ha-haproxy
topologyKey: kubernetes.io/hostname
containers:
- image: haproxy:2.0.25-alpine
- image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -1479,7 +1479,7 @@ spec:
- /readonly/haproxy_init.sh
command:
- sh
image: haproxy:2.0.25-alpine
image: haproxy:2.0.29-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:
@@ -1638,7 +1638,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2223,7 +2223,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -2261,7 +2261,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -2307,7 +2307,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:

View File

@@ -9692,7 +9692,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9764,7 +9764,7 @@ spec:
- command:
- /shared/argocd-dex
- rundex
image: ghcr.io/dexidp/dex:v2.30.2
image: ghcr.io/dexidp/dex:v2.32.0
imagePullPolicy: Always
name: dex
ports:
@@ -9789,7 +9789,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -9829,7 +9829,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -9904,7 +9904,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -10054,7 +10054,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -616,7 +616,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -688,7 +688,7 @@ spec:
- command:
- /shared/argocd-dex
- rundex
image: ghcr.io/dexidp/dex:v2.30.2
image: ghcr.io/dexidp/dex:v2.32.0
imagePullPolicy: Always
name: dex
ports:
@@ -713,7 +713,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -753,7 +753,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -828,7 +828,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.0-alpine
image: redis:7.0.4-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -978,7 +978,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.4.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
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.7
image: quay.io/argoproj/argocd:v2.4.9
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -161,6 +161,7 @@ nav:
- developer-guide/releasing.md
- developer-guide/site.md
- developer-guide/static-code-analysis.md
- developer-guide/ui-extensions.md
- developer-guide/faq.md
- faq.md
- security_considerations.md

View File

@@ -4,6 +4,7 @@ import (
"context"
"crypto/tls"
"fmt"
goio "io"
"io/fs"
"math"
"net"
@@ -12,6 +13,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
"reflect"
"regexp"
go_runtime "runtime"
@@ -100,6 +102,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/healthz"
httputil "github.com/argoproj/argo-cd/v2/util/http"
"github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/io/files"
jwtutil "github.com/argoproj/argo-cd/v2/util/jwt"
kubeutil "github.com/argoproj/argo-cd/v2/util/kube"
"github.com/argoproj/argo-cd/v2/util/oidc"
@@ -871,11 +874,11 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
registerDownloadHandlers(mux, "/download")
// Serve extensions
var extensionsApiPath = "/extensions/"
var extensionsSharedPath = "/tmp/extensions/"
extHandler := http.StripPrefix(extensionsApiPath, http.FileServer(http.Dir(extensionsSharedPath)))
mux.HandleFunc(extensionsApiPath, extHandler.ServeHTTP)
mux.HandleFunc("/extensions.js", func(writer http.ResponseWriter, _ *http.Request) {
a.serveExtensions(extensionsSharedPath, writer)
})
// Serve UI static assets
var assetsHandler http.Handler = http.HandlerFunc(a.newStaticAssetsHandler())
@@ -886,6 +889,48 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
return &httpS
}
var extensionsPattern = regexp.MustCompile(`^extension(.*)\.js$`)
func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) {
w.Header().Set("Content-Type", "application/javascript")
err := filepath.Walk(extensionsSharedPath, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("failed to iterate files in '%s': %w", extensionsSharedPath, err)
}
if !files.IsSymlink(info) && !info.IsDir() && extensionsPattern.MatchString(info.Name()) {
processFile := func() error {
if _, err = w.Write([]byte(fmt.Sprintf("// source: %s/%s \n", filePath, info.Name()))); err != nil {
return fmt.Errorf("failed to write to response: %w", err)
}
f, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("failed to open file '%s': %w", filePath, err)
}
defer io.Close(f)
if _, err := goio.Copy(w, f); err != nil {
return fmt.Errorf("failed to copy file '%s': %w", filePath, err)
}
return nil
}
if processFile() != nil {
return fmt.Errorf("failed to serve extension file '%s': %w", filePath, processFile())
}
}
return nil
})
if err != nil && !os.IsNotExist(err) {
log.Errorf("Failed to walk extensions directory: %v", err)
http.Error(w, "Internal error", http.StatusInternalServerError)
return
}
}
// registerDexHandlers will register dex HTTP handlers, creating the the OAuth client app
func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) {
if !a.settings.IsSSOConfigured() {

View File

@@ -1,4 +1,4 @@
FROM redis:7.0.0 as redis
FROM redis:7.0.4 as redis
FROM node:12.18.4-buster as node

View File

@@ -2285,6 +2285,13 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
When().
Sync("--prune").
And(func() {
// The extra configmap must not be pruned, because it's not tracked
cm, err := KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Get(context.Background(), "extra-configmap", metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, "extra-configmap", cm.Name)
}).
And(func() {
// Add a resource with an annotation that is self-referencing the
// resource.
@@ -2301,5 +2308,17 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
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
cm, err := KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Get(context.Background(), "other-configmap", metav1.GetOptions{})
require.Error(t, err)
require.Equal(t, "", cm.Name)
}).
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy))
}

View File

@@ -23,7 +23,7 @@
"json-merge-patch": "^0.2.3",
"lodash-es": "^4.17.21",
"minimatch": "^3.1.2",
"moment": "^2.29.2",
"moment": "^2.29.4",
"monaco-editor": "^0.33.0",
"path": "^0.12.7",
"prop-types": "^15.8.1",

View File

@@ -1,5 +1,4 @@
import {DataLoader, Tab, Tabs} from 'argo-ui';
import {useData} from 'argo-ui/v2';
import * as React from 'react';
import {EventsList, YamlEditor} from '../../../shared/components';
import * as models from '../../../shared/models';
@@ -7,7 +6,7 @@ import {ErrorBoundary} from '../../../shared/components/error-boundary/error-bou
import {Context} from '../../../shared/context';
import {Application, ApplicationTree, AppSourceType, Event, RepoAppDetails, ResourceNode, State, SyncStatuses} from '../../../shared/models';
import {services} from '../../../shared/services';
import {ExtensionComponentProps} from '../../../shared/services/extensions-service';
import {ResourceTabExtension} from '../../../shared/services/extensions-service';
import {NodeInfo, SelectNode} from '../application-details/application-details';
import {ApplicationNodeInfo} from '../application-node-info/application-node-info';
import {ApplicationParameters} from '../application-parameters/application-parameters';
@@ -48,9 +47,11 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
state: State,
podState: State,
events: Event[],
ExtensionComponent: React.ComponentType<ExtensionComponentProps>,
extensionTabs: ResourceTabExtension[],
tabs: Tab[],
execEnabled: boolean
execEnabled: boolean,
execAllowed: boolean,
logsAllowed: boolean
) => {
if (!node || node === undefined) {
return [];
@@ -87,31 +88,33 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
const onClickContainer = (group: any, i: number) => SelectNode(selectedNodeKey, group.offset + i, 'logs', appContext);
tabs = tabs.concat([
{
key: 'logs',
icon: 'fa fa-align-left',
title: 'LOGS',
content: (
<div className='application-details__tab-content-full-height'>
<PodsLogsViewer
podName={(state.kind === 'Pod' && state.metadata.name) || ''}
group={node.group}
kind={node.kind}
name={node.name}
namespace={podState.metadata.namespace}
applicationName={application.metadata.name}
containerName={AppUtils.getContainerName(podState, selectedNodeInfo.container)}
page={{number: page, untilTimes}}
setPage={pageData => appContext.navigation.goto('.', {page: pageData.number, untilTimes: pageData.untilTimes.join(',')})}
containerGroups={containerGroups}
onClickContainer={onClickContainer}
/>
</div>
)
}
]);
if (execEnabled) {
if (logsAllowed) {
tabs = tabs.concat([
{
key: 'logs',
icon: 'fa fa-align-left',
title: 'LOGS',
content: (
<div className='application-details__tab-content-full-height'>
<PodsLogsViewer
podName={(state.kind === 'Pod' && state.metadata.name) || ''}
group={node.group}
kind={node.kind}
name={node.name}
namespace={podState.metadata.namespace}
applicationName={application.metadata.name}
containerName={AppUtils.getContainerName(podState, selectedNodeInfo.container)}
page={{number: page, untilTimes}}
setPage={pageData => appContext.navigation.goto('.', {page: pageData.number, untilTimes: pageData.untilTimes.join(',')})}
containerGroups={containerGroups}
onClickContainer={onClickContainer}
/>
</div>
)
}
]);
}
if (execEnabled && execAllowed) {
tabs = tabs.concat([
{
key: 'exec',
@@ -124,15 +127,18 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
]);
}
}
if (ExtensionComponent && state) {
tabs.push({
title: 'More',
key: 'extension',
content: (
<ErrorBoundary message={`Something went wrong with Extension for ${state.kind}`}>
<ExtensionComponent tree={tree} resource={state} />
</ErrorBoundary>
)
if (state) {
extensionTabs.forEach((tabExtensions, i) => {
tabs.push({
title: tabExtensions.title,
key: `extension-${i}`,
content: (
<ErrorBoundary message={`Something went wrong with Extension for ${state.kind}`}>
<tabExtensions.component tree={tree} resource={state} application={application} />
</ErrorBoundary>
),
icon: tabExtensions.icon
});
});
}
return tabs;
@@ -209,19 +215,17 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
content: <ApplicationResourceEvents applicationName={application.metadata.name} />
});
return tabs;
const extensionTabs = services.extensions.getResourceTabs('argoproj.io', 'Application').map((ext, i) => ({
title: ext.title,
key: `extension-${i}`,
content: <ext.component resource={application} tree={tree} application={application} />,
icon: ext.icon
}));
return tabs.concat(extensionTabs);
};
const [extension, , error] = useData(
async () => {
if (selectedNode?.kind && selectedNode?.group) {
return await services.extensions.loadResourceExtension(selectedNode?.group || '', selectedNode?.kind || '');
}
},
null,
null,
[selectedNode]
);
const extensions = selectedNode?.kind ? services.extensions.getResourceTabs(selectedNode?.group || '', selectedNode?.kind) : [];
return (
<div style={{width: '100%', height: '100%'}}>
@@ -266,8 +270,9 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
const settings = await services.authService.settings();
const execEnabled = settings.execEnabled;
return {controlledState, liveState, events, podState, execEnabled};
const logsAllowed = await services.accounts.canI('logs', 'get', application.spec.project + '/' + application.metadata.name);
const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name);
return {controlledState, liveState, events, podState, execEnabled, execAllowed, logsAllowed};
}}>
{data => (
<React.Fragment>
@@ -302,7 +307,7 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
data.liveState,
data.podState,
data.events,
error.state ? null : extension?.component,
extensions,
[
{
title: 'SUMMARY',
@@ -311,7 +316,9 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
content: <ApplicationNodeInfo application={application} live={data.liveState} controlled={data.controlledState} node={selectedNode} />
}
],
data.execEnabled
data.execEnabled,
data.execAllowed,
data.logsAllowed
)}
selectedTabKey={props.tab}
onTabSelected={selected => appContext.navigation.goto('.', {tab: selected}, {replace: true})}

View File

@@ -355,16 +355,28 @@ function getActionItems(
action: () => appContext.apis.navigation.goto('.', {node: nodeKey(resource), tab: 'logs'}, {replace: true})
});
}
if (resource.kind === 'Pod') {
items.push({
title: 'Exec',
iconClassName: 'fa fa-terminal',
action: () => appContext.apis.navigation.goto('.', {node: nodeKey(resource), tab: 'exec'}, {replace: true})
});
}
if (isQuickStart) {
return from([items]);
}
const execAction = services.authService
.settings()
.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([
{
title: 'Exec',
iconClassName: 'fa fa-terminal',
action: async () => appContext.apis.navigation.goto('.', {node: nodeKey(resource), tab: 'exec'}, {replace: true})
}
]);
}
return items;
})
.catch(() => items);
const resourceActions = services.applications
.getResourceActions(application.metadata.name, resource)
.then(actions => {
@@ -389,7 +401,7 @@ function getActionItems(
);
})
.catch(() => items);
menuItems = merge(from([items]), from(resourceActions));
menuItems = merge(from([items]), from(resourceActions), from(execAction));
return menuItems;
}

View File

@@ -38,7 +38,7 @@ export const Help = () => {
<div className='help-box'>
<p>Want to download the CLI tool?</p>
<a href={`download/argocd-linux-${process.env.HOST_ARCH}`} className='user-info-panel-buttons argo-button argo-button--base'>
<i className='fab fa-linux' /> Linux (amd64)
<i className='fab fa-linux' /> Linux ({process.env.HOST_ARCH})
</a>
&nbsp;
{Object.keys(binaryUrls || {}).map(binaryName => {

View File

@@ -9,6 +9,7 @@
<link rel='icon' type='image/png' href='assets/favicon/favicon-32x32.png' sizes='32x32'/>
<link rel='icon' type='image/png' href='assets/favicon/favicon-16x16.png' sizes='16x16'/>
<link href="assets/fonts.css" rel="stylesheet">
</head>
<body>
@@ -20,5 +21,5 @@
</noscript>
<div id="app"></div>
</body>
<script defer src="extensions.js"></script>
</html>

View File

@@ -27,4 +27,8 @@ export class AccountsService {
public deleteToken(name: string, id: string): Promise<any> {
return requests.delete(`/account/${name}/token/${id}`);
}
public canI(resource: string, action: string, subresource: string): Promise<boolean> {
return requests.get(`/account/can-i/${resource}/${action}/${subresource}`).then(res => res.body.value === 'yes');
}
}

View File

@@ -1,40 +1,62 @@
import * as React from 'react';
import {ApplicationTree, State} from '../models';
import * as minimatch from 'minimatch';
const extensions: {resources: {[key: string]: Extension}} = {resources: {}};
const cache = new Map<string, Promise<Extension>>();
import {Application, ApplicationTree, State} from '../models';
const extensions = {
resourceExtentions: new Array<ResourceTabExtension>()
};
function registerResourceExtension(component: ExtensionComponent, group: string, kind: string, tabTitle: string, opts?: {icon: string}) {
extensions.resourceExtentions.push({component, group, kind, title: tabTitle, icon: opts?.icon});
}
let legacyInitialized = false;
function initLegacyExtensions() {
if (legacyInitialized) {
return;
}
legacyInitialized = true;
const resources = (window as any).extensions.resources;
Object.keys(resources).forEach(key => {
const [group, kind] = key.split('/');
registerResourceExtension(resources[key].component, group, kind, 'More');
});
}
export interface ResourceTabExtension {
title: string;
group: string;
kind: string;
component: ExtensionComponent;
icon?: string;
}
export type ExtensionComponent = React.ComponentType<ExtensionComponentProps>;
export interface Extension {
component: React.ComponentType<ExtensionComponentProps>;
component: ExtensionComponent;
}
export interface ExtensionComponentProps {
resource: State;
tree: ApplicationTree;
application: Application;
}
export class ExtensionsService {
public async loadResourceExtension(group: string, kind: string): Promise<Extension> {
const key = `${group}/${kind}`;
const res =
cache.get(key) ||
new Promise<Extension>((resolve, reject) => {
const script = document.createElement('script');
script.src = `extensions/resources/${group}/${kind}/ui/extensions.js`;
script.onload = () => {
const ext = extensions.resources[key];
if (!ext) {
reject(`Failed to load extension for ${group}/${kind}`);
} else {
resolve(ext);
}
};
script.onerror = reject;
document.body.appendChild(script);
});
cache.set(key, res);
return res;
public getResourceTabs(group: string, kind: string): ResourceTabExtension[] {
initLegacyExtensions();
const items = extensions.resourceExtentions.filter(extension => minimatch(group, extension.group) && minimatch(kind, extension.kind)).slice();
return items.sort((a, b) => a.title.localeCompare(b.title));
}
}
(window as any).extensions = extensions;
((window: any) => {
// deprecated: kept for backwards compatibility
window.extensions = {resources: {}};
window.extensionsAPI = {
registerResourceExtension
};
})(window);

View File

@@ -6338,15 +6338,10 @@ moment-timezone@^0.5.33:
dependencies:
moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.24.0, moment@^2.25.3:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
moment@^2.29.2:
version "2.29.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4"
integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==
"moment@>= 2.9.0", moment@^2.24.0, moment@^2.25.3, moment@^2.29.2, moment@^2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
monaco-editor-webpack-plugin@^7.0.0:
version "7.0.1"
@@ -6792,7 +6787,7 @@ parse-json@^5.2.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
parse-path@^4.0.4:
parse-path@^4.0.0:
version "4.0.4"
resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.4.tgz#4bf424e6b743fb080831f03b536af9fc43f0ffea"
integrity sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==
@@ -6803,13 +6798,13 @@ parse-path@^4.0.4:
query-string "^6.13.8"
parse-url@^6.0.0:
version "6.0.2"
resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-6.0.2.tgz#4a30b057bfc452af64512dfb1a7755c103db3ea1"
integrity sha512-uCSjOvD3T+6B/sPWhR+QowAZcU/o4bjPrVBQBGFxcDF6J6FraCGIaDBsdoQawiaaAVdHvtqBe3w3vKlfBKySOQ==
version "6.0.5"
resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-6.0.5.tgz#4acab8982cef1846a0f8675fa686cef24b2f6f9b"
integrity sha512-e35AeLTSIlkw/5GFq70IN7po8fmDUjpDPY1rIK+VubRfsUvBonjQ+PBZG+vWMACnQSmNlvl524IucoDmcioMxA==
dependencies:
is-ssh "^1.3.0"
normalize-url "^6.1.0"
parse-path "^4.0.4"
parse-path "^4.0.0"
protocols "^1.4.0"
parse5@6.0.1:

View File

@@ -190,7 +190,7 @@ func (a *ClientApp) verifyAppState(r *http.Request, w http.ResponseWriter, state
redirectURL := a.baseHRef
parts := strings.SplitN(cookieVal, ":", 2)
if len(parts) == 2 && parts[1] != "" {
if !isValidRedirectURL(parts[1], []string{a.settings.URL}) {
if !isValidRedirectURL(parts[1], []string{a.settings.URL, a.baseHRef}) {
sanitizedUrl := parts[1]
if len(sanitizedUrl) > 100 {
sanitizedUrl = sanitizedUrl[:100]

View File

@@ -192,6 +192,52 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
})
}
func Test_Login_Flow(t *testing.T) {
// Show that SSO login works when no redirect URL is provided, and we fall back to the configured base href for the
// Argo CD instance.
oidcTestServer := test.GetOIDCTestServer(t)
t.Cleanup(oidcTestServer.Close)
cdSettings := &settings.ArgoCDSettings{
URL: "https://argocd.example.com",
OIDCConfigRAW: fmt.Sprintf(`
name: Test
issuer: %s
clientID: xxx
clientSecret: yyy
requestedScopes: ["oidc"]`, oidcTestServer.URL),
OIDCTLSInsecureSkipVerify: true,
}
// The base href (the last argument for NewClientApp) is what HandleLogin will fall back to when no explicit
// redirect URL is given.
app, err := NewClientApp(cdSettings, "", "/")
require.NoError(t, err)
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "https://argocd.example.com/auth/login", nil)
app.HandleLogin(w, req)
redirectUrl, err := w.Result().Location()
require.NoError(t, err)
state := redirectUrl.Query()["state"]
req = httptest.NewRequest("GET", fmt.Sprintf("https://argocd.example.com/auth/callback?state=%s&code=abc", state), nil)
for _, cookie := range w.Result().Cookies() {
req.AddCookie(cookie)
}
w = httptest.NewRecorder()
app.HandleCallback(w, req)
assert.NotContains(t, w.Body.String(), InvalidRedirectURLError.Error())
}
func TestClientApp_HandleCallback(t *testing.T) {
oidcTestServer := test.GetOIDCTestServer(t)
t.Cleanup(oidcTestServer.Close)