mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 17:48:47 +01:00
Compare commits
43 Commits
release-3.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
259926ad99 | ||
|
|
d0b54e6b8f | ||
|
|
6054497bbc | ||
|
|
3a2cceea4f | ||
|
|
e7d1553cfc | ||
|
|
3c629baf09 | ||
|
|
f46333ea82 | ||
|
|
5f897118e1 | ||
|
|
a94a8eb422 | ||
|
|
a37a50b808 | ||
|
|
468ed0a1c2 | ||
|
|
0fdef4861e | ||
|
|
eafbf929da | ||
|
|
a552df5625 | ||
|
|
2c551ee4be | ||
|
|
7af770b11f | ||
|
|
36bade7a2d | ||
|
|
5754bd3357 | ||
|
|
095c5d616b | ||
|
|
c3b3a0fc58 | ||
|
|
c2c19f42ad | ||
|
|
8a3b36bd28 | ||
|
|
35a7350b74 | ||
|
|
241e6d0a6e | ||
|
|
dbd6b406ac | ||
|
|
a069639135 | ||
|
|
76241f9d3b | ||
|
|
bdda410463 | ||
|
|
2faa5c89d1 | ||
|
|
a12b7bdb74 | ||
|
|
9b21c25783 | ||
|
|
e1deca2a9e | ||
|
|
62621428b1 | ||
|
|
ab1f9e4658 | ||
|
|
36d1b42d5c | ||
|
|
8b9d25f6e3 | ||
|
|
323af4d562 | ||
|
|
a946b70b5e | ||
|
|
f9f1bdaabe | ||
|
|
e66b6109f7 | ||
|
|
53897e5019 | ||
|
|
7e0d8a490c | ||
|
|
3684a10332 |
@@ -95,7 +95,7 @@ commands:
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: argoproj/argocd-test-tools:v0.4.0
|
||||
- image: argoproj/argocd-test-tools:v0.5.0
|
||||
working_directory: /go/src/github.com/argoproj/argo-cd
|
||||
steps:
|
||||
- prepare_environment
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
|
||||
codegen:
|
||||
docker:
|
||||
- image: argoproj/argocd-test-tools:v0.4.0
|
||||
- image: argoproj/argocd-test-tools:v0.5.0
|
||||
working_directory: /go/src/github.com/argoproj/argo-cd
|
||||
steps:
|
||||
- prepare_environment
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
test:
|
||||
working_directory: /go/src/github.com/argoproj/argo-cd
|
||||
docker:
|
||||
- image: argoproj/argocd-test-tools:v0.4.0
|
||||
- image: argoproj/argocd-test-tools:v0.5.0
|
||||
steps:
|
||||
- prepare_environment
|
||||
- checkout
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
lint:
|
||||
working_directory: /go/src/github.com/argoproj/argo-cd
|
||||
docker:
|
||||
- image: argoproj/argocd-test-tools:v0.4.0
|
||||
- image: argoproj/argocd-test-tools:v0.5.0
|
||||
steps:
|
||||
- prepare_environment
|
||||
- checkout
|
||||
@@ -194,7 +194,7 @@ jobs:
|
||||
sonarcloud:
|
||||
working_directory: /go/src/github.com/argoproj/argo-cd
|
||||
docker:
|
||||
- image: argoproj/argocd-test-tools:v0.4.0
|
||||
- image: argoproj/argocd-test-tools:v0.5.0
|
||||
environment:
|
||||
NODE_MODULES: /go/src/github.com/argoproj/argo-cd/ui/node_modules
|
||||
steps:
|
||||
|
||||
@@ -52,7 +52,7 @@ RUN groupadd -g 999 argocd && \
|
||||
apt-get update && \
|
||||
apt-get install -y git git-lfs python3-pip && \
|
||||
apt-get clean && \
|
||||
pip3 install awscli==1.17.7 && \
|
||||
pip3 install awscli==1.18.80 && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY hack/git-ask-pass.sh /usr/local/bin/git-ask-pass.sh
|
||||
|
||||
2
Makefile
2
Makefile
@@ -22,7 +22,7 @@ ARGOCD_PROCFILE?=Procfile
|
||||
# Configuration for building argocd-test-tools image
|
||||
TEST_TOOLS_NAMESPACE?=argoproj
|
||||
TEST_TOOLS_IMAGE=argocd-test-tools
|
||||
TEST_TOOLS_TAG?=v0.4.0
|
||||
TEST_TOOLS_TAG?=v0.5.0
|
||||
ifdef TEST_TOOLS_NAMESPACE
|
||||
TEST_TOOLS_PREFIX=${TEST_TOOLS_NAMESPACE}/
|
||||
endif
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "List returns list of applications",
|
||||
"operationId": "ListMixin8",
|
||||
"operationId": "List",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -237,7 +237,7 @@
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "Create creates an application",
|
||||
"operationId": "CreateMixin8",
|
||||
"operationId": "Create",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
@@ -264,7 +264,7 @@
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "Update updates an application",
|
||||
"operationId": "UpdateMixin8",
|
||||
"operationId": "Update",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -395,7 +395,7 @@
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "Get returns an application by name",
|
||||
"operationId": "GetMixin8",
|
||||
"operationId": "Get",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -445,7 +445,7 @@
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "Delete deletes an application",
|
||||
"operationId": "DeleteMixin8",
|
||||
"operationId": "Delete",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1084,7 +1084,7 @@
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "List returns list of clusters",
|
||||
"operationId": "List",
|
||||
"operationId": "ListMixin4",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1106,7 +1106,7 @@
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "Create creates a cluster",
|
||||
"operationId": "Create",
|
||||
"operationId": "CreateMixin4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
@@ -1133,7 +1133,7 @@
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "Update updates a cluster",
|
||||
"operationId": "Update",
|
||||
"operationId": "UpdateMixin4",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1166,7 +1166,7 @@
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "Get returns a cluster by server address",
|
||||
"operationId": "GetMixin2",
|
||||
"operationId": "GetMixin4",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1189,7 +1189,7 @@
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "Delete deletes a cluster",
|
||||
"operationId": "Delete",
|
||||
"operationId": "DeleteMixin4",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1239,7 +1239,7 @@
|
||||
"ProjectService"
|
||||
],
|
||||
"summary": "List returns list of projects",
|
||||
"operationId": "ListMixin6",
|
||||
"operationId": "ListMixin5",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1261,7 +1261,7 @@
|
||||
"ProjectService"
|
||||
],
|
||||
"summary": "Create a new project.",
|
||||
"operationId": "CreateMixin6",
|
||||
"operationId": "CreateMixin5",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
@@ -1288,7 +1288,7 @@
|
||||
"ProjectService"
|
||||
],
|
||||
"summary": "Get returns a project by name",
|
||||
"operationId": "GetMixin6",
|
||||
"operationId": "GetMixin5",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1311,7 +1311,7 @@
|
||||
"ProjectService"
|
||||
],
|
||||
"summary": "Delete deletes a project",
|
||||
"operationId": "DeleteMixin6",
|
||||
"operationId": "DeleteMixin5",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1386,7 +1386,7 @@
|
||||
"ProjectService"
|
||||
],
|
||||
"summary": "Update updates a project",
|
||||
"operationId": "UpdateMixin6",
|
||||
"operationId": "UpdateMixin5",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -1905,7 +1905,7 @@
|
||||
"SettingsService"
|
||||
],
|
||||
"summary": "Get returns Argo CD settings",
|
||||
"operationId": "Get",
|
||||
"operationId": "GetMixin7",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "(empty)",
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/pkg/stats"
|
||||
rediscache "github.com/go-redis/cache"
|
||||
"github.com/go-redis/redis"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -25,8 +24,10 @@ import (
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||
cacheutil "github.com/argoproj/argo-cd/util/cache"
|
||||
appstatecache "github.com/argoproj/argo-cd/util/cache/appstate"
|
||||
"github.com/argoproj/argo-cd/util/cli"
|
||||
"github.com/argoproj/argo-cd/util/diff"
|
||||
"github.com/argoproj/argo-cd/util/kube"
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
@@ -81,6 +82,8 @@ func newCommand() *cobra.Command {
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace)
|
||||
kubectl := &kube.KubectlCmd{}
|
||||
legacyDiffDisabled := os.Getenv("ARGOCD_ENABLE_LEGACY_DIFF") == "false"
|
||||
diff.SetPopulateLegacyDiff(!legacyDiffDisabled)
|
||||
appController, err := controller.NewApplicationController(
|
||||
namespace,
|
||||
settingsMgr,
|
||||
@@ -94,14 +97,7 @@ func newCommand() *cobra.Command {
|
||||
metricsPort,
|
||||
kubectlParallelismLimit)
|
||||
errors.CheckError(err)
|
||||
metricsServer := appController.GetMetricsServer()
|
||||
redisClient.WrapProcess(func(oldProcess func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
|
||||
return func(cmd redis.Cmder) error {
|
||||
err := oldProcess(cmd)
|
||||
metricsServer.IncRedisRequest(err != nil && err != rediscache.ErrCacheMiss)
|
||||
return err
|
||||
}
|
||||
})
|
||||
cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer())
|
||||
|
||||
vers := common.GetVersion()
|
||||
log.Infof("Application Controller (version: %s, built: %s) starting (namespace: %s)", vers.Version, vers.BuildDate, namespace)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/pkg/stats"
|
||||
"github.com/go-redis/redis"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/reposerver"
|
||||
reposervercache "github.com/argoproj/argo-cd/reposerver/cache"
|
||||
"github.com/argoproj/argo-cd/reposerver/metrics"
|
||||
cacheutil "github.com/argoproj/argo-cd/util/cache"
|
||||
"github.com/argoproj/argo-cd/util/cli"
|
||||
"github.com/argoproj/argo-cd/util/tls"
|
||||
)
|
||||
@@ -33,6 +35,7 @@ func newCommand() *cobra.Command {
|
||||
metricsPort int
|
||||
cacheSrc func() (*reposervercache.Cache, error)
|
||||
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
|
||||
redisClient *redis.Client
|
||||
)
|
||||
var command = cobra.Command{
|
||||
Use: cliName,
|
||||
@@ -47,6 +50,7 @@ func newCommand() *cobra.Command {
|
||||
errors.CheckError(err)
|
||||
|
||||
metricsServer := metrics.NewMetricsServer()
|
||||
cacheutil.CollectMetrics(redisClient, metricsServer)
|
||||
server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, parallelismLimit)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -72,7 +76,9 @@ func newCommand() *cobra.Command {
|
||||
command.Flags().IntVar(&listenPort, "port", common.DefaultPortRepoServer, "Listen on given port for incoming connections")
|
||||
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortRepoServerMetrics, "Start metrics server on given port")
|
||||
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
|
||||
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command)
|
||||
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
|
||||
redisClient = client
|
||||
})
|
||||
return &command
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ type MetricsServer struct {
|
||||
clusterEventsCounter *prometheus.CounterVec
|
||||
redisRequestCounter *prometheus.CounterVec
|
||||
reconcileHistogram *prometheus.HistogramVec
|
||||
redisRequestHistogram *prometheus.HistogramVec
|
||||
registry *prometheus.Registry
|
||||
}
|
||||
|
||||
@@ -118,6 +119,15 @@ var (
|
||||
},
|
||||
[]string{"initiator", "failed"},
|
||||
)
|
||||
|
||||
redisRequestHistogram = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_redis_request_duration",
|
||||
Help: "Redis requests duration.",
|
||||
Buckets: []float64{0.01, 0.05, 0.10, 0.25, .5, 1},
|
||||
},
|
||||
[]string{"initiator"},
|
||||
)
|
||||
)
|
||||
|
||||
// NewMetricsServer returns a new prometheus server which collects application metrics
|
||||
@@ -139,6 +149,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, health
|
||||
registry.MustRegister(reconcileHistogram)
|
||||
registry.MustRegister(clusterEventsCounter)
|
||||
registry.MustRegister(redisRequestCounter)
|
||||
registry.MustRegister(redisRequestHistogram)
|
||||
|
||||
return &MetricsServer{
|
||||
registry: registry,
|
||||
@@ -153,6 +164,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, health
|
||||
reconcileHistogram: reconcileHistogram,
|
||||
clusterEventsCounter: clusterEventsCounter,
|
||||
redisRequestCounter: redisRequestCounter,
|
||||
redisRequestHistogram: redisRequestHistogram,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +217,11 @@ func (m *MetricsServer) IncRedisRequest(failed bool) {
|
||||
m.redisRequestCounter.WithLabelValues("argocd-application-controller", strconv.FormatBool(failed)).Inc()
|
||||
}
|
||||
|
||||
// ObserveRedisRequestDuration observes redis request duration
|
||||
func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
|
||||
m.redisRequestHistogram.WithLabelValues("argocd-application-controller").Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// IncReconcile increments the reconcile counter for an application
|
||||
func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.Duration) {
|
||||
m.reconcileHistogram.WithLabelValues(app.Namespace, app.Spec.Destination.Server).Observe(duration.Seconds())
|
||||
|
||||
@@ -246,6 +246,11 @@ http {
|
||||
}
|
||||
}
|
||||
```
|
||||
Flag ```--grpc-web-root-path ``` is used to provide a non-root path (e.g. /argo-cd)
|
||||
|
||||
```shell
|
||||
$ argocd login <host>:<port> --grpc-web-root-path /argo-cd
|
||||
```
|
||||
|
||||
## UI Base Path
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -eux -o pipefail
|
||||
|
||||
KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION:-3.5.4}
|
||||
KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION:-3.6.1}
|
||||
|
||||
# Note that kustomize release URIs have changed for v3.2.1. Then again for
|
||||
# v3.3.0. When upgrading to versions >= v3.3.0 please change the URI format. And
|
||||
|
||||
@@ -12,4 +12,4 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.5.7
|
||||
|
||||
@@ -18,4 +18,4 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.5.7
|
||||
|
||||
@@ -2869,7 +2869,7 @@ spec:
|
||||
- "10"
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2925,7 +2925,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2975,7 +2975,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3043,7 +3043,7 @@ spec:
|
||||
- /shared/app
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2784,7 +2784,7 @@ spec:
|
||||
- "10"
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2840,7 +2840,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2890,7 +2890,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2958,7 +2958,7 @@ spec:
|
||||
- /shared/app
|
||||
- --redis
|
||||
- argocd-redis-ha-haproxy:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2369,7 +2369,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2425,7 +2425,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2489,7 +2489,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2540,7 +2540,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -2284,7 +2284,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2340,7 +2340,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2404,7 +2404,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2455,7 +2455,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.5.7
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -56,7 +56,15 @@ func (c *client) executeRequest(fullMethodName string, msg []byte, md metadata.M
|
||||
schema = "http"
|
||||
}
|
||||
rootPath := strings.TrimRight(strings.TrimLeft(c.GRPCWebRootPath, "/"), "/")
|
||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s://%s/%s%s", schema, c.ServerAddr, rootPath, fullMethodName), bytes.NewReader(toFrame(msg)))
|
||||
|
||||
var requestURL string
|
||||
if rootPath != "" {
|
||||
requestURL = fmt.Sprintf("%s://%s/%s%s", schema, c.ServerAddr, rootPath, fullMethodName)
|
||||
} else {
|
||||
requestURL = fmt.Sprintf("%s://%s%s", schema, c.ServerAddr, fullMethodName)
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodPost, requestURL, bytes.NewReader(toFrame(msg)))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
5
reposerver/cache/cache.go
vendored
5
reposerver/cache/cache.go
vendored
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
@@ -23,12 +24,12 @@ func NewCache(cache *cacheutil.Cache, repoCacheExpiration time.Duration) *Cache
|
||||
return &Cache{cache, repoCacheExpiration}
|
||||
}
|
||||
|
||||
func AddCacheFlagsToCmd(cmd *cobra.Command) func() (*Cache, error) {
|
||||
func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) {
|
||||
var repoCacheExpiration time.Duration
|
||||
|
||||
cmd.Flags().DurationVar(&repoCacheExpiration, "repo-cache-expiration", 24*time.Hour, "Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data")
|
||||
|
||||
repoFactory := cacheutil.AddCacheFlagsToCmd(cmd)
|
||||
repoFactory := cacheutil.AddCacheFlagsToCmd(cmd, opts...)
|
||||
|
||||
return func() (*Cache, error) {
|
||||
cache, err := repoFactory()
|
||||
|
||||
@@ -2,6 +2,8 @@ package metrics
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
@@ -11,6 +13,8 @@ type MetricsServer struct {
|
||||
handler http.Handler
|
||||
gitRequestCounter *prometheus.CounterVec
|
||||
repoPendingRequestsGauge *prometheus.GaugeVec
|
||||
redisRequestCounter *prometheus.CounterVec
|
||||
redisRequestHistogram *prometheus.HistogramVec
|
||||
}
|
||||
|
||||
type GitRequestType string
|
||||
@@ -44,10 +48,31 @@ func NewMetricsServer() *MetricsServer {
|
||||
)
|
||||
registry.MustRegister(repoPendingRequestsGauge)
|
||||
|
||||
redisRequestCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "argocd_redis_request_total",
|
||||
Help: "Number of kubernetes requests executed during application reconciliation.",
|
||||
},
|
||||
[]string{"initiator", "failed"},
|
||||
)
|
||||
registry.MustRegister(redisRequestCounter)
|
||||
|
||||
redisRequestHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_redis_request_duration",
|
||||
Help: "Redis requests duration.",
|
||||
Buckets: []float64{0.1, 0.25, .5, 1, 2},
|
||||
},
|
||||
[]string{"initiator"},
|
||||
)
|
||||
registry.MustRegister(redisRequestHistogram)
|
||||
|
||||
return &MetricsServer{
|
||||
handler: promhttp.HandlerFor(registry, promhttp.HandlerOpts{}),
|
||||
gitRequestCounter: gitRequestCounter,
|
||||
repoPendingRequestsGauge: repoPendingRequestsGauge,
|
||||
redisRequestCounter: redisRequestCounter,
|
||||
redisRequestHistogram: redisRequestHistogram,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,3 +92,11 @@ func (m *MetricsServer) IncPendingRepoRequest(repo string) {
|
||||
func (m *MetricsServer) DecPendingRepoRequest(repo string) {
|
||||
m.repoPendingRequestsGauge.WithLabelValues(repo).Dec()
|
||||
}
|
||||
|
||||
func (m *MetricsServer) IncRedisRequest(failed bool) {
|
||||
m.redisRequestCounter.WithLabelValues("argocd-repo-server", strconv.FormatBool(failed)).Inc()
|
||||
}
|
||||
|
||||
func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
|
||||
m.redisRequestHistogram.WithLabelValues("argocd-repo-server").Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
@@ -25,4 +25,7 @@ actionTests:
|
||||
expectedOutputPath: testdata/pre_v0.6_not_paused_rollout.yaml
|
||||
- action: resume
|
||||
inputPath: testdata/has_pause_condition_rollout.yaml
|
||||
expectedOutputPath: testdata/no_pause_condition_rollout.yaml
|
||||
expectedOutputPath: testdata/no_pause_condition_rollout.yaml
|
||||
- action: restart
|
||||
inputPath: testdata/rollout_not_restarted.yaml
|
||||
expectedOutputPath: testdata/rollout_restarted.yaml
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
local os = require("os")
|
||||
obj.spec.restartAt = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
47
resource_customizations/argoproj.io/Rollout/actions/testdata/rollout_not_restarted.yaml
vendored
Normal file
47
resource_customizations/argoproj.io/Rollout/actions/testdata/rollout_not_restarted.yaml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
name: canary-demo
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 5
|
||||
revisionHistoryLimit: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: canary-demo
|
||||
strategy:
|
||||
canary:
|
||||
analysis:
|
||||
args:
|
||||
- name: ingress
|
||||
value: canary-demo
|
||||
templateName: success-rate
|
||||
canaryService: canary-demo-preview
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
steps:
|
||||
- setWeight: 40
|
||||
- pause: {}
|
||||
- setWeight: 60
|
||||
- pause:
|
||||
duration: 10
|
||||
- setWeight: 80
|
||||
- pause:
|
||||
duration: 10
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: canary-demo
|
||||
spec:
|
||||
containers:
|
||||
- image: argoproj/rollouts-demo:red
|
||||
imagePullPolicy: Always
|
||||
name: canary-demo
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: 5m
|
||||
memory: 32Mi
|
||||
48
resource_customizations/argoproj.io/Rollout/actions/testdata/rollout_restarted.yaml
vendored
Normal file
48
resource_customizations/argoproj.io/Rollout/actions/testdata/rollout_restarted.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
name: canary-demo
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 5
|
||||
restartAt: "0001-01-01T00:00:00Z"
|
||||
revisionHistoryLimit: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: canary-demo
|
||||
strategy:
|
||||
canary:
|
||||
analysis:
|
||||
args:
|
||||
- name: ingress
|
||||
value: canary-demo
|
||||
templateName: success-rate
|
||||
canaryService: canary-demo-preview
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
steps:
|
||||
- setWeight: 40
|
||||
- pause: {}
|
||||
- setWeight: 60
|
||||
- pause:
|
||||
duration: 10
|
||||
- setWeight: 80
|
||||
- pause:
|
||||
duration: 10
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: canary-demo
|
||||
spec:
|
||||
containers:
|
||||
- image: argoproj/rollouts-demo:red
|
||||
imagePullPolicy: Always
|
||||
name: canary-demo
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
cpu: 5m
|
||||
memory: 32Mi
|
||||
@@ -122,7 +122,11 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
badge = svgWidthPattern.ReplaceAllString(badge, fmt.Sprintf(`<svg width="%d" $2`, svgWidthWithRevision))
|
||||
badge = displayNonePattern.ReplaceAllString(badge, `display="inline"`)
|
||||
badge = revisionRectColorPattern.ReplaceAllString(badge, fmt.Sprintf(`id="revisionRect" fill="%s" $2`, rightColorString))
|
||||
badge = replaceFirstGroupSubMatch(revisionTextPattern, badge, fmt.Sprintf("(%s)", revision[:7]))
|
||||
shortRevision := revision
|
||||
if len(shortRevision) > 7 {
|
||||
shortRevision = shortRevision[:7]
|
||||
}
|
||||
badge = replaceFirstGroupSubMatch(revisionTextPattern, badge, fmt.Sprintf("(%s)", shortRevision))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
|
||||
@@ -110,6 +110,22 @@ func TestHandlerRevisionIsEnabledNoOperationState(t *testing.T) {
|
||||
assert.NotContains(t, response, "(aa29b85)")
|
||||
}
|
||||
|
||||
func TestHandlerRevisionIsEnabledShortCommitSHA(t *testing.T) {
|
||||
app := testApp.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Revision = "abc"
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(&argoCDCm, &argoCDSecret), "default")
|
||||
handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default")
|
||||
req, err := http.NewRequest("GET", "/api/badge?name=testApp&revision=true", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
response := rr.Body.String()
|
||||
assert.Contains(t, response, "(abc)")
|
||||
}
|
||||
|
||||
func TestHandlerFeatureIsDisabled(t *testing.T) {
|
||||
|
||||
argoCDCmDisabled := argoCDCm.DeepCopy()
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
@@ -11,7 +12,8 @@ import (
|
||||
|
||||
type MetricsServer struct {
|
||||
*http.Server
|
||||
redisRequestCounter *prometheus.CounterVec
|
||||
redisRequestCounter *prometheus.CounterVec
|
||||
redisRequestHistogram *prometheus.HistogramVec
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -22,6 +24,14 @@ var (
|
||||
},
|
||||
[]string{"initiator", "failed"},
|
||||
)
|
||||
redisRequestHistogram = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_redis_request_duration",
|
||||
Help: "Redis requests duration.",
|
||||
Buckets: []float64{0.1, 0.25, .5, 1, 2},
|
||||
},
|
||||
[]string{"initiator"},
|
||||
)
|
||||
)
|
||||
|
||||
// NewMetricsServer returns a new prometheus server which collects api server metrics
|
||||
@@ -34,16 +44,23 @@ func NewMetricsServer(port int) *MetricsServer {
|
||||
}, promhttp.HandlerOpts{}))
|
||||
|
||||
registry.MustRegister(redisRequestCounter)
|
||||
registry.MustRegister(redisRequestHistogram)
|
||||
|
||||
return &MetricsServer{
|
||||
Server: &http.Server{
|
||||
Addr: fmt.Sprintf("0.0.0.0:%d", port),
|
||||
Handler: mux,
|
||||
},
|
||||
redisRequestCounter: redisRequestCounter,
|
||||
redisRequestCounter: redisRequestCounter,
|
||||
redisRequestHistogram: redisRequestHistogram,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MetricsServer) IncRedisRequest(failed bool) {
|
||||
m.redisRequestCounter.WithLabelValues("argocd-server", strconv.FormatBool(failed)).Inc()
|
||||
}
|
||||
|
||||
// ObserveRedisRequestDuration observes redis request duration
|
||||
func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
|
||||
m.redisRequestHistogram.WithLabelValues("argocd-server").Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cacheutil "github.com/argoproj/argo-cd/util/cache"
|
||||
"github.com/argoproj/argo-cd/util/healthz"
|
||||
"github.com/argoproj/argo-cd/util/swagger"
|
||||
"github.com/argoproj/argo-cd/util/webhook"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
rediscache "github.com/go-redis/cache"
|
||||
"github.com/go-redis/redis"
|
||||
golang_proto "github.com/golang/protobuf/proto"
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
@@ -249,16 +249,14 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
httpsS.Handler = withRootPath(httpsS.Handler, a)
|
||||
}
|
||||
}
|
||||
httpS.Handler = &bug21955Workaround{handler: httpS.Handler}
|
||||
if httpsS != nil {
|
||||
httpsS.Handler = &bug21955Workaround{handler: httpsS.Handler}
|
||||
}
|
||||
|
||||
metricsServ := metrics.NewMetricsServer(metricsPort)
|
||||
if a.RedisClient != nil {
|
||||
a.RedisClient.WrapProcess(func(oldProcess func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
|
||||
return func(cmd redis.Cmder) error {
|
||||
err := oldProcess(cmd)
|
||||
metricsServ.IncRedisRequest(err != nil && err != rediscache.ErrCacheMiss)
|
||||
return err
|
||||
}
|
||||
})
|
||||
cacheutil.CollectMetrics(a.RedisClient, metricsServ)
|
||||
}
|
||||
|
||||
// Start listener
|
||||
@@ -580,7 +578,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
httpS := http.Server{
|
||||
Addr: endpoint,
|
||||
Handler: &handlerSwitcher{
|
||||
handler: &bug21955Workaround{handler: mux},
|
||||
handler: mux,
|
||||
urlToHandler: map[string]http.Handler{
|
||||
"/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace),
|
||||
},
|
||||
|
||||
15
util/cache/cache.go
vendored
15
util/cache/cache.go
vendored
@@ -2,6 +2,7 @@ package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -9,11 +10,16 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/util/env"
|
||||
)
|
||||
|
||||
const (
|
||||
// envRedisPassword is a env variable name which stores redis password
|
||||
envRedisPassword = "REDIS_PASSWORD"
|
||||
// envRedisRetryCount is a env variable name which stores redis retry count
|
||||
envRedisRetryCount = "REDIS_RETRY_COUNT"
|
||||
// defaultRedisRetryCount holds default number of retries
|
||||
defaultRedisRetryCount = 3
|
||||
)
|
||||
|
||||
func NewCache(client CacheClient) *Cache {
|
||||
@@ -35,12 +41,14 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client))
|
||||
cmd.Flags().DurationVar(&defaultCacheExpiration, "default-cache-expiration", 24*time.Hour, "Cache expiration default")
|
||||
return func() (*Cache, error) {
|
||||
password := os.Getenv(envRedisPassword)
|
||||
maxRetries := env.ParseNumFromEnv(envRedisRetryCount, defaultRedisRetryCount, 0, math.MaxInt32)
|
||||
if len(sentinelAddresses) > 0 {
|
||||
client := redis.NewFailoverClient(&redis.FailoverOptions{
|
||||
MasterName: sentinelMaster,
|
||||
SentinelAddrs: sentinelAddresses,
|
||||
DB: redisDB,
|
||||
Password: password,
|
||||
MaxRetries: maxRetries,
|
||||
})
|
||||
for i := range opts {
|
||||
opts[i](client)
|
||||
@@ -52,9 +60,10 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client))
|
||||
redisAddress = common.DefaultRedisAddr
|
||||
}
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: redisAddress,
|
||||
Password: password,
|
||||
DB: redisDB,
|
||||
Addr: redisAddress,
|
||||
Password: password,
|
||||
DB: redisDB,
|
||||
MaxRetries: maxRetries,
|
||||
})
|
||||
for i := range opts {
|
||||
opts[i](client)
|
||||
|
||||
51
util/cache/redis.go
vendored
51
util/cache/redis.go
vendored
@@ -1,7 +1,6 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
rediscache "github.com/go-redis/cache"
|
||||
@@ -29,39 +28,45 @@ type redisCache struct {
|
||||
codec *rediscache.Codec
|
||||
}
|
||||
|
||||
// if redis server goes down the first client request fails with EOF error
|
||||
func doWithRetry(action func() error) error {
|
||||
err := action()
|
||||
if err == io.EOF {
|
||||
return action()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *redisCache) Set(item *Item) error {
|
||||
expiration := item.Expiration
|
||||
if expiration == 0 {
|
||||
expiration = r.expiration
|
||||
}
|
||||
return doWithRetry(func() error {
|
||||
return r.codec.Set(&rediscache.Item{
|
||||
Key: item.Key,
|
||||
Object: item.Object,
|
||||
Expiration: expiration,
|
||||
})
|
||||
return r.codec.Set(&rediscache.Item{
|
||||
Key: item.Key,
|
||||
Object: item.Object,
|
||||
Expiration: expiration,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *redisCache) Get(key string, obj interface{}) error {
|
||||
return doWithRetry(func() error {
|
||||
err := r.codec.Get(key, obj)
|
||||
if err == rediscache.ErrCacheMiss {
|
||||
return ErrCacheMiss
|
||||
}
|
||||
return err
|
||||
})
|
||||
err := r.codec.Get(key, obj)
|
||||
if err == rediscache.ErrCacheMiss {
|
||||
return ErrCacheMiss
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *redisCache) Delete(key string) error {
|
||||
return r.codec.Delete(key)
|
||||
}
|
||||
|
||||
type MetricsRegistry interface {
|
||||
IncRedisRequest(failed bool)
|
||||
ObserveRedisRequestDuration(duration time.Duration)
|
||||
}
|
||||
|
||||
// CollectMetrics add transport wrapper that pushes metrics into the specified metrics registry
|
||||
func CollectMetrics(client *redis.Client, registry MetricsRegistry) {
|
||||
client.WrapProcess(func(oldProcess func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
|
||||
return func(cmd redis.Cmder) error {
|
||||
startTime := time.Now()
|
||||
err := oldProcess(cmd)
|
||||
registry.IncRedisRequest(err != nil && err != redis.Nil)
|
||||
duration := time.Since(startTime)
|
||||
registry.ObserveRedisRequestDuration(duration)
|
||||
return err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,6 +27,22 @@ import (
|
||||
jsonutil "github.com/argoproj/argo-cd/util/json"
|
||||
)
|
||||
|
||||
var (
|
||||
emptyGoJSONDiff = gojsondiff.New().CompareObjects(map[string]interface{}{}, map[string]interface{}{})
|
||||
populateLegacyDiff = true
|
||||
)
|
||||
|
||||
func SetPopulateLegacyDiff(val bool) {
|
||||
populateLegacyDiff = val
|
||||
}
|
||||
|
||||
func calcGoJsonDiff(left map[string]interface{}, right map[string]interface{}) gojsondiff.Diff {
|
||||
if !populateLegacyDiff {
|
||||
return emptyGoJSONDiff
|
||||
}
|
||||
return gojsondiff.New().CompareObjects(left, right)
|
||||
}
|
||||
|
||||
type DiffResult struct {
|
||||
// Deprecated: Use PredictedLive and NormalizedLive instead
|
||||
Diff gojsondiff.Diff
|
||||
@@ -76,7 +92,7 @@ func getLegacyTwoWayDiff(config, live *unstructured.Unstructured) gojsondiff.Dif
|
||||
if live != nil {
|
||||
liveObj = jsonutil.RemoveMapFields(configObj, live.Object)
|
||||
}
|
||||
return gojsondiff.New().CompareObjects(liveObj, configObj)
|
||||
return calcGoJsonDiff(liveObj, configObj)
|
||||
}
|
||||
|
||||
// TwoWayDiff performs a three-way diff and uses specified config as a recently applied config
|
||||
@@ -150,7 +166,7 @@ func ThreeWayDiff(orig, config, live *unstructured.Unstructured) (*DiffResult, e
|
||||
NormalizedLive: liveBytes,
|
||||
Modified: string(predictedLiveBytes) != string(liveBytes),
|
||||
// legacy diff for backward compatibility
|
||||
Diff: gojsondiff.New().CompareObjects(live.Object, predictedLive.Object),
|
||||
Diff: calcGoJsonDiff(live.Object, predictedLive.Object),
|
||||
}
|
||||
return &dr, nil
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ type Helm interface {
|
||||
// NewHelmApp create a new wrapper to run commands on the `helm` command-line tool.
|
||||
func NewHelmApp(workDir string, repos []HelmRepository, isLocal bool) (Helm, error) {
|
||||
cmd, err := NewCmd(workDir)
|
||||
cmd.IsLocal = isLocal
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.IsLocal = isLocal
|
||||
|
||||
return &helm{repos: repos, cmd: *cmd}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ package oidc
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gooidc "github.com/coreos/go-oidc"
|
||||
@@ -222,7 +224,8 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
log.Infof("Callback: %s", r.URL)
|
||||
if errMsg := r.FormValue("error"); errMsg != "" {
|
||||
http.Error(w, errMsg+": "+r.FormValue("error_description"), http.StatusBadRequest)
|
||||
errorDesc := r.FormValue("error_description")
|
||||
http.Error(w, html.EscapeString(errMsg)+": "+html.EscapeString(errorDesc), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
code := r.FormValue("code")
|
||||
@@ -253,7 +256,12 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, fmt.Sprintf("invalid session token: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
flags := []string{"path=/"}
|
||||
path := "/"
|
||||
if a.baseHRef != "" {
|
||||
path = strings.TrimRight(strings.TrimLeft(a.baseHRef, "/"), "/")
|
||||
}
|
||||
cookiePath := fmt.Sprintf("path=/%s", path)
|
||||
flags := []string{cookiePath, "SameSite=lax", "httpOnly"}
|
||||
if a.secureCookie {
|
||||
flags = append(flags, "Secure")
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package oidc
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
gooidc "github.com/coreos/go-oidc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/argoproj/argo-cd/server/settings/oidc"
|
||||
)
|
||||
@@ -65,3 +66,33 @@ func TestIDTokenClaims(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "{\"id_token\":{\"groups\":{\"essential\":true}}}", values.Get("claims"))
|
||||
}
|
||||
|
||||
type fakeProvider struct {
|
||||
}
|
||||
|
||||
func (p *fakeProvider) Endpoint() (*oauth2.Endpoint, error) {
|
||||
return &oauth2.Endpoint{}, nil
|
||||
}
|
||||
|
||||
func (p *fakeProvider) ParseConfig() (*OIDCConfiguration, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *fakeProvider) Verify(_, _ string) (*gooidc.IDToken, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestHandleCallback(t *testing.T) {
|
||||
app := ClientApp{provider: &fakeProvider{}}
|
||||
|
||||
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
|
||||
req.Form = url.Values{
|
||||
"error": []string{"login-failed"},
|
||||
"error_description": []string{"<script>alert('hello')</script>"},
|
||||
}
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
app.HandleCallback(w, req)
|
||||
|
||||
assert.Equal(t, "login-failed: <script>alert('hello')</script>\n", w.Body.String())
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ func (mgr *SessionManager) VerifyUsernamePassword(username string, password stri
|
||||
// introduces random delay to protect from timing-based user enumeration attack
|
||||
delayNanoseconds := verificationDelayNoiseMin.Nanoseconds() +
|
||||
int64(rand.Intn(int(verificationDelayNoiseMax.Nanoseconds()-verificationDelayNoiseMin.Nanoseconds())))
|
||||
// take into account amount of time spent since the request start
|
||||
// take into account amount of time spent since the request start
|
||||
delayNanoseconds = delayNanoseconds - time.Since(start).Nanoseconds()
|
||||
if delayNanoseconds > 0 {
|
||||
mgr.sleep(time.Duration(delayNanoseconds))
|
||||
|
||||
@@ -1030,10 +1030,15 @@ func (mgr *SettingsManager) notifySubscribers(newSettings *ArgoCDSettings) {
|
||||
mgr.mutex.Lock()
|
||||
defer mgr.mutex.Unlock()
|
||||
if len(mgr.subscribers) > 0 {
|
||||
log.Infof("Notifying %d settings subscribers: %v", len(mgr.subscribers), mgr.subscribers)
|
||||
for _, sub := range mgr.subscribers {
|
||||
sub <- newSettings
|
||||
}
|
||||
subscribers := make([]chan<- *ArgoCDSettings, len(mgr.subscribers))
|
||||
copy(subscribers, mgr.subscribers)
|
||||
// make sure subscribes are notified in a separate thread to avoid potential deadlock
|
||||
go func() {
|
||||
log.Infof("Notifying %d settings subscribers: %v", len(subscribers), subscribers)
|
||||
for _, sub := range subscribers {
|
||||
sub <- newSettings
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user