mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-06 08:28:50 +01:00
Compare commits
44 Commits
commit-ser
...
v1.8.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94017f2c8d | ||
|
|
3c53ea6cff | ||
|
|
7b2946962d | ||
|
|
df3422798d | ||
|
|
f44855fa4d | ||
|
|
1f4a052da3 | ||
|
|
74f5eae750 | ||
|
|
36a9465d85 | ||
|
|
9e6c04700e | ||
|
|
8abe96ad9a | ||
|
|
10de6e7cfc | ||
|
|
e57071a150 | ||
|
|
41db5fc010 | ||
|
|
31f257e957 | ||
|
|
5fd93a7db5 | ||
|
|
c2547dca95 | ||
|
|
522ed90f38 | ||
|
|
7a0266f0fb | ||
|
|
30348417a9 | ||
|
|
910eddbbf3 | ||
|
|
f150ba18fb | ||
|
|
97d030b4b2 | ||
|
|
5df269b3fa | ||
|
|
775f9711e7 | ||
|
|
3f974825a6 | ||
|
|
1d55439f7f | ||
|
|
41daf71851 | ||
|
|
f4796398a8 | ||
|
|
0f0b6ce278 | ||
|
|
aee4dfaa1e | ||
|
|
74a92c6031 | ||
|
|
4237c6f00f | ||
|
|
0f3d74fa58 | ||
|
|
868516f0bd | ||
|
|
e50c43fb3f | ||
|
|
9b6a0dc3cd | ||
|
|
1f63e99b78 | ||
|
|
589ad5d2ac | ||
|
|
4464f99df7 | ||
|
|
65a2d9f1ff | ||
|
|
bcaabc51a1 | ||
|
|
9140fea0fb | ||
|
|
d83e0ddb56 | ||
|
|
25ca589bff |
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
# Target version must match major.minor.patch and optional -rcX suffix
|
# Target version must match major.minor.patch and optional -rcX suffix
|
||||||
# where X must be a number.
|
# where X must be a number.
|
||||||
TARGET_VERSION=${SOURCE_TAG#*release-v}
|
TARGET_VERSION=${SOURCE_TAG#*release-v}
|
||||||
if ! echo ${TARGET_VERSION} | egrep '^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*$'; then
|
if ! echo "${TARGET_VERSION}" | egrep '^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*$'; then
|
||||||
echo "::error::Target version '${TARGET_VERSION}' is malformed, refusing to continue." >&2
|
echo "::error::Target version '${TARGET_VERSION}' is malformed, refusing to continue." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -101,16 +101,16 @@ jobs:
|
|||||||
# Whatever is in commit history for the tag, we only want that
|
# Whatever is in commit history for the tag, we only want that
|
||||||
# annotation from our tag. We discard everything else.
|
# annotation from our tag. We discard everything else.
|
||||||
if test "$begin" = "false"; then
|
if test "$begin" = "false"; then
|
||||||
if echo $line | grep -q "tag ${SOURCE_TAG#refs/tags/}"; then begin="true"; fi
|
if echo "$line" | grep -q "tag ${SOURCE_TAG#refs/tags/}"; then begin="true"; fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if test "$prefix" = "true"; then
|
if test "$prefix" = "true"; then
|
||||||
if test -z "$line"; then prefix=false; fi
|
if test -z "$line"; then prefix=false; fi
|
||||||
else
|
else
|
||||||
if echo $line | egrep -q '^commit [0-9a-f]+'; then
|
if echo "$line" | egrep -q '^commit [0-9a-f]+'; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
echo $line >> ${RELEASE_NOTES}
|
echo "$line" >> ${RELEASE_NOTES}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
58
CHANGELOG.md
58
CHANGELOG.md
@@ -1,5 +1,63 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.8.0 (Unreleased)
|
||||||
|
|
||||||
|
### Mono-Repository Improvements
|
||||||
|
|
||||||
|
Enhanced performance during manifest generation from mono-repository - the repository that represents the
|
||||||
|
desired state of the whole cluster and contains hundreds of applications. The improved argocd-repo-server
|
||||||
|
now able to concurrently generate manifests from the same repository and for the same commit SHA. This
|
||||||
|
might provide 10x performance improvement of manifests generation.
|
||||||
|
|
||||||
|
### Annotation Based Path Detection
|
||||||
|
|
||||||
|
The feature that allows specifying which source repository directories influence the application manifest generation
|
||||||
|
using the `argocd.argoproj.io/manifest-generate-paths` annotation. The annotation improves the Git webhook handler
|
||||||
|
behavior. The webhook avoids related applications reconciliation if no related files have been changed by the Git commit
|
||||||
|
and even allows to skip manifests generation for new commit by re-using generation manifests for the previous commit.
|
||||||
|
|
||||||
|
### Horizontal Controller Scaling
|
||||||
|
|
||||||
|
This release allows scaling the `argocd-application-controller` horizontally. This allows you to manage as many Kubernetes clusters
|
||||||
|
as needed using a single Argo CD instance.
|
||||||
|
|
||||||
|
## New Core Functionality Features
|
||||||
|
|
||||||
|
Besides performance improvements, Argo CD got a lot of usability enhancements and new features:
|
||||||
|
|
||||||
|
* Namespace and CRD creation [#4354](https://github.com/argoproj/argo-cd/issues/4354)
|
||||||
|
* Unknown fields of built-in K8S types [#1787](https://github.com/argoproj/argo-cd/issues/1787)
|
||||||
|
* Endpoints Diffing [#1816](https://github.com/argoproj/argo-cd/issues/1816)
|
||||||
|
* Better compatibility with Helm Hooks [#1816](https://github.com/argoproj/argo-cd/issues/1816)
|
||||||
|
* App-of-Apps Health Assessment [#3781](https://github.com/argoproj/argo-cd/issues/3781)
|
||||||
|
|
||||||
|
## Global Projects
|
||||||
|
|
||||||
|
This release makes it easy to manage an Argo CD that has hundreds of Projects. Instead of duplicating the same organization-wide rules in all projects
|
||||||
|
you can put such rules into one project and make this project “global” for all other projects. Rules defined in the global project are inherited by all
|
||||||
|
other projects and therefore don’t have to be duplicated. The sample below demonstrates how you can create a global project and specify which project should
|
||||||
|
inherit global project rules using Kubernetes labels.
|
||||||
|
|
||||||
|
## User Interface Improvements
|
||||||
|
|
||||||
|
The Argo CD user interface is an important part of a project and we keep working hard on improving the user experience. Here is an incomplete list of implemented improvements:
|
||||||
|
|
||||||
|
* Improved Applications Filters [#4622](https://github.com/argoproj/argo-cd/issues/4622)
|
||||||
|
* Git tags and branches autocompletion [#4713](https://github.com/argoproj/argo-cd/issues/4713)
|
||||||
|
* Project Details Page [#4400](https://github.com/argoproj/argo-cd/issues/4400)
|
||||||
|
* New version information panel [#4376](https://github.com/argoproj/argo-cd/issues/4376)
|
||||||
|
* Progress Indicators [#4411](https://github.com/argoproj/argo-cd/issues/4411)
|
||||||
|
* External links annotations [#4380](https://github.com/argoproj/argo-cd/issues/4380) and more!
|
||||||
|
|
||||||
|
## Config Management Tools Enhancements
|
||||||
|
|
||||||
|
* OCI Based Repositories [#4018](https://github.com/argoproj/argo-cd/issues/4018)
|
||||||
|
* Configurable Helm Versions [#4111](https://github.com/argoproj/argo-cd/issues/4111)
|
||||||
|
|
||||||
|
## Bug fixes and under the hood changes
|
||||||
|
|
||||||
|
In addition to new features and enhancements, we’ve fixed more than 50 bugs and upgraded third-party components and libraries that Argo CD relies on.
|
||||||
|
|
||||||
## v1.7.9 (2020-11-17)
|
## v1.7.9 (2020-11-17)
|
||||||
|
|
||||||
- fix: improve commit verification tolerance (#4825)
|
- fix: improve commit verification tolerance (#4825)
|
||||||
|
|||||||
2
Procfile
2
Procfile
@@ -1,6 +1,6 @@
|
|||||||
controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-application-controller/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-application-controller/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||||
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-server/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --staticassets ui/dist/app"
|
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-server/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --staticassets ui/dist/app"
|
||||||
dex: sh -c "go run github.com/argoproj/argo-cd/cmd/argocd-util gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml quay.io/dexidp/dex:v2.25.0 serve /dex.yaml"
|
dex: sh -c "go run github.com/argoproj/argo-cd/cmd/argocd-util gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.27.0 serve /dex.yaml"
|
||||||
redis: docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} redis:5.0.10-alpine --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}
|
redis: docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} redis:5.0.10-alpine --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}
|
||||||
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-repo-server/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} go run ./cmd/argocd-repo-server/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||||
ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start'
|
ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start'
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import (
|
|||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
|
||||||
"github.com/argoproj/argo-cd/common"
|
"github.com/argoproj/argo-cd/common"
|
||||||
"github.com/argoproj/argo-cd/reposerver"
|
"github.com/argoproj/argo-cd/reposerver"
|
||||||
|
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||||
reposervercache "github.com/argoproj/argo-cd/reposerver/cache"
|
reposervercache "github.com/argoproj/argo-cd/reposerver/cache"
|
||||||
"github.com/argoproj/argo-cd/reposerver/metrics"
|
"github.com/argoproj/argo-cd/reposerver/metrics"
|
||||||
"github.com/argoproj/argo-cd/reposerver/repository"
|
"github.com/argoproj/argo-cd/reposerver/repository"
|
||||||
@@ -23,6 +25,8 @@ import (
|
|||||||
"github.com/argoproj/argo-cd/util/env"
|
"github.com/argoproj/argo-cd/util/env"
|
||||||
"github.com/argoproj/argo-cd/util/errors"
|
"github.com/argoproj/argo-cd/util/errors"
|
||||||
"github.com/argoproj/argo-cd/util/gpg"
|
"github.com/argoproj/argo-cd/util/gpg"
|
||||||
|
"github.com/argoproj/argo-cd/util/healthz"
|
||||||
|
ioutil "github.com/argoproj/argo-cd/util/io"
|
||||||
"github.com/argoproj/argo-cd/util/tls"
|
"github.com/argoproj/argo-cd/util/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,8 +36,8 @@ const (
|
|||||||
gnuPGSourcePath = "/app/config/gpg/source"
|
gnuPGSourcePath = "/app/config/gpg/source"
|
||||||
|
|
||||||
defaultPauseGenerationAfterFailedGenerationAttempts = 3
|
defaultPauseGenerationAfterFailedGenerationAttempts = 3
|
||||||
defaultPauseGenerationOnFailureForMinutes = 0
|
defaultPauseGenerationOnFailureForMinutes = 60
|
||||||
defaultPauseGenerationOnFailureForRequests = 12
|
defaultPauseGenerationOnFailureForRequests = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
func getGnuPGSourcePath() string {
|
func getGnuPGSourcePath() string {
|
||||||
@@ -96,6 +100,28 @@ func NewCommand() *cobra.Command {
|
|||||||
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", listenPort))
|
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", listenPort))
|
||||||
errors.CheckError(err)
|
errors.CheckError(err)
|
||||||
|
|
||||||
|
healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error {
|
||||||
|
if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
|
||||||
|
// connect to itself to make sure repo server is able to serve connection
|
||||||
|
// used by liveness probe to auto restart repo server
|
||||||
|
// see https://github.com/argoproj/argo-cd/issues/5110 for more information
|
||||||
|
conn, err := apiclient.NewConnection(fmt.Sprintf("localhost:%d", listenPort), 60)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ioutil.Close(conn)
|
||||||
|
client := grpc_health_v1.NewHealthClient(conn)
|
||||||
|
res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.Status != grpc_health_v1.HealthCheckResponse_SERVING {
|
||||||
|
return fmt.Errorf("grpc health check status is '%v'", res.Status)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
http.Handle("/metrics", metricsServer.GetHandler())
|
http.Handle("/metrics", metricsServer.GetHandler())
|
||||||
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf(":%d", metricsPort), nil)) }()
|
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf(":%d", metricsPort), nil)) }()
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
@@ -278,7 +279,7 @@ func reconcileApplications(
|
|||||||
projLister := appInformerFactory.Argoproj().V1alpha1().AppProjects().Lister()
|
projLister := appInformerFactory.Argoproj().V1alpha1().AppProjects().Lister()
|
||||||
server, err := metrics.NewMetricsServer("", appLister, func(obj interface{}) bool {
|
server, err := metrics.NewMetricsServer("", appLister, func(obj interface{}) bool {
|
||||||
return true
|
return true
|
||||||
}, func() error {
|
}, func(r *http.Request) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc"
|
"github.com/coreos/go-oidc"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/skratchdot/open-golang/open"
|
"github.com/skratchdot/open-golang/open"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -113,7 +113,7 @@ func NewLoginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comman
|
|||||||
}
|
}
|
||||||
|
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
claims := jwt.MapClaims{}
|
claims := jwt.MapClaims{}
|
||||||
_, _, err := parser.ParseUnverified(tokenString, &claims)
|
_, _, err := parser.ParseUnverified(tokenString, &claims)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
timeutil "github.com/argoproj/pkg/time"
|
timeutil "github.com/argoproj/pkg/time"
|
||||||
jwtgo "github.com/dgrijalva/jwt-go"
|
jwtgo "github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
|
argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ const (
|
|||||||
DexAPIEndpoint = "/api/dex"
|
DexAPIEndpoint = "/api/dex"
|
||||||
// LoginEndpoint is Argo CD's shorthand login endpoint which redirects to dex's OAuth 2.0 provider's consent page
|
// LoginEndpoint is Argo CD's shorthand login endpoint which redirects to dex's OAuth 2.0 provider's consent page
|
||||||
LoginEndpoint = "/auth/login"
|
LoginEndpoint = "/auth/login"
|
||||||
|
// LogoutEndpoint is Argo CD's shorthand logout endpoint which invalidates OIDC session after logout
|
||||||
|
LogoutEndpoint = "/auth/logout"
|
||||||
// CallbackEndpoint is Argo CD's final callback endpoint we reach after OAuth 2.0 login flow has been completed
|
// CallbackEndpoint is Argo CD's final callback endpoint we reach after OAuth 2.0 login flow has been completed
|
||||||
CallbackEndpoint = "/auth/callback"
|
CallbackEndpoint = "/auth/callback"
|
||||||
// DexCallbackEndpoint is Argo CD's final callback endpoint when Dex is configured
|
// DexCallbackEndpoint is Argo CD's final callback endpoint when Dex is configured
|
||||||
@@ -180,6 +182,8 @@ const (
|
|||||||
EnvControllerReplicas = "ARGOCD_CONTROLLER_REPLICAS"
|
EnvControllerReplicas = "ARGOCD_CONTROLLER_REPLICAS"
|
||||||
// EnvControllerShard is the shard number that should be handled by controller
|
// EnvControllerShard is the shard number that should be handled by controller
|
||||||
EnvControllerShard = "ARGOCD_CONTROLLER_SHARD"
|
EnvControllerShard = "ARGOCD_CONTROLLER_SHARD"
|
||||||
|
// EnvEnableGRPCTimeHistogramEnv enables gRPC metrics collection
|
||||||
|
EnvEnableGRPCTimeHistogramEnv = "ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -189,7 +193,7 @@ const (
|
|||||||
MinClientVersion = "1.4.0"
|
MinClientVersion = "1.4.0"
|
||||||
// CacheVersion is a objects version cached using util/cache/cache.go.
|
// CacheVersion is a objects version cached using util/cache/cache.go.
|
||||||
// Number should be bumped in case of backward incompatible change to make sure cache is invalidated after upgrade.
|
// Number should be bumped in case of backward incompatible change to make sure cache is invalidated after upgrade.
|
||||||
CacheVersion = "1.8.1"
|
CacheVersion = "1.8.3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetGnuPGHomePath retrieves the path to use for GnuPG home directory, which is either taken from GNUPGHOME environment or a default value
|
// GetGnuPGHomePath retrieves the path to use for GnuPG home directory, which is either taken from GNUPGHOME environment or a default value
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -13,12 +14,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
logutils "github.com/argoproj/argo-cd/util/log"
|
|
||||||
|
|
||||||
"github.com/argoproj/gitops-engine/pkg/diff"
|
"github.com/argoproj/gitops-engine/pkg/diff"
|
||||||
"github.com/argoproj/gitops-engine/pkg/health"
|
"github.com/argoproj/gitops-engine/pkg/health"
|
||||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||||
|
jsonpatch "github.com/evanphx/json-patch"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sync/semaphore"
|
"golang.org/x/sync/semaphore"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
@@ -26,9 +26,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
@@ -42,7 +44,6 @@ import (
|
|||||||
"github.com/argoproj/argo-cd/pkg/apis/application"
|
"github.com/argoproj/argo-cd/pkg/apis/application"
|
||||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||||
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
||||||
appinformers "github.com/argoproj/argo-cd/pkg/client/informers/externalversions"
|
|
||||||
"github.com/argoproj/argo-cd/pkg/client/informers/externalversions/application/v1alpha1"
|
"github.com/argoproj/argo-cd/pkg/client/informers/externalversions/application/v1alpha1"
|
||||||
applisters "github.com/argoproj/argo-cd/pkg/client/listers/application/v1alpha1"
|
applisters "github.com/argoproj/argo-cd/pkg/client/listers/application/v1alpha1"
|
||||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||||
@@ -51,6 +52,7 @@ import (
|
|||||||
"github.com/argoproj/argo-cd/util/db"
|
"github.com/argoproj/argo-cd/util/db"
|
||||||
"github.com/argoproj/argo-cd/util/errors"
|
"github.com/argoproj/argo-cd/util/errors"
|
||||||
"github.com/argoproj/argo-cd/util/glob"
|
"github.com/argoproj/argo-cd/util/glob"
|
||||||
|
logutils "github.com/argoproj/argo-cd/util/log"
|
||||||
settings_util "github.com/argoproj/argo-cd/util/settings"
|
settings_util "github.com/argoproj/argo-cd/util/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -151,10 +153,7 @@ func NewApplicationController(
|
|||||||
ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit)
|
ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit)
|
||||||
}
|
}
|
||||||
kubectl.SetOnKubectlRun(ctrl.onKubectlRun)
|
kubectl.SetOnKubectlRun(ctrl.onKubectlRun)
|
||||||
appInformer, appLister, err := ctrl.newApplicationInformerAndLister()
|
appInformer, appLister := ctrl.newApplicationInformerAndLister()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}
|
||||||
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, indexers)
|
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, indexers)
|
||||||
projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
@@ -175,7 +174,8 @@ func NewApplicationController(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort)
|
metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort)
|
||||||
ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, func() error {
|
var err error
|
||||||
|
ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, func(r *http.Request) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -854,6 +854,11 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
|||||||
ctrl.requestAppRefresh(app.Name, CompareWithLatest.Pointer(), &retryAfter)
|
ctrl.requestAppRefresh(app.Name, CompareWithLatest.Pointer(), &retryAfter)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
// retrying operation. remove previous failure time in app since it is used as a trigger
|
||||||
|
// that previous failed and operation should be retried
|
||||||
|
state.FinishedAt = nil
|
||||||
|
ctrl.setOperationState(app, state)
|
||||||
|
// Get rid of sync results and null out previous operation completion time
|
||||||
state.SyncResult = nil
|
state.SyncResult = nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -944,6 +949,13 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if app.Status.OperationState != nil && app.Status.OperationState.FinishedAt != nil && state.FinishedAt == nil {
|
||||||
|
patchJSON, err = jsonpatch.MergeMergePatches(patchJSON, []byte(`{"status": {"operationState": {"finishedAt": null}}}`))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace)
|
appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace)
|
||||||
_, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patchJSON, metav1.PatchOptions{})
|
_, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patchJSON, metav1.PatchOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1392,11 +1404,6 @@ func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db)
|
|
||||||
if err != nil {
|
|
||||||
ctrl.setAppCondition(app, appv1.ApplicationCondition{Type: appv1.ApplicationConditionInvalidSpecError, Message: err.Error()})
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if ctrl.clusterFilter != nil {
|
if ctrl.clusterFilter != nil {
|
||||||
cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server)
|
cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1408,15 +1415,47 @@ func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.SharedIndexInformer, applisters.ApplicationLister, error) {
|
func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.SharedIndexInformer, applisters.ApplicationLister) {
|
||||||
appInformerFactory := appinformers.NewFilteredSharedInformerFactory(
|
informer := cache.NewSharedIndexInformer(
|
||||||
ctrl.applicationClientset,
|
&cache.ListWatch{
|
||||||
|
ListFunc: func(options metav1.ListOptions) (apiruntime.Object, error) {
|
||||||
|
return ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).List(context.TODO(), options)
|
||||||
|
},
|
||||||
|
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Watch(context.TODO(), options)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&appv1.Application{},
|
||||||
ctrl.statusRefreshTimeout,
|
ctrl.statusRefreshTimeout,
|
||||||
ctrl.namespace,
|
cache.Indexers{
|
||||||
func(options *metav1.ListOptions) {},
|
cache.NamespaceIndex: func(obj interface{}) ([]string, error) {
|
||||||
|
app, ok := obj.(*appv1.Application)
|
||||||
|
if ok {
|
||||||
|
if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil {
|
||||||
|
ctrl.setAppCondition(app, appv1.ApplicationCondition{Type: appv1.ApplicationConditionInvalidSpecError, Message: err.Error()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.MetaNamespaceIndexFunc(obj)
|
||||||
|
},
|
||||||
|
orphanedIndex: func(obj interface{}) (i []string, e error) {
|
||||||
|
app, ok := obj.(*appv1.Application)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
proj, err := ctrl.getAppProj(app)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if proj.Spec.OrphanedResources != nil {
|
||||||
|
return []string{app.Spec.Destination.Namespace}, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
informer := appInformerFactory.Argoproj().V1alpha1().Applications().Informer()
|
lister := applisters.NewApplicationLister(informer.GetIndexer())
|
||||||
lister := appInformerFactory.Argoproj().V1alpha1().Applications().Lister()
|
|
||||||
informer.AddEventHandler(
|
informer.AddEventHandler(
|
||||||
cache.ResourceEventHandlerFuncs{
|
cache.ResourceEventHandlerFuncs{
|
||||||
AddFunc: func(obj interface{}) {
|
AddFunc: func(obj interface{}) {
|
||||||
@@ -1461,24 +1500,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
err := informer.AddIndexers(cache.Indexers{
|
return informer, lister
|
||||||
orphanedIndex: func(obj interface{}) (i []string, e error) {
|
|
||||||
app, ok := obj.(*appv1.Application)
|
|
||||||
if !ok {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
proj, err := ctrl.getAppProj(app)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if proj.Spec.OrphanedResources != nil {
|
|
||||||
return []string{app.Spec.Destination.Namespace}, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return informer, lister, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctrl *ApplicationController) RegisterClusterSecretUpdater(ctx context.Context) {
|
func (ctrl *ApplicationController) RegisterClusterSecretUpdater(ctx context.Context) {
|
||||||
|
|||||||
@@ -1006,26 +1006,6 @@ func TestUpdateReconciledAt(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCanProcessApp_DestNameIsValid(t *testing.T) {
|
|
||||||
app := newFakeAppWithDestName()
|
|
||||||
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}})
|
|
||||||
|
|
||||||
ok := ctrl.canProcessApp(app)
|
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Len(t, app.Status.Conditions, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCanProcessApp_BothDestNameAndServer(t *testing.T) {
|
|
||||||
app := newFakeAppWithDestMismatch()
|
|
||||||
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}})
|
|
||||||
|
|
||||||
ok := ctrl.canProcessApp(app)
|
|
||||||
assert.False(t, ok)
|
|
||||||
assert.Len(t, app.Status.Conditions, 1)
|
|
||||||
assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, app.Status.Conditions[0].Type)
|
|
||||||
assert.Equal(t, "application destination can't have both name and server defined: another-cluster https://localhost:6443", app.Status.Conditions[0].Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFinalizeProjectDeletion_HasApplications(t *testing.T) {
|
func TestFinalizeProjectDeletion_HasApplications(t *testing.T) {
|
||||||
app := newFakeApp()
|
app := newFakeApp()
|
||||||
proj := &argoappv1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace}}
|
proj := &argoappv1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace}}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewMetricsServer returns a new prometheus server which collects application metrics
|
// NewMetricsServer returns a new prometheus server which collects application metrics
|
||||||
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func() error) (*MetricsServer, error) {
|
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func(r *http.Request) error) (*MetricsServer, error) {
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ status:
|
|||||||
status: Healthy
|
status: Healthy
|
||||||
`
|
`
|
||||||
|
|
||||||
var noOpHealthCheck = func() error {
|
var noOpHealthCheck = func(r *http.Request) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ and might fail. To avoid failed syncs use `ARGOCD_GIT_ATTEMPTS_COUNT` environmen
|
|||||||
|
|
||||||
* `argocd_git_request_total` - Number of git requests. The metric provides two tags: `repo` - Git repo URL; `request_type` - `ls-remote` or `fetch`.
|
* `argocd_git_request_total` - Number of git requests. The metric provides two tags: `repo` - Git repo URL; `request_type` - `ls-remote` or `fetch`.
|
||||||
|
|
||||||
|
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` (v1.8+) - environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
|
||||||
|
|
||||||
### argocd-application-controller
|
### argocd-application-controller
|
||||||
|
|
||||||
**settings:**
|
**settings:**
|
||||||
@@ -82,6 +84,8 @@ spec:
|
|||||||
value: "2"
|
value: "2"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` (v1.8+)- environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
|
||||||
|
|
||||||
**metrics**
|
**metrics**
|
||||||
|
|
||||||
* `argocd_app_reconcile` - reports application reconciliation duration. Can be used to build reconciliation duration heat map to get high-level reconciliation performance picture.
|
* `argocd_app_reconcile` - reports application reconciliation duration. Can be used to build reconciliation duration heat map to get high-level reconciliation performance picture.
|
||||||
@@ -92,6 +96,11 @@ non-preferred version and causes performance issues.
|
|||||||
|
|
||||||
The `argocd-server` is stateless and probably least likely to cause issues. You might consider increasing number of replicas to 3 or more to ensure there is no downtime during upgrades.
|
The `argocd-server` is stateless and probably least likely to cause issues. You might consider increasing number of replicas to 3 or more to ensure there is no downtime during upgrades.
|
||||||
|
|
||||||
|
**settings:**
|
||||||
|
|
||||||
|
* The `ARGOCD_GRPC_MAX_SIZE_MB` environment variable allows specifying the max size of the server response message in megabytes.
|
||||||
|
The default value is 200. You might need to increase for an Argo CD instance that manages 3000+ applications.
|
||||||
|
|
||||||
### argocd-dex-server, argocd-redis
|
### argocd-dex-server, argocd-redis
|
||||||
|
|
||||||
The `argocd-dex-server` uses an in-memory database, and two or more instances would have inconsistent data. `argocd-redis` is pre-configured with the understanding of only three total redis servers/sentinels.
|
The `argocd-dex-server` uses an in-memory database, and two or more instances would have inconsistent data. `argocd-redis` is pre-configured with the understanding of only three total redis servers/sentinels.
|
||||||
|
|||||||
47
docs/operator-manual/upgrading/1.7-1.8.md
Normal file
47
docs/operator-manual/upgrading/1.7-1.8.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# v1.7 to 1.8
|
||||||
|
|
||||||
|
## The argocd-application-controller converted to StatefulSet
|
||||||
|
|
||||||
|
The `argocd-application-controller` has been converted to StatefulSet. That means you need to manually delete `argocd-application-controller` Deployment after upgrading.
|
||||||
|
Similarly if you decided to rollback to v1.7 don't forget to delete `argocd-application-controller` StatefulSet.
|
||||||
|
|
||||||
|
|
||||||
|
## Health assessement of argoproj.io/Application CRD has been removed
|
||||||
|
|
||||||
|
The health assessement of `argoproj.io/Application` CRD has been removed (see [#3781](https://github.com/argoproj/argo-cd/issues/3781) for more information).
|
||||||
|
You might need to restore it if you are using app-of-apps pattern and orchestrating syncronization using sync waves. Add the following resource customization in
|
||||||
|
`argocd-cm` ConfigMap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: argocd-cm
|
||||||
|
namespace: argocd
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: argocd-cm
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
data:
|
||||||
|
resource.customizations: |
|
||||||
|
argoproj.io/Application:
|
||||||
|
health.lua: |
|
||||||
|
hs = {}
|
||||||
|
hs.status = "Healthy"
|
||||||
|
hs.message = ""
|
||||||
|
if obj.status ~= nil then
|
||||||
|
if obj.status.health ~= nil then
|
||||||
|
hs.status = obj.status.health.status
|
||||||
|
hs.message = obj.status.health.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return hs
|
||||||
|
```
|
||||||
|
|
||||||
|
## gRPC metrics are disabled by default
|
||||||
|
|
||||||
|
The gRPC metrics are not exposed by default by `argocd-server` and `argocd-repo-server` anymore. These metrics appear
|
||||||
|
to be too expensive so we've decided to disable them by default. Metrics can be enabled using
|
||||||
|
`ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM=true` environment variable.
|
||||||
|
|
||||||
|
From here on you can follow the [regular upgrade process](./overview.md).
|
||||||
@@ -37,6 +37,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/<v
|
|||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
* [v1.7 to v1.8](./1.7-1.8.md)
|
||||||
* [v1.6 to v1.7](./1.6-1.7.md)
|
* [v1.6 to v1.7](./1.6-1.7.md)
|
||||||
* [v1.5 to v1.6](./1.5-1.6.md)
|
* [v1.5 to v1.6](./1.5-1.6.md)
|
||||||
* [v1.4 to v1.5](./1.4-1.5.md)
|
* [v1.4 to v1.5](./1.4-1.5.md)
|
||||||
|
|||||||
@@ -263,3 +263,29 @@ For a simple case this can be:
|
|||||||
oidc.config: |
|
oidc.config: |
|
||||||
requestedIDTokenClaims: {"groups": {"essential": true}}
|
requestedIDTokenClaims: {"groups": {"essential": true}}
|
||||||
```
|
```
|
||||||
|
### Configuring a custom logout URL for your OIDC provider
|
||||||
|
|
||||||
|
Optionally, if your OIDC provider exposes a logout API and you wish to configure a custom logout URL for the purposes of invalidating
|
||||||
|
any active session post logout, you can do so by specifying it as follows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
oidc.config: |
|
||||||
|
name: example-OIDC-provider
|
||||||
|
issuer: https://example-OIDC-provider.com
|
||||||
|
clientID: xxxxxxxxx
|
||||||
|
clientSecret: xxxxxxxxx
|
||||||
|
requestedScopes: ["openid", "profile", "email", "groups"]
|
||||||
|
requestedIDTokenClaims: {"groups": {"essential": true}}
|
||||||
|
logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}}
|
||||||
|
```
|
||||||
|
By default, this would take the user to their OIDC provider's login page after logout. If you also wish to redirect the user back to Argo CD after logout, you can specify the logout URL as follows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
...
|
||||||
|
logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}
|
||||||
|
```
|
||||||
|
|
||||||
|
You are not required to specify a logoutRedirectURL as this is automatically generated by ArgoCD as your base ArgoCD url + Rootpath
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
The post logout redirect URI may need to be whitelisted against your OIDC provider's client settings for ArgoCD.
|
||||||
24
go.mod
24
go.mod
@@ -7,13 +7,13 @@ require (
|
|||||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
|
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
|
||||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 // indirect
|
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 // indirect
|
||||||
github.com/alicebob/miniredis v2.5.0+incompatible
|
github.com/alicebob/miniredis v2.5.0+incompatible
|
||||||
github.com/argoproj/gitops-engine v0.1.3-0.20201113084616-069a5e64fb79
|
github.com/argoproj/gitops-engine v0.2.1
|
||||||
github.com/argoproj/pkg v0.2.0
|
github.com/argoproj/pkg v0.2.0
|
||||||
github.com/bombsimon/logrusr v1.0.0
|
github.com/bombsimon/logrusr v1.0.0
|
||||||
github.com/casbin/casbin v1.9.1
|
github.com/casbin/casbin v1.9.1
|
||||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible
|
github.com/coreos/go-oidc v2.1.0+incompatible
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
|
||||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/evanphx/json-patch v4.9.0+incompatible
|
github.com/evanphx/json-patch v4.9.0+incompatible
|
||||||
@@ -23,19 +23,19 @@ require (
|
|||||||
github.com/go-openapi/loads v0.19.4
|
github.com/go-openapi/loads v0.19.4
|
||||||
github.com/go-openapi/runtime v0.19.4
|
github.com/go-openapi/runtime v0.19.4
|
||||||
github.com/go-openapi/spec v0.19.3
|
github.com/go-openapi/spec v0.19.3
|
||||||
github.com/go-redis/cache/v8 v8.0.0-beta.11
|
github.com/go-redis/cache/v8 v8.2.1
|
||||||
github.com/go-redis/redis/v8 v8.0.0-beta.9
|
github.com/go-redis/redis/v8 v8.3.2
|
||||||
github.com/gobuffalo/packr v1.11.0
|
github.com/gobuffalo/packr v1.11.0
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/gogits/go-gogs-client v0.0.0-20190616193657-5a05380e4bc2
|
github.com/gogits/go-gogs-client v0.0.0-20190616193657-5a05380e4bc2
|
||||||
github.com/gogo/protobuf v1.3.1
|
github.com/gogo/protobuf v1.3.1
|
||||||
github.com/golang/protobuf v1.4.2
|
github.com/golang/protobuf v1.4.3
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||||
github.com/google/go-cmp v0.5.1
|
github.com/google/go-cmp v0.5.2
|
||||||
github.com/google/go-jsonnet v0.16.0
|
github.com/google/go-jsonnet v0.17.0
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/handlers v1.5.0
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
@@ -43,6 +43,7 @@ require (
|
|||||||
github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
|
github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||||
github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 // indirect
|
github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 // indirect
|
||||||
|
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@@ -57,11 +58,13 @@ require (
|
|||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/undefinedlabs/go-mpatch v1.0.6
|
github.com/undefinedlabs/go-mpatch v1.0.6
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.1.0 // indirect
|
||||||
github.com/yuin/gopher-lua v0.0.0-20190115140932-732aa6820ec4
|
github.com/yuin/gopher-lua v0.0.0-20190115140932-732aa6820ec4
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
golang.org/x/exp v0.0.0-20200821190819-94841d0725da // indirect
|
||||||
|
golang.org/x/net v0.0.0-20201024042810-be3efd7ff127
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
|
||||||
google.golang.org/grpc v1.29.1
|
google.golang.org/grpc v1.29.1
|
||||||
gopkg.in/go-playground/webhooks.v5 v5.11.0
|
gopkg.in/go-playground/webhooks.v5 v5.11.0
|
||||||
@@ -85,6 +88,7 @@ require (
|
|||||||
|
|
||||||
replace (
|
replace (
|
||||||
github.com/golang/protobuf => github.com/golang/protobuf v1.4.2
|
github.com/golang/protobuf => github.com/golang/protobuf v1.4.2
|
||||||
|
github.com/gorilla/websocket => github.com/gorilla/websocket v1.4.2
|
||||||
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.12.2
|
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.12.2
|
||||||
github.com/improbable-eng/grpc-web => github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
|
github.com/improbable-eng/grpc-web => github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
|
||||||
|
|
||||||
|
|||||||
107
go.sum
107
go.sum
@@ -42,7 +42,6 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY
|
|||||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
|
||||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
|
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
|
||||||
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
|
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||||
@@ -64,8 +63,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
|
|||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7TPGZ8ZpLLY18HRvL7XJ3xcs0wnREgo=
|
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7TPGZ8ZpLLY18HRvL7XJ3xcs0wnREgo=
|
||||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d/go.mod h1:WML6KOYjeU8N6YyusMjj2qRvaPNUEvrQvaxuFcMRFJY=
|
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d/go.mod h1:WML6KOYjeU8N6YyusMjj2qRvaPNUEvrQvaxuFcMRFJY=
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
|
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
|
|
||||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
@@ -78,14 +75,12 @@ github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 h1:45bxf7AZMw
|
|||||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||||
github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI=
|
github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI=
|
||||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
|
||||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||||
github.com/argoproj/gitops-engine v0.1.3-0.20201113084616-069a5e64fb79 h1:+VXKYb/FNTag/vnSoH9/Pey/kXK/jBKDyOtwRfnmMMw=
|
github.com/argoproj/gitops-engine v0.2.1 h1:iXmTCCM0m2u/YVLMhJatU21awuAscGiirscn13rYQtE=
|
||||||
github.com/argoproj/gitops-engine v0.1.3-0.20201113084616-069a5e64fb79/go.mod h1:OxXp8YaT73rw9gEBnGBWg55af80nkV/uIjWCbJu1Nw0=
|
github.com/argoproj/gitops-engine v0.2.1/go.mod h1:OxXp8YaT73rw9gEBnGBWg55af80nkV/uIjWCbJu1Nw0=
|
||||||
github.com/argoproj/pkg v0.2.0 h1:ETgC600kr8WcAi3MEVY5sA1H7H/u1/IysYOobwsZ8No=
|
github.com/argoproj/pkg v0.2.0 h1:ETgC600kr8WcAi3MEVY5sA1H7H/u1/IysYOobwsZ8No=
|
||||||
github.com/argoproj/pkg v0.2.0/go.mod h1:F4TZgInLUEjzsWFB/BTJBsewoEy0ucnKSq6vmQiD/yc=
|
github.com/argoproj/pkg v0.2.0/go.mod h1:F4TZgInLUEjzsWFB/BTJBsewoEy0ucnKSq6vmQiD/yc=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
@@ -99,7 +94,6 @@ github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:
|
|||||||
github.com/aws/aws-sdk-go v1.6.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
|
github.com/aws/aws-sdk-go v1.6.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
|
||||||
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/aws/aws-sdk-go v1.33.16/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
github.com/aws/aws-sdk-go v1.33.16/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||||
github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
@@ -167,6 +161,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
|
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||||
|
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@@ -174,6 +170,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
|
||||||
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
@@ -291,11 +289,10 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K
|
|||||||
github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0=
|
github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0=
|
||||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||||
github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
|
github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
|
||||||
github.com/go-redis/cache/v8 v8.0.0-beta.11 h1:6QdpDYemSFQ2yrDkDkEofHpXid6Mm3UctqaVUzxGdn8=
|
github.com/go-redis/cache/v8 v8.2.1 h1:G4CtEQDT3JsiERPob1nUL/KTkiC317rAJvHx6GdWjiM=
|
||||||
github.com/go-redis/cache/v8 v8.0.0-beta.11/go.mod h1:4wxD/neK+Uw+SteOR+AXtlyQYMBlI/D1u7UahfDCBAI=
|
github.com/go-redis/cache/v8 v8.2.1/go.mod h1:8PFGBZrRqG2nToSHw76mSsozxgSKrn3vsZerq/NJtt8=
|
||||||
github.com/go-redis/redis/v8 v8.0.0-beta.2/go.mod h1:o1M7JtsgfDYyv3o+gBn/jJ1LkqpnCrmil7PSppZGBak=
|
github.com/go-redis/redis/v8 v8.3.2 h1:1bJscgN2yGtKLW6MsTRosa2LHyeq94j0hnNAgRZzj/M=
|
||||||
github.com/go-redis/redis/v8 v8.0.0-beta.9 h1:gcRNXZvs4PFi/mptho1D3hXant8JsbQKQxQ+0W3QGPw=
|
github.com/go-redis/redis/v8 v8.3.2/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU=
|
||||||
github.com/go-redis/redis/v8 v8.0.0-beta.9/go.mod h1:CCWlPAL3uftOyyBOGpJ+A0ps2WpG3+hqo14fVs5aQ6A=
|
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
@@ -326,8 +323,6 @@ github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
|||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||||
@@ -341,10 +336,11 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
|||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||||
github.com/google/go-jsonnet v0.16.0 h1:Nb4EEOp+rdeGGyB1rQ5eisgSAqrTnhf9ip+X6lzZbY0=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-jsonnet v0.16.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
|
github.com/google/go-jsonnet v0.17.0 h1:/9NIEfhK1NQRKl3sP2536b2+x5HnZMdql7x3yK/l8JY=
|
||||||
|
github.com/google/go-jsonnet v0.17.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
@@ -365,12 +361,11 @@ github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3i
|
|||||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
github.com/gorilla/handlers v1.5.0 h1:4wjo3sf9azi99c8hTmyaxp9y5S+pFszsy3pP0rAw/lw=
|
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||||
github.com/gorilla/handlers v1.5.0/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
@@ -425,8 +420,8 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT
|
|||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
|
github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE=
|
||||||
github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@@ -487,12 +482,12 @@ github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9
|
|||||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mmcloughlin/avo v0.0.0-20200504053806-fa88270b07e4 h1:HqABfvSTSz0ipb7ArOwybHX8/5lSzn0eU7BDYiBU/XY=
|
|
||||||
github.com/mmcloughlin/avo v0.0.0-20200504053806-fa88270b07e4/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
|
|
||||||
github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
|
github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
|
||||||
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
|
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
|
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf h1:Un6PNx5oMK6CCwO3QTUyPiK2mtZnPrpDl5UnZ64eCkw=
|
||||||
|
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -512,18 +507,26 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||||
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||||
|
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||||
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
|
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
|
||||||
|
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
|
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
|
||||||
|
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
@@ -535,7 +538,6 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
|
|||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
@@ -654,11 +656,13 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17
|
|||||||
github.com/vishvananda/netns v0.0.0-20200520041808-52d707b772fe/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20200520041808-52d707b772fe/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
|
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
|
||||||
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
|
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
github.com/vmihailenco/go-tinylfu v0.1.0 h1:wNwKigNq50gfiyQDPpseEuGK4TZtFyjduJSg0M6gBns=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.0.0-alpha.2 h1:0jVpYJSRJzGY7m21n9V5uIkl7Zre64W8DR1dxEKX2g4=
|
github.com/vmihailenco/go-tinylfu v0.1.0/go.mod h1:qZbD6U3F10Sfuxyy4c5wMq5CM4/t5I3eJJS9yMQoXU0=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.0.0-alpha.2/go.mod h1:LDfrk4wJpSFwkzNOJxrCWiSm8c7Iqw/hXNPT2fzQfE8=
|
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.5/go.mod h1:MPECSZPg8yittBek5Gq2MhEDJpB9FrbSzQOSWmJm38A=
|
||||||
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
|
github.com/vmihailenco/msgpack/v5 v5.1.0 h1:+od5YbEXxW95SPlW6beocmt8nOtlh83zqat5Ip9Hwdc=
|
||||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
github.com/vmihailenco/msgpack/v5 v5.1.0/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI=
|
||||||
|
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
|
||||||
|
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||||
@@ -679,14 +683,12 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
|
|||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opentelemetry.io/otel v0.5.0/go.mod h1:jzBIgIzK43Iu1BpDAXwqOd6UPsSAk+ewVZ5ofSXw4Ek=
|
go.opentelemetry.io/otel v0.13.0 h1:2isEnyzjjJZq6r2EKMsFj4TxiQiexsM04AVhwbR/oBA=
|
||||||
go.opentelemetry.io/otel v0.11.0 h1:IN2tzQa9Gc4ZVKnTaMbPVcHjvzOdg5n9QfnmlqiET7E=
|
go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY=
|
||||||
go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0=
|
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@@ -755,18 +757,20 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201024042810-be3efd7ff127 h1:pZPp9+iYUqwYKLjht0SDBbRCRK/9gAXDy7pz5fRDpjo=
|
||||||
|
golang.org/x/net v0.0.0-20201024042810-be3efd7ff127/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -780,6 +784,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -803,10 +809,10 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -823,9 +829,13 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
|
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
@@ -866,8 +876,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200519015757-0d0afa43d58a/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8=
|
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8=
|
||||||
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -892,8 +900,8 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
@@ -903,7 +911,6 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
|
|||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||||
@@ -914,6 +921,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
|
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||||
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -949,7 +958,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@@ -957,6 +965,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
|
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# The checksum of this file is used as cache key in our integration toolchain
|
# The checksum of this file is used as cache key in our integration toolchain
|
||||||
#
|
#
|
||||||
helm2_version=2.17.0
|
helm2_version=2.17.0
|
||||||
helm3_version=3.4.0
|
helm3_version=3.4.1
|
||||||
jq_version=1.6
|
jq_version=1.6
|
||||||
ksonnet_version=0.13.1
|
ksonnet_version=0.13.1
|
||||||
kubectl_version=1.17.8
|
kubectl_version=1.17.8
|
||||||
|
|||||||
@@ -42,3 +42,18 @@ spec:
|
|||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
serviceAccountName: argocd-application-controller
|
serviceAccountName: argocd-application-controller
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
- weight: 5
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ spec:
|
|||||||
name: static-files
|
name: static-files
|
||||||
containers:
|
containers:
|
||||||
- name: dex
|
- name: dex
|
||||||
image: quay.io/dexidp/dex:v2.25.0
|
image: ghcr.io/dexidp/dex:v2.27.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
command: [/shared/argocd-util, rundex]
|
command: [/shared/argocd-util, rundex]
|
||||||
ports:
|
ports:
|
||||||
@@ -39,3 +39,12 @@ spec:
|
|||||||
volumes:
|
volumes:
|
||||||
- emptyDir: {}
|
- emptyDir: {}
|
||||||
name: static-files
|
name: static-files
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 5
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
|||||||
images:
|
images:
|
||||||
- name: argoproj/argocd
|
- name: argoproj/argocd
|
||||||
newName: argoproj/argocd
|
newName: argoproj/argocd
|
||||||
newTag: latest
|
newTag: v1.8.2
|
||||||
resources:
|
resources:
|
||||||
- ./application-controller
|
- ./application-controller
|
||||||
- ./dex
|
- ./dex
|
||||||
|
|||||||
@@ -32,3 +32,18 @@ spec:
|
|||||||
- "no"
|
- "no"
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 6379
|
- containerPort: 6379
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-redis
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
- weight: 5
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|||||||
@@ -28,9 +28,17 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 8081
|
- containerPort: 8081
|
||||||
- containerPort: 8084
|
- containerPort: 8084
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8084
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
tcpSocket:
|
httpGet:
|
||||||
port: 8081
|
path: /healthz
|
||||||
|
port: 8084
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
@@ -54,3 +62,18 @@ spec:
|
|||||||
name: argocd-gpg-keys-cm
|
name: argocd-gpg-keys-cm
|
||||||
- name: gpg-keyring
|
- name: gpg-keyring
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-repo-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
- weight: 5
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
- containerPort: 8083
|
- containerPort: 8083
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 30
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /healthz
|
path: /healthz
|
||||||
@@ -44,3 +50,18 @@ spec:
|
|||||||
- name: tls-certs
|
- name: tls-certs
|
||||||
configMap:
|
configMap:
|
||||||
name: argocd-tls-certs-cm
|
name: argocd-tls-certs-cm
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
- weight: 5
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
|||||||
images:
|
images:
|
||||||
- name: argoproj/argocd
|
- name: argoproj/argocd
|
||||||
newName: argoproj/argocd
|
newName: argoproj/argocd
|
||||||
newTag: latest
|
newTag: v1.8.2
|
||||||
resources:
|
resources:
|
||||||
- ../../base/application-controller
|
- ../../base/application-controller
|
||||||
- ../../base/dex
|
- ../../base/dex
|
||||||
|
|||||||
@@ -2835,11 +2835,20 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-dex-server
|
app.kubernetes.io/name: argocd-dex-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- /shared/argocd-util
|
- /shared/argocd-util
|
||||||
- rundex
|
- rundex
|
||||||
image: quay.io/dexidp/dex:v2.25.0
|
image: ghcr.io/dexidp/dex:v2.27.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: dex
|
name: dex
|
||||||
ports:
|
ports:
|
||||||
@@ -2855,7 +2864,7 @@ spec:
|
|||||||
- -n
|
- -n
|
||||||
- /usr/local/bin/argocd-util
|
- /usr/local/bin/argocd-util
|
||||||
- /shared
|
- /shared
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: copyutil
|
name: copyutil
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
@@ -2993,17 +3002,25 @@ spec:
|
|||||||
- argocd-repo-server
|
- argocd-repo-server
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis-ha-haproxy:6379
|
- argocd-redis-ha-haproxy:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8084
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 5
|
||||||
name: argocd-repo-server
|
name: argocd-repo-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8081
|
- containerPort: 8081
|
||||||
- containerPort: 8084
|
- containerPort: 8084
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: 8084
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
tcpSocket:
|
|
||||||
port: 8081
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /app/config/ssh
|
- mountPath: /app/config/ssh
|
||||||
name: ssh-known-hosts
|
name: ssh-known-hosts
|
||||||
@@ -3067,8 +3084,14 @@ spec:
|
|||||||
env:
|
env:
|
||||||
- name: ARGOCD_API_SERVER_REPLICAS
|
- name: ARGOCD_API_SERVER_REPLICAS
|
||||||
value: "2"
|
value: "2"
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 30
|
||||||
name: argocd-server
|
name: argocd-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
@@ -3113,6 +3136,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-application-controller
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-application-controller
|
- argocd-application-controller
|
||||||
@@ -3122,7 +3160,7 @@ spec:
|
|||||||
- "10"
|
- "10"
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis-ha-haproxy:6379
|
- argocd-redis-ha-haproxy:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
|||||||
@@ -2750,11 +2750,20 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-dex-server
|
app.kubernetes.io/name: argocd-dex-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- /shared/argocd-util
|
- /shared/argocd-util
|
||||||
- rundex
|
- rundex
|
||||||
image: quay.io/dexidp/dex:v2.25.0
|
image: ghcr.io/dexidp/dex:v2.27.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: dex
|
name: dex
|
||||||
ports:
|
ports:
|
||||||
@@ -2770,7 +2779,7 @@ spec:
|
|||||||
- -n
|
- -n
|
||||||
- /usr/local/bin/argocd-util
|
- /usr/local/bin/argocd-util
|
||||||
- /shared
|
- /shared
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: copyutil
|
name: copyutil
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
@@ -2908,17 +2917,25 @@ spec:
|
|||||||
- argocd-repo-server
|
- argocd-repo-server
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis-ha-haproxy:6379
|
- argocd-redis-ha-haproxy:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8084
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 5
|
||||||
name: argocd-repo-server
|
name: argocd-repo-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8081
|
- containerPort: 8081
|
||||||
- containerPort: 8084
|
- containerPort: 8084
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: 8084
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
tcpSocket:
|
|
||||||
port: 8081
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /app/config/ssh
|
- mountPath: /app/config/ssh
|
||||||
name: ssh-known-hosts
|
name: ssh-known-hosts
|
||||||
@@ -2982,8 +2999,14 @@ spec:
|
|||||||
env:
|
env:
|
||||||
- name: ARGOCD_API_SERVER_REPLICAS
|
- name: ARGOCD_API_SERVER_REPLICAS
|
||||||
value: "2"
|
value: "2"
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 30
|
||||||
name: argocd-server
|
name: argocd-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
@@ -3028,6 +3051,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-application-controller
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-application-controller
|
- argocd-application-controller
|
||||||
@@ -3037,7 +3075,7 @@ spec:
|
|||||||
- "10"
|
- "10"
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis-ha-haproxy:6379
|
- argocd-redis-ha-haproxy:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
|||||||
@@ -2424,11 +2424,20 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-dex-server
|
app.kubernetes.io/name: argocd-dex-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- /shared/argocd-util
|
- /shared/argocd-util
|
||||||
- rundex
|
- rundex
|
||||||
image: quay.io/dexidp/dex:v2.25.0
|
image: ghcr.io/dexidp/dex:v2.27.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: dex
|
name: dex
|
||||||
ports:
|
ports:
|
||||||
@@ -2444,7 +2453,7 @@ spec:
|
|||||||
- -n
|
- -n
|
||||||
- /usr/local/bin/argocd-util
|
- /usr/local/bin/argocd-util
|
||||||
- /shared
|
- /shared
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: copyutil
|
name: copyutil
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
@@ -2472,6 +2481,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-redis
|
app.kubernetes.io/name: argocd-redis
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-redis
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- args:
|
- args:
|
||||||
- --save
|
- --save
|
||||||
@@ -2507,6 +2531,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-repo-server
|
app.kubernetes.io/name: argocd-repo-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-repo-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
automountServiceAccountToken: false
|
automountServiceAccountToken: false
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
@@ -2514,17 +2553,25 @@ spec:
|
|||||||
- argocd-repo-server
|
- argocd-repo-server
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis:6379
|
- argocd-redis:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8084
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 5
|
||||||
name: argocd-repo-server
|
name: argocd-repo-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8081
|
- containerPort: 8081
|
||||||
- containerPort: 8084
|
- containerPort: 8084
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: 8084
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
tcpSocket:
|
|
||||||
port: 8081
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /app/config/ssh
|
- mountPath: /app/config/ssh
|
||||||
name: ssh-known-hosts
|
name: ssh-known-hosts
|
||||||
@@ -2564,13 +2611,34 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-server
|
app.kubernetes.io/name: argocd-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-server
|
- argocd-server
|
||||||
- --staticassets
|
- --staticassets
|
||||||
- /shared/app
|
- /shared/app
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 30
|
||||||
name: argocd-server
|
name: argocd-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
@@ -2616,6 +2684,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-application-controller
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-application-controller
|
- argocd-application-controller
|
||||||
@@ -2623,7 +2706,7 @@ spec:
|
|||||||
- "20"
|
- "20"
|
||||||
- --operation-processors
|
- --operation-processors
|
||||||
- "10"
|
- "10"
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
|||||||
@@ -2339,11 +2339,20 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-dex-server
|
app.kubernetes.io/name: argocd-dex-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- /shared/argocd-util
|
- /shared/argocd-util
|
||||||
- rundex
|
- rundex
|
||||||
image: quay.io/dexidp/dex:v2.25.0
|
image: ghcr.io/dexidp/dex:v2.27.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: dex
|
name: dex
|
||||||
ports:
|
ports:
|
||||||
@@ -2359,7 +2368,7 @@ spec:
|
|||||||
- -n
|
- -n
|
||||||
- /usr/local/bin/argocd-util
|
- /usr/local/bin/argocd-util
|
||||||
- /shared
|
- /shared
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
name: copyutil
|
name: copyutil
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
@@ -2387,6 +2396,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-redis
|
app.kubernetes.io/name: argocd-redis
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-redis
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- args:
|
- args:
|
||||||
- --save
|
- --save
|
||||||
@@ -2422,6 +2446,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-repo-server
|
app.kubernetes.io/name: argocd-repo-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-repo-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
automountServiceAccountToken: false
|
automountServiceAccountToken: false
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
@@ -2429,17 +2468,25 @@ spec:
|
|||||||
- argocd-repo-server
|
- argocd-repo-server
|
||||||
- --redis
|
- --redis
|
||||||
- argocd-redis:6379
|
- argocd-redis:6379
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8084
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 5
|
||||||
name: argocd-repo-server
|
name: argocd-repo-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8081
|
- containerPort: 8081
|
||||||
- containerPort: 8084
|
- containerPort: 8084
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: 8084
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
tcpSocket:
|
|
||||||
port: 8081
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /app/config/ssh
|
- mountPath: /app/config/ssh
|
||||||
name: ssh-known-hosts
|
name: ssh-known-hosts
|
||||||
@@ -2479,13 +2526,34 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-server
|
app.kubernetes.io/name: argocd-server
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-server
|
- argocd-server
|
||||||
- --staticassets
|
- --staticassets
|
||||||
- /shared/app
|
- /shared/app
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz?full=true
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 30
|
||||||
name: argocd-server
|
name: argocd-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
@@ -2531,6 +2599,21 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: argocd-application-controller
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
spec:
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: argocd-application-controller
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 100
|
||||||
|
- podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/part-of: argocd
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
weight: 5
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- argocd-application-controller
|
- argocd-application-controller
|
||||||
@@ -2538,7 +2621,7 @@ spec:
|
|||||||
- "20"
|
- "20"
|
||||||
- --operation-processors
|
- --operation-processors
|
||||||
- "10"
|
- "10"
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:v1.8.2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -16,7 +17,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc"
|
"github.com/coreos/go-oidc"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@@ -39,6 +40,7 @@ import (
|
|||||||
versionpkg "github.com/argoproj/argo-cd/pkg/apiclient/version"
|
versionpkg "github.com/argoproj/argo-cd/pkg/apiclient/version"
|
||||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||||
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||||
|
"github.com/argoproj/argo-cd/util/env"
|
||||||
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
||||||
argoio "github.com/argoproj/argo-cd/util/io"
|
argoio "github.com/argoproj/argo-cd/util/io"
|
||||||
"github.com/argoproj/argo-cd/util/kube"
|
"github.com/argoproj/argo-cd/util/kube"
|
||||||
@@ -53,8 +55,13 @@ const (
|
|||||||
EnvArgoCDServer = "ARGOCD_SERVER"
|
EnvArgoCDServer = "ARGOCD_SERVER"
|
||||||
// EnvArgoCDAuthToken is the environment variable to look for an Argo CD auth token
|
// EnvArgoCDAuthToken is the environment variable to look for an Argo CD auth token
|
||||||
EnvArgoCDAuthToken = "ARGOCD_AUTH_TOKEN"
|
EnvArgoCDAuthToken = "ARGOCD_AUTH_TOKEN"
|
||||||
|
// EnvArgoCDgRPCMaxSizeMB is the environment variable to look for a max gRPC message size
|
||||||
|
EnvArgoCDgRPCMaxSizeMB = "ARGOCD_GRPC_MAX_SIZE_MB"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
// MaxGRPCMessageSize contains max grpc message size
|
// MaxGRPCMessageSize contains max grpc message size
|
||||||
MaxGRPCMessageSize = 100 * 1024 * 1024
|
MaxGRPCMessageSize = env.ParseNumFromEnv(EnvArgoCDgRPCMaxSizeMB, 200, 0, math.MaxInt32) * 1024 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client defines an interface for interaction with an Argo CD server.
|
// Client defines an interface for interaction with an Argo CD server.
|
||||||
@@ -321,14 +328,14 @@ func (c *client) refreshAuthToken(localCfg *localconfig.LocalConfig, ctxName, co
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
var claims jwt.StandardClaims
|
var claims jwt.StandardClaims
|
||||||
_, _, err = parser.ParseUnverified(configCtx.User.AuthToken, &claims)
|
_, _, err = parser.ParseUnverified(configCtx.User.AuthToken, &claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if claims.Valid() == nil {
|
if claims.Valid(jwt.DefaultValidationHelper) == nil {
|
||||||
// token is still valid
|
// token is still valid
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,10 +170,7 @@ func (a *ApplicationSource) IsHelmOci() bool {
|
|||||||
if a.Chart == "" {
|
if a.Chart == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if _, _, ok := helm.IsHelmOci(a.Chart); ok {
|
return helm.IsHelmOciChart(a.Chart)
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ApplicationSource) IsZero() bool {
|
func (a *ApplicationSource) IsZero() bool {
|
||||||
@@ -2398,6 +2395,17 @@ func (source *ApplicationSource) ExplicitType() (*ApplicationSourceType, error)
|
|||||||
|
|
||||||
// Equals compares two instances of ApplicationDestination and return true if instances are equal.
|
// Equals compares two instances of ApplicationDestination and return true if instances are equal.
|
||||||
func (dest ApplicationDestination) Equals(other ApplicationDestination) bool {
|
func (dest ApplicationDestination) Equals(other ApplicationDestination) bool {
|
||||||
|
// ignore destination cluster name and isServerInferred fields during comparison
|
||||||
|
// since server URL is inferred from cluster name
|
||||||
|
if dest.isServerInferred {
|
||||||
|
dest.Server = ""
|
||||||
|
dest.isServerInferred = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.isServerInferred {
|
||||||
|
other.Server = ""
|
||||||
|
other.isServerInferred = false
|
||||||
|
}
|
||||||
return reflect.DeepEqual(dest, other)
|
return reflect.DeepEqual(dest, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -429,6 +429,21 @@ func TestAppDestinationEquality(t *testing.T) {
|
|||||||
assert.False(t, left.Equals(*right))
|
assert.False(t, left.Equals(*right))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppDestinationEquality_InferredServerURL(t *testing.T) {
|
||||||
|
left := ApplicationDestination{
|
||||||
|
Name: "in-cluster",
|
||||||
|
Namespace: "default",
|
||||||
|
}
|
||||||
|
right := ApplicationDestination{
|
||||||
|
Name: "in-cluster",
|
||||||
|
Server: "https://kubernetes.default.svc",
|
||||||
|
Namespace: "default",
|
||||||
|
isServerInferred: true,
|
||||||
|
}
|
||||||
|
assert.True(t, left.Equals(right))
|
||||||
|
assert.True(t, right.Equals(left))
|
||||||
|
}
|
||||||
|
|
||||||
func TestAppProjectSpec_DestinationClusters(t *testing.T) {
|
func TestAppProjectSpec_DestinationClusters(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -30,13 +30,21 @@ type clientSet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientSet) NewRepoServerClient() (io.Closer, RepoServerServiceClient, error) {
|
func (c *clientSet) NewRepoServerClient() (io.Closer, RepoServerServiceClient, error) {
|
||||||
|
conn, err := NewConnection(c.address, c.timeoutSeconds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return conn, NewRepoServerServiceClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnection(address string, timeoutSeconds int) (*grpc.ClientConn, error) {
|
||||||
retryOpts := []grpc_retry.CallOption{
|
retryOpts := []grpc_retry.CallOption{
|
||||||
grpc_retry.WithMax(3),
|
grpc_retry.WithMax(3),
|
||||||
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)),
|
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)),
|
||||||
}
|
}
|
||||||
unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)}
|
unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)}
|
||||||
if c.timeoutSeconds > 0 {
|
if timeoutSeconds > 0 {
|
||||||
unaryInterceptors = append(unaryInterceptors, argogrpc.WithTimeout(time.Duration(c.timeoutSeconds)*time.Second))
|
unaryInterceptors = append(unaryInterceptors, argogrpc.WithTimeout(time.Duration(timeoutSeconds)*time.Second))
|
||||||
}
|
}
|
||||||
opts := []grpc.DialOption{
|
opts := []grpc.DialOption{
|
||||||
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})),
|
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})),
|
||||||
@@ -45,12 +53,12 @@ func (c *clientSet) NewRepoServerClient() (io.Closer, RepoServerServiceClient, e
|
|||||||
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)),
|
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)),
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := grpc.Dial(c.address, opts...)
|
conn, err := grpc.Dial(address, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to connect to repository service with address %s", c.address)
|
log.Errorf("Unable to connect to repository service with address %s", address)
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, NewRepoServerServiceClient(conn), nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRepoServerClientset creates new instance of repo server Clientset
|
// NewRepoServerClientset creates new instance of repo server Clientset
|
||||||
|
|||||||
4
reposerver/cache/cache.go
vendored
4
reposerver/cache/cache.go
vendored
@@ -127,11 +127,11 @@ func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource) string
|
|||||||
return fmt.Sprintf("appdetails|%s|%d", revision, appSourceKey(appSrc))
|
return fmt.Sprintf("appdetails|%s|%d", revision, appSourceKey(appSrc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) GetAppDetails(revision string, appSrc *appv1.ApplicationSource, res interface{}) error {
|
func (c *Cache) GetAppDetails(revision string, appSrc *appv1.ApplicationSource, res *apiclient.RepoAppDetailsResponse) error {
|
||||||
return c.cache.GetItem(appDetailsCacheKey(revision, appSrc), res)
|
return c.cache.GetItem(appDetailsCacheKey(revision, appSrc), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) SetAppDetails(revision string, appSrc *appv1.ApplicationSource, res interface{}) error {
|
func (c *Cache) SetAppDetails(revision string, appSrc *appv1.ApplicationSource, res *apiclient.RepoAppDetailsResponse) error {
|
||||||
return c.cache.SetItem(appDetailsCacheKey(revision, appSrc), res, c.repoCacheExpiration, res == nil)
|
return c.cache.SetItem(appDetailsCacheKey(revision, appSrc), res, c.repoCacheExpiration, res == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,6 +164,23 @@ type operationSettings struct {
|
|||||||
allowConcurrent bool
|
allowConcurrent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// operationContext contains request values which are generated by runRepoOperation (on demand) by a call to the
|
||||||
|
// provided operationContextSrc function.
|
||||||
|
type operationContext struct {
|
||||||
|
|
||||||
|
// application path or helm chart path
|
||||||
|
appPath string
|
||||||
|
|
||||||
|
// output of 'git verify-(tag/commit)', if signature verifiction is enabled (otherwise "")
|
||||||
|
verificationResult string
|
||||||
|
}
|
||||||
|
|
||||||
|
// The 'operation' function parameter of 'runRepoOperation' may call this function to retrieve
|
||||||
|
// the appPath or GPG verificationResult.
|
||||||
|
// Failure to generate either of these values will return an error which may be cached by
|
||||||
|
// the calling function (for example, 'runManifestGen')
|
||||||
|
type operationContextSrc = func() (*operationContext, error)
|
||||||
|
|
||||||
// runRepoOperation downloads either git folder or helm chart and executes specified operation
|
// runRepoOperation downloads either git folder or helm chart and executes specified operation
|
||||||
// - Returns a value from the cache if present (by calling getCached(...)); if no value is present, the
|
// - Returns a value from the cache if present (by calling getCached(...)); if no value is present, the
|
||||||
// provide operation(...) is called. The specific return type of this function is determined by the
|
// provide operation(...) is called. The specific return type of this function is determined by the
|
||||||
@@ -175,13 +192,12 @@ func (s *Service) runRepoOperation(
|
|||||||
source *v1alpha1.ApplicationSource,
|
source *v1alpha1.ApplicationSource,
|
||||||
verifyCommit bool,
|
verifyCommit bool,
|
||||||
getCached func(cacheKey string, firstInvocation bool) (bool, interface{}, error),
|
getCached func(cacheKey string, firstInvocation bool) (bool, interface{}, error),
|
||||||
operation func(appPath, repoRoot, commitSHA, cacheKey, verifyResult string) (interface{}, error),
|
operation func(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc) (interface{}, error),
|
||||||
settings operationSettings) (interface{}, error) {
|
settings operationSettings) (interface{}, error) {
|
||||||
|
|
||||||
var gitClient git.Client
|
var gitClient git.Client
|
||||||
var helmClient helm.Client
|
var helmClient helm.Client
|
||||||
var err error
|
var err error
|
||||||
var signature string
|
|
||||||
revision = textutils.FirstNonEmpty(revision, source.TargetRevision)
|
revision = textutils.FirstNonEmpty(revision, source.TargetRevision)
|
||||||
if source.IsHelm() {
|
if source.IsHelm() {
|
||||||
helmClient, revision, err = s.newHelmClientResolveRevision(repo, revision, source.Chart)
|
helmClient, revision, err = s.newHelmClientResolveRevision(repo, revision, source.Chart)
|
||||||
@@ -229,7 +245,9 @@ func (s *Service) runRepoOperation(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer io.Close(closer)
|
defer io.Close(closer)
|
||||||
return operation(chartPath, chartPath, revision, revision, "")
|
return operation(chartPath, revision, revision, func() (*operationContext, error) {
|
||||||
|
return &operationContext{chartPath, ""}, nil
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() error {
|
closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() error {
|
||||||
return checkoutRevision(gitClient, revision)
|
return checkoutRevision(gitClient, revision)
|
||||||
@@ -253,19 +271,22 @@ func (s *Service) runRepoOperation(
|
|||||||
return obj, err
|
return obj, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if verifyCommit {
|
// Here commitSHA refers to the SHA of the actual commit, whereas revision refers to the branch/tag name etc
|
||||||
signature, err = gitClient.VerifyCommitSignature(revision)
|
// We use the commitSHA to generate manifests and store them in cache, and revision to retrieve them from cache
|
||||||
|
return operation(gitClient.Root(), commitSHA, revision, func() (*operationContext, error) {
|
||||||
|
var signature string
|
||||||
|
if verifyCommit {
|
||||||
|
signature, err = gitClient.VerifyCommitSignature(revision)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appPath, err := argopath.Path(gitClient.Root(), source.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
return &operationContext{appPath, signature}, nil
|
||||||
appPath, err := argopath.Path(gitClient.Root(), source.Path)
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Here commitSHA refers to the SHA of the actual commit, whereas revision refers to the branch/tag name etc
|
|
||||||
// We use the commitSHA to generate manifests and store them in cache, and revision to retrieve them from cache
|
|
||||||
return operation(appPath, gitClient.Root(), commitSHA, revision, signature)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,8 +294,8 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq
|
|||||||
resultUncast, err := s.runRepoOperation(ctx, q.Revision, q.Repo, q.ApplicationSource, q.VerifySignature,
|
resultUncast, err := s.runRepoOperation(ctx, q.Revision, q.Repo, q.ApplicationSource, q.VerifySignature,
|
||||||
func(cacheKey string, firstInvocation bool) (bool, interface{}, error) {
|
func(cacheKey string, firstInvocation bool) (bool, interface{}, error) {
|
||||||
return s.getManifestCacheEntry(cacheKey, q, firstInvocation)
|
return s.getManifestCacheEntry(cacheKey, q, firstInvocation)
|
||||||
}, func(appPath, repoRoot, commitSHA, cacheKey, verifyResult string) (interface{}, error) {
|
}, func(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc) (interface{}, error) {
|
||||||
return s.runManifestGen(appPath, repoRoot, commitSHA, cacheKey, verifyResult, q)
|
return s.runManifestGen(repoRoot, commitSHA, cacheKey, ctxSrc, q)
|
||||||
}, operationSettings{sem: s.parallelismLimitSemaphore, noCache: q.NoCache, allowConcurrent: q.ApplicationSource.AllowsConcurrentProcessing()})
|
}, operationSettings{sem: s.parallelismLimitSemaphore, noCache: q.NoCache, allowConcurrent: q.ApplicationSource.AllowsConcurrentProcessing()})
|
||||||
result, ok := resultUncast.(*apiclient.ManifestResponse)
|
result, ok := resultUncast.(*apiclient.ManifestResponse)
|
||||||
if result != nil && !ok {
|
if result != nil && !ok {
|
||||||
@@ -289,8 +310,12 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq
|
|||||||
// - or, the cache does contain a value for this key, but it is an expired manifest generation entry
|
// - or, the cache does contain a value for this key, but it is an expired manifest generation entry
|
||||||
// - or, NoCache is true
|
// - or, NoCache is true
|
||||||
// Returns a ManifestResponse, or an error, but not both
|
// Returns a ManifestResponse, or an error, but not both
|
||||||
func (s *Service) runManifestGen(appPath, repoRoot, commitSHA, cacheKey, verifyResult string, q *apiclient.ManifestRequest) (interface{}, error) {
|
func (s *Service) runManifestGen(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc, q *apiclient.ManifestRequest) (interface{}, error) {
|
||||||
manifestGenResult, err := GenerateManifests(appPath, repoRoot, commitSHA, q, false)
|
var manifestGenResult *apiclient.ManifestResponse
|
||||||
|
ctx, err := ctxSrc()
|
||||||
|
if err == nil {
|
||||||
|
manifestGenResult, err = GenerateManifests(ctx.appPath, repoRoot, commitSHA, q, false)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
// If manifest generation error caching is enabled
|
// If manifest generation error caching is enabled
|
||||||
@@ -332,7 +357,7 @@ func (s *Service) runManifestGen(appPath, repoRoot, commitSHA, cacheKey, verifyR
|
|||||||
MostRecentError: "",
|
MostRecentError: "",
|
||||||
}
|
}
|
||||||
manifestGenResult.Revision = commitSHA
|
manifestGenResult.Revision = commitSHA
|
||||||
manifestGenResult.VerifyResult = verifyResult
|
manifestGenResult.VerifyResult = ctx.verificationResult
|
||||||
err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q.Namespace, q.AppLabelKey, q.AppLabelValue, &manifestGenCacheEntry)
|
err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q.Namespace, q.AppLabelKey, q.AppLabelValue, &manifestGenCacheEntry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err)
|
log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err)
|
||||||
@@ -742,7 +767,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path string) erro
|
|||||||
func GetAppSourceType(source *v1alpha1.ApplicationSource, path string) (v1alpha1.ApplicationSourceType, error) {
|
func GetAppSourceType(source *v1alpha1.ApplicationSource, path string) (v1alpha1.ApplicationSourceType, error) {
|
||||||
err := mergeSourceParameters(source, path)
|
err := mergeSourceParameters(source, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error while parsing .argocd-app.yaml: %v", err)
|
return "", fmt.Errorf("error while parsing .argocd-source.yaml: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appSourceType, err := source.ExplicitType()
|
appSourceType, err := source.ExplicitType()
|
||||||
@@ -837,23 +862,12 @@ func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := utfutil.ReadFile(path, utfutil.UTF8)
|
if strings.HasSuffix(f.Name(), ".jsonnet") {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(f.Name(), ".json") {
|
|
||||||
var obj unstructured.Unstructured
|
|
||||||
err = json.Unmarshal(out, &obj)
|
|
||||||
if err != nil {
|
|
||||||
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
|
||||||
}
|
|
||||||
objs = append(objs, &obj)
|
|
||||||
} else if strings.HasSuffix(f.Name(), ".jsonnet") {
|
|
||||||
vm, err := makeJsonnetVm(appPath, repoRoot, directory.Jsonnet, env)
|
vm, err := makeJsonnetVm(appPath, repoRoot, directory.Jsonnet, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
jsonStr, err := vm.EvaluateSnippet(path, string(out))
|
jsonStr, err := vm.EvaluateFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status.Errorf(codes.FailedPrecondition, "Failed to evaluate jsonnet %q: %v", f.Name(), err)
|
return status.Errorf(codes.FailedPrecondition, "Failed to evaluate jsonnet %q: %v", f.Name(), err)
|
||||||
}
|
}
|
||||||
@@ -872,24 +886,37 @@ func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory
|
|||||||
objs = append(objs, &jsonObj)
|
objs = append(objs, &jsonObj)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
yamlObjs, err := kube.SplitYAML(out)
|
out, err := utfutil.ReadFile(path, utfutil.UTF8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(yamlObjs) > 0 {
|
return err
|
||||||
// If we get here, we had a multiple objects in a single YAML file which had some
|
}
|
||||||
// valid k8s objects, but errors parsing others (within the same file). It's very
|
if strings.HasSuffix(f.Name(), ".json") {
|
||||||
// likely the user messed up a portion of the YAML, so report on that.
|
var obj unstructured.Unstructured
|
||||||
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
err = json.Unmarshal(out, &obj)
|
||||||
}
|
if err != nil {
|
||||||
// Otherwise, let's see if it looks like a resource, if yes, we return error
|
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
||||||
if bytes.Contains(out, []byte("apiVersion:")) &&
|
}
|
||||||
bytes.Contains(out, []byte("kind:")) &&
|
objs = append(objs, &obj)
|
||||||
bytes.Contains(out, []byte("metadata:")) {
|
} else {
|
||||||
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
yamlObjs, err := kube.SplitYAML(out)
|
||||||
}
|
if err != nil {
|
||||||
// Otherwise, it might be a unrelated YAML file which we will ignore
|
if len(yamlObjs) > 0 {
|
||||||
return nil
|
// If we get here, we had a multiple objects in a single YAML file which had some
|
||||||
|
// valid k8s objects, but errors parsing others (within the same file). It's very
|
||||||
|
// likely the user messed up a portion of the YAML, so report on that.
|
||||||
|
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
||||||
|
}
|
||||||
|
// Otherwise, let's see if it looks like a resource, if yes, we return error
|
||||||
|
if bytes.Contains(out, []byte("apiVersion:")) &&
|
||||||
|
bytes.Contains(out, []byte("kind:")) &&
|
||||||
|
bytes.Contains(out, []byte("metadata:")) {
|
||||||
|
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
|
||||||
|
}
|
||||||
|
// Otherwise, it might be a unrelated YAML file which we will ignore
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
objs = append(objs, yamlObjs...)
|
||||||
}
|
}
|
||||||
objs = append(objs, yamlObjs...)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -999,7 +1026,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
|||||||
|
|
||||||
getCached := func(revision string, _ bool) (bool, interface{}, error) {
|
getCached := func(revision string, _ bool) (bool, interface{}, error) {
|
||||||
res := &apiclient.RepoAppDetailsResponse{}
|
res := &apiclient.RepoAppDetailsResponse{}
|
||||||
err := s.cache.GetAppDetails(revision, q.Source, &res)
|
err := s.cache.GetAppDetails(revision, q.Source, res)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Infof("app details cache hit: %s/%s", revision, q.Source.Path)
|
log.Infof("app details cache hit: %s/%s", revision, q.Source.Path)
|
||||||
return true, res, nil
|
return true, res, nil
|
||||||
@@ -1014,7 +1041,12 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resultUncast, err := s.runRepoOperation(ctx, q.Source.TargetRevision, q.Repo, q.Source, false, getCached, func(appPath, repoRoot, commitSHA, revision, verifyResult string) (interface{}, error) {
|
resultUncast, err := s.runRepoOperation(ctx, q.Source.TargetRevision, q.Repo, q.Source, false, getCached, func(repoRoot, commitSHA, revision string, ctxSrc operationContextSrc) (interface{}, error) {
|
||||||
|
ctx, err := ctxSrc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
appPath := ctx.appPath
|
||||||
|
|
||||||
res := &apiclient.RepoAppDetailsResponse{}
|
res := &apiclient.RepoAppDetailsResponse{}
|
||||||
appSourceType, err := GetAppSourceType(q.Source, appPath)
|
appSourceType, err := GetAppSourceType(q.Source, appPath)
|
||||||
@@ -1245,10 +1277,13 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string) (helm.Client, string, error) {
|
func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string) (helm.Client, string, error) {
|
||||||
helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI)
|
helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI || helm.IsHelmOciChart(chart))
|
||||||
if helm.IsVersion(revision) {
|
if helm.IsVersion(revision) {
|
||||||
return helmClient, revision, nil
|
return helmClient, revision, nil
|
||||||
}
|
}
|
||||||
|
if repo.EnableOCI {
|
||||||
|
return nil, "", errors.New("OCI helm registers don't support semver ranges. Exact revision must be specified.")
|
||||||
|
}
|
||||||
constraints, err := semver.NewConstraint(revision)
|
constraints, err := semver.NewConstraint(revision)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("invalid revision '%s': %v", revision, err)
|
return nil, "", fmt.Errorf("invalid revision '%s': %v", revision, err)
|
||||||
|
|||||||
@@ -2,7 +2,19 @@ package reposerver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
|
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
|
||||||
|
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/health"
|
||||||
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
"google.golang.org/grpc/reflection"
|
||||||
|
|
||||||
|
"github.com/argoproj/argo-cd/common"
|
||||||
versionpkg "github.com/argoproj/argo-cd/pkg/apiclient/version"
|
versionpkg "github.com/argoproj/argo-cd/pkg/apiclient/version"
|
||||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||||
reposervercache "github.com/argoproj/argo-cd/reposerver/cache"
|
reposervercache "github.com/argoproj/argo-cd/reposerver/cache"
|
||||||
@@ -11,14 +23,6 @@ import (
|
|||||||
"github.com/argoproj/argo-cd/server/version"
|
"github.com/argoproj/argo-cd/server/version"
|
||||||
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
||||||
tlsutil "github.com/argoproj/argo-cd/util/tls"
|
tlsutil "github.com/argoproj/argo-cd/util/tls"
|
||||||
|
|
||||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
|
||||||
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
|
|
||||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/credentials"
|
|
||||||
"google.golang.org/grpc/reflection"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ArgoCDRepoServer is the repo server implementation
|
// ArgoCDRepoServer is the repo server implementation
|
||||||
@@ -49,7 +53,9 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach
|
|||||||
tlsConfig := &tls.Config{Certificates: []tls.Certificate{*cert}}
|
tlsConfig := &tls.Config{Certificates: []tls.Certificate{*cert}}
|
||||||
tlsConfCustomizer(tlsConfig)
|
tlsConfCustomizer(tlsConfig)
|
||||||
|
|
||||||
grpc_prometheus.EnableHandlingTimeHistogram()
|
if os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true" {
|
||||||
|
grpc_prometheus.EnableHandlingTimeHistogram()
|
||||||
|
}
|
||||||
|
|
||||||
serverLog := log.NewEntry(log.StandardLogger())
|
serverLog := log.NewEntry(log.StandardLogger())
|
||||||
streamInterceptors := []grpc.StreamServerInterceptor{grpc_logrus.StreamServerInterceptor(serverLog), grpc_prometheus.StreamServerInterceptor, grpc_util.PanicLoggerStreamServerInterceptor(serverLog)}
|
streamInterceptors := []grpc.StreamServerInterceptor{grpc_logrus.StreamServerInterceptor(serverLog), grpc_prometheus.StreamServerInterceptor, grpc_util.PanicLoggerStreamServerInterceptor(serverLog)}
|
||||||
@@ -77,6 +83,9 @@ func (a *ArgoCDRepoServer) CreateGRPC() *grpc.Server {
|
|||||||
manifestService := repository.NewService(a.metricsServer, a.cache, a.initConstants)
|
manifestService := repository.NewService(a.metricsServer, a.cache, a.initConstants)
|
||||||
apiclient.RegisterRepoServerServiceServer(server, manifestService)
|
apiclient.RegisterRepoServerServiceServer(server, manifestService)
|
||||||
|
|
||||||
|
healthService := health.NewServer()
|
||||||
|
grpc_health_v1.RegisterHealthServer(server, healthService)
|
||||||
|
|
||||||
// Register reflection service on gRPC server.
|
// Register reflection service on gRPC server.
|
||||||
reflection.Register(server)
|
reflection.Register(server)
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ actions["retry"] = {["disabled"] = fullyPromoted or not(obj.status.abort)}
|
|||||||
actions["promote-full"] = {["disabled"] = true}
|
actions["promote-full"] = {["disabled"] = true}
|
||||||
if obj.status ~= nil and not(fullyPromoted) then
|
if obj.status ~= nil and not(fullyPromoted) then
|
||||||
generation = tonumber(obj.status.observedGeneration)
|
generation = tonumber(obj.status.observedGeneration)
|
||||||
if generation == nil then
|
if generation == nil or generation > obj.metadata.generation then
|
||||||
-- rollouts v0.9 - full promotion only supported for canary
|
-- rollouts v0.9 - full promotion only supported for canary
|
||||||
actions["promote-full"] = {["disabled"] = obj.spec.strategy.blueGreen ~= nil}
|
actions["promote-full"] = {["disabled"] = obj.spec.strategy.blueGreen ~= nil}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
if obj.status ~= nil then
|
if obj.status ~= nil then
|
||||||
generation = tonumber(obj.status.observedGeneration)
|
generation = tonumber(obj.status.observedGeneration)
|
||||||
if generation == nil then
|
if generation == nil or generation > obj.metadata.generation then
|
||||||
-- rollouts v0.9 and below
|
-- rollouts v0.9 and below
|
||||||
obj.status.abort = nil
|
obj.status.abort = nil
|
||||||
if obj.spec.strategy.canary.steps ~= nil then
|
if obj.spec.strategy.canary.steps ~= nil then
|
||||||
|
|||||||
@@ -51,15 +51,23 @@ function checkPaused(obj)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
hs = {}
|
-- isGenerationObserved determines if the rollout spec has been observed by the controller. This
|
||||||
if obj.status == nil or obj.status.observedGeneration == nil then
|
-- only applies to v0.10 rollout which uses a numeric status.observedGeneration. For v0.9 rollouts
|
||||||
hs.status = "Progressing"
|
-- and below this function always returns true.
|
||||||
hs.message = "Waiting for rollout spec update to be observed"
|
function isGenerationObserved(obj)
|
||||||
return hs
|
if obj.status == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
observedGeneration = tonumber(obj.status.observedGeneration)
|
||||||
|
if observedGeneration == nil or observedGeneration > obj.metadata.generation then
|
||||||
|
-- if we get here, the rollout is a v0.9 rollout
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return observedGeneration == obj.metadata.generation
|
||||||
end
|
end
|
||||||
|
|
||||||
generation = tonumber(obj.status.observedGeneration)
|
hs = {}
|
||||||
if generation ~= nil and generation ~= obj.metadata.generation then
|
if not isGenerationObserved(obj) then
|
||||||
hs.status = "Progressing"
|
hs.status = "Progressing"
|
||||||
hs.message = "Waiting for rollout spec update to be observed"
|
hs.message = "Waiting for rollout spec update to be observed"
|
||||||
return hs
|
return hs
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ tests:
|
|||||||
status: Healthy
|
status: Healthy
|
||||||
message: ""
|
message: ""
|
||||||
inputPath: testdata/healthy_legacy_v0.9_observedGeneration.yaml
|
inputPath: testdata/healthy_legacy_v0.9_observedGeneration.yaml
|
||||||
|
- healthStatus:
|
||||||
|
status: Healthy
|
||||||
|
message: ""
|
||||||
|
inputPath: testdata/healthy_legacy_v0.9_observedGeneration_numeric.yaml
|
||||||
- healthStatus:
|
- healthStatus:
|
||||||
status: Degraded
|
status: Degraded
|
||||||
message: "The Rollout \"basic\" is invalid: spec.strategy.strategy: Required value: Rollout has missing field '.spec.strategy.canary or .spec.strategy.blueGreen'"
|
message: "The Rollout \"basic\" is invalid: spec.strategy.strategy: Required value: Rollout has missing field '.spec.strategy.canary or .spec.strategy.blueGreen'"
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Rollout
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: "2020-11-13T00:44:55Z"
|
||||||
|
generation: 1
|
||||||
|
name: basic
|
||||||
|
namespace: argocd-e2e
|
||||||
|
resourceVersion: "182108"
|
||||||
|
selfLink: /apis/argoproj.io/v1alpha1/namespaces/argocd-e2e/rollouts/basic
|
||||||
|
uid: 34e4bbfc-222c-4968-bd60-2b30ae81110d
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: basic
|
||||||
|
strategy:
|
||||||
|
canary:
|
||||||
|
steps:
|
||||||
|
- setWeight: 50
|
||||||
|
- pause: {}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app: basic
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx:1.19-alpine
|
||||||
|
name: basic
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 1m
|
||||||
|
memory: 16Mi
|
||||||
|
status:
|
||||||
|
HPAReplicas: 1
|
||||||
|
availableReplicas: 1
|
||||||
|
blueGreen: {}
|
||||||
|
canary: {}
|
||||||
|
conditions:
|
||||||
|
- lastTransitionTime: "2020-11-13T00:48:20Z"
|
||||||
|
lastUpdateTime: "2020-11-13T00:48:22Z"
|
||||||
|
message: ReplicaSet "basic-754cb84d5" has successfully progressed.
|
||||||
|
reason: NewReplicaSetAvailable
|
||||||
|
status: "True"
|
||||||
|
type: Progressing
|
||||||
|
- lastTransitionTime: "2020-11-13T00:48:22Z"
|
||||||
|
lastUpdateTime: "2020-11-13T00:48:22Z"
|
||||||
|
message: Rollout has minimum availability
|
||||||
|
reason: AvailableReason
|
||||||
|
status: "True"
|
||||||
|
type: Available
|
||||||
|
currentPodHash: 754cb84d5
|
||||||
|
currentStepHash: 757f5f97b
|
||||||
|
currentStepIndex: 2
|
||||||
|
observedGeneration: "8575574967" ## <---- uses legacy observedGeneration hash which are numbers
|
||||||
|
readyReplicas: 1
|
||||||
|
replicas: 1
|
||||||
|
selector: app=basic
|
||||||
|
stableRS: 754cb84d5
|
||||||
|
updatedReplicas: 1
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@@ -89,7 +89,7 @@ func ssoAdminContext(ctx context.Context, iat time.Time) context.Context {
|
|||||||
return context.WithValue(ctx, "claims", &jwt.StandardClaims{
|
return context.WithValue(ctx, "claims", &jwt.StandardClaims{
|
||||||
Subject: "admin",
|
Subject: "admin",
|
||||||
Issuer: "https://myargocdhost.com/api/dex",
|
Issuer: "https://myargocdhost.com/api/dex",
|
||||||
IssuedAt: iat.Unix(),
|
IssuedAt: jwt.At(iat),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -576,11 +576,12 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque
|
|||||||
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Patch type '%s' is not supported", q.PatchType))
|
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Patch type '%s' is not supported", q.PatchType))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(patchApp, &app)
|
newApp := &v1alpha1.Application{}
|
||||||
|
err = json.Unmarshal(patchApp, newApp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return s.validateAndUpdateApp(ctx, app, false, true)
|
return s.validateAndUpdateApp(ctx, newApp, false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes an application and all associated resources
|
// Delete removes an application and all associated resources
|
||||||
@@ -747,12 +748,12 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := argo.ValidateDestination(ctx, &app.Spec.Destination, s.db); err != nil {
|
||||||
|
return status.Errorf(codes.InvalidArgument, "application destination spec is invalid: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
var conditions []appv1.ApplicationCondition
|
var conditions []appv1.ApplicationCondition
|
||||||
if validate {
|
if validate {
|
||||||
if err := argo.ValidateDestination(ctx, &app.Spec.Destination, s.db); err != nil {
|
|
||||||
return status.Errorf(codes.InvalidArgument, "application destination spec is invalid: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
conditions, err = argo.ValidateRepo(ctx, app, s.repoClientset, s.db, kustomizeOptions, plugins, s.kubectl)
|
conditions, err = argo.ValidateRepo(ctx, app, s.repoClientset, s.db, kustomizeOptions, plugins, s.kubectl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1292,7 +1293,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
|
|||||||
if helm.IsVersion(ambiguousRevision) {
|
if helm.IsVersion(ambiguousRevision) {
|
||||||
return ambiguousRevision, ambiguousRevision, nil
|
return ambiguousRevision, ambiguousRevision, nil
|
||||||
}
|
}
|
||||||
client := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI)
|
client := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI || app.Spec.Source.IsHelmOci())
|
||||||
index, err := client.GetIndex()
|
index, err := client.GetIndex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||||
"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
|
"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
|
||||||
"github.com/argoproj/pkg/sync"
|
"github.com/argoproj/pkg/sync"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@@ -215,6 +215,26 @@ spec:
|
|||||||
name: fake-cluster
|
name: fake-cluster
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const fakeAppWithAnnotations = `
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: test-app
|
||||||
|
namespace: default
|
||||||
|
annotations:
|
||||||
|
test.annotation: test
|
||||||
|
spec:
|
||||||
|
source:
|
||||||
|
path: some/path
|
||||||
|
repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
ksonnet:
|
||||||
|
environment: default
|
||||||
|
destination:
|
||||||
|
namespace: ` + test.FakeDestNamespace + `
|
||||||
|
server: https://cluster-api.com
|
||||||
|
`
|
||||||
|
|
||||||
func newTestAppWithDestName(opts ...func(app *appsv1.Application)) *appsv1.Application {
|
func newTestAppWithDestName(opts ...func(app *appsv1.Application)) *appsv1.Application {
|
||||||
return createTestApp(fakeAppWithDestName, opts...)
|
return createTestApp(fakeAppWithDestName, opts...)
|
||||||
}
|
}
|
||||||
@@ -223,6 +243,10 @@ func newTestApp(opts ...func(app *appsv1.Application)) *appsv1.Application {
|
|||||||
return createTestApp(fakeApp, opts...)
|
return createTestApp(fakeApp, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newTestAppWithAnnotations(opts ...func(app *appsv1.Application)) *appsv1.Application {
|
||||||
|
return createTestApp(fakeAppWithAnnotations, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
func createTestApp(testApp string, opts ...func(app *appsv1.Application)) *appsv1.Application {
|
func createTestApp(testApp string, opts ...func(app *appsv1.Application)) *appsv1.Application {
|
||||||
var app appsv1.Application
|
var app appsv1.Application
|
||||||
err := yaml.Unmarshal([]byte(testApp), &app)
|
err := yaml.Unmarshal([]byte(testApp), &app)
|
||||||
@@ -499,7 +523,7 @@ p, admin, applications, update, my-proj/test-app, allow
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAppJsonPatch(t *testing.T) {
|
func TestAppJsonPatch(t *testing.T) {
|
||||||
testApp := newTestApp()
|
testApp := newTestAppWithAnnotations()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
ctx = context.WithValue(ctx, "claims", &jwt.StandardClaims{Subject: "admin"})
|
ctx = context.WithValue(ctx, "claims", &jwt.StandardClaims{Subject: "admin"})
|
||||||
@@ -517,6 +541,10 @@ func TestAppJsonPatch(t *testing.T) {
|
|||||||
app, err = appServer.Patch(ctx, &application.ApplicationPatchRequest{Name: &testApp.Name, Patch: `[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`})
|
app, err = appServer.Patch(ctx, &application.ApplicationPatchRequest{Name: &testApp.Name, Patch: `[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "foo", app.Spec.Source.Path)
|
assert.Equal(t, "foo", app.Spec.Source.Path)
|
||||||
|
|
||||||
|
app, err = appServer.Patch(ctx, &application.ApplicationPatchRequest{Name: &testApp.Name, Patch: `[{"op": "remove", "path": "/metadata/annotations/test.annotation"}]`})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotContains(t, app.Annotations, "test.annotation")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppMergePatch(t *testing.T) {
|
func TestAppMergePatch(t *testing.T) {
|
||||||
|
|||||||
97
server/logout/logout.go
Normal file
97
server/logout/logout.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package logout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
|
|
||||||
|
"github.com/argoproj/argo-cd/common"
|
||||||
|
"github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
||||||
|
"github.com/argoproj/argo-cd/util/session"
|
||||||
|
"github.com/argoproj/argo-cd/util/settings"
|
||||||
|
|
||||||
|
jwtutil "github.com/argoproj/argo-cd/util/jwt"
|
||||||
|
)
|
||||||
|
|
||||||
|
//NewHandler creates handler serving to do api/logout endpoint
|
||||||
|
func NewHandler(appClientset versioned.Interface, settingsMrg *settings.SettingsManager, sessionMgr *session.SessionManager, rootPath, namespace string) *Handler {
|
||||||
|
return &Handler{
|
||||||
|
appClientset: appClientset,
|
||||||
|
namespace: namespace,
|
||||||
|
settingsMgr: settingsMrg,
|
||||||
|
rootPath: rootPath,
|
||||||
|
verifyToken: sessionMgr.VerifyToken,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
namespace string
|
||||||
|
appClientset versioned.Interface
|
||||||
|
settingsMgr *settings.SettingsManager
|
||||||
|
rootPath string
|
||||||
|
verifyToken func(tokenString string) (jwt.Claims, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
tokenPattern = regexp.MustCompile(`{{token}}`)
|
||||||
|
logoutRedirectURLPattern = regexp.MustCompile(`{{logoutRedirectURL}}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func constructLogoutURL(logoutURL, token, logoutRedirectURL string) string {
|
||||||
|
constructedLogoutURL := tokenPattern.ReplaceAllString(logoutURL, token)
|
||||||
|
return logoutRedirectURLPattern.ReplaceAllString(constructedLogoutURL, logoutRedirectURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP is the logout handler for ArgoCD and constructs OIDC logout URL and redirects to it for OIDC issued sessions,
|
||||||
|
// and redirects user to '/login' for argocd issued sessions
|
||||||
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var tokenString string
|
||||||
|
var oidcConfig *settings.OIDCConfig
|
||||||
|
|
||||||
|
argoCDSettings, err := h.settingsMgr.GetSettings()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
http.Error(w, "Failed to retrieve argoCD settings: "+fmt.Sprintf("%s", err), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logoutRedirectURL := strings.TrimRight(strings.TrimLeft(argoCDSettings.URL, "/"), "/") + strings.TrimRight(strings.TrimLeft(h.rootPath, "/"), "/")
|
||||||
|
|
||||||
|
argocdCookie, err := r.Cookie(common.AuthCookieName)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
http.Error(w, "Failed to retrieve ArgoCD auth token: "+fmt.Sprintf("%s", err), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenString = argocdCookie.Value
|
||||||
|
|
||||||
|
argocdCookie.Value = ""
|
||||||
|
argocdCookie.Path = fmt.Sprintf("/%s", strings.TrimRight(strings.TrimLeft(h.rootPath, "/"), "/"))
|
||||||
|
w.Header().Set("Set-Cookie", argocdCookie.String())
|
||||||
|
|
||||||
|
claims, err := h.verifyToken(tokenString)
|
||||||
|
if err != nil {
|
||||||
|
http.Redirect(w, r, logoutRedirectURL, http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mapClaims, err := jwtutil.MapClaims(claims)
|
||||||
|
if err != nil {
|
||||||
|
http.Redirect(w, r, logoutRedirectURL, http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
issuer := jwtutil.GetField(mapClaims, "iss")
|
||||||
|
|
||||||
|
if argoCDSettings.OIDCConfig() == nil || argoCDSettings.OIDCConfig().LogoutURL == "" || issuer == session.SessionManagerClaimsIssuer {
|
||||||
|
http.Redirect(w, r, logoutRedirectURL, http.StatusSeeOther)
|
||||||
|
} else {
|
||||||
|
oidcConfig = argoCDSettings.OIDCConfig()
|
||||||
|
logoutURL := constructLogoutURL(oidcConfig.LogoutURL, tokenString, logoutRedirectURL)
|
||||||
|
http.Redirect(w, r, logoutURL, http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
}
|
||||||
291
server/logout/logout_test.go
Normal file
291
server/logout/logout_test.go
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
package logout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
|
||||||
|
"github.com/argoproj/argo-cd/common"
|
||||||
|
"github.com/argoproj/argo-cd/util/session"
|
||||||
|
"github.com/argoproj/argo-cd/util/settings"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
||||||
|
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned/fake"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
validJWTPattern = regexp.MustCompile(`[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+`)
|
||||||
|
baseURL = "http://localhost:4000"
|
||||||
|
baseLogoutURL = "http://localhost:4000/logout"
|
||||||
|
baseLogoutURLwithToken = "http://localhost:4000/logout?id_token_hint={{token}}"
|
||||||
|
baseLogoutURLwithRedirectURL = "http://localhost:4000/logout?post_logout_redirect_uri={{logoutRedirectURL}}"
|
||||||
|
baseLogoutURLwithTokenAndRedirectURL = "http://localhost:4000/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}"
|
||||||
|
invalidToken = "sample-token"
|
||||||
|
oidcToken = "eyJraWQiOiJYQi1MM3ZFdHhYWXJLcmRSQnVEV0NwdnZsSnk3SEJVb2d5N253M1U1Z1ZZIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHVqNnM1NDVyNU5peVNLcjVkNSIsIm5hbWUiOiJqZCByIiwiZW1haWwiOiJqYWlkZWVwMTdydWx6QGdtYWlsLmNvbSIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9kZXYtNTY5NTA5OC5va3RhLmNvbSIsImF1ZCI6IjBvYWowM2FmSEtqN3laWXJwNWQ1IiwiaWF0IjoxNjA1NTcyMzU5LCJleHAiOjE2MDU1NzU5NTksImp0aSI6IklELl9ORDJxVG5iREFtc3hIZUt2U2ZHeVBqTXRicXFEQXdkdlRQTDZCTnpfR3ciLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwb2lnaGZmdkpRTDYzWjhoNWQ1IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamFpZGVlcDE3cnVsekBnbWFpbC5jb20iLCJhdXRoX3RpbWUiOjE2MDU1NzIzNTcsImF0X2hhc2giOiJqZVEwRml2ak9nNGI2TUpXRDIxOWxnIn0.GHkqwXgW-lrAhJdypW7SVjW0YdNLFQiRL8iwgT6DHJxP9Nb0OtkH2NKcBYAA5N6bTPLRQUHgYwWcgm5zSXmvqa7ciIgPF3tiQI8UmJA9VFRRDR-x9ExX15nskCbXfiQ67MriLslUrQUyzSCfUrSjXKwnDxbKGQncrtmRsh5asfCzJFb9excn311W9HKbT3KA0Ot7eOMnVS6V7SGfXxnKs6szcXIEMa_FhB4zDAVLr-dnxvSG_uuWcHrAkLTUVhHbdQQXF7hXIEfyr5lkMJN-drjdz-bn40GaYulEmUvO1bjcL9toCVQ3Ismypyr0b8phj4w3uRsLDZQxTxK7jAXlyQ"
|
||||||
|
nonOidcToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MDU1NzQyMTIsImlzcyI6ImFyZ29jZCIsIm5iZiI6MTYwNTU3NDIxMiwic3ViIjoiYWRtaW4ifQ.zDJ4piwWnwsHON-oPusHMXWINlnrRDTQykYogT7afeE"
|
||||||
|
expectedNonOIDCLogoutURL = "http://localhost:4000"
|
||||||
|
expectedOIDCLogoutURL = "https://dev-5695098.okta.com/oauth2/v1/logout?id_token_hint=" + oidcToken + "&post_logout_redirect_uri=" + baseURL
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConstructLogoutURL(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
logoutURL string
|
||||||
|
token string
|
||||||
|
logoutRedirectURL string
|
||||||
|
expectedLogoutURL string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Case: No additional parameters passed to logout URL",
|
||||||
|
logoutURL: baseLogoutURL,
|
||||||
|
token: oidcToken,
|
||||||
|
logoutRedirectURL: baseURL,
|
||||||
|
expectedLogoutURL: baseLogoutURL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: ID token passed to logout URL",
|
||||||
|
logoutURL: baseLogoutURLwithToken,
|
||||||
|
token: oidcToken,
|
||||||
|
logoutRedirectURL: baseURL,
|
||||||
|
expectedLogoutURL: "http://localhost:4000/logout?id_token_hint=" + oidcToken,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: Redirect required",
|
||||||
|
logoutURL: baseLogoutURLwithRedirectURL,
|
||||||
|
token: oidcToken,
|
||||||
|
logoutRedirectURL: baseURL,
|
||||||
|
expectedLogoutURL: "http://localhost:4000/logout?post_logout_redirect_uri=" + baseURL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: ID token and redirect URL passed to logout URL",
|
||||||
|
logoutURL: baseLogoutURLwithTokenAndRedirectURL,
|
||||||
|
token: oidcToken,
|
||||||
|
logoutRedirectURL: baseURL,
|
||||||
|
expectedLogoutURL: "http://localhost:4000/logout?id_token_hint=" + oidcToken + "&post_logout_redirect_uri=" + baseURL,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
constructedLogoutURL := constructLogoutURL(tt.logoutURL, tt.token, tt.logoutRedirectURL)
|
||||||
|
assert.Equal(t, constructedLogoutURL, tt.expectedLogoutURL)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestHandlerConstructLogoutURL(t *testing.T) {
|
||||||
|
kubeClientWithOIDCConfig := fake.NewSimpleClientset(
|
||||||
|
&corev1.ConfigMap{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDConfigMapName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"oidc.config": "name: Okta \n" +
|
||||||
|
"issuer: https://dev-5695098.okta.com \n" +
|
||||||
|
"requestedScopes: [\"openid\", \"profile\", \"email\", \"groups\"] \n" +
|
||||||
|
"requestedIDTokenClaims: {\"groups\": {\"essential\": true}} \n" +
|
||||||
|
"logoutURL: https://dev-5695098.okta.com/oauth2/v1/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}}",
|
||||||
|
"url": "http://localhost:4000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDSecretName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"admin.password": nil,
|
||||||
|
"server.secretkey": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
kubeClientWithOIDCConfigButNoLogoutURL := fake.NewSimpleClientset(
|
||||||
|
&corev1.ConfigMap{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDConfigMapName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"oidc.config": "name: Okta \n" +
|
||||||
|
"issuer: https://dev-5695098.okta.com \n" +
|
||||||
|
"requestedScopes: [\"openid\", \"profile\", \"email\", \"groups\"] \n" +
|
||||||
|
"requestedIDTokenClaims: {\"groups\": {\"essential\": true}} \n",
|
||||||
|
"url": "http://localhost:4000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDSecretName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"admin.password": nil,
|
||||||
|
"server.secretkey": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
kubeClientWithoutOIDCConfig := fake.NewSimpleClientset(
|
||||||
|
&corev1.ConfigMap{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDConfigMapName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"url": "http://localhost:4000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: common.ArgoCDSecretName,
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app.kubernetes.io/part-of": "argocd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"admin.password": nil,
|
||||||
|
"server.secretkey": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
settingsManagerWithOIDCConfig := settings.NewSettingsManager(context.Background(), kubeClientWithOIDCConfig, "default")
|
||||||
|
settingsManagerWithoutOIDCConfig := settings.NewSettingsManager(context.Background(), kubeClientWithoutOIDCConfig, "default")
|
||||||
|
settingsManagerWithOIDCConfigButNoLogoutURL := settings.NewSettingsManager(context.Background(), kubeClientWithOIDCConfigButNoLogoutURL, "default")
|
||||||
|
|
||||||
|
sessionManager := session.NewSessionManager(settingsManagerWithOIDCConfig, "", session.NewInMemoryUserStateStorage())
|
||||||
|
|
||||||
|
oidcHandler := NewHandler(appclientset.NewSimpleClientset(), settingsManagerWithOIDCConfig, sessionManager, "", "default")
|
||||||
|
oidcHandler.verifyToken = func(tokenString string) (jwt.Claims, error) {
|
||||||
|
if !validJWTPattern.MatchString(tokenString) {
|
||||||
|
return nil, errors.New("invalid jwt")
|
||||||
|
}
|
||||||
|
return &jwt.StandardClaims{Issuer: "okta"}, nil
|
||||||
|
}
|
||||||
|
nonoidcHandler := NewHandler(appclientset.NewSimpleClientset(), settingsManagerWithoutOIDCConfig, sessionManager, "", "default")
|
||||||
|
nonoidcHandler.verifyToken = func(tokenString string) (jwt.Claims, error) {
|
||||||
|
if !validJWTPattern.MatchString(tokenString) {
|
||||||
|
return nil, errors.New("invalid jwt")
|
||||||
|
}
|
||||||
|
return &jwt.StandardClaims{Issuer: session.SessionManagerClaimsIssuer}, nil
|
||||||
|
}
|
||||||
|
oidcHandlerWithoutLogoutURL := NewHandler(appclientset.NewSimpleClientset(), settingsManagerWithOIDCConfigButNoLogoutURL, sessionManager, "", "default")
|
||||||
|
oidcHandlerWithoutLogoutURL.verifyToken = func(tokenString string) (jwt.Claims, error) {
|
||||||
|
if !validJWTPattern.MatchString(tokenString) {
|
||||||
|
return nil, errors.New("invalid jwt")
|
||||||
|
}
|
||||||
|
return &jwt.StandardClaims{Issuer: "okta"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
oidcTokenHeader := make(map[string][]string)
|
||||||
|
oidcTokenHeader["Cookie"] = []string{"argocd.token=" + oidcToken}
|
||||||
|
nonOidcTokenHeader := make(map[string][]string)
|
||||||
|
nonOidcTokenHeader["Cookie"] = []string{"argocd.token=" + nonOidcToken}
|
||||||
|
invalidHeader := make(map[string][]string)
|
||||||
|
invalidHeader["Cookie"] = []string{"argocd.token=" + invalidToken}
|
||||||
|
|
||||||
|
oidcRequest, err := http.NewRequest("GET", "http://localhost:4000/api/logout", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
oidcRequest.Header = oidcTokenHeader
|
||||||
|
nonoidcRequest, err := http.NewRequest("GET", "http://localhost:4000/api/logout", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
nonoidcRequest.Header = nonOidcTokenHeader
|
||||||
|
assert.NoError(t, err)
|
||||||
|
requestWithInvalidToken, err := http.NewRequest("GET", "http://localhost:4000/api/logout", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
requestWithInvalidToken.Header = invalidHeader
|
||||||
|
invalidRequest, err := http.NewRequest("GET", "http://localhost:4000/api/logout", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
kubeClient *fake.Clientset
|
||||||
|
handler http.Handler
|
||||||
|
request *http.Request
|
||||||
|
responseRecorder *httptest.ResponseRecorder
|
||||||
|
expectedLogoutURL string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Case: OIDC logout request with valid token",
|
||||||
|
handler: oidcHandler,
|
||||||
|
request: oidcRequest,
|
||||||
|
responseRecorder: httptest.NewRecorder(),
|
||||||
|
expectedLogoutURL: expectedOIDCLogoutURL,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: non-OIDC logout request with valid token",
|
||||||
|
handler: nonoidcHandler,
|
||||||
|
request: nonoidcRequest,
|
||||||
|
responseRecorder: httptest.NewRecorder(),
|
||||||
|
expectedLogoutURL: expectedNonOIDCLogoutURL,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: Logout request with invalid token",
|
||||||
|
handler: nonoidcHandler,
|
||||||
|
request: requestWithInvalidToken,
|
||||||
|
responseRecorder: httptest.NewRecorder(),
|
||||||
|
expectedLogoutURL: expectedNonOIDCLogoutURL,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case: Logout request with missing token",
|
||||||
|
handler: oidcHandler,
|
||||||
|
request: invalidRequest,
|
||||||
|
responseRecorder: httptest.NewRecorder(),
|
||||||
|
expectedLogoutURL: expectedNonOIDCLogoutURL,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Case:OIDC Logout request with missing logout URL configuration in config map",
|
||||||
|
handler: oidcHandlerWithoutLogoutURL,
|
||||||
|
request: oidcRequest,
|
||||||
|
responseRecorder: httptest.NewRecorder(),
|
||||||
|
expectedLogoutURL: expectedNonOIDCLogoutURL,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt.handler.ServeHTTP(tt.responseRecorder, tt.request)
|
||||||
|
if status := tt.responseRecorder.Code; status != http.StatusSeeOther {
|
||||||
|
if !tt.wantErr {
|
||||||
|
t.Errorf(tt.responseRecorder.Body.String())
|
||||||
|
t.Errorf("handler returned wrong status code: " + fmt.Sprintf("%d", tt.responseRecorder.Code))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if tt.wantErr {
|
||||||
|
t.Errorf("expected error but did not get one")
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, tt.expectedLogoutURL, tt.responseRecorder.Result().Header["Location"][0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/argoproj/pkg/sync"
|
"github.com/argoproj/pkg/sync"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
@@ -108,16 +108,21 @@ func (s *Server) CreateToken(ctx context.Context, q *project.ProjectTokenCreateR
|
|||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
claims := jwt.StandardClaims{}
|
claims := jwt.StandardClaims{}
|
||||||
_, _, err = parser.ParseUnverified(jwtToken, &claims)
|
_, _, err = parser.ParseUnverified(jwtToken, &claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
issuedAt := claims.IssuedAt
|
var issuedAt, expiresAt int64
|
||||||
expiresAt := claims.ExpiresAt
|
if claims.IssuedAt != nil {
|
||||||
id = claims.Id
|
issuedAt = claims.IssuedAt.Unix()
|
||||||
|
}
|
||||||
|
if claims.ExpiresAt != nil {
|
||||||
|
expiresAt = claims.ExpiresAt.Unix()
|
||||||
|
}
|
||||||
|
id = claims.ID
|
||||||
|
|
||||||
items := append(prj.Status.JWTTokensByRole[q.Role].Items, v1alpha1.JWTToken{IssuedAt: issuedAt, ExpiresAt: expiresAt, ID: id})
|
items := append(prj.Status.JWTTokensByRole[q.Role].Items, v1alpha1.JWTToken{IssuedAt: issuedAt, ExpiresAt: expiresAt, ID: id})
|
||||||
if _, found := prj.Status.JWTTokensByRole[q.Role]; found {
|
if _, found := prj.Status.JWTTokensByRole[q.Role]; found {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
k8scache "k8s.io/client-go/tools/cache"
|
k8scache "k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
|
|
||||||
"github.com/argoproj/argo-cd/common"
|
"github.com/argoproj/argo-cd/common"
|
||||||
"github.com/argoproj/argo-cd/pkg/apiclient/project"
|
"github.com/argoproj/argo-cd/pkg/apiclient/project"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package rbacpolicy
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ func (s *Server) ListRepositoryCredentials(ctx context.Context, q *repocredspkg.
|
|||||||
|
|
||||||
// CreateRepositoryCredentials creates a new credential set in the configuration
|
// CreateRepositoryCredentials creates a new credential set in the configuration
|
||||||
func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsCreateRequest) (*appsv1.RepoCreds, error) {
|
func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsCreateRequest) (*appsv1.RepoCreds, error) {
|
||||||
|
if q.Creds == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
|
||||||
|
}
|
||||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionCreate, q.Creds.URL); err != nil {
|
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionCreate, q.Creds.URL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -96,6 +99,9 @@ func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspk
|
|||||||
|
|
||||||
// UpdateRepositoryCredentials updates a repository credential set
|
// UpdateRepositoryCredentials updates a repository credential set
|
||||||
func (s *Server) UpdateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsUpdateRequest) (*appsv1.RepoCreds, error) {
|
func (s *Server) UpdateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsUpdateRequest) (*appsv1.RepoCreds, error) {
|
||||||
|
if q.Creds == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
|
||||||
|
}
|
||||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, q.Creds.URL); err != nil {
|
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, q.Creds.URL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,9 @@ func (s *Server) ListApps(ctx context.Context, q *repositorypkg.RepoAppsQuery) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDetailsQuery) (*apiclient.RepoAppDetailsResponse, error) {
|
func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDetailsQuery) (*apiclient.RepoAppDetailsResponse, error) {
|
||||||
|
if q.Source == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
|
||||||
|
}
|
||||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, q.Source.RepoURL); err != nil {
|
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, q.Source.RepoURL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -262,6 +265,9 @@ func (s *Server) Create(ctx context.Context, q *repositorypkg.RepoCreateRequest)
|
|||||||
|
|
||||||
// CreateRepository creates a repository configuration
|
// CreateRepository creates a repository configuration
|
||||||
func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) {
|
func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) {
|
||||||
|
if q.Repo == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
|
||||||
|
}
|
||||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionCreate, q.Repo.Repo); err != nil {
|
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionCreate, q.Repo.Repo); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -320,6 +326,9 @@ func (s *Server) Update(ctx context.Context, q *repositorypkg.RepoUpdateRequest)
|
|||||||
|
|
||||||
// UpdateRepository updates a repository configuration
|
// UpdateRepository updates a repository configuration
|
||||||
func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) {
|
func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) {
|
||||||
|
if q.Repo == nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
|
||||||
|
}
|
||||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, q.Repo.Repo); err != nil {
|
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, q.Repo.Repo); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
"github.com/argoproj/pkg/jwt/zjwt"
|
"github.com/argoproj/pkg/jwt/zjwt"
|
||||||
"github.com/argoproj/pkg/sync"
|
"github.com/argoproj/pkg/sync"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
@@ -73,6 +73,7 @@ import (
|
|||||||
"github.com/argoproj/argo-cd/server/certificate"
|
"github.com/argoproj/argo-cd/server/certificate"
|
||||||
"github.com/argoproj/argo-cd/server/cluster"
|
"github.com/argoproj/argo-cd/server/cluster"
|
||||||
"github.com/argoproj/argo-cd/server/gpgkey"
|
"github.com/argoproj/argo-cd/server/gpgkey"
|
||||||
|
"github.com/argoproj/argo-cd/server/logout"
|
||||||
"github.com/argoproj/argo-cd/server/metrics"
|
"github.com/argoproj/argo-cd/server/metrics"
|
||||||
"github.com/argoproj/argo-cd/server/project"
|
"github.com/argoproj/argo-cd/server/project"
|
||||||
"github.com/argoproj/argo-cd/server/rbacpolicy"
|
"github.com/argoproj/argo-cd/server/rbacpolicy"
|
||||||
@@ -104,7 +105,6 @@ import (
|
|||||||
|
|
||||||
const maxConcurrentLoginRequestsCountEnv = "ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT"
|
const maxConcurrentLoginRequestsCountEnv = "ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT"
|
||||||
const replicasCountEnv = "ARGOCD_API_SERVER_REPLICAS"
|
const replicasCountEnv = "ARGOCD_API_SERVER_REPLICAS"
|
||||||
const enableGRPCTimeHistogramEnv = "ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM"
|
|
||||||
|
|
||||||
// ErrNoSession indicates no auth token was supplied as part of a request
|
// ErrNoSession indicates no auth token was supplied as part of a request
|
||||||
var ErrNoSession = status.Errorf(codes.Unauthenticated, "no session information")
|
var ErrNoSession = status.Errorf(codes.Unauthenticated, "no session information")
|
||||||
@@ -138,7 +138,7 @@ func init() {
|
|||||||
if replicasCount > 0 {
|
if replicasCount > 0 {
|
||||||
maxConcurrentLoginRequestsCount = maxConcurrentLoginRequestsCount / replicasCount
|
maxConcurrentLoginRequestsCount = maxConcurrentLoginRequestsCount / replicasCount
|
||||||
}
|
}
|
||||||
enableGRPCTimeHistogram = os.Getenv(enableGRPCTimeHistogramEnv) != "false"
|
enableGRPCTimeHistogram = os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArgoCDServer is the API server for Argo CD
|
// ArgoCDServer is the API server for Argo CD
|
||||||
@@ -241,6 +241,22 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// catches corrupted informer state; see https://github.com/argoproj/argo-cd/issues/4960 for more information
|
||||||
|
notObjectErrMsg = "object does not implement the Object interfaces"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *ArgoCDServer) healthCheck(r *http.Request) error {
|
||||||
|
if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
|
||||||
|
argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset)
|
||||||
|
_, err := argoDB.ListClusters(r.Context())
|
||||||
|
if err != nil && strings.Contains(err.Error(), notObjectErrMsg) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Run runs the API Server
|
// Run runs the API Server
|
||||||
// We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types.
|
// We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types.
|
||||||
// k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of
|
// k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of
|
||||||
@@ -596,9 +612,7 @@ func withRootPath(handler http.Handler, a *ArgoCDServer) http.Handler {
|
|||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/"+root+"/", http.StripPrefix("/"+root, handler))
|
mux.Handle("/"+root+"/", http.StripPrefix("/"+root, handler))
|
||||||
|
|
||||||
healthz.ServeHealthCheck(mux, func() error {
|
healthz.ServeHealthCheck(mux, a.healthCheck)
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
@@ -624,7 +638,8 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
|||||||
Handler: &handlerSwitcher{
|
Handler: &handlerSwitcher{
|
||||||
handler: mux,
|
handler: mux,
|
||||||
urlToHandler: map[string]http.Handler{
|
urlToHandler: map[string]http.Handler{
|
||||||
"/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace),
|
"/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace),
|
||||||
|
common.LogoutEndpoint: logout.NewHandler(a.AppClientset, a.settingsMgr, a.sessionMgr, a.ArgoCDServerOpts.RootPath, a.Namespace),
|
||||||
},
|
},
|
||||||
contentTypeToHandler: map[string]http.Handler{
|
contentTypeToHandler: map[string]http.Handler{
|
||||||
"application/grpc-web+proto": grpcWebHandler,
|
"application/grpc-web+proto": grpcWebHandler,
|
||||||
@@ -680,9 +695,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
|||||||
|
|
||||||
// Swagger UI
|
// Swagger UI
|
||||||
swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", a.RootPath)
|
swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", a.RootPath)
|
||||||
healthz.ServeHealthCheck(mux, func() error {
|
healthz.ServeHealthCheck(mux, a.healthCheck)
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// Dex reverse proxy and client app and OAuth2 login/callback
|
// Dex reverse proxy and client app and OAuth2 login/callback
|
||||||
a.registerDexHandlers(mux)
|
a.registerDexHandlers(mux)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/argocd-application-controller/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/argocd-application-controller/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||||
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/argocd-server/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --staticassets ui/dist/app"
|
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/argocd-server/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --staticassets ui/dist/app"
|
||||||
dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; go run github.com/argoproj/argo-cd/cmd/argocd-util gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml quay.io/dexidp/dex:v2.25.0 serve /dex.yaml"
|
dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; go run github.com/argoproj/argo-cd/cmd/argocd-util gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.27.0 serve /dex.yaml"
|
||||||
redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}"
|
redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||||
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} go run ./cmd/argocd-repo-server/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} go run ./cmd/argocd-repo-server/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||||
ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start"
|
ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start"
|
||||||
|
|||||||
@@ -1370,10 +1370,11 @@ func TestNamespaceAutoCreation(t *testing.T) {
|
|||||||
|
|
||||||
func TestFailedSyncWithRetry(t *testing.T) {
|
func TestFailedSyncWithRetry(t *testing.T) {
|
||||||
Given(t).
|
Given(t).
|
||||||
Path(guestbookPath).
|
Path("hook").
|
||||||
When().
|
When().
|
||||||
// app should be attempted to auto-synced once and marked with error after failed attempt detected
|
PatchFile("hook.yaml", `[{"op": "replace", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/hook": "PreSync"}}]`).
|
||||||
PatchFile("guestbook-ui-deployment.yaml", `[{"op": "replace", "path": "/spec/revisionHistoryLimit", "value": "badValue"}]`).
|
// make hook fail
|
||||||
|
PatchFile("hook.yaml", `[{"op": "replace", "path": "/spec/containers/0/command", "value": ["false"]}]`).
|
||||||
Create().
|
Create().
|
||||||
IgnoreErrors().
|
IgnoreErrors().
|
||||||
Sync("--retry-limit=1", "--retry-backoff-duration=1s").
|
Sync("--retry-limit=1", "--retry-backoff-duration=1s").
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {AutocompleteField, DropDownMenu, FormField, FormSelect, HelpIcon, PopupApi} from 'argo-ui';
|
import {AutocompleteField, DropDownMenu, FormField, FormSelect, HelpIcon, PopupApi} from 'argo-ui';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {FormApi, Text} from 'react-form';
|
import {FormApi, Text} from 'react-form';
|
||||||
import {Cluster, DataLoader, EditablePanel, EditablePanelItem, Expandable, MapInputField, Repo, Revision, RevisionHelpIcon} from '../../../shared/components';
|
import {Cluster, DataLoader, EditablePanel, EditablePanelItem, Expandable, MapInputField, NumberField, Repo, Revision, RevisionHelpIcon} from '../../../shared/components';
|
||||||
import {BadgePanel, Spinner} from '../../../shared/components';
|
import {BadgePanel, Spinner} from '../../../shared/components';
|
||||||
import {Consumer} from '../../../shared/context';
|
import {Consumer} from '../../../shared/context';
|
||||||
import * as models from '../../../shared/models';
|
import * as models from '../../../shared/models';
|
||||||
@@ -202,7 +202,7 @@ export const ApplicationSummary = (props: {app: models.Application; updateApp: (
|
|||||||
view: app.spec.revisionHistoryLimit,
|
view: app.spec.revisionHistoryLimit,
|
||||||
edit: (formApi: FormApi) => (
|
edit: (formApi: FormApi) => (
|
||||||
<div style={{position: 'relative'}}>
|
<div style={{position: 'relative'}}>
|
||||||
<FormField formApi={formApi} field='spec.revisionHistoryLimit' component={Text} />
|
<FormField formApi={formApi} field='spec.revisionHistoryLimit' componentProps={{style: {paddingRight: '1em'}, placeholder: '10'}} component={NumberField} />
|
||||||
<div style={{position: 'absolute', right: '0', top: '0'}}>
|
<div style={{position: 'absolute', right: '0', top: '0'}}>
|
||||||
<HelpIcon
|
<HelpIcon
|
||||||
title='This limits this number of items kept in the apps revision history.
|
title='This limits this number of items kept in the apps revision history.
|
||||||
|
|||||||
@@ -23,3 +23,4 @@ export * from './revision';
|
|||||||
export * from './timestamp';
|
export * from './timestamp';
|
||||||
export * from './spinner';
|
export * from './spinner';
|
||||||
export * from './badge-panel/badge-panel';
|
export * from './badge-panel/badge-panel';
|
||||||
|
export * from './number-field';
|
||||||
|
|||||||
11
ui/src/app/shared/components/number-field.tsx
Normal file
11
ui/src/app/shared/components/number-field.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactForm from 'react-form';
|
||||||
|
|
||||||
|
export const NumberField = ReactForm.FormField((props: {fieldApi: ReactForm.FieldApi; className: string}) => {
|
||||||
|
const {
|
||||||
|
fieldApi: {getValue, setValue},
|
||||||
|
...rest
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
return <input {...rest} className={props.className} type='number' value={getValue()} onChange={el => setValue(parseInt(el.target.value, 10))} />;
|
||||||
|
});
|
||||||
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|||||||
import {BehaviorSubject, Observable} from 'rxjs';
|
import {BehaviorSubject, Observable} from 'rxjs';
|
||||||
import {AppContext} from '../context';
|
import {AppContext} from '../context';
|
||||||
import {services} from '../services';
|
import {services} from '../services';
|
||||||
|
import requests from '../services/requests';
|
||||||
const mostRecentLoggedIn = new BehaviorSubject<boolean>(false);
|
const mostRecentLoggedIn = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
function isLoggedIn(): Observable<boolean> {
|
function isLoggedIn(): Observable<boolean> {
|
||||||
@@ -51,9 +51,10 @@ export class Page extends React.Component<{title: string; toolbar?: Toolbar | Ob
|
|||||||
|
|
||||||
private async goToLogin(logout = false) {
|
private async goToLogin(logout = false) {
|
||||||
if (logout) {
|
if (logout) {
|
||||||
await services.users.logout();
|
window.location.href = requests.toAbsURL('/auth/logout');
|
||||||
|
} else {
|
||||||
|
this.appContext.history.push('/login');
|
||||||
}
|
}
|
||||||
this.appContext.history.push('/login');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private get appContext(): AppContext {
|
private get appContext(): AppContext {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class ClustersService {
|
|||||||
public update(cluster: models.Cluster, ...paths: string[]): Promise<models.Cluster> {
|
public update(cluster: models.Cluster, ...paths: string[]): Promise<models.Cluster> {
|
||||||
return requests
|
return requests
|
||||||
.put(`/clusters/${encodeURIComponent(cluster.server)}`)
|
.put(`/clusters/${encodeURIComponent(cluster.server)}`)
|
||||||
.query({updatedPaths: paths})
|
.query({updatedFields: paths})
|
||||||
.send(cluster)
|
.send(cluster)
|
||||||
.then(res => res.body as models.Cluster);
|
.then(res => res.body as models.Cluster);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,12 +131,8 @@ func TestRepoWithKnownType(repo *argoappv1.Repository, isHelm bool, isHelmOci bo
|
|||||||
} else {
|
} else {
|
||||||
repo.Type = "git"
|
repo.Type = "git"
|
||||||
}
|
}
|
||||||
|
repo.EnableOCI = repo.EnableOCI || isHelmOci
|
||||||
|
|
||||||
if isHelmOci {
|
|
||||||
repo.EnableOCI = true
|
|
||||||
} else {
|
|
||||||
repo.EnableOCI = false
|
|
||||||
}
|
|
||||||
return TestRepo(repo)
|
return TestRepo(repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
util/cache/cache.go
vendored
6
util/cache/cache.go
vendored
@@ -79,13 +79,13 @@ type Cache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) SetItem(key string, item interface{}, expiration time.Duration, delete bool) error {
|
func (c *Cache) SetItem(key string, item interface{}, expiration time.Duration, delete bool) error {
|
||||||
if item == nil {
|
|
||||||
return fmt.Errorf("cannot set item to nil for key %s", key)
|
|
||||||
}
|
|
||||||
key = fmt.Sprintf("%s|%s", key, common.CacheVersion)
|
key = fmt.Sprintf("%s|%s", key, common.CacheVersion)
|
||||||
if delete {
|
if delete {
|
||||||
return c.client.Delete(key)
|
return c.client.Delete(key)
|
||||||
} else {
|
} else {
|
||||||
|
if item == nil {
|
||||||
|
return fmt.Errorf("cannot set item to nil for key %s", key)
|
||||||
|
}
|
||||||
return c.client.Set(&Item{Object: item, Key: key, Expiration: expiration})
|
return c.client.Set(&Item{Object: item, Key: key, Expiration: expiration})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
util/cache/redis.go
vendored
19
util/cache/redis.go
vendored
@@ -2,6 +2,7 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ioutil "github.com/argoproj/argo-cd/util/io"
|
ioutil "github.com/argoproj/argo-cd/util/io"
|
||||||
@@ -30,20 +31,28 @@ func (r *redisCache) Set(item *Item) error {
|
|||||||
expiration = r.expiration
|
expiration = r.expiration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val, err := json.Marshal(item.Object)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return r.cache.Set(&rediscache.Item{
|
return r.cache.Set(&rediscache.Item{
|
||||||
Key: item.Key,
|
Key: item.Key,
|
||||||
Value: item.Object,
|
Value: val,
|
||||||
TTL: expiration,
|
TTL: expiration,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *redisCache) Get(key string, obj interface{}) error {
|
func (r *redisCache) Get(key string, obj interface{}) error {
|
||||||
err := r.cache.Get(context.TODO(), key, obj)
|
var data []byte
|
||||||
|
err := r.cache.Get(context.TODO(), key, &data)
|
||||||
if err == rediscache.ErrCacheMiss {
|
if err == rediscache.ErrCacheMiss {
|
||||||
return ErrCacheMiss
|
err = ErrCacheMiss
|
||||||
}
|
}
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(data, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *redisCache) Delete(key string) error {
|
func (r *redisCache) Delete(key string) error {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
@@ -296,14 +296,14 @@ type ServiceAccountClaims struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Valid satisfies the jwt.Claims interface to enable JWT parsing
|
// Valid satisfies the jwt.Claims interface to enable JWT parsing
|
||||||
func (sac *ServiceAccountClaims) Valid() error {
|
func (sac *ServiceAccountClaims) Valid(helper *jwt.ValidationHelper) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseServiceAccountToken parses a Kubernetes service account token
|
// ParseServiceAccountToken parses a Kubernetes service account token
|
||||||
func ParseServiceAccountToken(token string) (*ServiceAccountClaims, error) {
|
func ParseServiceAccountToken(token string) (*ServiceAccountClaims, error) {
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
var claims ServiceAccountClaims
|
var claims ServiceAccountClaims
|
||||||
_, _, err := parser.ParseUnverified(token, &claims)
|
_, _, err := parser.ParseUnverified(token, &claims)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ func GenerateDexConfigYAML(settings *settings.ArgoCDSettings) ([]byte, error) {
|
|||||||
"public": true,
|
"public": true,
|
||||||
"redirectURIs": []string{
|
"redirectURIs": []string{
|
||||||
"http://localhost",
|
"http://localhost",
|
||||||
|
"http://localhost:8085/auth/callback",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
// ServeHealthCheck serves the health check endpoint.
|
// ServeHealthCheck serves the health check endpoint.
|
||||||
// ServeHealthCheck relies on the provided function to return an error if unhealthy and nil otherwise.
|
// ServeHealthCheck relies on the provided function to return an error if unhealthy and nil otherwise.
|
||||||
func ServeHealthCheck(mux *http.ServeMux, f func() error) {
|
func ServeHealthCheck(mux *http.ServeMux, f func(r *http.Request) error) {
|
||||||
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := f(); err != nil {
|
if err := f(r); err != nil {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
log.Errorln(w, err)
|
log.Errorln(w, err)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func TestHealthCheck(t *testing.T) {
|
|||||||
c <- listener.Addr().String()
|
c <- listener.Addr().String()
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
ServeHealthCheck(mux, func() error {
|
ServeHealthCheck(mux, func(r *http.Request) error {
|
||||||
if sentinel {
|
if sentinel {
|
||||||
return fmt.Errorf("This is a dummy error")
|
return fmt.Errorf("This is a dummy error")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func (c *nativeHelmChart) ensureHelmChartRepoPath() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *nativeHelmChart) CleanChartCache(chart string, version *semver.Version) error {
|
func (c *nativeHelmChart) CleanChartCache(chart string, version *semver.Version) error {
|
||||||
return os.RemoveAll(c.getChartPath(chart, version))
|
return os.RemoveAll(c.getCachedChartPath(chart, version))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *nativeHelmChart) ExtractChart(chart string, version *semver.Version) (string, io.Closer, error) {
|
func (c *nativeHelmChart) ExtractChart(chart string, version *semver.Version) (string, io.Closer, error) {
|
||||||
@@ -98,77 +98,99 @@ func (c *nativeHelmChart) ExtractChart(chart string, version *semver.Version) (s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
chartPath := c.getChartPath(chart, version)
|
|
||||||
|
|
||||||
c.repoLock.Lock(chartPath)
|
// always use Helm V3 since we don't have chart content to determine correct Helm version
|
||||||
defer c.repoLock.Unlock(chartPath)
|
helmCmd, err := NewCmdWithVersion(c.repoPath, HelmV3, c.enableOci)
|
||||||
|
|
||||||
exists, err := fileExist(chartPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
defer helmCmd.Close()
|
||||||
|
|
||||||
|
_, err = helmCmd.Init()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw away temp directory that stores extracted chart and should be deleted as soon as no longer needed by returned closer
|
||||||
|
tempDir, err := ioutil.TempDir("", "helm")
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedChartPath := c.getCachedChartPath(chart, version)
|
||||||
|
|
||||||
|
c.repoLock.Lock(cachedChartPath)
|
||||||
|
defer c.repoLock.Unlock(cachedChartPath)
|
||||||
|
|
||||||
|
// check if chart tar is already downloaded
|
||||||
|
exists, err := fileExist(cachedChartPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
// always use Helm V3 since we don't have chart content to determine correct Helm version
|
// create empty temp directory to extract chart from the registry
|
||||||
helmCmd, err := NewCmdWithVersion(c.repoPath, HelmV3, c.enableOci)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
defer helmCmd.Close()
|
|
||||||
|
|
||||||
_, err = helmCmd.Init()
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.enableOci {
|
|
||||||
_, err = helmCmd.Login(c.repoURL, c.creds)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_, _ = helmCmd.Logout(c.repoURL, c.creds)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// (1) because `helm fetch` downloads an arbitrary file name, we download to an empty temp directory
|
|
||||||
tempDest, err := ioutil.TempDir("", "helm")
|
tempDest, err := ioutil.TempDir("", "helm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
defer func() { _ = os.RemoveAll(tempDest) }()
|
defer func() { _ = os.RemoveAll(tempDest) }()
|
||||||
_, err = helmCmd.Fetch(c.repoURL, chart, version.String(), tempDest, c.creds)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.enableOci {
|
if c.enableOci {
|
||||||
_, err = helmCmd.Export(c.repoURL, chart, version.String(), tempDest)
|
if c.creds.Password != "" && c.creds.Username != "" {
|
||||||
|
_, err = helmCmd.Login(c.repoURL, c.creds)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_, _ = helmCmd.Logout(c.repoURL, c.creds)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'helm chart pull' ensures that chart is downloaded into local repository cache
|
||||||
|
_, err = helmCmd.ChartPull(c.repoURL, chart, version.String())
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'helm chart export' copies cached chart into temp directory
|
||||||
|
_, err = helmCmd.ChartExport(c.repoURL, chart, version.String(), tempDest)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// use downloaded chart content to produce tar file in expected cache location
|
||||||
|
cmd := exec.Command("tar", "-zcvf", cachedChartPath, normalizeChartName(chart))
|
||||||
|
cmd.Dir = tempDest
|
||||||
|
_, err = executil.Run(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err = helmCmd.Fetch(c.repoURL, chart, version.String(), tempDest, c.creds)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'helm fetch' file downloads chart into the tgz file and we move that to where we want it
|
||||||
|
infos, err := ioutil.ReadDir(tempDest)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
if len(infos) != 1 {
|
||||||
|
return "", nil, fmt.Errorf("expected 1 file, found %v", len(infos))
|
||||||
|
}
|
||||||
|
err = os.Rename(filepath.Join(tempDest, infos[0].Name()), cachedChartPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (2) then we assume that the only file downloaded into the directory is the tgz file
|
|
||||||
// and we move that to where we want it
|
|
||||||
infos, err := ioutil.ReadDir(tempDest)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
if len(infos) != 1 {
|
|
||||||
return "", nil, fmt.Errorf("expected 1 file, found %v", len(infos))
|
|
||||||
}
|
|
||||||
err = os.Rename(filepath.Join(tempDest, infos[0].Name()), chartPath)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// untar helm chart into throw away temp directory which should be deleted as soon as no longer needed
|
|
||||||
tempDir, err := ioutil.TempDir("", "helm")
|
cmd := exec.Command("tar", "-zxvf", cachedChartPath)
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
cmd := exec.Command("tar", "-zxvf", chartPath)
|
|
||||||
cmd.Dir = tempDir
|
cmd.Dir = tempDir
|
||||||
_, err = executil.Run(cmd)
|
_, err = executil.Run(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -214,16 +236,19 @@ func (c *nativeHelmChart) TestHelmOCI() (bool, error) {
|
|||||||
}
|
}
|
||||||
defer helmCmd.Close()
|
defer helmCmd.Close()
|
||||||
|
|
||||||
_, err = helmCmd.Login(c.repoURL, c.creds)
|
// Looks like there is no good way to test access to OCI repo if credentials are not provided
|
||||||
if err != nil {
|
// just assume it is accessible
|
||||||
return false, err
|
if c.creds.Username != "" && c.creds.Password != "" {
|
||||||
|
_, err = helmCmd.Login(c.repoURL, c.creds)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_, _ = helmCmd.Logout(c.repoURL, c.creds)
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.WithFields(log.Fields{"seconds": time.Since(start).Seconds()}).Info("took to test helm oci repository")
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
_, _ = helmCmd.Logout(c.repoURL, c.creds)
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{"seconds": time.Since(start).Seconds()}).Info("took to test helm oci repository")
|
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,6 +318,7 @@ func newTLSConfig(creds Creds) (*tls.Config, error) {
|
|||||||
|
|
||||||
// Normalize a chart name for file system use, that is, if chart name is foo/bar/baz, returns the last component as chart name.
|
// Normalize a chart name for file system use, that is, if chart name is foo/bar/baz, returns the last component as chart name.
|
||||||
func normalizeChartName(chart string) string {
|
func normalizeChartName(chart string) string {
|
||||||
|
strings.Join(strings.Split(chart, "/"), "_")
|
||||||
_, nc := path.Split(chart)
|
_, nc := path.Split(chart)
|
||||||
// We do not want to return the empty string or something else related to filesystem access
|
// We do not want to return the empty string or something else related to filesystem access
|
||||||
// Instead, return original string
|
// Instead, return original string
|
||||||
@@ -302,17 +328,11 @@ func normalizeChartName(chart string) string {
|
|||||||
return nc
|
return nc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *nativeHelmChart) getChartPath(chart string, version *semver.Version) string {
|
func (c *nativeHelmChart) getCachedChartPath(chart string, version *semver.Version) string {
|
||||||
if repoNamespace, chartName, isHelmOci := IsHelmOci(chart); isHelmOci {
|
return path.Join(c.repoPath, fmt.Sprintf("%s-%v.tgz", strings.ReplaceAll(chart, "/", "_"), version))
|
||||||
return path.Join(c.repoPath, fmt.Sprintf("%s-%s-%v.tgz", repoNamespace, normalizeChartName(chartName), version))
|
|
||||||
}
|
|
||||||
return path.Join(c.repoPath, fmt.Sprintf("%s-%v.tgz", normalizeChartName(chart), version))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsHelmOci(chart string) (string, string, bool) {
|
// Only OCI registries support storing charts under sub-directories.
|
||||||
chartArray := strings.Split(chart, "/")
|
func IsHelmOciChart(chart string) bool {
|
||||||
if len(chartArray) == 2 {
|
return strings.Contains(chart, "/")
|
||||||
return chartArray[0], chartArray[1], true
|
|
||||||
}
|
|
||||||
return "", "", false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,26 +211,18 @@ func writeToTmp(data []byte) (string, io.Closer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cmd) Fetch(repo, chartName, version, destination string, creds Creds) (string, error) {
|
func (c *Cmd) Fetch(repo, chartName, version, destination string, creds Creds) (string, error) {
|
||||||
args := []string{}
|
args := []string{c.pullCommand, "--destination", destination}
|
||||||
|
if version != "" {
|
||||||
if _, _, isHelmOci := IsHelmOci(chartName); isHelmOci {
|
args = append(args, "--version", version)
|
||||||
args = append(args, "chart", "pull")
|
|
||||||
repoUrl := fmt.Sprintf(repo + "/" + chartName + ":" + version)
|
|
||||||
args = append(args, repoUrl)
|
|
||||||
} else {
|
|
||||||
args = append(args, c.pullCommand, "--destination", destination)
|
|
||||||
if version != "" {
|
|
||||||
args = append(args, "--version", version)
|
|
||||||
}
|
|
||||||
if creds.Username != "" {
|
|
||||||
args = append(args, "--username", creds.Username)
|
|
||||||
}
|
|
||||||
if creds.Password != "" {
|
|
||||||
args = append(args, "--password", creds.Password)
|
|
||||||
}
|
|
||||||
|
|
||||||
args = append(args, "--repo", repo, chartName)
|
|
||||||
}
|
}
|
||||||
|
if creds.Username != "" {
|
||||||
|
args = append(args, "--username", creds.Username)
|
||||||
|
}
|
||||||
|
if creds.Password != "" {
|
||||||
|
args = append(args, "--password", creds.Password)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "--repo", repo, chartName)
|
||||||
|
|
||||||
if creds.CAPath != "" {
|
if creds.CAPath != "" {
|
||||||
args = append(args, "--ca-file", creds.CAPath)
|
args = append(args, "--ca-file", creds.CAPath)
|
||||||
@@ -255,29 +247,16 @@ func (c *Cmd) Fetch(repo, chartName, version, destination string, creds Creds) (
|
|||||||
return c.run(args...)
|
return c.run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cmd) Export(repo, chartName, version, destination string) (string, error) {
|
func (c *Cmd) ChartPull(repo string, chart string, version string) (string, error) {
|
||||||
output := ""
|
return c.run("chart", "pull", fmt.Sprintf("%s/%s:%s", repo, chart, version))
|
||||||
var err error
|
}
|
||||||
|
|
||||||
|
func (c *Cmd) ChartExport(repo string, chartName string, version string, destination string) (string, error) {
|
||||||
args := []string{"chart", "export"}
|
args := []string{"chart", "export"}
|
||||||
repoUrl := fmt.Sprintf(repo + "/" + chartName + ":" + version)
|
chartURL := fmt.Sprintf(repo + "/" + chartName + ":" + version)
|
||||||
args = append(args, repoUrl, "--destination", destination)
|
args = append(args, chartURL, "--destination", destination)
|
||||||
|
|
||||||
output, err = c.run(args...)
|
return c.run(args...)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// tar helm chart
|
|
||||||
repoNamespace, repoName, _ := IsHelmOci(chartName)
|
|
||||||
cmd := exec.Command("tar", "-zcvf", repoNamespace+"-"+repoName+"-"+version+".tgz", repoName)
|
|
||||||
cmd.Dir = destination
|
|
||||||
_, err = executil.Run(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer func() { _ = os.RemoveAll(destination + "/" + repoName) }()
|
|
||||||
|
|
||||||
return output, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cmd) dependencyBuild() (string, error) {
|
func (c *Cmd) dependencyBuild() (string, error) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
jwtgo "github.com/dgrijalva/jwt-go"
|
jwtgo "github.com/dgrijalva/jwt-go/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MapClaims converts a jwt.Claims to a MapClaims
|
// MapClaims converts a jwt.Claims to a MapClaims
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package jwt
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
|
|
||||||
configUtil "github.com/argoproj/argo-cd/util/config"
|
configUtil "github.com/argoproj/argo-cd/util/config"
|
||||||
)
|
)
|
||||||
@@ -64,7 +64,7 @@ type User struct {
|
|||||||
// Claims returns the standard claims from the JWT claims
|
// Claims returns the standard claims from the JWT claims
|
||||||
func (u *User) Claims() (*jwt.StandardClaims, error) {
|
func (u *User) Claims() (*jwt.StandardClaims, error) {
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
claims := jwt.StandardClaims{}
|
claims := jwt.StandardClaims{}
|
||||||
_, _, err := parser.ParseUnverified(u.AuthToken, &claims)
|
_, _, err := parser.ParseUnverified(u.AuthToken, &claims)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/argoproj/pkg/jwt/zjwt"
|
"github.com/argoproj/pkg/jwt/zjwt"
|
||||||
gooidc "github.com/coreos/go-oidc"
|
gooidc "github.com/coreos/go-oidc"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/casbin/casbin"
|
"github.com/casbin/casbin"
|
||||||
"github.com/casbin/casbin/model"
|
"github.com/casbin/casbin/model"
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
@@ -318,19 +318,19 @@ func TestEnforceErrorMessage(t *testing.T) {
|
|||||||
iat := time.Unix(int64(1593035962), 0).Format(time.RFC3339)
|
iat := time.Unix(int64(1593035962), 0).Format(time.RFC3339)
|
||||||
exp := fmt.Sprintf("rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin, iat: %s", iat)
|
exp := fmt.Sprintf("rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin, iat: %s", iat)
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{Subject: "proj:default:admin", IssuedAt: 1593035962})
|
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{Subject: "proj:default:admin", IssuedAt: jwt.NewTime(1593035962)})
|
||||||
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Equal(t, exp, err.Error())
|
assert.Equal(t, exp, err.Error())
|
||||||
|
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{ExpiresAt: 1})
|
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{ExpiresAt: jwt.NewTime(1)})
|
||||||
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project", err.Error())
|
assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project", err.Error())
|
||||||
|
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{Subject: "proj:default:admin", IssuedAt: 0})
|
ctx = context.WithValue(context.Background(), "claims", &jwt.StandardClaims{Subject: "proj:default:admin", IssuedAt: nil})
|
||||||
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
err = enf.EnforceErr(ctx.Value("claims"), "project")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin", err.Error())
|
assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: project, sub: proj:default:admin", err.Error())
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
oidc "github.com/coreos/go-oidc"
|
||||||
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@@ -172,15 +173,15 @@ func (mgr *SessionManager) Create(subject string, secondsBeforeExpiry int64, id
|
|||||||
// you would like it to contain.
|
// you would like it to contain.
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
claims := jwt.StandardClaims{
|
claims := jwt.StandardClaims{
|
||||||
IssuedAt: now.Unix(),
|
IssuedAt: jwt.At(now),
|
||||||
Issuer: SessionManagerClaimsIssuer,
|
Issuer: SessionManagerClaimsIssuer,
|
||||||
NotBefore: now.Unix(),
|
NotBefore: jwt.At(now),
|
||||||
Subject: subject,
|
Subject: subject,
|
||||||
Id: id,
|
ID: id,
|
||||||
}
|
}
|
||||||
if secondsBeforeExpiry > 0 {
|
if secondsBeforeExpiry > 0 {
|
||||||
expires := now.Add(time.Duration(secondsBeforeExpiry) * time.Second)
|
expires := now.Add(time.Duration(secondsBeforeExpiry) * time.Second)
|
||||||
claims.ExpiresAt = expires.Unix()
|
claims.ExpiresAt = jwt.At(expires)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mgr.signClaims(claims)
|
return mgr.signClaims(claims)
|
||||||
@@ -422,7 +423,7 @@ func (mgr *SessionManager) VerifyUsernamePassword(username string, password stri
|
|||||||
// We choose how to verify based on the issuer.
|
// We choose how to verify based on the issuer.
|
||||||
func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, error) {
|
func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, error) {
|
||||||
parser := &jwt.Parser{
|
parser := &jwt.Parser{
|
||||||
SkipClaimsValidation: true,
|
ValidationHelper: jwt.NewValidationHelper(jwt.WithoutClaimsValidation()),
|
||||||
}
|
}
|
||||||
var claims jwt.StandardClaims
|
var claims jwt.StandardClaims
|
||||||
_, _, err := parser.ParseUnverified(tokenString, &claims)
|
_, _, err := parser.ParseUnverified(tokenString, &claims)
|
||||||
@@ -439,7 +440,16 @@ func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return claims, err
|
return claims, err
|
||||||
}
|
}
|
||||||
idToken, err := prov.Verify(claims.Audience, tokenString)
|
|
||||||
|
// Token must be verified for at least one audience
|
||||||
|
// TODO(jannfis): Is this the right way? Shouldn't we know our audience and only validate for the correct one?
|
||||||
|
var idToken *oidc.IDToken
|
||||||
|
for _, aud := range claims.Audience {
|
||||||
|
idToken, err = prov.Verify(aud, tokenString)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return claims, err
|
return claims, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/v4"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ type OIDCConfig struct {
|
|||||||
CLIClientID string `json:"cliClientID,omitempty"`
|
CLIClientID string `json:"cliClientID,omitempty"`
|
||||||
RequestedScopes []string `json:"requestedScopes,omitempty"`
|
RequestedScopes []string `json:"requestedScopes,omitempty"`
|
||||||
RequestedIDTokenClaims map[string]*oidc.Claim `json:"requestedIDTokenClaims,omitempty"`
|
RequestedIDTokenClaims map[string]*oidc.Claim `json:"requestedIDTokenClaims,omitempty"`
|
||||||
|
LogoutURL string `json:"logoutURL,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEPRECATED. Helm repository credentials are now managed using RepoCredentials
|
// DEPRECATED. Helm repository credentials are now managed using RepoCredentials
|
||||||
|
|||||||
Reference in New Issue
Block a user