mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-27 13:08:46 +01:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
844f79eb9d | ||
|
|
ecfa0da491 | ||
|
|
fac8466e86 | ||
|
|
ac34ff23c4 | ||
|
|
a85d88d479 | ||
|
|
40075da70c | ||
|
|
779e383f64 | ||
|
|
3e523dbab7 | ||
|
|
4df892fecf | ||
|
|
670a1756d7 | ||
|
|
5721f559f0 | ||
|
|
e23178a8d1 | ||
|
|
918e5eadf4 | ||
|
|
55de2b9dab | ||
|
|
c48004f944 | ||
|
|
f7b6a38041 | ||
|
|
91eb9925ef | ||
|
|
6190964899 | ||
|
|
81630e6d50 | ||
|
|
e31fdb6105 | ||
|
|
2e194b1087 | ||
|
|
cec5799d97 | ||
|
|
7ab2ba361c | ||
|
|
1d5e15c600 | ||
|
|
f4f52212ba | ||
|
|
507c669259 | ||
|
|
993459aebc | ||
|
|
3293aa0bb7 | ||
|
|
aafb6ce0a3 | ||
|
|
d3d490632d | ||
|
|
a48bca03c7 | ||
|
|
6930ceb414 | ||
|
|
01b7a73922 | ||
|
|
ff2d9b918d | ||
|
|
cea91ce935 | ||
|
|
51b73096f5 | ||
|
|
2c166dac97 | ||
|
|
16c015f0cb | ||
|
|
7ca60cb957 | ||
|
|
d0c80ee0bb | ||
|
|
9f1a33865a | ||
|
|
f09c84f30a | ||
|
|
f7f7493e9f | ||
|
|
c1ddb53d29 | ||
|
|
e04288482d | ||
|
|
1f3e1ec803 | ||
|
|
c3423e8df3 | ||
|
|
5ef48c1123 | ||
|
|
e3ae286e2d | ||
|
|
7abf6713b4 | ||
|
|
0232073ccf | ||
|
|
860d8fd7e1 | ||
|
|
147ff80543 | ||
|
|
3800a1e49d | ||
|
|
fe80bdcfdc | ||
|
|
94c09dff59 | ||
|
|
3d9e4d439e | ||
|
|
4a955e25a0 | ||
|
|
4f99f251bf | ||
|
|
fd418cec0d | ||
|
|
dc291a629f | ||
|
|
e23a1c6026 | ||
|
|
aee88c6452 | ||
|
|
3f111cc640 | ||
|
|
596038fc0f |
2
.github/workflows/ci-build.yaml
vendored
2
.github/workflows/ci-build.yaml
vendored
@@ -407,7 +407,7 @@ jobs:
|
||||
run: |
|
||||
docker pull quay.io/dexidp/dex:v2.25.0
|
||||
docker pull argoproj/argo-cd-ci-builder:v1.0.0
|
||||
docker pull redis:7.0.0-alpine
|
||||
docker pull redis:7.0.4-alpine
|
||||
- name: Create target directory for binaries in the build-process
|
||||
run: |
|
||||
mkdir -p dist
|
||||
|
||||
@@ -92,12 +92,13 @@ COPY ["ui/", "."]
|
||||
|
||||
ARG ARGO_VERSION=latest
|
||||
ENV ARGO_VERSION=$ARGO_VERSION
|
||||
RUN HOST_ARCH='amd64' NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OPTIONS=--max_old_space_size=8192 yarn build
|
||||
ARG TARGETARCH
|
||||
RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OPTIONS=--max_old_space_size=8192 yarn build
|
||||
|
||||
####################################################################################################
|
||||
# Argo CD Build stage which performs the actual build of Argo CD binaries
|
||||
####################################################################################################
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.18 AS argocd-build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.18 AS argocd-build
|
||||
|
||||
WORKDIR /go/src/github.com/argoproj/argo-cd
|
||||
|
||||
|
||||
1
USERS.md
1
USERS.md
@@ -37,6 +37,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Chargetrip](https://chargetrip.com)
|
||||
1. [Chime](https://www.chime.com)
|
||||
1. [Cisco ET&I](https://eti.cisco.com/)
|
||||
1. [Cobalt](https://www.cobalt.io/)
|
||||
1. [Codefresh](https://www.codefresh.io/)
|
||||
1. [Codility](https://www.codility.com/)
|
||||
1. [Commonbond](https://commonbond.co/)
|
||||
|
||||
@@ -162,8 +162,10 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []
|
||||
}
|
||||
params["path"] = path.Dir(filePath)
|
||||
params["path.basename"] = path.Base(params["path"])
|
||||
params["path.filename"] = path.Base(filePath)
|
||||
params["path.basenameNormalized"] = sanitizeName(path.Base(params["path"]))
|
||||
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
|
||||
params["path.filenameNormalized"] = sanitizeName(path.Base(params["path.filename"]))
|
||||
for k, v := range strings.Split(params["path"], "/") {
|
||||
if len(v) > 0 {
|
||||
params["path["+strconv.Itoa(k)+"]"] = v
|
||||
}
|
||||
@@ -213,7 +215,7 @@ func (g *GitGenerator) generateParamsFromApps(requestedApps []string, _ *argopro
|
||||
params["path"] = a
|
||||
params["path.basename"] = path.Base(a)
|
||||
params["path.basenameNormalized"] = sanitizeName(path.Base(a))
|
||||
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
|
||||
for k, v := range strings.Split(params["path"], "/") {
|
||||
if len(v) > 0 {
|
||||
params["path["+strconv.Itoa(k)+"]"] = v
|
||||
}
|
||||
|
||||
@@ -47,6 +47,28 @@ func (a argoCDServiceMock) GetDirectories(ctx context.Context, repoURL string, r
|
||||
return args.Get(0).([]string), args.Error(1)
|
||||
}
|
||||
|
||||
func Test_generateParamsFromGitFile(t *testing.T) {
|
||||
params, err := (*GitGenerator)(nil).generateParamsFromGitFile("path/dir/file_name.yaml", []byte(`
|
||||
foo:
|
||||
bar: baz
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"foo.bar": "baz",
|
||||
"path": "path/dir",
|
||||
"path.basename": "dir",
|
||||
"path.filename": "file_name.yaml",
|
||||
"path.basenameNormalized": "dir",
|
||||
"path.filenameNormalized": "file-name.yaml",
|
||||
"path[0]": "path",
|
||||
"path[1]": "dir",
|
||||
},
|
||||
}, params)
|
||||
}
|
||||
|
||||
func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
@@ -68,9 +90,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3"},
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "path[0]": "app2"},
|
||||
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3", "path[0]": "app_3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -85,8 +107,8 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path.basenameNormalized": "app2"},
|
||||
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path[2]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -102,9 +124,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -120,9 +142,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -238,7 +260,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "foo.bar@example.com",
|
||||
@@ -247,7 +272,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/staging",
|
||||
"path.basename": "staging",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "staging",
|
||||
"path.basenameNormalized": "staging",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -305,7 +333,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "john.doe@example.com",
|
||||
@@ -314,7 +345,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -353,7 +387,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "foo.bar@example.com",
|
||||
@@ -362,7 +399,10 @@ cluster:
|
||||
"path": "cluster-config/staging",
|
||||
"path.basename": "staging",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "staging",
|
||||
"path.basenameNormalized": "staging",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -393,7 +433,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "john.doe@example.com",
|
||||
@@ -402,7 +445,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
|
||||
@@ -81,6 +81,7 @@ func NewCommand() *cobra.Command {
|
||||
redisClient *redis.Client
|
||||
disableTLS bool
|
||||
maxCombinedDirectoryManifestsSize string
|
||||
cmpTarExcludedGlobs []string
|
||||
)
|
||||
var command = cobra.Command{
|
||||
Use: cliName,
|
||||
@@ -113,6 +114,7 @@ func NewCommand() *cobra.Command {
|
||||
PauseGenerationOnFailureForRequests: getPauseGenerationOnFailureForRequests(),
|
||||
SubmoduleEnabled: getSubmoduleEnabled(),
|
||||
MaxCombinedDirectoryManifestsSize: maxCombinedDirectoryManifestsQuantity,
|
||||
CMPTarExcludedGlobs: cmpTarExcludedGlobs,
|
||||
}, askPassServer)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -189,6 +191,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_REPO_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
|
||||
command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_TLS", false), "Disable TLS on the gRPC endpoint")
|
||||
command.Flags().StringVar(&maxCombinedDirectoryManifestsSize, "max-combined-directory-manifests-size", env.StringFromEnv("ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE", "10M"), "Max combined size of manifest files in a directory-type Application")
|
||||
command.Flags().StringArrayVar(&cmpTarExcludedGlobs, "plugin-tar-exclude", env.StringsFromEnv("ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS", []string{}, ";"), "Globs to filter when sending tarballs to plugins.")
|
||||
|
||||
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
|
||||
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
|
||||
|
||||
@@ -153,6 +153,7 @@ func NewCommand() *cobra.Command {
|
||||
stats.StartStatsTicker(10 * time.Minute)
|
||||
stats.RegisterHeapDumper("memprofile")
|
||||
argocd := server.NewServer(context.Background(), argoCDOpts)
|
||||
argocd.Init(context.Background())
|
||||
lns, err := argocd.Listen()
|
||||
errors.CheckError(err)
|
||||
for {
|
||||
|
||||
@@ -215,6 +215,7 @@ func StartLocalServer(clientOpts *apiclient.ClientOptions, ctxStr string, port *
|
||||
ListenHost: *address,
|
||||
RepoClientset: &forwardRepoClientset{namespace: namespace, context: ctxStr},
|
||||
})
|
||||
srv.Init(ctx)
|
||||
|
||||
lns, err := srv.Listen()
|
||||
if err != nil {
|
||||
|
||||
@@ -68,7 +68,8 @@ argocd login cd.argoproj.io --core`,
|
||||
server = "kubernetes"
|
||||
} else {
|
||||
server = args[0]
|
||||
tlsTestResult, err := grpc_util.TestTLS(server)
|
||||
dialTime := 30 * time.Second
|
||||
tlsTestResult, err := grpc_util.TestTLS(server, dialTime)
|
||||
errors.CheckError(err)
|
||||
if !tlsTestResult.TLS {
|
||||
if !globalClientOpts.PlainText {
|
||||
|
||||
@@ -2,12 +2,13 @@ package cmpserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
|
||||
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"
|
||||
@@ -24,6 +25,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/server/version"
|
||||
"github.com/argoproj/argo-cd/v2/util/errors"
|
||||
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
)
|
||||
|
||||
// ArgoCDCMPServer is the config management plugin server implementation
|
||||
@@ -61,6 +63,11 @@ func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, e
|
||||
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)),
|
||||
grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.KeepaliveEnforcementPolicy(
|
||||
keepalive.EnforcementPolicy{
|
||||
MinTime: common.GRPCKeepAliveEnforcementMinimum,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
return &ArgoCDCMPServer{
|
||||
|
||||
@@ -286,3 +286,10 @@ const (
|
||||
// AnnotationApplicationRefresh is an annotation that is added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconcilation.
|
||||
AnnotationApplicationSetRefresh = "argocd.argoproj.io/application-set-refresh"
|
||||
)
|
||||
|
||||
// gRPC settings
|
||||
const (
|
||||
GRPCKeepAliveEnforcementMinimum = 10 * time.Second
|
||||
// Keep alive is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors
|
||||
GRPCKeepAliveTime = 2 * GRPCKeepAliveEnforcementMinimum
|
||||
)
|
||||
|
||||
12
controller/cache/cache.go
vendored
12
controller/cache/cache.go
vendored
@@ -176,6 +176,7 @@ func NewLiveStateCache(
|
||||
type cacheSettings struct {
|
||||
clusterSettings clustercache.Settings
|
||||
appInstanceLabelKey string
|
||||
trackingMethod appv1.TrackingMethod
|
||||
}
|
||||
|
||||
type liveStateCache struct {
|
||||
@@ -210,7 +211,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
|
||||
ResourceHealthOverride: lua.ResourceHealthOverrides(resourceOverrides),
|
||||
ResourcesFilter: resourcesFilter,
|
||||
}
|
||||
return &cacheSettings{clusterSettings, appInstanceLabelKey}, nil
|
||||
return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr)}, nil
|
||||
}
|
||||
|
||||
func asResourceNode(r *clustercache.Resource) appv1.ResourceNode {
|
||||
@@ -354,7 +355,8 @@ func isTransientNetworkErr(err error) bool {
|
||||
}
|
||||
if strings.Contains(errorString, "net/http: TLS handshake timeout") ||
|
||||
strings.Contains(errorString, "i/o timeout") ||
|
||||
strings.Contains(errorString, "connection timed out") {
|
||||
strings.Contains(errorString, "connection timed out") ||
|
||||
strings.Contains(errorString, "connection reset by peer") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -387,7 +389,6 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
|
||||
return nil, fmt.Errorf("controller is configured to ignore cluster %s", cluster.Server)
|
||||
}
|
||||
|
||||
trackingMethod := argo.GetTrackingMethod(c.settingsMgr)
|
||||
clusterCacheOpts := []clustercache.UpdateSettingsFunc{
|
||||
clustercache.SetListSemaphore(semaphore.NewWeighted(clusterCacheListSemaphoreSize)),
|
||||
clustercache.SetListPageSize(clusterCacheListPageSize),
|
||||
@@ -400,9 +401,12 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
|
||||
clustercache.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (interface{}, bool) {
|
||||
res := &ResourceInfo{}
|
||||
populateNodeInfo(un, res)
|
||||
c.lock.RLock()
|
||||
cacheSettings := c.cacheSettings
|
||||
c.lock.RUnlock()
|
||||
res.Health, _ = health.GetResourceHealth(un, cacheSettings.clusterSettings.ResourceHealthOverride)
|
||||
|
||||
appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, trackingMethod)
|
||||
appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, cacheSettings.trackingMethod)
|
||||
if isRoot && appName != "" {
|
||||
res.AppName = appName
|
||||
}
|
||||
|
||||
4
controller/cache/cache_test.go
vendored
4
controller/cache/cache_test.go
vendored
@@ -111,6 +111,7 @@ func TestIsRetryableError(t *testing.T) {
|
||||
tlsHandshakeTimeoutErr net.Error = netError("net/http: TLS handshake timeout")
|
||||
ioTimeoutErr net.Error = netError("i/o timeout")
|
||||
connectionTimedout net.Error = netError("connection timed out")
|
||||
connectionReset net.Error = netError("connection reset by peer")
|
||||
)
|
||||
t.Run("Nil", func(t *testing.T) {
|
||||
assert.False(t, isRetryableError(nil))
|
||||
@@ -148,4 +149,7 @@ func TestIsRetryableError(t *testing.T) {
|
||||
t.Run("ConnectionTimeout", func(t *testing.T) {
|
||||
assert.True(t, isRetryableError(connectionTimedout))
|
||||
})
|
||||
t.Run("ConnectionReset", func(t *testing.T) {
|
||||
assert.True(t, isRetryableError(connectionReset))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -494,6 +494,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
|
||||
}
|
||||
gvk := obj.GroupVersionKind()
|
||||
|
||||
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, appLabelKey, trackingMethod)
|
||||
|
||||
resState := v1alpha1.ResourceStatus{
|
||||
Namespace: obj.GetNamespace(),
|
||||
Name: obj.GetName(),
|
||||
@@ -501,7 +503,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
|
||||
Version: gvk.Version,
|
||||
Group: gvk.Group,
|
||||
Hook: hookutil.IsHook(obj),
|
||||
RequiresPruning: targetObj == nil && liveObj != nil,
|
||||
RequiresPruning: targetObj == nil && liveObj != nil && isSelfReferencedObj,
|
||||
}
|
||||
|
||||
var diffResult diff.DiffResult
|
||||
@@ -510,8 +512,11 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
|
||||
} else {
|
||||
diffResult = diff.DiffResult{Modified: false, NormalizedLive: []byte("{}"), PredictedLive: []byte("{}")}
|
||||
}
|
||||
if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) {
|
||||
// For resource hooks or skipped resources, don't store sync status, and do not affect overall sync status
|
||||
if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) || !isSelfReferencedObj {
|
||||
// For resource hooks, skipped resources or objects that may have
|
||||
// been created by another controller with annotations copied from
|
||||
// the source object, don't store sync status, and do not affect
|
||||
// overall sync status
|
||||
} else if diffResult.Modified || targetObj == nil || liveObj == nil {
|
||||
// Set resource state to OutOfSync since one of the following is true:
|
||||
// * target and live resource are different
|
||||
@@ -667,3 +672,33 @@ func NewAppStateManager(
|
||||
resourceTracking: resourceTracking,
|
||||
}
|
||||
}
|
||||
|
||||
// isSelfReferencedObj returns whether the given obj is managed by the application
|
||||
// according to the values in the tracking annotation. It returns true when all
|
||||
// of the properties in the annotation (name, namespace, group and kind) match
|
||||
// the properties of the inspected object, or if the tracking method used does
|
||||
// not provide the required properties for matching.
|
||||
func (m *appStateManager) isSelfReferencedObj(obj *unstructured.Unstructured, appLabelKey string, trackingMethod v1alpha1.TrackingMethod) bool {
|
||||
if obj == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// If tracking method doesn't contain required metadata for this check,
|
||||
// we are not able to determine and just assume the object to be managed.
|
||||
if trackingMethod == argo.TrackingMethodLabel {
|
||||
return true
|
||||
}
|
||||
|
||||
// In order for us to assume obj to be managed by this application, the
|
||||
// values from the annotation have to match the properties from the live
|
||||
// object.
|
||||
appInstance := m.resourceTracking.GetAppInstance(obj, appLabelKey, trackingMethod)
|
||||
if appInstance != nil {
|
||||
return obj.GetNamespace() == appInstance.Namespace &&
|
||||
obj.GetName() == appInstance.Name &&
|
||||
obj.GetObjectKind().GroupVersionKind().Group == appInstance.Group &&
|
||||
obj.GetObjectKind().GroupVersionKind().Kind == appInstance.Kind
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
. "github.com/argoproj/gitops-engine/pkg/utils/testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -21,6 +22,7 @@ import (
|
||||
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/test"
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
)
|
||||
|
||||
// TestCompareAppStateEmpty tests comparison when both git and live have no objects
|
||||
@@ -770,3 +772,128 @@ func TestComparisonResult_GetSyncStatus(t *testing.T) {
|
||||
|
||||
assert.Equal(t, status, res.GetSyncStatus())
|
||||
}
|
||||
|
||||
func TestIsLiveResourceManaged(t *testing.T) {
|
||||
managedObj := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap1",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
|
||||
},
|
||||
},
|
||||
})
|
||||
managedObjWithLabel := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap1",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: "guestbook",
|
||||
},
|
||||
},
|
||||
})
|
||||
unmanagedObjWrongName := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
|
||||
},
|
||||
},
|
||||
})
|
||||
unmanagedObjWrongKind := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/Service:default/configmap2",
|
||||
},
|
||||
},
|
||||
})
|
||||
unmanagedObjWrongGroup := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:apps/ConfigMap:default/configmap2",
|
||||
},
|
||||
},
|
||||
})
|
||||
unmanagedObjWrongNamespace := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:fakens/configmap2",
|
||||
},
|
||||
},
|
||||
})
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(managedObj): managedObj,
|
||||
kube.GetResourceKey(unmanagedObjWrongName): unmanagedObjWrongName,
|
||||
kube.GetResourceKey(unmanagedObjWrongKind): unmanagedObjWrongKind,
|
||||
kube.GetResourceKey(unmanagedObjWrongGroup): unmanagedObjWrongGroup,
|
||||
kube.GetResourceKey(unmanagedObjWrongNamespace): unmanagedObjWrongNamespace,
|
||||
},
|
||||
})
|
||||
|
||||
manager := ctrl.appStateManager.(*appStateManager)
|
||||
|
||||
// Managed resource w/ annotations
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
|
||||
// Managed resource w/ label
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
|
||||
// Wrong resource name
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
|
||||
// Wrong resource group
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
|
||||
// Wrong resource kind
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
|
||||
// Wrong resource namespace
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel))
|
||||
|
||||
// Nil resource
|
||||
assert.True(t, manager.isSelfReferencedObj(nil, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
}
|
||||
|
||||
BIN
docs/assets/terminal.png
Normal file
BIN
docs/assets/terminal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
@@ -4,10 +4,10 @@ You can download the latest Argo CD version from [the latest release page of thi
|
||||
|
||||
## Linux and WSL
|
||||
|
||||
### ArchLinux User Repository ([AUR](https://aur.archlinux.org/packages/))
|
||||
### ArchLinux
|
||||
|
||||
```bash
|
||||
yay -Sy argocd-bin
|
||||
pacman -S argocd
|
||||
```
|
||||
|
||||
### Homebrew
|
||||
|
||||
@@ -24,8 +24,7 @@ You will need at least the following things in your toolchain in order to develo
|
||||
|
||||
* A Kubernetes cluster. You won't need a fully blown multi-master, multi-node cluster, but you will need something like K3S, Minikube or microk8s. You will also need a working Kubernetes client (`kubectl`) configuration in your development environment. The configuration must reside in `~/.kube/config` and the API server URL must point to the IP address of your local machine (or VM), and **not** to `localhost` or `127.0.0.1` if you are using the virtualized development toolchain (see below)
|
||||
|
||||
* You will also need a working Docker runtime environment, to be able to build and run images.
|
||||
The Docker version must be fairly recent, and support multi-stage builds. You should not work as root. Make your local user a member of the `docker` group to be able to control the Docker service on your machine.
|
||||
* You will also need a working Docker runtime environment, to be able to build and run images. The Docker version must be 17.05.0 or higher, to support multi-stage builds.
|
||||
|
||||
* Obviously, you will need a `git` client for pulling source code and pushing back your changes.
|
||||
|
||||
|
||||
64
docs/developer-guide/ui-extensions.md
Normal file
64
docs/developer-guide/ui-extensions.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# UI Extensions
|
||||
|
||||
Argo CD web user interface can be extended with additional UI elements. Extensions should be delivered as a javascript file
|
||||
in the `argocd-server` Pods that are placed in the `/tmp/extensions` directory and starts with `extension` prefix ( matches to `^extension(.*)\.js$` regex ).
|
||||
|
||||
```
|
||||
/tmp/extensions
|
||||
├── example1
|
||||
│ └── extension-1.js
|
||||
└── example2
|
||||
└── extension-2.js
|
||||
```
|
||||
|
||||
Extensions are loaded during initial page rendering and should register themselves using API exposed in the `extensionsAPI` global variable. (See
|
||||
corresponding extension type details for additional information).
|
||||
|
||||
The extension should provide a React component that is responsible for rendering the UI element. Extension should not bundle the React library.
|
||||
Instead extension should use the `react` global variable. You can leverage `externals` setting if you are using webpack:
|
||||
|
||||
```js
|
||||
externals: {
|
||||
react: 'React'
|
||||
}
|
||||
```
|
||||
|
||||
## Resource Tab Extensions
|
||||
|
||||
Resource Tab extensions is an extension that provides an additional tab for the resource sliding panel at the Argo CD Application details page.
|
||||
|
||||
The resource tab extension should be registered using the `extensionsAPI.registerResourceExtension` method:
|
||||
|
||||
```typescript
|
||||
registerResourceExtension(component: ExtensionComponent, group: string, kind: string, tabTitle: string)
|
||||
```
|
||||
|
||||
* `component: ExtensionComponent` is a React component that receives the following properties:
|
||||
|
||||
* application: Application - Argo CD Application resource;
|
||||
* resource: State - the kubernetes resource object;
|
||||
* tree: ApplicationTree - includes list of all resources that comprise the application;
|
||||
|
||||
See properties interfaces in [models.ts](https://github.com/argoproj/argo-cd/blob/master/ui/src/app/shared/models.ts)
|
||||
|
||||
* `group: string` - the glob expression that matches the group of the resource; note: use globstar (`**`) to match all groups including empty string;
|
||||
* `kind: string` - the glob expression that matches the kind of the resource;
|
||||
* `tabTitle: string` - the extension tab title.
|
||||
* `opts: Object` - additional options:
|
||||
* `icon: string` - the class name the represents the icon from the [https://fontawesome.com/](https://fontawesome.com/) library (e.g. 'fa-calendar-alt');
|
||||
|
||||
Below is an example of a resource tab extension:
|
||||
|
||||
```javascript
|
||||
((window) => {
|
||||
const component = () => {
|
||||
return React.createElement( 'div', {}, 'Hello World' );
|
||||
};
|
||||
window.extensionsAPI.registerResourceExtension(component, '*', '*', 'Nice extension');
|
||||
})(window)
|
||||
```
|
||||
|
||||
## Application Tab Extensions
|
||||
|
||||
Since the Argo CD Application is a Kubernetes resource, application tabs can be the same as any other resource tab.
|
||||
Make sure to use 'argoproj.io'/'Application' as group/kind and an extension will be used to render the application-level tab.
|
||||
@@ -174,7 +174,9 @@ argocd ... --grpc-web
|
||||
|
||||
## Why Am I Getting `x509: certificate signed by unknown authority` When Using The CLI?
|
||||
|
||||
Your not running your server with correct certs.
|
||||
The certificate created by default by Argo CD is not automatically recognised by the Argo CD CLI, in order
|
||||
to create a secure system you must follow the instructions to [install a certificate](/operator-manual/tls/)
|
||||
and configure your client OS to trust that certificate.
|
||||
|
||||
If you're not running in a production system (e.g. you're testing Argo CD out), try the `--insecure` flag:
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@ kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml
|
||||
```
|
||||
|
||||
This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work.
|
||||
Do one of:
|
||||
|
||||
* Follow the [instructions to configure a certificate](./operator-manual/tls) (and ensure that the client OS trusts it).
|
||||
* Configure the client OS to trust the self signed certificate.
|
||||
* Use the --insecure flag on all Argo CD CLI operations in this guide.
|
||||
|
||||
Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5.
|
||||
|
||||
## 2. Download Argo CD CLI
|
||||
|
||||
@@ -92,6 +92,12 @@ spec:
|
||||
- code: false
|
||||
name: foo
|
||||
value: bar
|
||||
# Exclude contains a glob pattern to match paths against that should be explicitly excluded from being used during
|
||||
# manifest generation. This takes precedence over the `include` field.
|
||||
exclude: string
|
||||
# Include contains a glob pattern to match paths against that should be explicitly included during manifest
|
||||
# generation. If this field is set, only matching manifests will be included.
|
||||
include: string
|
||||
|
||||
# plugin specific config
|
||||
plugin:
|
||||
|
||||
@@ -65,13 +65,15 @@ The generator parameters are:
|
||||
- `{{path.basename}}`: For any directory path within the Git repository that matches the `path` wildcard, the right-most path name is extracted (e.g. `/directory/directory2` would produce `directory2`).
|
||||
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
|
||||
|
||||
Whenever a new Helm chart/Kustomize YAML/Application/plain subfolder is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
|
||||
**Note**: The right-most path name always becomes `{{path.basename}}`. For example, for `- path: /one/two/three/four`, `{{path.basename}}` is `four`.
|
||||
|
||||
Whenever a new Helm chart/Kustomize YAML/Application/plain subdirectory is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
|
||||
|
||||
As with other generators, clusters *must* already be defined within Argo CD, in order to generate Applications for them.
|
||||
|
||||
### Exclude directories
|
||||
|
||||
The Git directory generator will automatically exclude folders that begin with `.` (such as `.git`).
|
||||
The Git directory generator will automatically exclude directories that begin with `.` (such as `.git`).
|
||||
|
||||
The Git directory generator also supports an `exclude` option in order to exclude directories in the repository from being scanned by the ApplicationSet controller:
|
||||
|
||||
@@ -105,7 +107,7 @@ spec:
|
||||
```
|
||||
(*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/examples/applicationset/git-generator-directory/excludes).*)
|
||||
|
||||
This example excludes the `exclude-helm-guestbook` directory from the list of directories scanned for this `ApplictionSet` resource.
|
||||
This example excludes the `exclude-helm-guestbook` directory from the list of directories scanned for this `ApplicationSet` resource.
|
||||
|
||||
!!! note "Exclude rules have higher priority than include rules"
|
||||
|
||||
@@ -205,7 +207,7 @@ Suppose you have a Git repository with the following directory structure:
|
||||
└── git-generator-files.yaml
|
||||
```
|
||||
|
||||
The folders are:
|
||||
The directories are:
|
||||
|
||||
- `guestbook` contains the Kubernetes resources for a simple guestbook application
|
||||
- `cluster-config` contains JSON/YAML files describing the individual engineering clusters: one for `dev` and one for `prod`.
|
||||
@@ -269,10 +271,16 @@ As with other generators, clusters *must* already be defined within Argo CD, in
|
||||
|
||||
In addition to the flattened key/value pairs from the configuration file, the following generator parameters are provided:
|
||||
|
||||
- `{{path}}`: The path to the folder containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
|
||||
- `{{path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
|
||||
- `{{path[n]}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `path[0]: clusters`, `path[1]: clusterA`
|
||||
- `{{path.basename}}`: Basename of the path to the folder containing the configuration file (e.g. `clusterA`, with the above example.)
|
||||
- `{{path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.)
|
||||
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
|
||||
- `{{path.filename}}`: The matched filename. e.g., `config.json` in the above example.
|
||||
- `{{path.filenameNormalized}}`: The matched filename with unsupported characters replaced with `-`.
|
||||
|
||||
**Note**: The right-most *directory* name always becomes `{{path.basename}}`. For example, from `- path: /one/two/three/four/config.json`, `{{path.basename}}` will be `four`.
|
||||
The filename can always be accessed using `{{path.filename}}`.
|
||||
|
||||
|
||||
## Webhook Configuration
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ resources of Argo CD itself (like the RBAC ConfigMap).
|
||||
ApplicationSets can also quickly create an arbitrary number of Applications and just as quickly delete them.
|
||||
|
||||
Finally, ApplicationSets can reveal privileged information. For example, the [git generator](./Generators-Git.md) can
|
||||
read Secrets in the Argo CD namespace and send them to arbitrary URLs as auth headers. (This functionality is intended
|
||||
for authorizing requests to SCM providers like GitHub, but it could be abused by a malicious user.)
|
||||
read Secrets in the Argo CD namespace and send them to arbitrary URLs (e.g. URL provided for the `api` field) as auth headers.
|
||||
(This functionality is intended for authorizing requests to SCM providers like GitHub, but it could be abused by a malicious user.)
|
||||
|
||||
For these reasons, **only admins** may be given permission (via Kubernetes RBAC or any other mechanism) to create,
|
||||
update, or delete ApplicationSets.
|
||||
|
||||
@@ -36,9 +36,12 @@ data:
|
||||
help.chatUrl: "https://mycorp.slack.com/argo-cd"
|
||||
# the text for getting chat help, defaults to "Chat now!"
|
||||
help.chatText: "Chat now!"
|
||||
# The URLs to download additional ArgoCD binaries (besides the Linux amd64 binary included by default)
|
||||
# The URLs to download additional ArgoCD binaries (besides the Linux with current platform binary included by default)
|
||||
# for different OS architectures. If provided, additional download buttons will be displayed on the help page.
|
||||
help.download.linux-amd64: "path-or-url-to-download"
|
||||
help.download.linux-arm64: "path-or-url-to-download"
|
||||
help.download.linux-ppc64le: "path-or-url-to-download"
|
||||
help.download.linux-s390x: "path-or-url-to-download"
|
||||
help.download.darwin-amd64: "path-or-url-to-download"
|
||||
help.download.darwin-arm64: "path-or-url-to-download"
|
||||
help.download.windows-amd64: "path-or-url-to-download"
|
||||
@@ -231,6 +234,14 @@ data:
|
||||
# If omitted, Argo CD injects the app name into the label: 'app.kubernetes.io/instance'
|
||||
application.instanceLabelKey: mycompany.com/appname
|
||||
|
||||
# You can change the resource tracking method Argo CD uses by changing the
|
||||
# setting application.resourceTrackingMethod to the desired method.
|
||||
# The following methods are available:
|
||||
# - label : Uses the application.instanceLabelKey label for tracking
|
||||
# - annotation : Uses an annotation with additional metadata for tracking instead of the label
|
||||
# - annotation+label : Also uses an annotation for tracking, but additionally labels the resource with the application name
|
||||
application.resourceTrackingMethod: annotation
|
||||
|
||||
# disables admin user. Admin is enabled by default
|
||||
admin.enabled: "false"
|
||||
# add an additional local user with apiKey and login capabilities
|
||||
@@ -288,3 +299,12 @@ data:
|
||||
|
||||
# exec.enabled indicates whether the UI exec feature is enabled. It is disabled by default.
|
||||
exec.enabled: "false"
|
||||
|
||||
# exec.shells restricts which shells are allowed for `exec`, and in which order they are attempted
|
||||
exec.shells: "bash,sh,powershell,cmd"
|
||||
|
||||
# oidc.tls.insecure.skip.verify determines whether certificate verification is skipped when verifying tokens with the
|
||||
# configured OIDC provider (either external or the bundled Dex instance). Setting this to "true" will cause JWT
|
||||
# token verification to pass despite the OIDC provider having an invalid certificate. Only set to "true" if you
|
||||
# understand the risks.
|
||||
oidc.tls.insecure.skip.verify: "false"
|
||||
|
||||
@@ -111,3 +111,5 @@ data:
|
||||
# for 300x memory expansion and N Applications running at the same time.
|
||||
# (example 10M max * 300 expansion * 10 Apps = 30G max theoretical memory usage).
|
||||
reposerver.max.combined.directory.manifests.size: '10M'
|
||||
# Paths to be excluded from the tarball streamed to plugins. Separate with ;
|
||||
reposerver.plugin.tar.exclusions: ""
|
||||
|
||||
@@ -81,3 +81,20 @@ resources:
|
||||
|
||||
The Argo CD can be installed using [Helm](https://helm.sh/). The Helm chart is currently community maintained and available at
|
||||
[argo-helm/charts/argo-cd](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd).
|
||||
|
||||
## Supported versions
|
||||
|
||||
Similar to the Kubernetes project, the supported versions of Argo CD at any given point in time are the latest patch releases for the N
|
||||
and N - 1 minor versions.
|
||||
These Argo CD versions are supported on the same versions of Kubernetes that are supported by Kubernetes itself (normally the last 3 released versions).
|
||||
|
||||
Essentially the Argo CD project follows the same support scheme as Kubernetes but for N, N-1 while Kubernetes supports N, N-1, N-2 versions.
|
||||
|
||||
For example if the latest minor version of ArgoCD are 2.4.3 and 2.3.5 while supported Kubernetes versions are 1.24, 1.23 and 1.22 then the following combinations are supported:
|
||||
|
||||
* Argo CD 2.4.3 on Kubernetes 1.24
|
||||
* Argo CD 2.4.3 on Kubernetes 1.23
|
||||
* Argo CD 2.4.3 on Kubernetes 1.22
|
||||
* Argo CD 2.3.5 on Kubernetes 1.24
|
||||
* Argo CD 2.3.5 on Kubernetes 1.23
|
||||
* Argo CD 2.3.5 on Kubernetes 1.22
|
||||
@@ -67,8 +67,10 @@ Scraped at the `argocd-server-metrics:8083/metrics` endpoint.
|
||||
| Metric | Type | Description |
|
||||
|--------|:----:|-------------|
|
||||
| `argocd_redis_request_duration` | histogram | Redis requests duration. |
|
||||
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. |
|
||||
|
||||
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application
|
||||
reconciliation. |
|
||||
| `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. |
|
||||
| `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. |
|
||||
## Repo Server Metrics
|
||||
Metrics about the Repo Server.
|
||||
Scraped at the `argocd-repo-server:8084/metrics` endpoint.
|
||||
|
||||
@@ -59,22 +59,7 @@ also use glob patterns in the action path: `action/*` (or regex patterns if you
|
||||
`exec` is a special resource. When enabled with the `create` action, this privilege allows a user to `exec` into Pods via
|
||||
the Argo CD UI. The functionality is similar to `kubectl exec`.
|
||||
|
||||
`exec` is a powerful privilege. It allows the user to run arbitrary code on any Pod managed by an Application for which
|
||||
they have `create` privileges. If the Pod mounts a ServiceAccount token (which is the default behavior of Kubernetes),
|
||||
then the user effectively has the same privileges as that ServiceAccount.
|
||||
|
||||
The exec feature is disabled entirely by default. To enable it, set the `exec.enabled` key to "true" on the argocd-cm
|
||||
ConfigMap. You will also need to add the following to the argocd-api-server Role (if you're using Argo CD in namespaced
|
||||
mode) or ClusterRole (if you're using Argo CD in cluster mode).
|
||||
|
||||
```yaml
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
```
|
||||
See [Web-based Terminal](web_based_terminal.md) for more info.
|
||||
|
||||
## Tying It All Together
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ argocd-repo-server [flags]
|
||||
--metrics-port int Start metrics server on given port (default 8084)
|
||||
--otlp-address string OpenTelemetry collector address to send traces to
|
||||
--parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.
|
||||
--plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins.
|
||||
--port int Listen on given port for incoming connections (default 8081)
|
||||
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
|
||||
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
|
||||
|
||||
@@ -14,3 +14,76 @@ Note that bundled Helm has been upgraded from 3.6.0 to v3.7+. This includes foll
|
||||
- Experimental OCI support has been rewritten.
|
||||
|
||||
More information in the [Helm v3.7.0 release notes](https://github.com/helm/helm/releases/tag/v3.7.0).
|
||||
|
||||
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed in 2.2.12
|
||||
|
||||
Argo CD 2.2.12 upgraded its base image from Ubuntu 21.10 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
|
||||
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
|
||||
|
||||
The signature algorithm is _not_ the same as the algorithm used when generating the key. There is no need to update
|
||||
keys.
|
||||
|
||||
The signature algorithm is negotiated with the SSH server when the connection is being set up. The client offers its
|
||||
list of accepted signature algorithms, and if the server has a match, the connection proceeds. For most SSH servers on
|
||||
up-to-date git providers, acceptable algorithms other than `ssh-rsa` should be available.
|
||||
|
||||
Before upgrading to Argo CD 2.2.12, check whether your git provider(s) using SSH authentication support algorithms newer
|
||||
than `rsa-ssh`.
|
||||
|
||||
1. Make sure your version of SSH >= 8.9 (the version used by Argo CD). If not, upgrade it before proceeding.
|
||||
|
||||
```shell
|
||||
ssh -V
|
||||
```
|
||||
|
||||
Example output: `OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022`
|
||||
|
||||
2. Once you have a recent version of OpenSSH, follow the directions from the [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.7):
|
||||
|
||||
> To check whether a server is using the weak ssh-rsa public key
|
||||
> algorithm, for host authentication, try to connect to it after
|
||||
> removing the ssh-rsa algorithm from ssh(1)'s allowed list:
|
||||
>
|
||||
> ```shell
|
||||
> ssh -oHostKeyAlgorithms=-ssh-rsa user@host
|
||||
> ```
|
||||
>
|
||||
> If the host key verification fails and no other supported host key
|
||||
> types are available, the server software on that host should be
|
||||
> upgraded.
|
||||
|
||||
If the server does not support an acceptable version, you will get an error similar to this;
|
||||
|
||||
```
|
||||
$ ssh -oHostKeyAlgorithms=-ssh-rsa vs-ssh.visualstudio.com
|
||||
Unable to negotiate with 20.42.134.1 port 22: no matching host key type found. Their offer: ssh-rsa
|
||||
```
|
||||
|
||||
This indicates that the server needs to update its supported key signature algorithms, and Argo CD will not connect
|
||||
to it.
|
||||
|
||||
### Workaround
|
||||
|
||||
The [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.8) describe a workaround if you cannot change the
|
||||
server's key signature algorithms configuration.
|
||||
|
||||
> Incompatibility is more likely when connecting to older SSH
|
||||
> implementations that have not been upgraded or have not closely tracked
|
||||
> improvements in the SSH protocol. For these cases, it may be necessary
|
||||
> to selectively re-enable RSA/SHA1 to allow connection and/or user
|
||||
> authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
|
||||
> options. For example, the following stanza in ~/.ssh/config will enable
|
||||
> RSA/SHA1 for host and user authentication for a single destination host:
|
||||
>
|
||||
> ```
|
||||
> Host old-host
|
||||
> HostkeyAlgorithms +ssh-rsa
|
||||
> PubkeyAcceptedAlgorithms +ssh-rsa
|
||||
> ```
|
||||
>
|
||||
> We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
|
||||
> implementations can be upgraded or reconfigured with another key type
|
||||
> (such as ECDSA or Ed25519).
|
||||
|
||||
To apply this to Argo CD, you could create a ConfigMap with the desired ssh config file and then mount it at
|
||||
`/home/argocd/.ssh/config`.
|
||||
|
||||
@@ -46,3 +46,77 @@ Note that bundled Kustomize version has been upgraded from 4.2.0 to 4.4.1.
|
||||
## Upgraded Helm Version
|
||||
|
||||
Note that bundled Helm version has been upgraded from 3.7.1 to 3.8.0.
|
||||
|
||||
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed in 2.3.7
|
||||
|
||||
Argo CD 2.3.7 upgraded its base image from Ubuntu 21.04 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
|
||||
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
|
||||
|
||||
The signature algorithm is _not_ the same as the algorithm used when generating the key. There is no need to update
|
||||
keys.
|
||||
|
||||
The signature algorithm is negotiated with the SSH server when the connection is being set up. The client offers its
|
||||
list of accepted signature algorithms, and if the server has a match, the connection proceeds. For most SSH servers on
|
||||
up-to-date git providers, acceptable algorithms other than `ssh-rsa` should be available.
|
||||
|
||||
Before upgrading to Argo CD 2.3.7, check whether your git provider(s) using SSH authentication support algorithms newer
|
||||
than `rsa-ssh`.
|
||||
|
||||
1. Make sure your version of SSH >= 8.9 (the version used by Argo CD). If not, upgrade it before proceeding.
|
||||
|
||||
```shell
|
||||
ssh -V
|
||||
```
|
||||
|
||||
Example output: `OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022`
|
||||
|
||||
2. Once you have a recent version of OpenSSH, follow the directions from the [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.7):
|
||||
|
||||
> To check whether a server is using the weak ssh-rsa public key
|
||||
> algorithm, for host authentication, try to connect to it after
|
||||
> removing the ssh-rsa algorithm from ssh(1)'s allowed list:
|
||||
>
|
||||
> ```shell
|
||||
> ssh -oHostKeyAlgorithms=-ssh-rsa user@host
|
||||
> ```
|
||||
>
|
||||
> If the host key verification fails and no other supported host key
|
||||
> types are available, the server software on that host should be
|
||||
> upgraded.
|
||||
|
||||
If the server does not support an acceptable version, you will get an error similar to this;
|
||||
|
||||
```
|
||||
$ ssh -oHostKeyAlgorithms=-ssh-rsa vs-ssh.visualstudio.com
|
||||
Unable to negotiate with 20.42.134.1 port 22: no matching host key type found. Their offer: ssh-rsa
|
||||
```
|
||||
|
||||
This indicates that the server needs to update its supported key signature algorithms, and Argo CD will not connect
|
||||
to it.
|
||||
|
||||
### Workaround
|
||||
|
||||
The [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.8) describe a workaround if you cannot change the
|
||||
server's key signature algorithms configuration.
|
||||
|
||||
> Incompatibility is more likely when connecting to older SSH
|
||||
> implementations that have not been upgraded or have not closely tracked
|
||||
> improvements in the SSH protocol. For these cases, it may be necessary
|
||||
> to selectively re-enable RSA/SHA1 to allow connection and/or user
|
||||
> authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
|
||||
> options. For example, the following stanza in ~/.ssh/config will enable
|
||||
> RSA/SHA1 for host and user authentication for a single destination host:
|
||||
>
|
||||
> ```
|
||||
> Host old-host
|
||||
> HostkeyAlgorithms +ssh-rsa
|
||||
> PubkeyAcceptedAlgorithms +ssh-rsa
|
||||
> ```
|
||||
>
|
||||
> We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
|
||||
> implementations can be upgraded or reconfigured with another key type
|
||||
> (such as ECDSA or Ed25519).
|
||||
|
||||
To apply this to Argo CD, you could create a ConfigMap with the desired ssh config file and then mount it at
|
||||
`/home/argocd/.ssh/config`.
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ Helm 2 support was preserved in the Argo CD. We feel that Helm 3 is stable, and
|
||||
|
||||
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed
|
||||
|
||||
Note: this change was back-ported to 2.3.7 and 2.2.12.
|
||||
|
||||
Argo CD 2.4 upgraded its base image from Ubuntu 20.04 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
|
||||
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
|
||||
|
||||
|
||||
@@ -197,6 +197,7 @@ NOTES:
|
||||
* There is no need to set `redirectURI` in the `connectors.config` as shown in the dex documentation.
|
||||
Argo CD will automatically use the correct `redirectURI` for any OAuth2 connectors, to match the
|
||||
correct external callback URL (e.g. `https://argocd.example.com/api/dex/callback`)
|
||||
* When using a custom secret (e.g., `some_K8S_secret` above,) it *must* have the label `app.kubernetes.io/part-of: argocd`.
|
||||
|
||||
## OIDC Configuration with DEX
|
||||
|
||||
@@ -495,3 +496,20 @@ data:
|
||||
clientSecret: $another-secret:oidc.auth0.clientSecret # Mind the ':'
|
||||
...
|
||||
```
|
||||
|
||||
### Skipping certificate verification on OIDC provider connections
|
||||
|
||||
By default, all connections made by the API server to OIDC providers (either external providers or the bundled Dex
|
||||
instance) must pass certificate validation. These connections occur when getting the OIDC provider's well-known
|
||||
configuration, when getting the OIDC provider's keys, and when exchanging an authorization code or verifying an ID
|
||||
token as part of an OIDC login flow.
|
||||
|
||||
Disabling certificate verification might make sense if:
|
||||
* You are using the bundled Dex instance **and** your Argo CD instance has TLS configured with a self-signed certificate
|
||||
**and** you understand and accept the risks of skipping OIDC provider cert verification.
|
||||
* You are using an external OIDC provider **and** that provider uses an invalid certificate **and** you cannot solve
|
||||
the problem by setting `oidcConfig.rootCA` **and** you understand and accept the risks of skipping OIDC provider cert
|
||||
verification.
|
||||
|
||||
If either of those two applies, then you can disable OIDC provider certificate verification by setting
|
||||
`oidc.tls.insecure.skip.verify` to `"true"` in the `argocd-cm` ConfigMap.
|
||||
|
||||
45
docs/operator-manual/web_based_terminal.md
Normal file
45
docs/operator-manual/web_based_terminal.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Web-based Terminal
|
||||
|
||||

|
||||
|
||||
Since v2.4, Argo CD has a web-based terminal that allows you to get a shell inside a running pod just like you would with
|
||||
`kubectl exec`. It's basically SSH from your browser, full ANSI color support and all! However, for security this feature
|
||||
is disabled by default.
|
||||
|
||||
This is a powerful privilege. It allows the user to run arbitrary code on any Pod managed by an Application for which
|
||||
they have the `exec/create` privilege. If the Pod mounts a ServiceAccount token (which is the default behavior of
|
||||
Kubernetes), then the user effectively has the same privileges as that ServiceAccount.
|
||||
|
||||
## Enabling the terminal
|
||||
|
||||
1. Set the `exec.enabled` key to `"true"` on the `argocd-cm` ConfigMap.
|
||||
|
||||
2. Patch the `argocd-server` Role (if using namespaced Argo) or ClusterRole (if using clustered Argo) to allow `argocd-server`
|
||||
to exec into pods
|
||||
```yaml
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
```
|
||||
|
||||
3. Add RBAC rules to allow your users to `create` the `exec` resource, i.e.
|
||||
```
|
||||
p, role:myrole, exec, create, */*, allow
|
||||
```
|
||||
|
||||
See [RBAC Configuration](rbac.md#exec-resource) for more info.
|
||||
|
||||
## Changing allowed shells
|
||||
|
||||
By default, Argo CD attempts to execute shells in this order:
|
||||
|
||||
1. bash
|
||||
2. sh
|
||||
3. powershell
|
||||
4. cmd
|
||||
|
||||
If none of the shells are found, the terminal session will fail. To add to or change the allowed shells, change the
|
||||
`exec.shells` key in the `argocd-cm` ConfigMap, separating them with commas.
|
||||
@@ -2,4 +2,5 @@ mkdocs==1.2.3
|
||||
mkdocs-material==7.1.7
|
||||
markdown_include==0.6.0
|
||||
pygments==2.7.4
|
||||
jinja2===3.0.3
|
||||
jinja2==3.0.3
|
||||
markdown==3.3.7
|
||||
@@ -234,3 +234,18 @@ If you don't need to set any environment variables, you can set an empty plugin
|
||||
Each CMP command will also independently timeout on the `ARGOCD_EXEC_TIMEOUT` set for the CMP sidecar. The default
|
||||
is 90s. So if you increase the repo server timeout greater than 90s, be sure to set `ARGOCD_EXEC_TIMEOUT` on the
|
||||
sidecar.
|
||||
|
||||
## Plugin tar stream exclusions
|
||||
|
||||
In order to increase the speed of manifest generation, certain files and folders can be excluded from being sent to your
|
||||
plugin. We recommend excluding your `.git` folder if it isn't necessary. Use Go's
|
||||
[filepatch.Match](https://pkg.go.dev/path/filepath#Match) syntax.
|
||||
|
||||
You can set it one of three ways:
|
||||
|
||||
1. The `--plugin-tar-exclude` argument on the repo server.
|
||||
2. The `reposerver.plugin.tar.exclusions` key if you are using `argocd-cmd-params-cm`
|
||||
3. Directly setting `ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS` environment variable on the repo server.
|
||||
|
||||
For option 1, the flag can be repeated multiple times. For option 2 and 3, you can specify multiple globs by separating
|
||||
them with semicolons.
|
||||
@@ -85,3 +85,22 @@ argocd app set <appName> --kustomize-version v3.5.4
|
||||
## Build Environment
|
||||
|
||||
Kustomize does not support parameters and therefore cannot support the standard [build environment](build-environment.md).
|
||||
|
||||
## Kustomizing Helm charts
|
||||
|
||||
It's possible to [render Helm charts with Kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md).
|
||||
Doing so requires that you pass the `--enable-helm` flag to the `kustomize build` command.
|
||||
This flag is not part of the Kustomize options within Argo CD.
|
||||
If you would like to render Helm charts through Kustomize in an Argo CD application, you have two options:
|
||||
You can either create a [custom plugin](https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/), or modify the `argocd-cm` ConfigMap to include the `--enable-helm` flag globally for all Kustomize applications:
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cm
|
||||
namespace: argocd
|
||||
data:
|
||||
kustomize.buildOptions: --enable-helm
|
||||
```
|
||||
|
||||
|
||||
3
go.mod
3
go.mod
@@ -257,6 +257,9 @@ replace (
|
||||
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/improbable-eng/grpc-web => github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a
|
||||
|
||||
// Avoid CVE-2022-28948
|
||||
gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
||||
|
||||
// https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280
|
||||
k8s.io/api => k8s.io/api v0.23.1
|
||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.1
|
||||
|
||||
6
go.sum
6
go.sum
@@ -1814,10 +1814,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: dex
|
||||
image: ghcr.io/dexidp/dex:v2.30.2
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
imagePullPolicy: Always
|
||||
command: [/shared/argocd-dex, rundex]
|
||||
securityContext:
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.3
|
||||
newTag: v2.4.8
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -21,7 +21,7 @@ spec:
|
||||
serviceAccountName: argocd-redis
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: Always
|
||||
args:
|
||||
- "--save"
|
||||
|
||||
@@ -107,6 +107,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
|
||||
@@ -9385,7 +9385,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9465,7 +9465,7 @@ spec:
|
||||
- ""
|
||||
- --appendonly
|
||||
- "no"
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: Always
|
||||
name: redis
|
||||
ports:
|
||||
@@ -9603,13 +9603,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -9658,7 +9664,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -9845,7 +9851,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.3
|
||||
newTag: v2.4.8
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.3
|
||||
newTag: v2.4.8
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -770,7 +770,7 @@ spec:
|
||||
topologyKey: kubernetes.io/hostname
|
||||
initContainers:
|
||||
- name: config-init
|
||||
image: haproxy:2.0.25-alpine
|
||||
image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
{}
|
||||
@@ -790,7 +790,7 @@ spec:
|
||||
runAsUser: 1000
|
||||
containers:
|
||||
- name: haproxy
|
||||
image: haproxy:2.0.25-alpine
|
||||
image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -878,7 +878,7 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
initContainers:
|
||||
- name: config-init
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
{}
|
||||
@@ -906,7 +906,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- redis-server
|
||||
@@ -947,7 +947,7 @@ spec:
|
||||
lifecycle:
|
||||
{}
|
||||
- name: sentinel
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- redis-sentinel
|
||||
|
||||
@@ -9,12 +9,12 @@ redis-ha:
|
||||
haproxy:
|
||||
enabled: true
|
||||
image:
|
||||
tag: 2.0.25-alpine
|
||||
tag: 2.0.29-alpine
|
||||
timeout:
|
||||
server: 6m
|
||||
client: 6m
|
||||
checkInterval: 3s
|
||||
image:
|
||||
tag: 7.0.0-alpine
|
||||
tag: 7.0.4-alpine
|
||||
sentinel:
|
||||
bind: "0.0.0.0"
|
||||
|
||||
@@ -10320,7 +10320,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -10392,7 +10392,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.30.2
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -10417,7 +10417,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -10457,7 +10457,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10526,7 +10526,7 @@ spec:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers:
|
||||
- image: haproxy:2.0.25-alpine
|
||||
- image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -10555,7 +10555,7 @@ spec:
|
||||
- /readonly/haproxy_init.sh
|
||||
command:
|
||||
- sh
|
||||
image: haproxy:2.0.25-alpine
|
||||
image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
volumeMounts:
|
||||
@@ -10702,13 +10702,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10757,7 +10763,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -11004,7 +11010,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -11212,7 +11218,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -11293,7 +11299,7 @@ spec:
|
||||
- /data/conf/redis.conf
|
||||
command:
|
||||
- redis-server
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -11331,7 +11337,7 @@ spec:
|
||||
- /data/conf/sentinel.conf
|
||||
command:
|
||||
- redis-sentinel
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -11377,7 +11383,7 @@ spec:
|
||||
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
|
||||
- name: SENTINEL_ID_2
|
||||
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
volumeMounts:
|
||||
|
||||
@@ -1244,7 +1244,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1316,7 +1316,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.30.2
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -1341,7 +1341,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1381,7 +1381,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1450,7 +1450,7 @@ spec:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers:
|
||||
- image: haproxy:2.0.25-alpine
|
||||
- image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -1479,7 +1479,7 @@ spec:
|
||||
- /readonly/haproxy_init.sh
|
||||
command:
|
||||
- sh
|
||||
image: haproxy:2.0.25-alpine
|
||||
image: haproxy:2.0.29-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
volumeMounts:
|
||||
@@ -1626,13 +1626,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1681,7 +1687,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1928,7 +1934,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2136,7 +2142,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2217,7 +2223,7 @@ spec:
|
||||
- /data/conf/redis.conf
|
||||
command:
|
||||
- redis-server
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -2255,7 +2261,7 @@ spec:
|
||||
- /data/conf/sentinel.conf
|
||||
command:
|
||||
- redis-sentinel
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
@@ -2301,7 +2307,7 @@ spec:
|
||||
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
|
||||
- name: SENTINEL_ID_2
|
||||
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
volumeMounts:
|
||||
|
||||
@@ -9692,7 +9692,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9764,7 +9764,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.30.2
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -9789,7 +9789,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -9829,7 +9829,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -9904,7 +9904,7 @@ spec:
|
||||
- ""
|
||||
- --appendonly
|
||||
- "no"
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: Always
|
||||
name: redis
|
||||
ports:
|
||||
@@ -10042,13 +10042,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10097,7 +10103,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -10340,7 +10346,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -10542,7 +10548,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -616,7 +616,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -688,7 +688,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.30.2
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -713,7 +713,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -753,7 +753,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -828,7 +828,7 @@ spec:
|
||||
- ""
|
||||
- --appendonly
|
||||
- "no"
|
||||
image: redis:7.0.0-alpine
|
||||
image: redis:7.0.4-alpine
|
||||
imagePullPolicy: Always
|
||||
name: redis
|
||||
ports:
|
||||
@@ -966,13 +966,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1021,7 +1027,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1264,7 +1270,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1466,7 +1472,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.3
|
||||
image: quay.io/argoproj/argocd:v2.4.8
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -44,6 +44,7 @@ nav:
|
||||
- operator-manual/custom_tools.md
|
||||
- operator-manual/custom-styles.md
|
||||
- operator-manual/metrics.md
|
||||
- operator-manual/web_based_terminal.md
|
||||
- Notification:
|
||||
- Overview: operator-manual/notifications/index.md
|
||||
- operator-manual/notifications/triggers.md
|
||||
@@ -160,6 +161,7 @@ nav:
|
||||
- developer-guide/releasing.md
|
||||
- developer-guide/site.md
|
||||
- developer-guide/static-code-analysis.md
|
||||
- developer-guide/ui-extensions.md
|
||||
- developer-guide/faq.md
|
||||
- faq.md
|
||||
- security_considerations.md
|
||||
|
||||
@@ -1542,6 +1542,19 @@ func isValidAction(action string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: same as validActions, refacotor to use rbacpolicy.ResourceApplications etc.
|
||||
var validResources = map[string]bool{
|
||||
"applications": true,
|
||||
"repositories": true,
|
||||
"clusters": true,
|
||||
"exec": true,
|
||||
"logs": true,
|
||||
}
|
||||
|
||||
func isValidResource(resource string) bool {
|
||||
return validResources[resource]
|
||||
}
|
||||
|
||||
func validatePolicy(proj string, role string, policy string) error {
|
||||
policyComponents := strings.Split(policy, ",")
|
||||
if len(policyComponents) != 6 || strings.Trim(policyComponents[0], " ") != "p" {
|
||||
@@ -1555,7 +1568,7 @@ func validatePolicy(proj string, role string, policy string) error {
|
||||
}
|
||||
// resource
|
||||
resource := strings.Trim(policyComponents[2], " ")
|
||||
if resource != "applications" && resource != "repositories" && resource != "clusters" {
|
||||
if !isValidResource(resource) {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', 'repositories' or 'clusters', not '%s'", policy, resource)
|
||||
}
|
||||
// action
|
||||
|
||||
@@ -2546,10 +2546,19 @@ func Test_validatePolicy_projIsNotRegex(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_validatePolicy_ValidResource(t *testing.T) {
|
||||
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
|
||||
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, exec, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, logs, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, unknown, *, some-project/*, allow")
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestEnvsubst(t *testing.T) {
|
||||
|
||||
@@ -103,6 +103,7 @@ type RepoServerInitConstants struct {
|
||||
PauseGenerationOnFailureForRequests int
|
||||
SubmoduleEnabled bool
|
||||
MaxCombinedDirectoryManifestsSize resource.Quantity
|
||||
CMPTarExcludedGlobs []string
|
||||
}
|
||||
|
||||
// NewService returns a new instance of the Manifest service
|
||||
@@ -213,7 +214,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (*
|
||||
}
|
||||
|
||||
defer io.Close(closer)
|
||||
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes)
|
||||
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -465,7 +466,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
|
||||
var manifestGenResult *apiclient.ManifestResponse
|
||||
opContext, err := opContextSrc()
|
||||
if err == nil {
|
||||
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh))
|
||||
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs))
|
||||
}
|
||||
if err != nil {
|
||||
// If manifest generation error caching is enabled
|
||||
@@ -858,7 +859,8 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v
|
||||
|
||||
type GenerateManifestOpt func(*generateManifestOpt)
|
||||
type generateManifestOpt struct {
|
||||
cmpTarDoneCh chan<- bool
|
||||
cmpTarDoneCh chan<- bool
|
||||
cmpTarExcludedGlobs []string
|
||||
}
|
||||
|
||||
func newGenerateManifestOpt(opts ...GenerateManifestOpt) *generateManifestOpt {
|
||||
@@ -878,6 +880,14 @@ func WithCMPTarDoneChannel(ch chan<- bool) GenerateManifestOpt {
|
||||
}
|
||||
}
|
||||
|
||||
// WithCMPTarExcludedGlobs defines globs for files to filter out when streaming the tarball
|
||||
// to a CMP sidecar.
|
||||
func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt {
|
||||
return func(o *generateManifestOpt) {
|
||||
o.cmpTarExcludedGlobs = excludedGlobs
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource.
|
||||
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
|
||||
opt := newGenerateManifestOpt(opts...)
|
||||
@@ -886,7 +896,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
|
||||
|
||||
resourceTracking := argo.NewResourceTracking()
|
||||
|
||||
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes)
|
||||
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes, opt.cmpTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -910,7 +920,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
|
||||
if q.ApplicationSource.Plugin != nil && q.ApplicationSource.Plugin.Name != "" {
|
||||
targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore))
|
||||
} else {
|
||||
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh)
|
||||
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("plugin sidecar failed. %s", err.Error())
|
||||
}
|
||||
@@ -1044,7 +1054,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str
|
||||
}
|
||||
|
||||
// GetAppSourceType returns explicit application source type or examines a directory and determines its application source type
|
||||
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool) (v1alpha1.ApplicationSourceType, error) {
|
||||
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool, tarExcludedGlobs []string) (v1alpha1.ApplicationSourceType, error) {
|
||||
err := mergeSourceParameters(source, path, appName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error while parsing source parameters: %v", err)
|
||||
@@ -1061,7 +1071,7 @@ func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, p
|
||||
}
|
||||
return *appSourceType, nil
|
||||
}
|
||||
appType, err := discovery.AppType(ctx, path, enableGenerateManifests)
|
||||
appType, err := discovery.AppType(ctx, path, enableGenerateManifests, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1465,7 +1475,7 @@ func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds gi
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool) ([]*unstructured.Unstructured, error) {
|
||||
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) {
|
||||
// compute variables.
|
||||
env, err := getPluginEnvs(envVars, q, creds, true)
|
||||
if err != nil {
|
||||
@@ -1473,14 +1483,14 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
|
||||
}
|
||||
|
||||
// detect config management plugin server (sidecar)
|
||||
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env)
|
||||
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer io.Close(conn)
|
||||
|
||||
// generate manifests using commands provided in plugin config file in detected cmp-server sidecar
|
||||
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh)
|
||||
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating manifests in cmp: %s", err)
|
||||
}
|
||||
@@ -1498,7 +1508,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
|
||||
// generateManifestsCMP will send the appPath files to the cmp-server over a gRPC stream.
|
||||
// The cmp-server will generate the manifests. Returns a response object with the generated
|
||||
// manifests.
|
||||
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool) (*pluginclient.ManifestResponse, error) {
|
||||
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) {
|
||||
generateManifestStream, err := cmpClient.GenerateManifest(ctx, grpc_retry.Disable())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting generateManifestStream: %s", err)
|
||||
@@ -1506,7 +1516,7 @@ func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []s
|
||||
opts := []cmp.SenderOption{
|
||||
cmp.WithTarDoneChan(tarDoneCh),
|
||||
}
|
||||
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, opts...)
|
||||
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, tarExcludedGlobs, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error sending file to cmp-server: %s", err)
|
||||
}
|
||||
@@ -1524,7 +1534,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
||||
return err
|
||||
}
|
||||
|
||||
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes)
|
||||
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1639,7 +1649,7 @@ func loadFileIntoIfExists(path pathutil.ResolvedFilePath, destination *string) e
|
||||
info, err := os.Stat(stringPath)
|
||||
|
||||
if err == nil && !info.IsDir() {
|
||||
bytes, err := ioutil.ReadFile(stringPath);
|
||||
bytes, err := ioutil.ReadFile(stringPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -133,6 +133,31 @@ func newServiceWithCommitSHA(root, revision string) *Service {
|
||||
return service
|
||||
}
|
||||
|
||||
// createSymlink creates a symlink with name linkName to file destName in
|
||||
// workingDir
|
||||
func createSymlink(t *testing.T, workingDir, destName, linkName string) error {
|
||||
oldWorkingDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if workingDir != "" {
|
||||
err = os.Chdir(workingDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := os.Chdir(oldWorkingDir); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
err = os.Symlink(destName, linkName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestGenerateYamlManifestInDir(t *testing.T) {
|
||||
service := newService("../..")
|
||||
|
||||
@@ -1049,15 +1074,15 @@ func TestGenerateNullList(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) {
|
||||
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{})
|
||||
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{})
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{})
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
}
|
||||
@@ -1582,7 +1607,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
source := &argoappv1.ApplicationSource{
|
||||
Path: path,
|
||||
}
|
||||
sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it.
|
||||
sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it.
|
||||
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
ApplicationSource: sourceCopy,
|
||||
@@ -2008,7 +2033,12 @@ func Test_getPotentiallyValidManifests(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("circular link should throw an error", func(t *testing.T) {
|
||||
require.DirExists(t, "./testdata/circular-link")
|
||||
const testDir = "./testdata/circular-link"
|
||||
require.DirExists(t, testDir)
|
||||
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
|
||||
defer os.Remove(path.Join(testDir, "a.json"))
|
||||
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
|
||||
defer os.Remove(path.Join(testDir, "b.json"))
|
||||
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", false, "", "", resource.MustParse("0"))
|
||||
assert.Empty(t, manifests)
|
||||
assert.Error(t, err)
|
||||
@@ -2103,7 +2133,12 @@ func Test_findManifests(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("circular link should throw an error", func(t *testing.T) {
|
||||
require.DirExists(t, "./testdata/circular-link")
|
||||
const testDir = "./testdata/circular-link"
|
||||
require.DirExists(t, testDir)
|
||||
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
|
||||
defer os.Remove(path.Join(testDir, "a.json"))
|
||||
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
|
||||
defer os.Remove(path.Join(testDir, "b.json"))
|
||||
manifests, err := findManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", nil, noRecurse, nil, resource.MustParse("0"))
|
||||
assert.Empty(t, manifests)
|
||||
assert.Error(t, err)
|
||||
|
||||
0
reposerver/repository/testdata/circular-link/.keep
vendored
Normal file
0
reposerver/repository/testdata/circular-link/.keep
vendored
Normal file
@@ -1 +0,0 @@
|
||||
b.json
|
||||
@@ -1 +0,0 @@
|
||||
a.json
|
||||
@@ -3,10 +3,11 @@ package reposerver
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
|
||||
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"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/health"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
"google.golang.org/grpc/reflection"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
@@ -86,6 +88,11 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach
|
||||
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)),
|
||||
grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.KeepaliveEnforcementPolicy(
|
||||
keepalive.EnforcementPolicy{
|
||||
MinTime: common.GRPCKeepAliveEnforcementMinimum,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
// We do allow for non-TLS servers to be created, in case of mTLS will be
|
||||
|
||||
@@ -33,17 +33,19 @@ type terminalHandler struct {
|
||||
enf *rbac.Enforcer
|
||||
cache *servercache.Cache
|
||||
appResourceTreeFn func(ctx context.Context, app *appv1.Application) (*appv1.ApplicationTree, error)
|
||||
allowedShells []string
|
||||
}
|
||||
|
||||
// NewHandler returns a new terminal handler.
|
||||
func NewHandler(appLister applisters.ApplicationNamespaceLister, db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache,
|
||||
appResourceTree AppResourceTreeFn) *terminalHandler {
|
||||
appResourceTree AppResourceTreeFn, allowedShells []string) *terminalHandler {
|
||||
return &terminalHandler{
|
||||
appLister: appLister,
|
||||
db: db,
|
||||
enf: enf,
|
||||
cache: cache,
|
||||
appResourceTreeFn: appResourceTree,
|
||||
allowedShells: allowedShells,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Namespace name is not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
shell := q.Get("shell") // No need to validate. Will only buse used if it's in the allow-list.
|
||||
shell := q.Get("shell") // No need to validate. Will only be used if it's in the allow-list.
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
@@ -216,14 +218,12 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer session.Done()
|
||||
|
||||
validShells := []string{"bash", "sh", "powershell", "cmd"}
|
||||
if isValidShell(validShells, shell) {
|
||||
if isValidShell(s.allowedShells, shell) {
|
||||
cmd := []string{shell}
|
||||
err = startProcess(kubeClientset, config, namespace, podName, container, cmd, session)
|
||||
} else {
|
||||
// No shell given or it was not valid: try some shells until one succeeds or all fail
|
||||
// FIXME: if the first shell fails then the first keyboard event is lost
|
||||
for _, testShell := range validShells {
|
||||
// No shell given or the given shell was not allowed: try the configured shells until one succeeds or all fail.
|
||||
for _, testShell := range s.allowedShells {
|
||||
cmd := []string{testShell}
|
||||
if err = startProcess(kubeClientset, config, namespace, podName, container, cmd, session); err == nil {
|
||||
break
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
@@ -22,10 +23,12 @@ var upgrader = func() websocket.Upgrader {
|
||||
|
||||
// terminalSession implements PtyHandler
|
||||
type terminalSession struct {
|
||||
wsConn *websocket.Conn
|
||||
sizeChan chan remotecommand.TerminalSize
|
||||
doneChan chan struct{}
|
||||
tty bool
|
||||
wsConn *websocket.Conn
|
||||
sizeChan chan remotecommand.TerminalSize
|
||||
doneChan chan struct{}
|
||||
tty bool
|
||||
readLock sync.Mutex
|
||||
writeLock sync.Mutex
|
||||
}
|
||||
|
||||
// newTerminalSession create terminalSession
|
||||
@@ -60,7 +63,9 @@ func (t *terminalSession) Next() *remotecommand.TerminalSize {
|
||||
|
||||
// Read called in a loop from remotecommand as long as the process is running
|
||||
func (t *terminalSession) Read(p []byte) (int, error) {
|
||||
t.readLock.Lock()
|
||||
_, message, err := t.wsConn.ReadMessage()
|
||||
t.readLock.Unlock()
|
||||
if err != nil {
|
||||
log.Errorf("read message err: %v", err)
|
||||
return copy(p, EndOfTransmission), err
|
||||
@@ -91,7 +96,10 @@ func (t *terminalSession) Write(p []byte) (int, error) {
|
||||
log.Errorf("write parse message err: %v", err)
|
||||
return 0, err
|
||||
}
|
||||
if err := t.wsConn.WriteMessage(websocket.TextMessage, msg); err != nil {
|
||||
t.writeLock.Lock()
|
||||
err = t.wsConn.WriteMessage(websocket.TextMessage, msg)
|
||||
t.writeLock.Unlock()
|
||||
if err != nil {
|
||||
log.Errorf("write message err: %v", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
goio "io"
|
||||
"io/fs"
|
||||
"math"
|
||||
"net"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
go_runtime "runtime"
|
||||
@@ -22,6 +24,8 @@ import (
|
||||
// nolint:staticcheck
|
||||
golang_proto "github.com/golang/protobuf/proto"
|
||||
|
||||
netCtx "context"
|
||||
|
||||
"github.com/argoproj/pkg/sync"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
@@ -35,11 +39,11 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/soheilhy/cmux"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
netCtx "golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -98,6 +102,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/healthz"
|
||||
httputil "github.com/argoproj/argo-cd/v2/util/http"
|
||||
"github.com/argoproj/argo-cd/v2/util/io"
|
||||
"github.com/argoproj/argo-cd/v2/util/io/files"
|
||||
jwtutil "github.com/argoproj/argo-cd/v2/util/jwt"
|
||||
kubeutil "github.com/argoproj/argo-cd/v2/util/kube"
|
||||
"github.com/argoproj/argo-cd/v2/util/oidc"
|
||||
@@ -362,6 +367,12 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) {
|
||||
return &Listeners{Main: mainLn, Metrics: metricsLn, GatewayConn: conn}, nil
|
||||
}
|
||||
|
||||
// Init starts informers used by the API server
|
||||
func (a *ArgoCDServer) Init(ctx context.Context) {
|
||||
go a.projInformer.Run(ctx.Done())
|
||||
go a.appInformer.Run(ctx.Done())
|
||||
}
|
||||
|
||||
// Run runs the API Server
|
||||
// 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
|
||||
@@ -429,9 +440,6 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) {
|
||||
log.Infof("argocd %s serving on port %d (url: %s, tls: %v, namespace: %s, sso: %v)",
|
||||
common.GetVersion(), a.ListenPort, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured())
|
||||
|
||||
go a.projInformer.Run(ctx.Done())
|
||||
go a.appInformer.Run(ctx.Done())
|
||||
|
||||
go func() { a.checkServeErr("grpcS", grpcS.Serve(grpcL)) }()
|
||||
go func() { a.checkServeErr("httpS", httpS.Serve(httpL)) }()
|
||||
if a.useTLS() {
|
||||
@@ -604,6 +612,11 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre
|
||||
grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize),
|
||||
grpc.ConnectionTimeout(300 * time.Second),
|
||||
grpc.KeepaliveEnforcementPolicy(
|
||||
keepalive.EnforcementPolicy{
|
||||
MinTime: common.GRPCKeepAliveEnforcementMinimum,
|
||||
},
|
||||
),
|
||||
}
|
||||
sensitiveMethods := map[string]bool{
|
||||
"/cluster.ClusterService/Create": true,
|
||||
@@ -798,7 +811,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
}
|
||||
mux.Handle("/api/", handler)
|
||||
|
||||
terminalHandler := application.NewHandler(a.appLister, a.db, a.enf, a.Cache, appResourceTreeFn)
|
||||
terminalHandler := application.NewHandler(a.appLister, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells)
|
||||
mux.HandleFunc("/terminal", func(writer http.ResponseWriter, request *http.Request) {
|
||||
argocdSettings, err := a.settingsMgr.GetSettings()
|
||||
if err != nil {
|
||||
@@ -861,11 +874,11 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
registerDownloadHandlers(mux, "/download")
|
||||
|
||||
// Serve extensions
|
||||
var extensionsApiPath = "/extensions/"
|
||||
var extensionsSharedPath = "/tmp/extensions/"
|
||||
|
||||
extHandler := http.StripPrefix(extensionsApiPath, http.FileServer(http.Dir(extensionsSharedPath)))
|
||||
mux.HandleFunc(extensionsApiPath, extHandler.ServeHTTP)
|
||||
mux.HandleFunc("/extensions.js", func(writer http.ResponseWriter, _ *http.Request) {
|
||||
a.serveExtensions(extensionsSharedPath, writer)
|
||||
})
|
||||
|
||||
// Serve UI static assets
|
||||
var assetsHandler http.Handler = http.HandlerFunc(a.newStaticAssetsHandler())
|
||||
@@ -876,6 +889,48 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
return &httpS
|
||||
}
|
||||
|
||||
var extensionsPattern = regexp.MustCompile(`^extension(.*)\.js$`)
|
||||
|
||||
func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) {
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
|
||||
err := filepath.Walk(extensionsSharedPath, func(filePath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to iterate files in '%s': %w", extensionsSharedPath, err)
|
||||
}
|
||||
if !files.IsSymlink(info) && !info.IsDir() && extensionsPattern.MatchString(info.Name()) {
|
||||
processFile := func() error {
|
||||
if _, err = w.Write([]byte(fmt.Sprintf("// source: %s/%s \n", filePath, info.Name()))); err != nil {
|
||||
return fmt.Errorf("failed to write to response: %w", err)
|
||||
}
|
||||
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open file '%s': %w", filePath, err)
|
||||
}
|
||||
defer io.Close(f)
|
||||
|
||||
if _, err := goio.Copy(w, f); err != nil {
|
||||
return fmt.Errorf("failed to copy file '%s': %w", filePath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if processFile() != nil {
|
||||
return fmt.Errorf("failed to serve extension file '%s': %w", filePath, processFile())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
log.Errorf("Failed to walk extensions directory: %v", err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// registerDexHandlers will register dex HTTP handlers, creating the the OAuth client app
|
||||
func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) {
|
||||
if !a.settings.IsSSOConfigured() {
|
||||
|
||||
@@ -36,6 +36,7 @@ func TestUserAgent(t *testing.T) {
|
||||
defer cancelInformer()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
@@ -101,6 +102,7 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
defer cancelInformer()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
@@ -129,6 +131,7 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
@@ -157,6 +160,7 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ func fakeServer() (*ArgoCDServer, func()) {
|
||||
),
|
||||
RedisClient: redis,
|
||||
}
|
||||
return NewServer(context.Background(), argoCDOpts), closer
|
||||
srv := NewServer(context.Background(), argoCDOpts)
|
||||
return srv, closer
|
||||
}
|
||||
|
||||
func TestEnforceProjectToken(t *testing.T) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM redis:7.0.0 as redis
|
||||
FROM redis:7.0.4 as redis
|
||||
|
||||
FROM node:12.18.4-buster as node
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project"
|
||||
repoFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos"
|
||||
"github.com/argoproj/argo-cd/v2/test/e2e/testdata"
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
. "github.com/argoproj/argo-cd/v2/util/argo"
|
||||
. "github.com/argoproj/argo-cd/v2/util/errors"
|
||||
"github.com/argoproj/argo-cd/v2/util/io"
|
||||
@@ -947,7 +948,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
And(func(app *Application) {
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 80")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.2")
|
||||
assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2")
|
||||
}).
|
||||
Given().
|
||||
LocalPath(guestbookPathLocal).
|
||||
@@ -958,7 +959,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
And(func(app *Application) {
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 81")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.3")
|
||||
assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.3")
|
||||
}).
|
||||
Given().
|
||||
LocalPath("").
|
||||
@@ -969,7 +970,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
And(func(app *Application) {
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 80")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.2")
|
||||
assert.Contains(t, res, "image: quay.io/argoprojlabs/argocd-e2e-container:0.2")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1190,7 +1191,8 @@ func TestPermissionWithScopedRepo(t *testing.T) {
|
||||
Name(projName).
|
||||
Destination("*,*").
|
||||
When().
|
||||
Create()
|
||||
Create().
|
||||
AddSource("*")
|
||||
|
||||
repoFixture.Given(t, true).
|
||||
When().
|
||||
@@ -2063,3 +2065,241 @@ func TestDisableManifestGeneration(t *testing.T) {
|
||||
assert.Equal(t, app.Status.SourceType, ApplicationSourceTypeDirectory)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSwitchTrackingMethod(t *testing.T) {
|
||||
ctx := Given(t)
|
||||
|
||||
ctx.
|
||||
SetTrackingMethod(string(argo.TrackingMethodAnnotation)).
|
||||
Path("deployment").
|
||||
When().
|
||||
CreateApp().
|
||||
Sync().
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add resource with tracking annotation. This should put the
|
||||
// application OutOfSync.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Delete resource to bring application back in sync
|
||||
FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
SetTrackingMethod(string(argo.TrackingMethodLabel)).
|
||||
Sync().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a resource with a tracking annotation. This should not
|
||||
// affect the application, because we now use the tracking method
|
||||
// "label".
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a resource with the tracking label. The app should become
|
||||
// OutOfSync.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "extra-configmap",
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: Name(),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Delete resource to bring application back in sync
|
||||
FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "extra-configmap", metav1.DeleteOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy))
|
||||
}
|
||||
|
||||
func TestSwitchTrackingLabel(t *testing.T) {
|
||||
ctx := Given(t)
|
||||
|
||||
ctx.
|
||||
Path("deployment").
|
||||
When().
|
||||
CreateApp().
|
||||
Sync().
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add extra resource that carries the default tracking label
|
||||
// We expect the app to go out of sync.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: Name(),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Delete resource to bring application back in sync
|
||||
FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
// Change tracking label
|
||||
SetTrackingLabel("argocd.tracking").
|
||||
Sync().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Create resource with the new tracking label, the application
|
||||
// is expected to go out of sync
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Labels: map[string]string{
|
||||
"argocd.tracking": Name(),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Delete resource to bring application back in sync
|
||||
FailOnErr(nil, KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Delete(context.Background(), "other-configmap", metav1.DeleteOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add extra resource that carries the default tracking label
|
||||
// We expect the app to stay in sync, because the configured
|
||||
// label is different.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: Name(),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy))
|
||||
}
|
||||
|
||||
func TestAnnotationTrackingExtraResources(t *testing.T) {
|
||||
ctx := Given(t)
|
||||
|
||||
SetTrackingMethod(string(argo.TrackingMethodAnnotation))
|
||||
ctx.
|
||||
Path("deployment").
|
||||
When().
|
||||
CreateApp().
|
||||
Sync().
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a resource with an annotation that is not referencing the
|
||||
// resource.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "extra-configmap",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:apps/Deployment:%s/guestbook-cm", Name(), DeploymentNamespace()),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a resource with an annotation that is self-referencing the
|
||||
// resource.
|
||||
FailOnErr(KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create(context.Background(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "other-configmap",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", Name(), DeploymentNamespace()),
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy))
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
@@ -43,7 +43,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
@@ -341,3 +341,13 @@ func (a *Actions) verifyAction() {
|
||||
a.Then().Expect(Success(""))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions {
|
||||
fixture.SetTrackingMethod(trackingMethod)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions {
|
||||
fixture.SetTrackingLabel(trackingLabel)
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -308,3 +308,8 @@ func (c *Context) HelmSkipCrds() *Context {
|
||||
c.helmSkipCrds = true
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Context) SetTrackingMethod(trackingMethod string) *Context {
|
||||
fixture.SetTrackingMethod(trackingMethod)
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -14,11 +14,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
argocommon "github.com/argoproj/argo-cd/v2/common"
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils"
|
||||
"github.com/argoproj/argo-cd/v2/util/clusterauth"
|
||||
)
|
||||
|
||||
// this implements the "when" part of given/when/then
|
||||
@@ -61,42 +62,6 @@ func (a *Actions) Then() *Consequences {
|
||||
return &Consequences{a.context, a}
|
||||
}
|
||||
|
||||
// GetServiceAccountBearerToken will attempt to get the provided service account until it
|
||||
// exists, iterate the secrets associated with it looking for one of type
|
||||
// kubernetes.io/service-account-token, and return it's token if found.
|
||||
// (function based on 'GetServiceAccountBearerToken' from Argo CD's 'clusterauth.go')
|
||||
func GetServiceAccountBearerToken(clientset kubernetes.Interface, ns string, sa string) (string, error) {
|
||||
var serviceAccount *corev1.ServiceAccount
|
||||
var secret *corev1.Secret
|
||||
var err error
|
||||
err = wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||
serviceAccount, err = clientset.CoreV1().ServiceAccounts(ns).Get(context.Background(), sa, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Scan all secrets looking for one of the correct type:
|
||||
for _, oRef := range serviceAccount.Secrets {
|
||||
var getErr error
|
||||
secret, err = clientset.CoreV1().Secrets(ns).Get(context.Background(), oRef.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to retrieve secret %q: %v", oRef.Name, getErr)
|
||||
}
|
||||
if secret.Type == corev1.SecretTypeServiceAccountToken {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to wait for service account secret: %v", err)
|
||||
}
|
||||
token, ok := secret.Data["token"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("secret %q for service account %q did not have a token", secret.Name, serviceAccount)
|
||||
}
|
||||
return string(token), nil
|
||||
}
|
||||
|
||||
// CreateClusterSecret creates a faux cluster secret, with the given cluster server and cluster name (this cluster
|
||||
// will not actually be used by the Argo CD controller, but that's not needed for our E2E tests)
|
||||
func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clusterServer string) *Actions {
|
||||
@@ -135,7 +100,7 @@ func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clu
|
||||
|
||||
if err == nil {
|
||||
var bearerToken string
|
||||
bearerToken, err = GetServiceAccountBearerToken(fixtureClient.KubeClientset, utils.ArgoCDNamespace, serviceAccountName)
|
||||
bearerToken, err = clusterauth.GetServiceAccountBearerToken(fixtureClient.KubeClientset, utils.ArgoCDNamespace, serviceAccountName, common.BearerTokenTimeout)
|
||||
|
||||
// bearerToken
|
||||
secret := &corev1.Secret{
|
||||
|
||||
@@ -160,7 +160,8 @@ func init() {
|
||||
adminUsername = GetEnvWithDefault(EnvAdminUsername, defaultAdminUsername)
|
||||
AdminPassword = GetEnvWithDefault(EnvAdminPassword, defaultAdminPassword)
|
||||
|
||||
tlsTestResult, err := grpcutil.TestTLS(apiServerAddress)
|
||||
dialTime := 30 * time.Second
|
||||
tlsTestResult, err := grpcutil.TestTLS(apiServerAddress, dialTime)
|
||||
CheckError(err)
|
||||
|
||||
ArgoCDClientset, err = apiclient.NewClient(&apiclient.ClientOptions{Insecure: true, ServerAddr: apiServerAddress, PlainText: !tlsTestResult.TLS})
|
||||
@@ -357,6 +358,13 @@ func SetTrackingMethod(trackingMethod string) {
|
||||
})
|
||||
}
|
||||
|
||||
func SetTrackingLabel(trackingLabel string) {
|
||||
updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
|
||||
cm.Data["application.instanceLabelKey"] = trackingLabel
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func SetResourceOverridesSplitKeys(overrides map[string]v1alpha1.ResourceOverride) {
|
||||
updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
|
||||
for k, v := range overrides {
|
||||
|
||||
@@ -15,6 +15,7 @@ type Context struct {
|
||||
timeout int
|
||||
name string
|
||||
destination string
|
||||
repos []string
|
||||
}
|
||||
|
||||
func Given(t *testing.T) *Context {
|
||||
@@ -43,6 +44,11 @@ func (c *Context) Destination(destination string) *Context {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Context) SourceRepositories(repos []string) *Context {
|
||||
c.repos = repos
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Context) And(block func()) *Context {
|
||||
block()
|
||||
return c
|
||||
|
||||
@@ -171,7 +171,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- "true"
|
||||
image: "alpine:latest"
|
||||
image: "quay.io/argoprojlabs/argocd-e2e-container:0.1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: main
|
||||
restartPolicy: Never
|
||||
@@ -202,7 +202,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- "true"
|
||||
image: "alpine:latest"
|
||||
image: "quay.io/argoprojlabs/argocd-e2e-container:0.1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: main
|
||||
restartPolicy: Never
|
||||
@@ -218,7 +218,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- "false"
|
||||
image: "alpine:latest"
|
||||
image: "quay.io/argoprojlabs/argocd-e2e-container:0.1"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: main
|
||||
restartPolicy: Never
|
||||
|
||||
2
test/e2e/multiarch-container/Dockerfile
Normal file
2
test/e2e/multiarch-container/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM docker.io/library/busybox
|
||||
CMD exec sh -c "trap : TERM INT; echo 'Hi' && tail -f /dev/null"
|
||||
11
test/e2e/multiarch-container/build.sh
Executable file
11
test/e2e/multiarch-container/build.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
VERSIONS="0.1 0.2 0.3"
|
||||
PLATFORMS="linux/amd64,linux/arm64,linux/s390x,linux/ppc64le"
|
||||
for version in $VERSIONS; do
|
||||
docker buildx build \
|
||||
-t "quay.io/argoprojlabs/argocd-e2e-container:${version}" \
|
||||
--platform "${PLATFORMS}" \
|
||||
--push \
|
||||
.
|
||||
done
|
||||
2
test/e2e/testdata/cluster-role/pod.yaml
vendored
2
test/e2e/testdata/cluster-role/pod.yaml
vendored
@@ -5,7 +5,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.17.4-alpine
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
ports:
|
||||
- containerPort: "80"
|
||||
imagePullPolicy: IfNotPresent
|
||||
2
test/e2e/testdata/deployment/deployment.yaml
vendored
2
test/e2e/testdata/deployment/deployment.yaml
vendored
@@ -16,6 +16,6 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.17.4-alpine
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: extensions-deployment
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2"
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
@@ -14,13 +14,8 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: busybox
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
command:
|
||||
- sh
|
||||
args:
|
||||
- -c
|
||||
- "echo \"Hi\" && tail -f /dev/null"
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.3
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.3
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: nginx:1.17.4-alpine
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
|
||||
@@ -10,7 +10,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- "true"
|
||||
image: "alpine:3.10.2"
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: main
|
||||
restartPolicy: Never
|
||||
2
test/e2e/testdata/hook/hook.yaml
vendored
2
test/e2e/testdata/hook/hook.yaml
vendored
@@ -8,7 +8,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- "true"
|
||||
image: "alpine:latest"
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: main
|
||||
restartPolicy: Never
|
||||
2
test/e2e/testdata/hook/pod.yaml
vendored
2
test/e2e/testdata/hook/pod.yaml
vendored
@@ -5,7 +5,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:latest
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
2
test/e2e/testdata/kustomize/pod.yaml
vendored
2
test/e2e/testdata/kustomize/pod.yaml
vendored
@@ -5,7 +5,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
@@ -22,7 +22,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.17.4-alpine
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -39,7 +39,7 @@ spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [sh, -c, "sleep 10"]
|
||||
|
||||
@@ -56,6 +56,6 @@ spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [sh, -c, "sleep 10"]
|
||||
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: helm-guestbook
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2"
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
@@ -30,4 +30,4 @@ spec:
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
port: http
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: helm-guestbook
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2"
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -16,6 +16,6 @@ spec:
|
||||
containers:
|
||||
- name: main
|
||||
command: ["sleep", "999"]
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
|
||||
|
||||
2
test/e2e/testdata/two-nice-pods/pod-1.yaml
vendored
2
test/e2e/testdata/two-nice-pods/pod-1.yaml
vendored
@@ -5,7 +5,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: main
|
||||
image: alpine:3.10.2
|
||||
image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "true"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user