mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 09:38:49 +01:00
Compare commits
44 Commits
crenshaw-d
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0bd546a07 | ||
|
|
984829fcc8 | ||
|
|
c48e27f265 | ||
|
|
5fe1447b72 | ||
|
|
539516bd43 | ||
|
|
8a57d544ff | ||
|
|
cd77e2a048 | ||
|
|
a52f766815 | ||
|
|
646fd37e16 | ||
|
|
c74ca22023 | ||
|
|
2d170be242 | ||
|
|
079101522d | ||
|
|
1bea98e01b | ||
|
|
7c09221f7c | ||
|
|
6355e910d4 | ||
|
|
891e0320d7 | ||
|
|
486323ae58 | ||
|
|
4ef875aa0b | ||
|
|
e756b8db7a | ||
|
|
8023f8ac8d | ||
|
|
803408904a | ||
|
|
702f9095da | ||
|
|
0b9ee1ae6d | ||
|
|
2f003e08ff | ||
|
|
e090857d6b | ||
|
|
4e29fff5a3 | ||
|
|
e279377696 | ||
|
|
5e52839ce3 | ||
|
|
3ca632a552 | ||
|
|
cfe55357ac | ||
|
|
0f6d768eca | ||
|
|
75330da328 | ||
|
|
a1bcbab0e5 | ||
|
|
db9272032a | ||
|
|
d6d6c655ff | ||
|
|
58acc92790 | ||
|
|
c3074c0977 | ||
|
|
af254f3047 | ||
|
|
c140976eeb | ||
|
|
05c22d4ddc | ||
|
|
3e08938a20 | ||
|
|
5937bb574d | ||
|
|
ded55b26d1 | ||
|
|
d79ed65de0 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -22,17 +22,11 @@ Argo CD introduces Custom Resource Actions to allow users to provide their own L
|
||||
|
||||
* Remove deprecated componentParameterOverrides field #1372
|
||||
|
||||
### Changes since v0.12.1
|
||||
|
||||
#### New Features
|
||||
|
||||
+ Issue #357 - Expose application nodes networking information (#1333)
|
||||
+ Support for customizable resource actions as Lua scripts #86
|
||||
+ Surface Service/Ingress external IPs, hostname to application #908
|
||||
+ Update argocd-util import/export to support proper backup and restore (#1328)
|
||||
### Changes since v0.12.2
|
||||
|
||||
#### Enhancements
|
||||
|
||||
* `argocd app wait` should have `--resource` flag like sync #1206
|
||||
* Adds support for `kustomize edit set image`. Closes #1275 (#1324)
|
||||
* Allow wait to return on health or suspended (#1392)
|
||||
* Application warning when a manifest is defined twice #1070
|
||||
@@ -41,30 +35,32 @@ Argo CD introduces Custom Resource Actions to allow users to provide their own L
|
||||
* Display number of errors on resource tab #1477
|
||||
* Displays resources that are being deleted as "Progressing". Closes #1410 (#1426)
|
||||
* Generate random name for grpc proxy unix socket file instead of time stamp (#1455)
|
||||
* Issue #357 - Expose application nodes networking information (#1333)
|
||||
* Issue #1404 - App controller unnecessary set namespace to cluster level resources (#1405)
|
||||
* Nils health if the resource does not provide it. Closes #1383 (#1408)
|
||||
* Perform health assessments on all resource nodes in the tree. Closes #1382 (#1422)
|
||||
* Remove deprecated componentParameterOverrides field #1372
|
||||
* Shows the health of the application. Closes #1433 (#1434)
|
||||
* Surface Service/Ingress external IPs, hostname to application #908
|
||||
* Surface pod status to tree view #1358
|
||||
* Support for customizable resource actions as Lua scripts #86
|
||||
* UI / API Errors Truncated, Time Out #1386
|
||||
* UI Enhancement Proposals Quick Wins #1274
|
||||
* Update argocd-util import/export to support proper backup and restore (#1328)
|
||||
* Whitelisting repos/clusters in projects should consider repo/cluster permissions #1432
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- "bind: address already in use" after switching to gRPC-Web #1451
|
||||
- Annoying warning while using `--grpc-web` flag #1420
|
||||
- Don't compare secrets in the CLI, since argo-cd doesn't have access to their data (#1459)
|
||||
- Dropdown menu should not have sync item for unmanaged resources #1357
|
||||
- Fixes goroutine leak. Closes #1381 (#1457)
|
||||
- Improve input style #1217
|
||||
- Issue #1389 - Fix null pointer exception in secret normalization function (#1428)
|
||||
- Issue #1425 - Argo CD should not delete CRDs (#1428)
|
||||
- Issue #1446 - Delete helm temp directories (#1449)
|
||||
- Issue #908 - Surface Service/Ingress external IPs, hostname to application (#1347)
|
||||
- kustomization fields are all mandatory #1504
|
||||
- Resource node details is crashing if live resource is missing $1505
|
||||
- Rollback UI is not showing correct ksonnet parameters in preview #1326
|
||||
- See details of applications fails with "r.nodes is undefined" #1371
|
||||
- UI fails to load custom actions is resource is not deployed #1502
|
||||
- Unable to create app from private repo: x509: certificate signed by unknown authority #1171
|
||||
|
||||
## v0.12.2 (2019-04-22)
|
||||
|
||||
2
Gopkg.lock
generated
2
Gopkg.lock
generated
@@ -1496,7 +1496,7 @@
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:324305490fa0113cac244a48e648bf8a566f0a6e5e25c498e8c033a0b4e23c96"
|
||||
digest = "1:aae856b28533bfdb39112514290f7722d00a55a99d2d0b897c6ee82e6feb87b3"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = [
|
||||
"cmd/openapi-gen",
|
||||
|
||||
5
Makefile
5
Makefile
@@ -11,6 +11,8 @@ GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ;
|
||||
PACKR_CMD=$(shell if [ "`which packr`" ]; then echo "packr"; else echo "go run vendor/github.com/gobuffalo/packr/packr/main.go"; fi)
|
||||
TEST_CMD=$(shell [ "`which gotestsum`" != "" ] && echo gotestsum -- || echo go test)
|
||||
|
||||
PATH:=$(PATH):$(PWD)/hack
|
||||
|
||||
# docker image publishing options
|
||||
DOCKER_PUSH=false
|
||||
IMAGE_TAG=latest
|
||||
@@ -148,6 +150,7 @@ test-e2e: cli
|
||||
|
||||
.PHONY: start-e2e
|
||||
start-e2e: cli
|
||||
killall goreman || true
|
||||
kubectl create ns argocd-e2e || true
|
||||
kubens argocd-e2e
|
||||
kustomize build test/manifests/base | kubectl apply -f -
|
||||
@@ -178,4 +181,4 @@ release-precheck: manifests
|
||||
@if [ "$(GIT_TAG)" != "v`cat VERSION`" ]; then echo 'VERSION does not match git tag'; exit 1; fi
|
||||
|
||||
.PHONY: release
|
||||
release: release-precheck precheckin image release-cli
|
||||
release: release-precheck pre-commit image release-cli
|
||||
|
||||
2
Procfile
2
Procfile
@@ -2,4 +2,4 @@ controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/a
|
||||
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true go run ./cmd/argocd-server/main.go --loglevel debug --redis localhost:6379 --disable-auth --insecure --dex-server http://localhost:5556 --repo-server localhost:8081 --staticassets ../argo-cd-ui/dist/app"
|
||||
repo-server: sh -c "FORCE_LOG_COLORS=1 go run ./cmd/argocd-repo-server/main.go --loglevel debug --redis localhost:6379"
|
||||
dex: sh -c "go run ./cmd/argocd-util/main.go gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p 5556:5556 -v `pwd`/dist/dex.yaml:/dex.yaml quay.io/dexidp/dex:v2.14.0 serve /dex.yaml"
|
||||
redis: docker run --rm -i -p 6379:6379 redis:5.0.3-alpine --save "" --appendonly no
|
||||
redis: docker run --rm --name argocd-redis -i -p 6379:6379 redis:5.0.3-alpine --save ""--appendonly no
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
},
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "resourceVersion",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -212,6 +217,11 @@
|
||||
},
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "resourceVersion",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -777,33 +787,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/clusters-kubeconfig": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"ClusterService"
|
||||
],
|
||||
"summary": "CreateFromKubeConfig installs the argocd-manager service account into the cluster specified in the given kubeconfig and context",
|
||||
"operationId": "CreateFromKubeConfig",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clusterClusterCreateFromKubeConfigRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "(empty)",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1alpha1Cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/clusters/{cluster.server}": {
|
||||
"put": {
|
||||
"tags": [
|
||||
@@ -1387,6 +1370,11 @@
|
||||
},
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "resourceVersion",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -1540,25 +1528,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"clusterClusterCreateFromKubeConfigRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"context": {
|
||||
"type": "string"
|
||||
},
|
||||
"inCluster": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
"kubeconfig": {
|
||||
"type": "string"
|
||||
},
|
||||
"upsert": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clusterClusterResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
@@ -1598,6 +1567,12 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2651,13 +2626,6 @@
|
||||
"$ref": "#/definitions/v1alpha1ApplicationCondition"
|
||||
}
|
||||
},
|
||||
"externalURLs": {
|
||||
"description": "ExternalURLs holds all external URLs of application child resources.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"health": {
|
||||
"$ref": "#/definitions/v1alpha1HealthStatus"
|
||||
},
|
||||
@@ -2685,11 +2653,33 @@
|
||||
"sourceType": {
|
||||
"type": "string"
|
||||
},
|
||||
"summary": {
|
||||
"$ref": "#/definitions/v1alpha1ApplicationSummary"
|
||||
},
|
||||
"sync": {
|
||||
"$ref": "#/definitions/v1alpha1SyncStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1ApplicationSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"externalURLs": {
|
||||
"description": "ExternalURLs holds all external URLs of application child resources.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"description": "Images holds all images of application child resources.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1ApplicationTree": {
|
||||
"type": "object",
|
||||
"title": "ApplicationTree holds nodes which belongs to the application",
|
||||
|
||||
@@ -37,14 +37,15 @@ const (
|
||||
|
||||
func newCommand() *cobra.Command {
|
||||
var (
|
||||
clientConfig clientcmd.ClientConfig
|
||||
appResyncPeriod int64
|
||||
repoServerAddress string
|
||||
statusProcessors int
|
||||
operationProcessors int
|
||||
logLevel string
|
||||
glogLevel int
|
||||
cacheSrc func() (*cache.Cache, error)
|
||||
clientConfig clientcmd.ClientConfig
|
||||
appResyncPeriod int64
|
||||
repoServerAddress string
|
||||
repoServerTimeoutSeconds int
|
||||
statusProcessors int
|
||||
operationProcessors int
|
||||
logLevel string
|
||||
glogLevel int
|
||||
cacheSrc func() (*cache.Cache, error)
|
||||
)
|
||||
var command = cobra.Command{
|
||||
Use: cliName,
|
||||
@@ -54,9 +55,9 @@ func newCommand() *cobra.Command {
|
||||
cli.SetGLogLevel(glogLevel)
|
||||
|
||||
config, err := clientConfig.ClientConfig()
|
||||
errors.CheckError(err)
|
||||
config.QPS = common.K8sClientConfigQPS
|
||||
config.Burst = common.K8sClientConfigBurst
|
||||
errors.CheckError(err)
|
||||
|
||||
kubeClient := kubernetes.NewForConfigOrDie(config)
|
||||
appClient := appclientset.NewForConfigOrDie(config)
|
||||
@@ -65,7 +66,7 @@ func newCommand() *cobra.Command {
|
||||
errors.CheckError(err)
|
||||
|
||||
resyncDuration := time.Duration(appResyncPeriod) * time.Second
|
||||
repoClientset := reposerver.NewRepoServerClientset(repoServerAddress)
|
||||
repoClientset := reposerver.NewRepoServerClientset(repoServerAddress, repoServerTimeoutSeconds)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -98,6 +99,7 @@ func newCommand() *cobra.Command {
|
||||
clientConfig = cli.AddKubectlFlagsToCmd(&command)
|
||||
command.Flags().Int64Var(&appResyncPeriod, "app-resync", defaultAppResyncPeriod, "Time period in seconds for application resync.")
|
||||
command.Flags().StringVar(&repoServerAddress, "repo-server", common.DefaultRepoServerAddr, "Repo server address.")
|
||||
command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", 60, "Repo server RPC call timeout seconds.")
|
||||
command.Flags().IntVar(&statusProcessors, "status-processors", 1, "Number of application status processors")
|
||||
command.Flags().IntVar(&operationProcessors, "operation-processors", 1, "Number of application operation processors")
|
||||
command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
|
||||
|
||||
@@ -57,7 +57,7 @@ func NewCommand() *cobra.Command {
|
||||
|
||||
kubeclientset := kubernetes.NewForConfigOrDie(config)
|
||||
appclientset := appclientset.NewForConfigOrDie(config)
|
||||
repoclientset := reposerver.NewRepoServerClientset(repoServerAddress)
|
||||
repoclientset := reposerver.NewRepoServerClientset(repoServerAddress, 0)
|
||||
|
||||
argoCDOpts := server.ArgoCDServerOpts{
|
||||
Insecure: insecure,
|
||||
|
||||
@@ -957,6 +957,7 @@ func formatConditionsSummary(app argoappv1.Application) string {
|
||||
const (
|
||||
resourceFieldDelimiter = ":"
|
||||
resourceFieldCount = 3
|
||||
labelFieldDelimiter = "="
|
||||
)
|
||||
|
||||
func parseSelectedResources(resources []string) []argoappv1.SyncOperationResource {
|
||||
@@ -979,6 +980,21 @@ func parseSelectedResources(resources []string) []argoappv1.SyncOperationResourc
|
||||
return selectedResources
|
||||
}
|
||||
|
||||
func parseLabels(labels []string) (map[string]string, error) {
|
||||
var selectedLabels map[string]string
|
||||
if labels != nil {
|
||||
selectedLabels = map[string]string{}
|
||||
for _, r := range labels {
|
||||
fields := strings.Split(r, labelFieldDelimiter)
|
||||
if len(fields) != 2 {
|
||||
return nil, fmt.Errorf("labels should have key%svalue, but instead got: %s", labelFieldDelimiter, r)
|
||||
}
|
||||
selectedLabels[fields[0]] = fields[1]
|
||||
}
|
||||
}
|
||||
return selectedLabels, nil
|
||||
}
|
||||
|
||||
// NewApplicationWaitCommand returns a new instance of an `argocd app wait` command
|
||||
func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
var (
|
||||
@@ -1073,6 +1089,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
var (
|
||||
revision string
|
||||
resources []string
|
||||
labels []string
|
||||
prune bool
|
||||
dryRun bool
|
||||
timeout uint
|
||||
@@ -1091,8 +1108,51 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
conn, appIf := acdClient.NewApplicationClientOrDie()
|
||||
defer util.Close(conn)
|
||||
|
||||
selectedResources := parseSelectedResources(resources)
|
||||
appName := args[0]
|
||||
|
||||
selectedLabels, parseErr := parseLabels(labels)
|
||||
if parseErr != nil {
|
||||
log.Fatal(parseErr)
|
||||
}
|
||||
|
||||
if len(selectedLabels) > 0 {
|
||||
ctx := context.Background()
|
||||
|
||||
if revision == "" {
|
||||
revision = "HEAD"
|
||||
}
|
||||
|
||||
q := application.ApplicationManifestQuery{
|
||||
Name: &appName,
|
||||
Revision: revision,
|
||||
}
|
||||
|
||||
res, err := appIf.GetManifests(ctx, &q)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, mfst := range res.Manifests {
|
||||
obj, err := argoappv1.UnmarshalToUnstructured(mfst)
|
||||
errors.CheckError(err)
|
||||
for key, selectedValue := range selectedLabels {
|
||||
if objectValue, ok := obj.GetLabels()[key]; ok && selectedValue == objectValue {
|
||||
gvk := obj.GroupVersionKind()
|
||||
resources = append(resources, fmt.Sprintf("%s:%s:%s", gvk.Group, gvk.Kind, obj.GetName()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If labels are provided and none are found return error only if specific resources were also not
|
||||
// specified.
|
||||
if len(resources) == 0 {
|
||||
log.Fatalf("No matching resources found for labels: %v", labels)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
selectedResources := parseSelectedResources(resources)
|
||||
|
||||
syncReq := application.ApplicationSyncRequest{
|
||||
Name: &appName,
|
||||
DryRun: dryRun,
|
||||
@@ -1117,18 +1177,21 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
app, err := waitOnApplicationStatus(acdClient, appName, timeout, false, false, true, false, selectedResources)
|
||||
errors.CheckError(err)
|
||||
|
||||
pruningRequired := 0
|
||||
for _, resDetails := range app.Status.OperationState.SyncResult.Resources {
|
||||
if resDetails.Status == argoappv1.ResultCodePruneSkipped {
|
||||
pruningRequired++
|
||||
// Only get resources to be pruned if sync was application-wide
|
||||
if len(selectedResources) == 0 {
|
||||
pruningRequired := 0
|
||||
for _, resDetails := range app.Status.OperationState.SyncResult.Resources {
|
||||
if resDetails.Status == argoappv1.ResultCodePruneSkipped {
|
||||
pruningRequired++
|
||||
}
|
||||
}
|
||||
if pruningRequired > 0 {
|
||||
log.Fatalf("%d resources require pruning", pruningRequired)
|
||||
}
|
||||
}
|
||||
if pruningRequired > 0 {
|
||||
log.Fatalf("%d resources require pruning", pruningRequired)
|
||||
}
|
||||
|
||||
if !app.Status.OperationState.Phase.Successful() && !dryRun {
|
||||
os.Exit(1)
|
||||
if !app.Status.OperationState.Phase.Successful() && !dryRun {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -1136,6 +1199,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
command.Flags().BoolVar(&prune, "prune", false, "Allow deleting unexpected resources")
|
||||
command.Flags().StringVar(&revision, "revision", "", "Sync to a specific revision. Preserves parameter overrides")
|
||||
command.Flags().StringArrayVar(&resources, "resource", []string{}, fmt.Sprintf("Sync only specific resources as GROUP%sKIND%sNAME. Fields may be blank. This option may be specified repeatedly", resourceFieldDelimiter, resourceFieldDelimiter))
|
||||
command.Flags().StringArrayVar(&labels, "label", []string{}, fmt.Sprintf("Sync only specific resources with a label. This option may be specified repeatedly."))
|
||||
command.Flags().UintVar(&timeout, "timeout", defaultCheckTimeoutSeconds, "Time out after this many seconds")
|
||||
command.Flags().StringVar(&strategy, "strategy", "", "Sync strategy (one of: apply|hook)")
|
||||
command.Flags().BoolVar(&force, "force", false, "Use a force apply")
|
||||
|
||||
25
cmd/argocd/commands/app_test.go
Normal file
25
cmd/argocd/commands/app_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseLabels(t *testing.T) {
|
||||
validLabels := []string{"key=value", "foo=bar", "intuit=inc"}
|
||||
|
||||
result, err := parseLabels(validLabels)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, result, 3)
|
||||
|
||||
invalidLabels := []string{"key=value", "too=many=equals"}
|
||||
_, err = parseLabels(invalidLabels)
|
||||
assert.Error(t, err)
|
||||
|
||||
emptyLabels := []string{}
|
||||
result, err = parseLabels(emptyLabels)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, result, 0)
|
||||
|
||||
}
|
||||
@@ -154,20 +154,8 @@ func NewCluster(name string, conf *rest.Config, managerBearerToken string, awsAu
|
||||
tlsClientConfig := argoappv1.TLSClientConfig{
|
||||
Insecure: conf.TLSClientConfig.Insecure,
|
||||
ServerName: conf.TLSClientConfig.ServerName,
|
||||
CertData: conf.TLSClientConfig.CertData,
|
||||
KeyData: conf.TLSClientConfig.KeyData,
|
||||
CAData: conf.TLSClientConfig.CAData,
|
||||
}
|
||||
if len(conf.TLSClientConfig.CertData) == 0 && conf.TLSClientConfig.CertFile != "" {
|
||||
data, err := ioutil.ReadFile(conf.TLSClientConfig.CertFile)
|
||||
errors.CheckError(err)
|
||||
tlsClientConfig.CertData = data
|
||||
}
|
||||
if len(conf.TLSClientConfig.KeyData) == 0 && conf.TLSClientConfig.KeyFile != "" {
|
||||
data, err := ioutil.ReadFile(conf.TLSClientConfig.KeyFile)
|
||||
errors.CheckError(err)
|
||||
tlsClientConfig.KeyData = data
|
||||
}
|
||||
if len(conf.TLSClientConfig.CAData) == 0 && conf.TLSClientConfig.CAFile != "" {
|
||||
data, err := ioutil.ReadFile(conf.TLSClientConfig.CAFile)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -68,7 +68,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
// See issue #315
|
||||
err := git.TestRepo(repo.Repo, "", "", repo.SSHPrivateKey, repo.InsecureIgnoreHostKey)
|
||||
if err != nil {
|
||||
if git.IsSSHURL(repo.Repo) {
|
||||
if yes, _ := git.IsSSHURL(repo.Repo); yes {
|
||||
// If we failed using git SSH credentials, then the repo is automatically bad
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -110,21 +112,43 @@ func NewApplicationController(
|
||||
}
|
||||
appInformer, appLister := ctrl.newApplicationInformerAndLister()
|
||||
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, cache.Indexers{})
|
||||
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settings, kubectlCmd, func(appName string, fullRefresh bool) {
|
||||
ctrl.requestAppRefresh(appName, fullRefresh)
|
||||
ctrl.appRefreshQueue.Add(fmt.Sprintf("%s/%s", ctrl.namespace, appName))
|
||||
})
|
||||
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectlCmd, ctrl.settings, stateCache, projInformer)
|
||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", common.PortArgoCDMetrics)
|
||||
ctrl.metricsServer = metrics.NewMetricsServer(metricsAddr, appLister)
|
||||
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settings, kubectlCmd, ctrl.metricsServer, ctrl.handleAppUpdated)
|
||||
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectlCmd, ctrl.settings, stateCache, projInformer, ctrl.metricsServer)
|
||||
ctrl.appInformer = appInformer
|
||||
ctrl.appLister = appLister
|
||||
ctrl.projInformer = projInformer
|
||||
ctrl.appStateManager = appStateManager
|
||||
ctrl.stateCache = stateCache
|
||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", common.PortArgoCDMetrics)
|
||||
ctrl.metricsServer = metrics.NewMetricsServer(metricsAddr, ctrl.appLister)
|
||||
|
||||
return &ctrl, nil
|
||||
}
|
||||
|
||||
func isSelfReferencedApp(app *appv1.Application, ref v1.ObjectReference) bool {
|
||||
gvk := ref.GroupVersionKind()
|
||||
return ref.UID == app.UID &&
|
||||
ref.Name == app.Name &&
|
||||
ref.Namespace == app.Namespace &&
|
||||
gvk.Group == application.Group &&
|
||||
gvk.Kind == application.ApplicationKind
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) handleAppUpdated(appName string, fullRefresh bool, ref v1.ObjectReference) {
|
||||
skipForceRefresh := false
|
||||
|
||||
obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(ctrl.namespace + "/" + appName)
|
||||
if app, ok := obj.(*appv1.Application); exists && err == nil && ok && isSelfReferencedApp(app, ref) {
|
||||
// Don't force refresh app if related resource is application itself. This prevents infinite reconciliation loop.
|
||||
skipForceRefresh = true
|
||||
}
|
||||
|
||||
if !skipForceRefresh {
|
||||
ctrl.requestAppRefresh(appName, fullRefresh)
|
||||
}
|
||||
ctrl.appRefreshQueue.Add(fmt.Sprintf("%s/%s", ctrl.namespace, appName))
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) setAppManagedResources(a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) {
|
||||
managedResources, err := ctrl.managedResources(a, comparisonResult)
|
||||
if err != nil {
|
||||
@@ -327,6 +351,10 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b
|
||||
return
|
||||
}
|
||||
|
||||
func shouldBeDeleted(app *appv1.Application, obj *unstructured.Unstructured) bool {
|
||||
return !kube.IsCRD(obj) && !isSelfReferencedApp(app, kube.GetObjectRef(obj))
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Application) error {
|
||||
logCtx := log.WithField("application", app.Name)
|
||||
logCtx.Infof("Deleting resources")
|
||||
@@ -345,13 +373,20 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic
|
||||
}
|
||||
objs := make([]*unstructured.Unstructured, 0)
|
||||
for k := range objsMap {
|
||||
if objsMap[k].GetDeletionTimestamp() == nil && !kube.IsCRD(objsMap[k]) {
|
||||
if objsMap[k].GetDeletionTimestamp() == nil && shouldBeDeleted(app, objsMap[k]) {
|
||||
objs = append(objs, objsMap[k])
|
||||
}
|
||||
}
|
||||
|
||||
cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, cluster.RESTConfig())
|
||||
|
||||
err = util.RunAllAsync(len(objs), func(i int) error {
|
||||
obj := objs[i]
|
||||
return ctrl.stateCache.Delete(app.Spec.Destination.Server, obj)
|
||||
return ctrl.kubectl.DeleteResource(config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), false)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -361,6 +396,11 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, obj := range objsMap {
|
||||
if !shouldBeDeleted(app, obj) {
|
||||
delete(objsMap, k)
|
||||
}
|
||||
}
|
||||
if len(objsMap) > 0 {
|
||||
logCtx.Infof("%d objects remaining for deletion", len(objsMap))
|
||||
return nil
|
||||
@@ -589,7 +629,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
if tree, err := ctrl.getResourceTree(app, managedResources); err != nil {
|
||||
app.Status.Conditions = []appv1.ApplicationCondition{{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}}
|
||||
} else {
|
||||
app.Status.ExternalURLs = tree.GetBrowableURLs()
|
||||
app.Status.Summary = tree.GetSummary()
|
||||
if err = ctrl.cache.SetAppResourcesTree(app.Name, tree); err != nil {
|
||||
logCtx.Errorf("Failed to cache resources tree: %v", err)
|
||||
return
|
||||
@@ -621,7 +661,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
if err != nil {
|
||||
logCtx.Errorf("Failed to cache app resources: %v", err)
|
||||
} else {
|
||||
app.Status.ExternalURLs = tree.GetBrowableURLs()
|
||||
app.Status.Summary = tree.GetSummary()
|
||||
}
|
||||
|
||||
syncErrCond := ctrl.autoSync(app, compareResult.syncStatus)
|
||||
@@ -688,7 +728,7 @@ func (ctrl *ApplicationController) refreshAppConditions(app *appv1.Application)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
specConditions, _, err := argo.GetSpecErrors(context.Background(), &app.Spec, proj, ctrl.repoClientset, ctrl.db)
|
||||
specConditions, err := argo.ValidatePermissions(context.Background(), &app.Spec, proj, ctrl.db)
|
||||
if err != nil {
|
||||
conditions = append(conditions, appv1.ApplicationCondition{
|
||||
Type: appv1.ApplicationConditionUnknownError,
|
||||
@@ -927,6 +967,7 @@ func (ctrl *ApplicationController) watchSettings(ctx context.Context) {
|
||||
ctrl.settingsMgr.Subscribe(updateCh)
|
||||
prevAppLabelKey := ctrl.settings.GetAppInstanceLabelKey()
|
||||
prevResourceExclusions := ctrl.settings.ResourceExclusions
|
||||
prevResourceInclusions := ctrl.settings.ResourceInclusions
|
||||
done := false
|
||||
for !done {
|
||||
select {
|
||||
@@ -939,10 +980,15 @@ func (ctrl *ApplicationController) watchSettings(ctx context.Context) {
|
||||
prevAppLabelKey = newAppLabelKey
|
||||
}
|
||||
if !reflect.DeepEqual(prevResourceExclusions, newSettings.ResourceExclusions) {
|
||||
log.Infof("resource exclusions modified")
|
||||
log.WithFields(log.Fields{"prevResourceExclusions": prevResourceExclusions, "newResourceExclusions": newSettings.ResourceExclusions}).Info("resource exclusions modified")
|
||||
ctrl.stateCache.Invalidate()
|
||||
prevResourceExclusions = newSettings.ResourceExclusions
|
||||
}
|
||||
if !reflect.DeepEqual(prevResourceInclusions, newSettings.ResourceInclusions) {
|
||||
log.WithFields(log.Fields{"prevResourceInclusions": prevResourceInclusions, "newResourceInclusions": newSettings.ResourceInclusions}).Info("resource inclusions modified")
|
||||
ctrl.stateCache.Invalidate()
|
||||
prevResourceInclusions = newSettings.ResourceInclusions
|
||||
}
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@@ -119,6 +121,7 @@ var fakeApp = `
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
uid: "123"
|
||||
name: my-app
|
||||
namespace: ` + test.FakeArgoCDNamespace + `
|
||||
spec:
|
||||
@@ -353,20 +356,26 @@ func TestAutoSyncParameterOverrides(t *testing.T) {
|
||||
// TestFinalizeAppDeletion verifies application deletion
|
||||
func TestFinalizeAppDeletion(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}})
|
||||
app.Spec.Destination.Namespace = test.FakeArgoCDNamespace
|
||||
appObj := kube.MustToUnstructured(&app)
|
||||
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(appObj): appObj,
|
||||
}})
|
||||
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
patched := false
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
defaultReactor := fakeAppCs.ReactionChain[0]
|
||||
fakeAppCs.ReactionChain = nil
|
||||
fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return defaultReactor.React(action)
|
||||
})
|
||||
fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
patched = true
|
||||
return true, nil, nil
|
||||
})
|
||||
err := ctrl.finalizeApplicationDeletion(app)
|
||||
// TODO: use an interface to fake out the calls to GetResourcesWithLabel and DeleteResourceWithLabel
|
||||
// For now just ensure we have an expected error condition
|
||||
assert.Error(t, err) // Change this to assert.Nil when we stub out GetResourcesWithLabel/DeleteResourceWithLabel
|
||||
assert.False(t, patched) // Change this to assert.True when we stub out GetResourcesWithLabel/DeleteResourceWithLabel
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, patched)
|
||||
}
|
||||
|
||||
// TestNormalizeApplication verifies we normalize an application during reconciliation
|
||||
@@ -442,3 +451,18 @@ func TestNormalizeApplication(t *testing.T) {
|
||||
assert.False(t, normalized)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleAppUpdated(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.Destination.Namespace = test.FakeArgoCDNamespace
|
||||
app.Spec.Destination.Server = common.KubernetesInternalAPIServerAddr
|
||||
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}})
|
||||
|
||||
ctrl.handleAppUpdated(app.Name, true, kube.GetObjectRef(kube.MustToUnstructured(app)))
|
||||
isRequested, _ := ctrl.isRefreshRequested(app.Name)
|
||||
assert.False(t, isRequested)
|
||||
|
||||
ctrl.handleAppUpdated(app.Name, true, corev1.ObjectReference{UID: "test", Kind: kube.DeploymentKind, Name: "test", Namespace: "default"})
|
||||
isRequested, _ = ctrl.isRefreshRequested(app.Name)
|
||||
assert.True(t, isRequested)
|
||||
}
|
||||
|
||||
55
controller/cache/cache.go
vendored
55
controller/cache/cache.go
vendored
@@ -5,11 +5,13 @@ import (
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"github.com/argoproj/argo-cd/controller/metrics"
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
"github.com/argoproj/argo-cd/util/db"
|
||||
@@ -25,12 +27,12 @@ type LiveStateCache interface {
|
||||
GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)
|
||||
// Starts watching resources of each controlled cluster.
|
||||
Run(ctx context.Context)
|
||||
// Deletes specified resource from cluster.
|
||||
Delete(server string, obj *unstructured.Unstructured) error
|
||||
// Invalidate invalidates the entire cluster state cache
|
||||
Invalidate()
|
||||
}
|
||||
|
||||
type AppUpdatedHandler = func(appName string, fullRefresh bool, ref v1.ObjectReference)
|
||||
|
||||
func GetTargetObjKey(a *appv1.Application, un *unstructured.Unstructured, isNamespaced bool) kube.ResourceKey {
|
||||
key := kube.GetResourceKey(un)
|
||||
if !isNamespaced {
|
||||
@@ -42,26 +44,35 @@ func GetTargetObjKey(a *appv1.Application, un *unstructured.Unstructured, isName
|
||||
return key
|
||||
}
|
||||
|
||||
func NewLiveStateCache(db db.ArgoDB, appInformer cache.SharedIndexInformer, settings *settings.ArgoCDSettings, kubectl kube.Kubectl, onAppUpdated func(appName string, fullRefresh bool)) LiveStateCache {
|
||||
func NewLiveStateCache(
|
||||
db db.ArgoDB,
|
||||
appInformer cache.SharedIndexInformer,
|
||||
settings *settings.ArgoCDSettings,
|
||||
kubectl kube.Kubectl,
|
||||
metricsServer *metrics.MetricsServer,
|
||||
onAppUpdated AppUpdatedHandler) LiveStateCache {
|
||||
|
||||
return &liveStateCache{
|
||||
appInformer: appInformer,
|
||||
db: db,
|
||||
clusters: make(map[string]*clusterInfo),
|
||||
lock: &sync.Mutex{},
|
||||
onAppUpdated: onAppUpdated,
|
||||
kubectl: kubectl,
|
||||
settings: settings,
|
||||
appInformer: appInformer,
|
||||
db: db,
|
||||
clusters: make(map[string]*clusterInfo),
|
||||
lock: &sync.Mutex{},
|
||||
onAppUpdated: onAppUpdated,
|
||||
kubectl: kubectl,
|
||||
settings: settings,
|
||||
metricsServer: metricsServer,
|
||||
}
|
||||
}
|
||||
|
||||
type liveStateCache struct {
|
||||
db db.ArgoDB
|
||||
clusters map[string]*clusterInfo
|
||||
lock *sync.Mutex
|
||||
appInformer cache.SharedIndexInformer
|
||||
onAppUpdated func(appName string, fullRefresh bool)
|
||||
kubectl kube.Kubectl
|
||||
settings *settings.ArgoCDSettings
|
||||
db db.ArgoDB
|
||||
clusters map[string]*clusterInfo
|
||||
lock *sync.Mutex
|
||||
appInformer cache.SharedIndexInformer
|
||||
onAppUpdated AppUpdatedHandler
|
||||
kubectl kube.Kubectl
|
||||
settings *settings.ArgoCDSettings
|
||||
metricsServer *metrics.MetricsServer
|
||||
}
|
||||
|
||||
func (c *liveStateCache) getCluster(server string) (*clusterInfo, error) {
|
||||
@@ -116,14 +127,6 @@ func (c *liveStateCache) Invalidate() {
|
||||
log.Info("live state cache invalidated")
|
||||
}
|
||||
|
||||
func (c *liveStateCache) Delete(server string, obj *unstructured.Unstructured) error {
|
||||
clusterInfo, err := c.getSyncedCluster(server)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clusterInfo.delete(obj)
|
||||
}
|
||||
|
||||
func (c *liveStateCache) IsNamespaced(server string, obj *unstructured.Unstructured) (bool, error) {
|
||||
clusterInfo, err := c.getSyncedCluster(server)
|
||||
if err != nil {
|
||||
@@ -146,7 +149,7 @@ func (c *liveStateCache) GetManagedLiveObjs(a *appv1.Application, targetObjs []*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clusterInfo.getManagedLiveObjs(a, targetObjs)
|
||||
return clusterInfo.getManagedLiveObjs(a, targetObjs, c.metricsServer)
|
||||
}
|
||||
|
||||
func isClusterHasApps(apps []interface{}, cluster *appv1.Cluster) bool {
|
||||
|
||||
41
controller/cache/cluster.go
vendored
41
controller/cache/cluster.go
vendored
@@ -7,8 +7,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/controller/metrics"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -44,7 +45,7 @@ type clusterInfo struct {
|
||||
nodes map[kube.ResourceKey]*node
|
||||
nsIndex map[string]map[kube.ResourceKey]*node
|
||||
|
||||
onAppUpdated func(appName string, fullRefresh bool)
|
||||
onAppUpdated AppUpdatedHandler
|
||||
kubectl kube.Kubectl
|
||||
cluster *appv1.Cluster
|
||||
log *log.Entry
|
||||
@@ -93,13 +94,8 @@ func (c *clusterInfo) createObjInfo(un *unstructured.Unstructured, appInstanceLa
|
||||
}
|
||||
nodeInfo := &node{
|
||||
resourceVersion: un.GetResourceVersion(),
|
||||
ref: v1.ObjectReference{
|
||||
APIVersion: un.GetAPIVersion(),
|
||||
Kind: un.GetKind(),
|
||||
Name: un.GetName(),
|
||||
Namespace: un.GetNamespace(),
|
||||
},
|
||||
ownerRefs: ownerRefs,
|
||||
ref: kube.GetObjectRef(un),
|
||||
ownerRefs: ownerRefs,
|
||||
}
|
||||
populateNodeInfo(un, nodeInfo)
|
||||
appName := kube.GetAppInstanceLabel(un, appInstanceLabel)
|
||||
@@ -351,7 +347,7 @@ func (c *clusterInfo) isNamespaced(obj *unstructured.Unstructured) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) {
|
||||
func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured, metricsServer *metrics.MetricsServer) (map[kube.ResourceKey]*unstructured.Unstructured, error) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
@@ -362,6 +358,7 @@ func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*uns
|
||||
managedObjs[key] = o.resource
|
||||
}
|
||||
}
|
||||
config := metrics.AddMetricsTransportWrapper(metricsServer, a, c.cluster.RESTConfig())
|
||||
// iterate target objects and identify ones that already exist in the cluster,\
|
||||
// but are simply missing our label
|
||||
lock := &sync.Mutex{}
|
||||
@@ -378,7 +375,7 @@ func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*uns
|
||||
managedObj = existingObj.resource
|
||||
} else {
|
||||
var err error
|
||||
managedObj, err = c.kubectl.GetResource(c.cluster.RESTConfig(), targetObj.GroupVersionKind(), existingObj.ref.Name, existingObj.ref.Namespace)
|
||||
managedObj, err = c.kubectl.GetResource(config, targetObj.GroupVersionKind(), existingObj.ref.Name, existingObj.ref.Namespace)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil
|
||||
@@ -390,9 +387,19 @@ func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*uns
|
||||
}
|
||||
|
||||
if managedObj != nil {
|
||||
managedObj, err := c.kubectl.ConvertToVersion(managedObj, targetObj.GroupVersionKind().Group, targetObj.GroupVersionKind().Version)
|
||||
converted, err := c.kubectl.ConvertToVersion(managedObj, targetObj.GroupVersionKind().Group, targetObj.GroupVersionKind().Version)
|
||||
if err != nil {
|
||||
return err
|
||||
// fallback to loading resource from kubernetes if conversion fails
|
||||
log.Warnf("Failed to convert resource: %v", err)
|
||||
managedObj, err = c.kubectl.GetResource(config, targetObj.GroupVersionKind(), managedObj.GetName(), managedObj.GetNamespace())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
managedObj = converted
|
||||
}
|
||||
lock.Lock()
|
||||
managedObjs[key] = managedObj
|
||||
@@ -407,10 +414,6 @@ func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*uns
|
||||
return managedObjs, nil
|
||||
}
|
||||
|
||||
func (c *clusterInfo) delete(obj *unstructured.Unstructured) error {
|
||||
return c.kubectl.DeleteResource(c.cluster.RESTConfig(), obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), false)
|
||||
}
|
||||
|
||||
func (c *clusterInfo) processEvent(event watch.EventType, un *unstructured.Unstructured) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
@@ -447,7 +450,7 @@ func (c *clusterInfo) onNodeUpdated(exists bool, existingNode *node, un *unstruc
|
||||
}
|
||||
}
|
||||
for name, full := range toNotify {
|
||||
c.onAppUpdated(name, full)
|
||||
c.onAppUpdated(name, full, newObj.ref)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +462,7 @@ func (c *clusterInfo) onNodeRemoved(key kube.ResourceKey, n *node) {
|
||||
|
||||
c.removeNode(key)
|
||||
if appName != "" {
|
||||
c.onAppUpdated(appName, n.isRootAppNode())
|
||||
c.onAppUpdated(appName, n.isRootAppNode(), n.ref)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
controller/cache/cluster_test.go
vendored
10
controller/cache/cluster_test.go
vendored
@@ -107,6 +107,10 @@ var (
|
||||
serviceName: helm-guestbook
|
||||
servicePort: 443
|
||||
path: /
|
||||
- backend:
|
||||
serviceName: helm-guestbook
|
||||
servicePort: https
|
||||
path: /
|
||||
status:
|
||||
loadBalancer:
|
||||
ingress:
|
||||
@@ -142,7 +146,7 @@ func newClusterExt(kubectl kube.Kubectl) *clusterInfo {
|
||||
return &clusterInfo{
|
||||
lock: &sync.Mutex{},
|
||||
nodes: make(map[kube.ResourceKey]*node),
|
||||
onAppUpdated: func(appName string, fullRefresh bool) {},
|
||||
onAppUpdated: func(appName string, fullRefresh bool, reference corev1.ObjectReference) {},
|
||||
kubectl: kubectl,
|
||||
nsIndex: make(map[string]map[kube.ResourceKey]*node),
|
||||
cluster: &appv1.Cluster{},
|
||||
@@ -225,7 +229,7 @@ metadata:
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
}, []*unstructured.Unstructured{targetDeploy})
|
||||
}, []*unstructured.Unstructured{targetDeploy}, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, managedObjs, map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.NewResourceKey("apps", "Deployment", "default", "helm-guestbook"): testDeploy,
|
||||
@@ -351,7 +355,7 @@ func TestUpdateResourceTags(t *testing.T) {
|
||||
func TestUpdateAppResource(t *testing.T) {
|
||||
updatesReceived := make([]string, 0)
|
||||
cluster := newCluster(testPod, testRS, testDeploy)
|
||||
cluster.onAppUpdated = func(appName string, fullRefresh bool) {
|
||||
cluster.onAppUpdated = func(appName string, fullRefresh bool, _ corev1.ObjectReference) {
|
||||
updatesReceived = append(updatesReceived, fmt.Sprintf("%s: %v", appName, fullRefresh))
|
||||
}
|
||||
|
||||
|
||||
63
controller/cache/info.go
vendored
63
controller/cache/info.go
vendored
@@ -9,6 +9,7 @@ import (
|
||||
k8snode "k8s.io/kubernetes/pkg/util/node"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
"github.com/argoproj/argo-cd/util/kube"
|
||||
)
|
||||
|
||||
@@ -63,14 +64,15 @@ func populateServiceInfo(un *unstructured.Unstructured, node *node) {
|
||||
}
|
||||
|
||||
func populateIngressInfo(un *unstructured.Unstructured, node *node) {
|
||||
targets := make([]v1alpha1.ResourceRef, 0)
|
||||
ingress := getIngress(un)
|
||||
targetsMap := make(map[v1alpha1.ResourceRef]bool)
|
||||
if backend, ok, err := unstructured.NestedMap(un.Object, "spec", "backend"); ok && err == nil {
|
||||
targets = append(targets, v1alpha1.ResourceRef{
|
||||
targetsMap[v1alpha1.ResourceRef{
|
||||
Group: "",
|
||||
Kind: kube.ServiceKind,
|
||||
Namespace: un.GetNamespace(),
|
||||
Name: fmt.Sprintf("%s", backend["serviceName"]),
|
||||
})
|
||||
}] = true
|
||||
}
|
||||
urlsSet := make(map[string]bool)
|
||||
if rules, ok, err := unstructured.NestedSlice(un.Object, "spec", "rules"); ok && err == nil {
|
||||
@@ -80,6 +82,14 @@ func populateIngressInfo(un *unstructured.Unstructured, node *node) {
|
||||
continue
|
||||
}
|
||||
host := rule["host"]
|
||||
if host == nil || host == "" {
|
||||
for i := range ingress {
|
||||
host = util.FirstNonEmpty(ingress[i].Hostname, ingress[i].IP)
|
||||
if host != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
paths, ok, err := unstructured.NestedSlice(rule, "http", "paths")
|
||||
if !ok || err != nil {
|
||||
continue
|
||||
@@ -91,32 +101,48 @@ func populateIngressInfo(un *unstructured.Unstructured, node *node) {
|
||||
}
|
||||
|
||||
if serviceName, ok, err := unstructured.NestedString(path, "backend", "serviceName"); ok && err == nil {
|
||||
targets = append(targets, v1alpha1.ResourceRef{
|
||||
targetsMap[v1alpha1.ResourceRef{
|
||||
Group: "",
|
||||
Kind: kube.ServiceKind,
|
||||
Namespace: un.GetNamespace(),
|
||||
Name: serviceName,
|
||||
})
|
||||
}] = true
|
||||
}
|
||||
|
||||
if port, ok, err := unstructured.NestedFieldNoCopy(path, "backend", "servicePort"); ok && err == nil && host != "" {
|
||||
switch fmt.Sprintf("%v", port) {
|
||||
case "80":
|
||||
if port, ok, err := unstructured.NestedFieldNoCopy(path, "backend", "servicePort"); ok && err == nil && host != "" && host != nil {
|
||||
stringPort := ""
|
||||
switch typedPod := port.(type) {
|
||||
case int64:
|
||||
stringPort = fmt.Sprintf("%d", typedPod)
|
||||
case float64:
|
||||
stringPort = fmt.Sprintf("%d", int64(typedPod))
|
||||
case string:
|
||||
stringPort = typedPod
|
||||
default:
|
||||
stringPort = fmt.Sprintf("%v", port)
|
||||
}
|
||||
|
||||
switch stringPort {
|
||||
case "80", "http":
|
||||
urlsSet[fmt.Sprintf("http://%s", host)] = true
|
||||
case "443":
|
||||
case "443", "https":
|
||||
urlsSet[fmt.Sprintf("https://%s", host)] = true
|
||||
default:
|
||||
urlsSet[fmt.Sprintf("http://%s:%s", host, port)] = true
|
||||
urlsSet[fmt.Sprintf("http://%s:%s", host, stringPort)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targets := make([]v1alpha1.ResourceRef, 0)
|
||||
for target := range targetsMap {
|
||||
targets = append(targets, target)
|
||||
}
|
||||
urls := make([]string, 0)
|
||||
for url := range urlsSet {
|
||||
urls = append(urls, url)
|
||||
}
|
||||
node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, Ingress: getIngress(un), ExternalURLs: urls}
|
||||
node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, Ingress: ingress, ExternalURLs: urls}
|
||||
}
|
||||
|
||||
func populatePodInfo(un *unstructured.Unstructured, node *node) {
|
||||
@@ -135,13 +161,20 @@ func populatePodInfo(un *unstructured.Unstructured, node *node) {
|
||||
reason = pod.Status.Reason
|
||||
}
|
||||
|
||||
initializing := false
|
||||
|
||||
// note that I ignore initContainers
|
||||
imagesSet := make(map[string]bool)
|
||||
for _, container := range pod.Spec.InitContainers {
|
||||
imagesSet[container.Image] = true
|
||||
}
|
||||
for _, container := range pod.Spec.Containers {
|
||||
node.images = append(node.images, container.Image)
|
||||
imagesSet[container.Image] = true
|
||||
}
|
||||
|
||||
node.images = nil
|
||||
for image := range imagesSet {
|
||||
node.images = append(node.images, image)
|
||||
}
|
||||
|
||||
initializing := false
|
||||
for i := range pod.Status.InitContainerStatuses {
|
||||
container := pod.Status.InitContainerStatuses[i]
|
||||
restarts += int(container.RestartCount)
|
||||
|
||||
40
controller/cache/info_test.go
vendored
40
controller/cache/info_test.go
vendored
@@ -1,6 +1,8 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -50,6 +52,9 @@ func TestGetIngressInfo(t *testing.T) {
|
||||
node := &node{}
|
||||
populateNodeInfo(testIngress, node)
|
||||
assert.Equal(t, 0, len(node.info))
|
||||
sort.Slice(node.networkingInfo.TargetRefs, func(i, j int) bool {
|
||||
return strings.Compare(node.networkingInfo.TargetRefs[j].Name, node.networkingInfo.TargetRefs[i].Name) < 0
|
||||
})
|
||||
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
|
||||
Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
|
||||
TargetRefs: []v1alpha1.ResourceRef{{
|
||||
@@ -66,3 +71,38 @@ func TestGetIngressInfo(t *testing.T) {
|
||||
ExternalURLs: []string{"https://helm-guestbook.com"},
|
||||
}, node.networkingInfo)
|
||||
}
|
||||
|
||||
func TestGetIngressInfoNoHost(t *testing.T) {
|
||||
ingress := strToUnstructured(`
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: helm-guestbook
|
||||
namespace: default
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: helm-guestbook
|
||||
servicePort: 443
|
||||
path: /
|
||||
status:
|
||||
loadBalancer:
|
||||
ingress:
|
||||
- ip: 107.178.210.11`)
|
||||
|
||||
node := &node{}
|
||||
populateNodeInfo(ingress, node)
|
||||
|
||||
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
|
||||
Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
|
||||
TargetRefs: []v1alpha1.ResourceRef{{
|
||||
Namespace: "default",
|
||||
Group: "",
|
||||
Kind: kube.ServiceKind,
|
||||
Name: "helm-guestbook",
|
||||
}},
|
||||
ExternalURLs: []string{"https://107.178.210.11"},
|
||||
}, node.networkingInfo)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package metrics
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
type MetricsServer struct {
|
||||
*http.Server
|
||||
syncCounter *prometheus.CounterVec
|
||||
k8sRequestCounter *prometheus.CounterVec
|
||||
reconcileHistogram *prometheus.HistogramVec
|
||||
}
|
||||
|
||||
@@ -72,6 +74,14 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister) *Metri
|
||||
append(descAppDefaultLabels, "phase"),
|
||||
)
|
||||
appRegistry.MustRegister(syncCounter)
|
||||
k8sRequestCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "argocd_app_k8s_request_total",
|
||||
Help: "Number of kubernetes requests executed during application reconciliation.",
|
||||
},
|
||||
append(descAppDefaultLabels, "response_code"),
|
||||
)
|
||||
appRegistry.MustRegister(k8sRequestCounter)
|
||||
|
||||
reconcileHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
@@ -91,6 +101,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister) *Metri
|
||||
Handler: mux,
|
||||
},
|
||||
syncCounter: syncCounter,
|
||||
k8sRequestCounter: k8sRequestCounter,
|
||||
reconcileHistogram: reconcileHistogram,
|
||||
}
|
||||
}
|
||||
@@ -103,6 +114,11 @@ func (m *MetricsServer) IncSync(app *argoappv1.Application, state *argoappv1.Ope
|
||||
m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), string(state.Phase)).Inc()
|
||||
}
|
||||
|
||||
// IncKubernetesRequest increments the kubernetes requests counter for an application
|
||||
func (m *MetricsServer) IncKubernetesRequest(app *argoappv1.Application, statusCode int) {
|
||||
m.k8sRequestCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), strconv.Itoa(statusCode)).Inc()
|
||||
}
|
||||
|
||||
// IncReconcile increments the reconcile counter for an application
|
||||
func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.Duration) {
|
||||
m.reconcileHistogram.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject()).Observe(duration.Seconds())
|
||||
|
||||
37
controller/metrics/transportwrapper.go
Normal file
37
controller/metrics/transportwrapper.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
type metricsRoundTripper struct {
|
||||
roundTripper http.RoundTripper
|
||||
app *v1alpha1.Application
|
||||
metricsServer *MetricsServer
|
||||
}
|
||||
|
||||
func (mrt *metricsRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
resp, err := mrt.roundTripper.RoundTrip(r)
|
||||
statusCode := 0
|
||||
if resp != nil {
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
mrt.metricsServer.IncKubernetesRequest(mrt.app, statusCode)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// AddMetricsTransportWrapper adds a transport wrapper which increments 'argocd_app_k8s_request_total' counter on each kubernetes request
|
||||
func AddMetricsTransportWrapper(server *MetricsServer, app *v1alpha1.Application, config *rest.Config) *rest.Config {
|
||||
wrap := config.WrapTransport
|
||||
config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
|
||||
if wrap != nil {
|
||||
rt = wrap(rt)
|
||||
}
|
||||
return &metricsRoundTripper{roundTripper: rt, metricsServer: server, app: app}
|
||||
}
|
||||
return config
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
statecache "github.com/argoproj/argo-cd/controller/cache"
|
||||
"github.com/argoproj/argo-cd/controller/metrics"
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
||||
@@ -73,6 +74,7 @@ type comparisonResult struct {
|
||||
|
||||
// appStateManager allows to compare applications to git
|
||||
type appStateManager struct {
|
||||
metricsServer *metrics.MetricsServer
|
||||
db db.ArgoDB
|
||||
settings *settings.ArgoCDSettings
|
||||
appclientset appclientset.Interface
|
||||
@@ -88,7 +90,10 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
repo := m.getRepo(source.RepoURL)
|
||||
repo, err := m.db.GetRepository(context.Background(), source.RepoURL)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
conn, repoClient, err := m.repoClientset.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
@@ -311,7 +316,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision st
|
||||
syncStatus.Revision = manifestInfo.Revision
|
||||
}
|
||||
|
||||
healthStatus, err := health.SetApplicationHealth(resourceSummaries, GetLiveObjs(managedResources), m.settings.ResourceOverrides)
|
||||
healthStatus, err := health.SetApplicationHealth(resourceSummaries, GetLiveObjs(managedResources), m.settings.ResourceOverrides, func(obj *unstructured.Unstructured) bool {
|
||||
return !isSelfReferencedApp(app, kubeutil.GetObjectRef(obj))
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
conditions = append(conditions, appv1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error()})
|
||||
}
|
||||
@@ -332,15 +340,6 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision st
|
||||
return &compRes, nil
|
||||
}
|
||||
|
||||
func (m *appStateManager) getRepo(repoURL string) *v1alpha1.Repository {
|
||||
repo, err := m.db.GetRepository(context.Background(), repoURL)
|
||||
if err != nil {
|
||||
// If we couldn't retrieve from the repo service, assume public repositories
|
||||
repo = &v1alpha1.Repository{Repo: repoURL}
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource) error {
|
||||
var nextID int64
|
||||
if len(app.Status.History) > 0 {
|
||||
@@ -379,6 +378,7 @@ func NewAppStateManager(
|
||||
settings *settings.ArgoCDSettings,
|
||||
liveStateCache statecache.LiveStateCache,
|
||||
projInformer cache.SharedIndexInformer,
|
||||
metricsServer *metrics.MetricsServer,
|
||||
) AppStateManager {
|
||||
return &appStateManager{
|
||||
liveStateCache: liveStateCache,
|
||||
@@ -389,5 +389,6 @@ func NewAppStateManager(
|
||||
namespace: namespace,
|
||||
settings: settings,
|
||||
projInformer: projInformer,
|
||||
metricsServer: metricsServer,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -178,3 +181,83 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) {
|
||||
})
|
||||
assert.Equal(t, 2, len(compRes.resources))
|
||||
}
|
||||
|
||||
var defaultProj = argoappv1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default",
|
||||
Namespace: test.FakeArgoCDNamespace,
|
||||
},
|
||||
Spec: argoappv1.AppProjectSpec{
|
||||
SourceRepos: []string{"*"},
|
||||
Destinations: []argoappv1.ApplicationDestination{
|
||||
{
|
||||
Server: "*",
|
||||
Namespace: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestSetHealth(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
deployment := kube.MustToUnstructured(&v1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1beta1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: "default",
|
||||
},
|
||||
})
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &repository.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(deployment): deployment,
|
||||
},
|
||||
})
|
||||
|
||||
compRes, err := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, compRes.healthStatus.Status, argoappv1.HealthStatusHealthy)
|
||||
}
|
||||
|
||||
func TestSetHealthSelfReferencedApp(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
unstructuredApp := kube.MustToUnstructured(app)
|
||||
deployment := kube.MustToUnstructured(&v1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1beta1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: "default",
|
||||
},
|
||||
})
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &repository.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(deployment): deployment,
|
||||
kube.GetResourceKey(unstructuredApp): unstructuredApp,
|
||||
},
|
||||
})
|
||||
|
||||
compRes, err := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, compRes.healthStatus.Status, argoappv1.HealthStatusHealthy)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/argoproj/argo-cd/controller/metrics"
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/pkg/client/listers/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/argo"
|
||||
@@ -116,7 +117,7 @@ func (m *appStateManager) SyncAppState(app *appv1.Application, state *appv1.Oper
|
||||
return
|
||||
}
|
||||
|
||||
restConfig := clst.RESTConfig()
|
||||
restConfig := metrics.AddMetricsTransportWrapper(m.metricsServer, app, clst.RESTConfig())
|
||||
dynamicIf, err := dynamic.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
state.Phase = appv1.OperationError
|
||||
|
||||
@@ -29,6 +29,8 @@ data:
|
||||
issuer: https://dev-123456.oktapreview.com
|
||||
clientID: aaaabbbbccccddddeee
|
||||
clientSecret: $oidc.okta.clientSecret
|
||||
# Optional set of OIDC scopes to request. If omitted, defaults to: ["openid", "profile", "email", "groups"]
|
||||
requestedScopes: ["openid", "profile", "email"]
|
||||
|
||||
# Git repositories configure Argo CD with (optional).
|
||||
# This list is updated when configuring/removing repos from the UI/CLI
|
||||
|
||||
@@ -19,3 +19,8 @@ data:
|
||||
# authorizing API requests (optional). If omitted or empty, users may be still be able to login,
|
||||
# but will see no apps, projects, etc...
|
||||
policy.default: role:readonly
|
||||
|
||||
# scopes controls which OIDC scopes to examine during rbac enforcement (in addition to `sub` scope).
|
||||
# If omitted, defaults to: `[groups]`. The scope value can be a string, or a list of strings.
|
||||
scopes: [cognito:groups, email]
|
||||
|
||||
|
||||
@@ -150,6 +150,88 @@ data:
|
||||
key: sshPrivateKey
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The Kubernetes documentation has [instructions for creating a secret containing a private key](https://kubernetes.io/docs/concepts/configuration/secret/#use-case-pod-with-ssh-keys).
|
||||
|
||||
|
||||
### Repository Credentials (v1.1+)
|
||||
|
||||
If you want to use the same credentials for multiple repositories, you can use `repository.credentials`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cm
|
||||
data:
|
||||
repositories: |
|
||||
- url: https://github.com/argoproj/private-repo
|
||||
- url: https://github.com/argoproj/other-private-repo
|
||||
repository.credentials: |
|
||||
- url: https://github.com/argoproj
|
||||
passwordSecret:
|
||||
name: my-secret
|
||||
key: password
|
||||
usernameSecret:
|
||||
name: my-secret
|
||||
key: username
|
||||
```
|
||||
|
||||
Argo CD will only use the credentials if you omit `usernameSecret`, `passwordSecret`, and `sshPrivateKeySecret` fields (`insecureIgnoreHostKey` is ignored).
|
||||
|
||||
A credential may be match if it's URL is the prefix of the repository's URL. The means that credentials may match, e.g in the above example both [https://github.com/argoproj](https://github.com/argoproj) and [https://github.com](https://github.com) would match. Argo CD selects the first one that matches.
|
||||
|
||||
!!! tip
|
||||
Order your credentials with the most specific at the top and the least specific at the bottom.
|
||||
|
||||
A complete example.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cm
|
||||
data:
|
||||
repositories: |
|
||||
# this has it's own credentials
|
||||
- url: https://github.com/argoproj/private-repo
|
||||
passwordSecret:
|
||||
name: private-repo-secret
|
||||
key: password
|
||||
usernameSecret:
|
||||
name: private-repo-secret
|
||||
key: username
|
||||
sshPrivateKeySecret:
|
||||
name: private-repo-secret
|
||||
key: sshPrivateKey
|
||||
- url: https://github.com/argoproj/other-private-repo
|
||||
- url: https://github.com/otherproj/another-private-repo
|
||||
repository.credentials: |
|
||||
# this will be used for the second repo
|
||||
- url: https://github.com/argoproj
|
||||
passwordSecret:
|
||||
name: other-private-repo-secret
|
||||
key: password
|
||||
usernameSecret:
|
||||
name: other-private-repo-secret
|
||||
key: username
|
||||
sshPrivateKeySecret:
|
||||
name: other-private-repo-secret
|
||||
key: sshPrivateKey
|
||||
# this will be used for the third repo
|
||||
- url: https://github.com
|
||||
passwordSecret:
|
||||
name: another-private-repo-secret
|
||||
key: password
|
||||
usernameSecret:
|
||||
name: another-private-repo-secret
|
||||
key: username
|
||||
sshPrivateKeySecret:
|
||||
name: another-private-repo-secret
|
||||
key: sshPrivateKey
|
||||
```
|
||||
|
||||
|
||||
## Clusters
|
||||
|
||||
Cluster credentials are stored in secrets same as repository credentials but does not require entry in `argocd-cm` config map. Each secret must have label
|
||||
|
||||
@@ -12,7 +12,7 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.0.2
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: latest
|
||||
newTag: v1.0.2
|
||||
|
||||
@@ -32,3 +32,8 @@ spec:
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
|
||||
@@ -41,6 +41,12 @@ spec:
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: static-files
|
||||
|
||||
@@ -479,12 +479,6 @@ spec:
|
||||
- message
|
||||
type: object
|
||||
type: array
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application child
|
||||
resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
health:
|
||||
properties:
|
||||
message:
|
||||
@@ -1144,6 +1138,20 @@ spec:
|
||||
type: array
|
||||
sourceType:
|
||||
type: string
|
||||
summary:
|
||||
properties:
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application
|
||||
child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
images:
|
||||
description: Images holds all images of application child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
sync:
|
||||
description: SyncStatus is a comparison result of application spec and
|
||||
deployed application.
|
||||
|
||||
@@ -17,7 +17,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.0.2
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: latest
|
||||
newTag: v1.0.2
|
||||
|
||||
@@ -185,10 +185,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -419,10 +415,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources for
|
||||
kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository containing
|
||||
@@ -633,10 +625,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -670,9 +658,6 @@ spec:
|
||||
- source
|
||||
type: object
|
||||
type: array
|
||||
ingress:
|
||||
items: {}
|
||||
type: array
|
||||
observedAt: {}
|
||||
operationState:
|
||||
description: OperationState contains information about state of currently
|
||||
@@ -853,10 +838,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to
|
||||
resources for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1092,10 +1073,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1162,6 +1139,20 @@ spec:
|
||||
type: array
|
||||
sourceType:
|
||||
type: string
|
||||
summary:
|
||||
properties:
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application
|
||||
child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
images:
|
||||
description: Images holds all images of application child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
sync:
|
||||
description: SyncStatus is a comparison result of application spec and
|
||||
deployed application.
|
||||
@@ -1312,10 +1303,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -2138,7 +2125,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -2185,7 +2172,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2240,8 +2227,13 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8081
|
||||
name: argocd-repo-server
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
@@ -2297,8 +2289,14 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
name: argocd-server
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
@@ -2318,7 +2316,7 @@ spec:
|
||||
- -r
|
||||
- /app
|
||||
- /shared
|
||||
image: argoproj/argocd-ui:latest
|
||||
image: argoproj/argocd-ui:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: ui
|
||||
volumeMounts:
|
||||
|
||||
@@ -185,10 +185,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -419,10 +415,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources for
|
||||
kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository containing
|
||||
@@ -633,10 +625,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -670,9 +658,6 @@ spec:
|
||||
- source
|
||||
type: object
|
||||
type: array
|
||||
ingress:
|
||||
items: {}
|
||||
type: array
|
||||
observedAt: {}
|
||||
operationState:
|
||||
description: OperationState contains information about state of currently
|
||||
@@ -853,10 +838,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to
|
||||
resources for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1092,10 +1073,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1162,6 +1139,20 @@ spec:
|
||||
type: array
|
||||
sourceType:
|
||||
type: string
|
||||
summary:
|
||||
properties:
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application
|
||||
child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
images:
|
||||
description: Images holds all images of application child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
sync:
|
||||
description: SyncStatus is a comparison result of application spec and
|
||||
deployed application.
|
||||
@@ -1312,10 +1303,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -2053,7 +2040,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -2100,7 +2087,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2155,8 +2142,13 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8081
|
||||
name: argocd-repo-server
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
@@ -2212,8 +2204,14 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
name: argocd-server
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
@@ -2233,7 +2231,7 @@ spec:
|
||||
- -r
|
||||
- /app
|
||||
- /shared
|
||||
image: argoproj/argocd-ui:latest
|
||||
image: argoproj/argocd-ui:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: ui
|
||||
volumeMounts:
|
||||
|
||||
@@ -185,10 +185,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -419,10 +415,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources for
|
||||
kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository containing
|
||||
@@ -633,10 +625,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -670,9 +658,6 @@ spec:
|
||||
- source
|
||||
type: object
|
||||
type: array
|
||||
ingress:
|
||||
items: {}
|
||||
type: array
|
||||
observedAt: {}
|
||||
operationState:
|
||||
description: OperationState contains information about state of currently
|
||||
@@ -853,10 +838,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to
|
||||
resources for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1092,10 +1073,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1162,6 +1139,20 @@ spec:
|
||||
type: array
|
||||
sourceType:
|
||||
type: string
|
||||
summary:
|
||||
properties:
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application
|
||||
child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
images:
|
||||
description: Images holds all images of application child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
sync:
|
||||
description: SyncStatus is a comparison result of application spec and
|
||||
deployed application.
|
||||
@@ -1312,10 +1303,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1902,7 +1889,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -1949,7 +1936,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2012,8 +1999,13 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8081
|
||||
name: argocd-repo-server
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
@@ -2046,8 +2038,14 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
name: argocd-server
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
@@ -2067,7 +2065,7 @@ spec:
|
||||
- -r
|
||||
- /app
|
||||
- /shared
|
||||
image: argoproj/argocd-ui:latest
|
||||
image: argoproj/argocd-ui:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: ui
|
||||
volumeMounts:
|
||||
|
||||
@@ -185,10 +185,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -419,10 +415,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources for
|
||||
kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository containing
|
||||
@@ -633,10 +625,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -670,9 +658,6 @@ spec:
|
||||
- source
|
||||
type: object
|
||||
type: array
|
||||
ingress:
|
||||
items: {}
|
||||
type: array
|
||||
observedAt: {}
|
||||
operationState:
|
||||
description: OperationState contains information about state of currently
|
||||
@@ -853,10 +838,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to
|
||||
resources for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1092,10 +1073,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1162,6 +1139,20 @@ spec:
|
||||
type: array
|
||||
sourceType:
|
||||
type: string
|
||||
summary:
|
||||
properties:
|
||||
externalURLs:
|
||||
description: ExternalURLs holds all external URLs of application
|
||||
child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
images:
|
||||
description: Images holds all images of application child resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
sync:
|
||||
description: SyncStatus is a comparison result of application spec and
|
||||
deployed application.
|
||||
@@ -1312,10 +1303,6 @@ spec:
|
||||
description: NamePrefix is a prefix appended to resources
|
||||
for kustomize apps
|
||||
type: string
|
||||
required:
|
||||
- namePrefix
|
||||
- imageTags
|
||||
- images
|
||||
type: object
|
||||
path:
|
||||
description: Path is a directory path within the repository
|
||||
@@ -1817,7 +1804,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -1864,7 +1851,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -1927,8 +1914,13 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8081
|
||||
name: argocd-repo-server
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
@@ -1961,8 +1953,14 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 30
|
||||
name: argocd-server
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
@@ -1982,7 +1980,7 @@ spec:
|
||||
- -r
|
||||
- /app
|
||||
- /shared
|
||||
image: argoproj/argocd-ui:latest
|
||||
image: argoproj/argocd-ui:v1.0.2
|
||||
imagePullPolicy: Always
|
||||
name: ui
|
||||
volumeMounts:
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
oidc "github.com/coreos/go-oidc"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
"google.golang.org/grpc"
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/server/version"
|
||||
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
||||
"github.com/argoproj/argo-cd/util/localconfig"
|
||||
oidcutil "github.com/argoproj/argo-cd/util/oidc"
|
||||
tls_util "github.com/argoproj/argo-cd/util/tls"
|
||||
)
|
||||
|
||||
@@ -51,10 +52,6 @@ const (
|
||||
MaxGRPCMessageSize = 100 * 1024 * 1024
|
||||
)
|
||||
|
||||
var (
|
||||
clientScopes = []string{"openid", "profile", "email", "groups", "offline_access"}
|
||||
)
|
||||
|
||||
// Client defines an interface for interaction with an Argo CD server.
|
||||
type Client interface {
|
||||
ClientOptions() ClientOptions
|
||||
@@ -197,16 +194,18 @@ func NewClient(opts *ClientOptions) (Client, error) {
|
||||
func (c *client) OIDCConfig(ctx context.Context, set *settings.Settings) (*oauth2.Config, *oidc.Provider, error) {
|
||||
var clientID string
|
||||
var issuerURL string
|
||||
if set.DexConfig != nil && len(set.DexConfig.Connectors) > 0 {
|
||||
clientID = common.ArgoCDCLIClientAppID
|
||||
issuerURL = fmt.Sprintf("%s%s", set.URL, common.DexAPIEndpoint)
|
||||
} else if set.OIDCConfig != nil && set.OIDCConfig.Issuer != "" {
|
||||
var scopes []string
|
||||
if set.OIDCConfig != nil && set.OIDCConfig.Issuer != "" {
|
||||
if set.OIDCConfig.CLIClientID != "" {
|
||||
clientID = set.OIDCConfig.CLIClientID
|
||||
} else {
|
||||
clientID = set.OIDCConfig.ClientID
|
||||
}
|
||||
issuerURL = set.OIDCConfig.Issuer
|
||||
scopes = set.OIDCConfig.Scopes
|
||||
} else if set.DexConfig != nil && len(set.DexConfig.Connectors) > 0 {
|
||||
clientID = common.ArgoCDCLIClientAppID
|
||||
issuerURL = fmt.Sprintf("%s%s", set.URL, common.DexAPIEndpoint)
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("%s is not configured with SSO", c.ServerAddr)
|
||||
}
|
||||
@@ -214,9 +213,17 @@ func (c *client) OIDCConfig(ctx context.Context, set *settings.Settings) (*oauth
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to query provider %q: %v", issuerURL, err)
|
||||
}
|
||||
oidcConf, err := oidcutil.ParseConfig(provider)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to parse provider config: %v", err)
|
||||
}
|
||||
scopes = oidcutil.GetScopesOrDefault(scopes)
|
||||
if oidcutil.OfflineAccess(oidcConf.ScopesSupported) {
|
||||
scopes = append(scopes, oidc.ScopeOfflineAccess)
|
||||
}
|
||||
oauth2conf := oauth2.Config{
|
||||
ClientID: clientID,
|
||||
Scopes: clientScopes,
|
||||
Scopes: scopes,
|
||||
Endpoint: provider.Endpoint(),
|
||||
}
|
||||
return &oauth2conf, provider, nil
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -223,8 +223,15 @@ message ApplicationStatus {
|
||||
|
||||
optional string sourceType = 9;
|
||||
|
||||
optional ApplicationSummary summary = 10;
|
||||
}
|
||||
|
||||
message ApplicationSummary {
|
||||
// ExternalURLs holds all external URLs of application child resources.
|
||||
repeated string externalURLs = 10;
|
||||
repeated string externalURLs = 1;
|
||||
|
||||
// Images holds all images of application child resources.
|
||||
repeated string images = 2;
|
||||
}
|
||||
|
||||
// ApplicationTree holds nodes which belongs to the application
|
||||
|
||||
@@ -30,6 +30,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationSourcePlugin": schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationSpec": schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationSummary": schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationTree": schema_pkg_apis_application_v1alpha1_ApplicationTree(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationWatchEvent": schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref),
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.Cluster": schema_pkg_apis_application_v1alpha1_Cluster(ref),
|
||||
@@ -840,6 +841,25 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"summary": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationSummary"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"externalURLs": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ExternalURLs holds all external URLs of application child resources.",
|
||||
@@ -854,11 +874,23 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference
|
||||
},
|
||||
},
|
||||
},
|
||||
"images": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Images holds all images of application child resources.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,8 +225,7 @@ type ApplicationStatus struct {
|
||||
OperationState *OperationState `json:"operationState,omitempty" protobuf:"bytes,7,opt,name=operationState"`
|
||||
ObservedAt metav1.Time `json:"observedAt,omitempty" protobuf:"bytes,8,opt,name=observedAt"`
|
||||
SourceType ApplicationSourceType `json:"sourceType,omitempty" protobuf:"bytes,9,opt,name=sourceType"`
|
||||
// ExternalURLs holds all external URLs of application child resources.
|
||||
ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,10,opt,name=externalURLs"`
|
||||
Summary ApplicationSummary `json:"summary,omitempty" protobuf:"bytes,10,opt,name=summary"`
|
||||
}
|
||||
|
||||
// Operation contains requested operation parameters.
|
||||
@@ -538,6 +537,13 @@ type ApplicationTree struct {
|
||||
Nodes []ResourceNode `json:"nodes,omitempty" protobuf:"bytes,1,rep,name=nodes"`
|
||||
}
|
||||
|
||||
type ApplicationSummary struct {
|
||||
// ExternalURLs holds all external URLs of application child resources.
|
||||
ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,1,opt,name=externalURLs"`
|
||||
// Images holds all images of application child resources.
|
||||
Images []string `json:"images,omitempty" protobuf:"bytes,2,opt,name=images"`
|
||||
}
|
||||
|
||||
func (t *ApplicationTree) FindNode(group string, kind string, namespace string, name string) *ResourceNode {
|
||||
for _, n := range t.Nodes {
|
||||
if n.Group == group && n.Kind == kind && n.Namespace == namespace && n.Name == name {
|
||||
@@ -547,20 +553,28 @@ func (t *ApplicationTree) FindNode(group string, kind string, namespace string,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ApplicationTree) GetBrowableURLs() []string {
|
||||
func (t *ApplicationTree) GetSummary() ApplicationSummary {
|
||||
urlsSet := make(map[string]bool)
|
||||
imagesSet := make(map[string]bool)
|
||||
for _, node := range t.Nodes {
|
||||
if node.NetworkingInfo != nil {
|
||||
for _, url := range node.NetworkingInfo.ExternalURLs {
|
||||
urlsSet[url] = true
|
||||
}
|
||||
}
|
||||
for _, image := range node.Images {
|
||||
imagesSet[image] = true
|
||||
}
|
||||
}
|
||||
urls := make([]string, 0)
|
||||
for url := range urlsSet {
|
||||
urls = append(urls, url)
|
||||
}
|
||||
return urls
|
||||
images := make([]string, 0)
|
||||
for image := range imagesSet {
|
||||
images = append(images, image)
|
||||
}
|
||||
return ApplicationSummary{ExternalURLs: urls, Images: images}
|
||||
}
|
||||
|
||||
// ResourceRef includes fields which unique identify resource
|
||||
@@ -756,6 +770,17 @@ type Repository struct {
|
||||
InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty" protobuf:"bytes,6,opt,name=insecureIgnoreHostKey"`
|
||||
}
|
||||
|
||||
func (m *Repository) HasCredentials() bool {
|
||||
return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.InsecureIgnoreHostKey
|
||||
}
|
||||
|
||||
func (m *Repository) CopyCredentialsFrom(source Repository) {
|
||||
m.Username = source.Username
|
||||
m.Password = source.Password
|
||||
m.SSHPrivateKey = source.SSHPrivateKey
|
||||
m.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey
|
||||
}
|
||||
|
||||
// RepositoryList is a collection of Repositories.
|
||||
type RepositoryList struct {
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
@@ -199,3 +199,87 @@ func TestAppProjectSpec_DestinationClusters(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepository_HasCredentials(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
repo Repository
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "TestHasRepo",
|
||||
repo: Repository{Repo: "foo"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "TestHasUsername",
|
||||
repo: Repository{Username: "foo"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "TestHasPassword",
|
||||
repo: Repository{Password: "foo"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "TestHasSSHPrivateKey",
|
||||
repo: Repository{SSHPrivateKey: "foo"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "TestHasInsecureHostKey",
|
||||
repo: Repository{InsecureIgnoreHostKey: true},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.repo.HasCredentials(); got != tt.want {
|
||||
t.Errorf("Repository.HasCredentials() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepository_CopyCredentialsFrom(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
source Repository
|
||||
want Repository
|
||||
}{
|
||||
|
||||
{
|
||||
name: "TestHasRepo",
|
||||
source: Repository{Repo: "foo"},
|
||||
want: Repository{},
|
||||
},
|
||||
{
|
||||
name: "TestHasUsername",
|
||||
source: Repository{Username: "foo"},
|
||||
want: Repository{Username: "foo"},
|
||||
},
|
||||
{
|
||||
name: "TestHasPassword",
|
||||
source: Repository{Password: "foo"},
|
||||
want: Repository{Password: "foo"},
|
||||
},
|
||||
{
|
||||
name: "TestHasSSHPrivateKey",
|
||||
source: Repository{SSHPrivateKey: "foo"},
|
||||
want: Repository{SSHPrivateKey: "foo"},
|
||||
},
|
||||
{
|
||||
name: "TestHasInsecureHostKey",
|
||||
source: Repository{InsecureIgnoreHostKey: true},
|
||||
want: Repository{InsecureIgnoreHostKey: true},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
repo := Repository{}
|
||||
repo.CopyCredentialsFrom(tt.source)
|
||||
assert.Equal(t, tt.want, repo)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,11 +461,7 @@ func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) {
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.ObservedAt.DeepCopyInto(&out.ObservedAt)
|
||||
if in.ExternalURLs != nil {
|
||||
in, out := &in.ExternalURLs, &out.ExternalURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Summary.DeepCopyInto(&out.Summary)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -479,6 +475,32 @@ func (in *ApplicationStatus) DeepCopy() *ApplicationStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationSummary) DeepCopyInto(out *ApplicationSummary) {
|
||||
*out = *in
|
||||
if in.ExternalURLs != nil {
|
||||
in, out := &in.ExternalURLs, &out.ExternalURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Images != nil {
|
||||
in, out := &in.Images, &out.Images
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSummary.
|
||||
func (in *ApplicationSummary) DeepCopy() *ApplicationSummary {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ApplicationSummary)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationTree) DeepCopyInto(out *ApplicationTree) {
|
||||
*out = *in
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
"time"
|
||||
|
||||
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
"github.com/argoproj/argo-cd/reposerver/repository"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
argogrpc "github.com/argoproj/argo-cd/util/grpc"
|
||||
)
|
||||
|
||||
// Clientset represets repository server api clients
|
||||
@@ -20,7 +20,8 @@ type Clientset interface {
|
||||
}
|
||||
|
||||
type clientSet struct {
|
||||
address string
|
||||
address string
|
||||
timeoutSeconds int
|
||||
}
|
||||
|
||||
func (c *clientSet) NewRepoServerClient() (util.Closer, repository.RepoServerServiceClient, error) {
|
||||
@@ -28,10 +29,14 @@ func (c *clientSet) NewRepoServerClient() (util.Closer, repository.RepoServerSer
|
||||
grpc_retry.WithMax(3),
|
||||
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)),
|
||||
}
|
||||
conn, err := grpc.Dial(c.address,
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})),
|
||||
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)),
|
||||
grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(retryOpts...)))
|
||||
grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(retryOpts...))}
|
||||
if c.timeoutSeconds > 0 {
|
||||
opts = append(opts, grpc.WithUnaryInterceptor(argogrpc.WithTimeout(time.Duration(c.timeoutSeconds)*time.Second)))
|
||||
}
|
||||
conn, err := grpc.Dial(c.address, opts...)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to connect to repository service with address %s", c.address)
|
||||
return nil, nil, err
|
||||
@@ -40,6 +45,6 @@ func (c *clientSet) NewRepoServerClient() (util.Closer, repository.RepoServerSer
|
||||
}
|
||||
|
||||
// NewRepoServerClientset creates new instance of repo server Clientset
|
||||
func NewRepoServerClientset(address string) Clientset {
|
||||
return &clientSet{address: address}
|
||||
func NewRepoServerClientset(address string, timeoutSeconds int) Clientset {
|
||||
return &clientSet{address: address, timeoutSeconds: timeoutSeconds}
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ func pathExists(ss ...string) bool {
|
||||
func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision string) (git.Client, string, error) {
|
||||
repoURL := git.NormalizeGitURL(repo.Repo)
|
||||
appRepoPath := tempRepoPath(repoURL)
|
||||
gitClient, err := s.gitFactory.NewClient(repoURL, appRepoPath, repo.Username, repo.Password, repo.SSHPrivateKey, repo.InsecureIgnoreHostKey)
|
||||
gitClient, err := s.gitFactory.NewClient(repo.Repo, appRepoPath, repo.Username, repo.Password, repo.SSHPrivateKey, repo.InsecureIgnoreHostKey)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func (m *ManifestRequest) Reset() { *m = ManifestRequest{} }
|
||||
func (m *ManifestRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ManifestRequest) ProtoMessage() {}
|
||||
func (*ManifestRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{0}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{0}
|
||||
}
|
||||
func (m *ManifestRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -154,7 +154,7 @@ func (m *ManifestResponse) Reset() { *m = ManifestResponse{} }
|
||||
func (m *ManifestResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ManifestResponse) ProtoMessage() {}
|
||||
func (*ManifestResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{1}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{1}
|
||||
}
|
||||
func (m *ManifestResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -232,7 +232,7 @@ func (m *ListDirRequest) Reset() { *m = ListDirRequest{} }
|
||||
func (m *ListDirRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListDirRequest) ProtoMessage() {}
|
||||
func (*ListDirRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{2}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{2}
|
||||
}
|
||||
func (m *ListDirRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -294,7 +294,7 @@ func (m *FileList) Reset() { *m = FileList{} }
|
||||
func (m *FileList) String() string { return proto.CompactTextString(m) }
|
||||
func (*FileList) ProtoMessage() {}
|
||||
func (*FileList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{3}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{3}
|
||||
}
|
||||
func (m *FileList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -344,7 +344,7 @@ func (m *GetFileRequest) Reset() { *m = GetFileRequest{} }
|
||||
func (m *GetFileRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetFileRequest) ProtoMessage() {}
|
||||
func (*GetFileRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{4}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{4}
|
||||
}
|
||||
func (m *GetFileRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -406,7 +406,7 @@ func (m *GetFileResponse) Reset() { *m = GetFileResponse{} }
|
||||
func (m *GetFileResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetFileResponse) ProtoMessage() {}
|
||||
func (*GetFileResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{5}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{5}
|
||||
}
|
||||
func (m *GetFileResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -460,7 +460,7 @@ func (m *RepoServerAppDetailsQuery) Reset() { *m = RepoServerAppDetailsQ
|
||||
func (m *RepoServerAppDetailsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoServerAppDetailsQuery) ProtoMessage() {}
|
||||
func (*RepoServerAppDetailsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{6}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{6}
|
||||
}
|
||||
func (m *RepoServerAppDetailsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -549,7 +549,7 @@ func (m *HelmAppDetailsQuery) Reset() { *m = HelmAppDetailsQuery{} }
|
||||
func (m *HelmAppDetailsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*HelmAppDetailsQuery) ProtoMessage() {}
|
||||
func (*HelmAppDetailsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{7}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{7}
|
||||
}
|
||||
func (m *HelmAppDetailsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -596,7 +596,7 @@ func (m *KsonnetAppDetailsQuery) Reset() { *m = KsonnetAppDetailsQuery{}
|
||||
func (m *KsonnetAppDetailsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*KsonnetAppDetailsQuery) ProtoMessage() {}
|
||||
func (*KsonnetAppDetailsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{8}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{8}
|
||||
}
|
||||
func (m *KsonnetAppDetailsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -648,7 +648,7 @@ func (m *RepoAppDetailsResponse) Reset() { *m = RepoAppDetailsResponse{}
|
||||
func (m *RepoAppDetailsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoAppDetailsResponse) ProtoMessage() {}
|
||||
func (*RepoAppDetailsResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{9}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{9}
|
||||
}
|
||||
func (m *RepoAppDetailsResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -728,7 +728,7 @@ func (m *KsonnetAppSpec) Reset() { *m = KsonnetAppSpec{} }
|
||||
func (m *KsonnetAppSpec) String() string { return proto.CompactTextString(m) }
|
||||
func (*KsonnetAppSpec) ProtoMessage() {}
|
||||
func (*KsonnetAppSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{10}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{10}
|
||||
}
|
||||
func (m *KsonnetAppSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -800,7 +800,7 @@ func (m *HelmAppSpec) Reset() { *m = HelmAppSpec{} }
|
||||
func (m *HelmAppSpec) String() string { return proto.CompactTextString(m) }
|
||||
func (*HelmAppSpec) ProtoMessage() {}
|
||||
func (*HelmAppSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{11}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{11}
|
||||
}
|
||||
func (m *HelmAppSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -873,7 +873,7 @@ func (m *KustomizeAppSpec) Reset() { *m = KustomizeAppSpec{} }
|
||||
func (m *KustomizeAppSpec) String() string { return proto.CompactTextString(m) }
|
||||
func (*KustomizeAppSpec) ProtoMessage() {}
|
||||
func (*KustomizeAppSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{12}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{12}
|
||||
}
|
||||
func (m *KustomizeAppSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -941,7 +941,7 @@ func (m *KsonnetEnvironment) Reset() { *m = KsonnetEnvironment{} }
|
||||
func (m *KsonnetEnvironment) String() string { return proto.CompactTextString(m) }
|
||||
func (*KsonnetEnvironment) ProtoMessage() {}
|
||||
func (*KsonnetEnvironment) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{13}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{13}
|
||||
}
|
||||
func (m *KsonnetEnvironment) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1012,7 +1012,7 @@ func (m *KsonnetEnvironmentDestination) Reset() { *m = KsonnetEnvironmen
|
||||
func (m *KsonnetEnvironmentDestination) String() string { return proto.CompactTextString(m) }
|
||||
func (*KsonnetEnvironmentDestination) ProtoMessage() {}
|
||||
func (*KsonnetEnvironmentDestination) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{14}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{14}
|
||||
}
|
||||
func (m *KsonnetEnvironmentDestination) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1066,7 +1066,7 @@ func (m *DirectoryAppSpec) Reset() { *m = DirectoryAppSpec{} }
|
||||
func (m *DirectoryAppSpec) String() string { return proto.CompactTextString(m) }
|
||||
func (*DirectoryAppSpec) ProtoMessage() {}
|
||||
func (*DirectoryAppSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_7075e68bfb1c8d80, []int{15}
|
||||
return fileDescriptor_repository_a40b5a752434083f, []int{15}
|
||||
}
|
||||
func (m *DirectoryAppSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -5127,10 +5127,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("reposerver/repository/repository.proto", fileDescriptor_repository_7075e68bfb1c8d80)
|
||||
proto.RegisterFile("reposerver/repository/repository.proto", fileDescriptor_repository_a40b5a752434083f)
|
||||
}
|
||||
|
||||
var fileDescriptor_repository_7075e68bfb1c8d80 = []byte{
|
||||
var fileDescriptor_repository_a40b5a752434083f = []byte{
|
||||
// 1103 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xdd, 0x6e, 0x1b, 0xc5,
|
||||
0x17, 0xcf, 0xda, 0x4e, 0x1c, 0x1f, 0xa7, 0x6d, 0x32, 0xff, 0x28, 0xff, 0xc5, 0x0d, 0xc6, 0x1a,
|
||||
|
||||
@@ -2,6 +2,9 @@ discoveryTests:
|
||||
- inputPath: testdata/paused_rollout.yaml
|
||||
result:
|
||||
- name: resume
|
||||
- inputPath: testdata/v0.2_paused_rollout.yaml
|
||||
result:
|
||||
- name: resume
|
||||
- inputPath: testdata/not_paused_rollout.yaml
|
||||
result: []
|
||||
- inputPath: testdata/nil_paused_rollout.yaml
|
||||
@@ -10,4 +13,6 @@ actionTests:
|
||||
- action: resume
|
||||
inputPath: testdata/paused_rollout.yaml
|
||||
expectedOutputPath: testdata/not_paused_rollout.yaml
|
||||
|
||||
- action: resume
|
||||
inputPath: testdata/v0.2_paused_rollout.yaml
|
||||
expectedOutputPath: testdata/v0.2_not_paused_rollout.yaml
|
||||
@@ -1,6 +1,13 @@
|
||||
actions = {}
|
||||
|
||||
if obj.spec.paused ~= nil and obj.spec.paused then
|
||||
local paused = false
|
||||
if obj.status.verifyingPreview ~= nil then
|
||||
paused = obj.status.verifyingPreview
|
||||
elseif obj.spec.paused ~= nil then
|
||||
paused = obj.spec.paused
|
||||
end
|
||||
|
||||
if paused then
|
||||
actions["resume"] = {}
|
||||
end
|
||||
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
obj.spec.paused = false
|
||||
if obj.status.verifyingPreview ~= nil and obj.status.verifyingPreview then
|
||||
obj.status.verifyingPreview = false
|
||||
end
|
||||
|
||||
if obj.spec.paused ~= nil and obj.spec.paused then
|
||||
obj.spec.paused = false
|
||||
end
|
||||
|
||||
return obj
|
||||
55
resource_customizations/argoproj.io/Rollout/actions/testdata/v0.2_not_paused_rollout.yaml
vendored
Normal file
55
resource_customizations/argoproj.io/Rollout/actions/testdata/v0.2_not_paused_rollout.yaml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
rollout.argoproj.io/revision: "7"
|
||||
clusterName: ""
|
||||
creationTimestamp: 2019-01-22T16:52:54Z
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-default
|
||||
name: ks-guestbook-ui
|
||||
namespace: default
|
||||
resourceVersion: "164113"
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/ks-guestbook-ui
|
||||
uid: 29802403-1e66-11e9-a6a4-025000000001
|
||||
spec:
|
||||
minReadySeconds: 30
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ks-guestbook-ui
|
||||
strategy:
|
||||
blueGreen:
|
||||
activeService: ks-guestbook-ui-active
|
||||
previewService: ks-guestbook-ui-preview
|
||||
type: BlueGreenUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 83
|
||||
resources: {}
|
||||
status:
|
||||
blueGreen:
|
||||
activeSelector: 85f9884f5d
|
||||
previewSelector: 697fb9575c
|
||||
availableReplicas: 6
|
||||
conditions:
|
||||
- lastTransitionTime: 2019-01-25T07:44:26Z
|
||||
lastUpdateTime: 2019-01-25T07:44:26Z
|
||||
message: Rollout is serving traffic from the active service.
|
||||
reason: Available
|
||||
status: "True"
|
||||
type: Available
|
||||
currentPodHash: 697fb9575c
|
||||
observedGeneration: 767f98959f
|
||||
readyReplicas: 6
|
||||
replicas: 6
|
||||
updatedReplicas: 3
|
||||
verifyingPreview: false
|
||||
55
resource_customizations/argoproj.io/Rollout/actions/testdata/v0.2_paused_rollout.yaml
vendored
Normal file
55
resource_customizations/argoproj.io/Rollout/actions/testdata/v0.2_paused_rollout.yaml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
rollout.argoproj.io/revision: "7"
|
||||
clusterName: ""
|
||||
creationTimestamp: 2019-01-22T16:52:54Z
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-default
|
||||
name: ks-guestbook-ui
|
||||
namespace: default
|
||||
resourceVersion: "164113"
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/ks-guestbook-ui
|
||||
uid: 29802403-1e66-11e9-a6a4-025000000001
|
||||
spec:
|
||||
minReadySeconds: 30
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ks-guestbook-ui
|
||||
strategy:
|
||||
blueGreen:
|
||||
activeService: ks-guestbook-ui-active
|
||||
previewService: ks-guestbook-ui-preview
|
||||
type: BlueGreenUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 83
|
||||
resources: {}
|
||||
status:
|
||||
blueGreen:
|
||||
activeSelector: 85f9884f5d
|
||||
previewSelector: 697fb9575c
|
||||
availableReplicas: 6
|
||||
conditions:
|
||||
- lastTransitionTime: 2019-01-25T07:44:26Z
|
||||
lastUpdateTime: 2019-01-25T07:44:26Z
|
||||
message: Rollout is serving traffic from the active service.
|
||||
reason: Available
|
||||
status: "True"
|
||||
type: Available
|
||||
currentPodHash: 697fb9575c
|
||||
observedGeneration: 767f98959f
|
||||
readyReplicas: 6
|
||||
replicas: 6
|
||||
updatedReplicas: 3
|
||||
verifyingPreview: true
|
||||
@@ -1,3 +1,55 @@
|
||||
function checkReplicasStatus(obj)
|
||||
hs = {}
|
||||
if obj.spec.replicas ~= nil and obj.status.updatedReplicas < obj.spec.replicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: More replicas need to be updated"
|
||||
return hs
|
||||
end
|
||||
if obj.status.replicas > obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: old replicas are pending termination"
|
||||
return hs
|
||||
end
|
||||
if obj.status.availableReplicas < obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: updated replicas are still becoming available"
|
||||
return hs
|
||||
end
|
||||
if obj.spec.replicas ~= nil and obj.status.updatedReplicas < obj.spec.replicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: More replicas need to be updated"
|
||||
return hs
|
||||
end
|
||||
if obj.status.replicas > obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: old replicas are pending termination"
|
||||
return hs
|
||||
end
|
||||
if obj.status.availableReplicas < obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: updated replicas are still becoming available"
|
||||
return hs
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function checkPaused(obj)
|
||||
hs = {}
|
||||
local paused = false
|
||||
if obj.status.verifyingPreview ~= nil then
|
||||
paused = obj.status.verifyingPreview
|
||||
elseif obj.spec.paused ~= nil then
|
||||
paused = obj.spec.paused
|
||||
end
|
||||
|
||||
if paused then
|
||||
hs.status = "Suspended"
|
||||
hs.message = "Rollout is paused"
|
||||
return hs
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
hs = {}
|
||||
if obj.status ~= nil then
|
||||
if obj.status.conditions ~= nil then
|
||||
@@ -7,44 +59,76 @@ if obj.status ~= nil then
|
||||
hs.message = condition.message
|
||||
return hs
|
||||
end
|
||||
if condition.type == "Progressing" and condition.reason == "ProgressDeadlineExceeded" then
|
||||
hs.status = "Degraded"
|
||||
hs.message = condition.message
|
||||
return hs
|
||||
end
|
||||
end
|
||||
end
|
||||
if obj.status.currentPodHash ~= nil then
|
||||
if obj.spec.replicas ~= nil and obj.status.updatedReplicas < obj.spec.replicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: More replicas need to be updated"
|
||||
return hs
|
||||
end
|
||||
|
||||
if obj.spec.paused then
|
||||
hs.status = "Suspended"
|
||||
if obj.status.blueGreen.previewSelector ~= nil and obj.status.blueGreen.previewSelector == obj.status.currentPodHash then
|
||||
hs.message = "The preview Service is serving traffic to the current pod spec"
|
||||
elseif obj.status.blueGreen.activeSelector ~= nil and obj.status.blueGreen.activeSelector == obj.status.currentPodHash then
|
||||
hs.message = "The active Service is serving traffic to the current pod spec"
|
||||
if obj.spec.strategy.blueGreen ~= nil then
|
||||
isPaused = checkPaused(obj)
|
||||
if isPaused ~= nil then
|
||||
return isPaused
|
||||
end
|
||||
replicasHS = checkReplicasStatus(obj)
|
||||
if replicasHS ~= nil then
|
||||
return replicasHS
|
||||
end
|
||||
if obj.status.blueGreen.activeSelector ~= nil and obj.status.blueGreen.activeSelector == obj.status.currentPodHash then
|
||||
hs.status = "Healthy"
|
||||
hs.message = "The active Service is serving traffic to the current pod spec"
|
||||
return hs
|
||||
end
|
||||
return hs
|
||||
end
|
||||
|
||||
if obj.status.replicas > obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: old replicas are pending termination"
|
||||
return hs
|
||||
end
|
||||
if obj.status.availableReplicas < obj.status.updatedReplicas then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for roll out to finish: updated replicas are still becoming available"
|
||||
hs.message = "The current pod spec is not receiving traffic from the active service"
|
||||
return hs
|
||||
end
|
||||
if obj.spec.strategy.canary ~= nil then
|
||||
currentRSIsStable = obj.status.canary.stableRS == obj.status.currentPodHash
|
||||
if obj.spec.strategy.canary.steps ~= nil then
|
||||
stepCount = table.getn(obj.spec.strategy.canary.steps)
|
||||
if obj.status.currentStepIndex ~= nil then
|
||||
currentStepIndex = obj.status.currentStepIndex
|
||||
isPaused = checkPaused(obj)
|
||||
if isPaused ~= nil then
|
||||
return isPaused
|
||||
end
|
||||
|
||||
if paused then
|
||||
hs.status = "Suspended"
|
||||
hs.message = "Rollout is paused"
|
||||
return hs
|
||||
end
|
||||
if currentRSIsStable and stepCount == currentStepIndex then
|
||||
replicasHS = checkReplicasStatus(obj)
|
||||
if replicasHS ~= nil then
|
||||
return replicasHS
|
||||
end
|
||||
hs.status = "Healthy"
|
||||
hs.message = "The rollout has completed all steps"
|
||||
return hs
|
||||
end
|
||||
end
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for rollout to finish steps"
|
||||
return hs
|
||||
end
|
||||
|
||||
if obj.status.blueGreen.activeSelector ~= nil and obj.status.blueGreen.activeSelector == obj.status.currentPodHash then
|
||||
hs.status = "Healthy"
|
||||
hs.message = "The active Service is serving traffic to the current pod spec"
|
||||
return hs
|
||||
-- The detecting the health of the Canary deployment when there are no steps
|
||||
replicasHS = checkReplicasStatus(obj)
|
||||
if replicasHS ~= nil then
|
||||
return replicasHS
|
||||
end
|
||||
if currentRSIsStable then
|
||||
hs.status = "Healthy"
|
||||
hs.message = "The rollout has completed canary deployment"
|
||||
return hs
|
||||
end
|
||||
hs.status = "Progressing"
|
||||
hs.message = "Waiting for rollout to finish canary deployment"
|
||||
end
|
||||
hs.status = "Progressing"
|
||||
hs.message = "The current pod spec is not receiving traffic from the active service"
|
||||
return hs
|
||||
end
|
||||
end
|
||||
hs.status = "Progressing"
|
||||
|
||||
@@ -1,25 +1,55 @@
|
||||
tests:
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: The active Service is serving traffic to the current pod spec
|
||||
inputPath: testdata/healthy_servingActiveService.yaml
|
||||
- healthStatus:
|
||||
status: Suspended
|
||||
message: The preview Service is serving traffic to the current pod spec
|
||||
inputPath: testdata/suspended_servingPreviewService.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: More replicas need to be updated"
|
||||
inputPath: testdata/progressing_addingMoreReplicas.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: old replicas are pending termination"
|
||||
inputPath: testdata/progressing_killingOldReplicas.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: updated replicas are still becoming available"
|
||||
inputPath: testdata/progressing_waitingUntilAvailable.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: Rollout has missing field '.Spec.Strategy.Type'
|
||||
inputPath: testdata/degraded_invalidSpec.yaml
|
||||
inputPath: testdata/degraded_invalidSpec.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: ReplicaSet "guestbook-bluegreen-helm-guestbook-6b8cf6f7db" has timed out progressing.
|
||||
inputPath: testdata/degraded_rolloutTimeout.yaml
|
||||
#BlueGreen
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: The active Service is serving traffic to the current pod spec
|
||||
inputPath: testdata/bluegreen/healthy_servingActiveService.yaml
|
||||
- healthStatus:
|
||||
status: Suspended
|
||||
message: Rollout is paused
|
||||
inputPath: testdata/bluegreen/suspended_servingPreviewService.yaml
|
||||
- healthStatus:
|
||||
status: Suspended
|
||||
message: Rollout is paused
|
||||
inputPath: testdata/v0.2_suspended_servingPreviewService.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: More replicas need to be updated"
|
||||
inputPath: testdata/bluegreen/progressing_addingMoreReplicas.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: old replicas are pending termination"
|
||||
inputPath: testdata/bluegreen/progressing_killingOldReplicas.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "Waiting for roll out to finish: updated replicas are still becoming available"
|
||||
inputPath: testdata/bluegreen/progressing_waitingUntilAvailable.yaml
|
||||
#Canary
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: Waiting for rollout to finish steps
|
||||
inputPath: testdata/canary/progressing_setWeightStep.yaml
|
||||
- healthStatus:
|
||||
status: Suspended
|
||||
message: Rollout is paused
|
||||
inputPath: testdata/canary/suspended_pausedStep.yaml
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: The rollout has completed all steps
|
||||
inputPath: testdata/canary/healthy_executedAllSteps.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: 'Waiting for roll out to finish: old replicas are pending termination'
|
||||
inputPath: testdata/canary/progressing_noSteps.yaml
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: The rollout has completed canary deployment
|
||||
inputPath: testdata/canary/healthy_noSteps.yaml
|
||||
73
resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml
vendored
Normal file
73
resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_executedAllSteps.yaml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '1'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-canary
|
||||
ksonnet.io/component: guestbook-ui
|
||||
name: guestbook-canary
|
||||
namespace: default
|
||||
resourceVersion: '955764'
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/guestbook-canary
|
||||
uid: d6105ccd-6c5b-11e9-b8d7-025000000001
|
||||
spec:
|
||||
minReadySeconds: 10
|
||||
replicas: 5
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook-canary
|
||||
strategy:
|
||||
canary:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
steps:
|
||||
- setWeight: 20
|
||||
- pause:
|
||||
duration: 30
|
||||
- setWeight: 40
|
||||
- pause: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 5
|
||||
availableReplicas: 5
|
||||
blueGreen: {}
|
||||
canary:
|
||||
stableRS: 84ccfddd66
|
||||
conditions:
|
||||
- lastTransitionTime: '2019-05-01T21:55:30Z'
|
||||
lastUpdateTime: '2019-05-01T21:55:58Z'
|
||||
message: ReplicaSet "guestbook-canary-84ccfddd66" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: 'True'
|
||||
type: Progressing
|
||||
- lastTransitionTime: '2019-05-01T21:55:58Z'
|
||||
lastUpdateTime: '2019-05-01T21:55:58Z'
|
||||
message: Rollout has minimum availability
|
||||
reason: AvailableReason
|
||||
status: 'True'
|
||||
type: Available
|
||||
currentPodHash: 84ccfddd66
|
||||
currentStepHash: 5f8fbdf7bb
|
||||
currentStepIndex: 4
|
||||
observedGeneration: c45557fd9
|
||||
readyReplicas: 5
|
||||
replicas: 5
|
||||
selector: app=guestbook-canary
|
||||
updatedReplicas: 5
|
||||
66
resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml
vendored
Normal file
66
resource_customizations/argoproj.io/Rollout/testdata/canary/healthy_noSteps.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '2'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-canary
|
||||
ksonnet.io/component: guestbook-ui
|
||||
name: guestbook-canary
|
||||
namespace: default
|
||||
resourceVersion: '956205'
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/guestbook-canary
|
||||
uid: d6105ccd-6c5b-11e9-b8d7-025000000001
|
||||
spec:
|
||||
minReadySeconds: 10
|
||||
replicas: 5
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook-canary
|
||||
strategy:
|
||||
canary:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 5
|
||||
availableReplicas: 5
|
||||
blueGreen: {}
|
||||
canary:
|
||||
stableRS: 567dd56d89
|
||||
conditions:
|
||||
- lastTransitionTime: '2019-05-01T22:00:16Z'
|
||||
lastUpdateTime: '2019-05-01T22:00:16Z'
|
||||
message: Rollout has minimum availability
|
||||
reason: AvailableReason
|
||||
status: 'True'
|
||||
type: Available
|
||||
- lastTransitionTime: '2019-05-01T21:55:30Z'
|
||||
lastUpdateTime: '2019-05-01T22:00:16Z'
|
||||
message: ReplicaSet "guestbook-canary-567dd56d89" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: 'True'
|
||||
type: Progressing
|
||||
currentPodHash: 567dd56d89
|
||||
currentStepHash: 6c9545789c
|
||||
observedGeneration: 6886f85bff
|
||||
readyReplicas: 5
|
||||
replicas: 5
|
||||
selector: app=guestbook-canary
|
||||
updatedReplicas: 5
|
||||
66
resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml
vendored
Normal file
66
resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_noSteps.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '2'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-canary
|
||||
ksonnet.io/component: guestbook-ui
|
||||
name: guestbook-canary
|
||||
namespace: default
|
||||
resourceVersion: '956159'
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/guestbook-canary
|
||||
uid: d6105ccd-6c5b-11e9-b8d7-025000000001
|
||||
spec:
|
||||
minReadySeconds: 10
|
||||
replicas: 5
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook-canary
|
||||
strategy:
|
||||
canary:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 6
|
||||
availableReplicas: 2
|
||||
blueGreen: {}
|
||||
canary:
|
||||
stableRS: 567dd56d89
|
||||
conditions:
|
||||
- lastTransitionTime: '2019-05-01T21:59:58Z'
|
||||
lastUpdateTime: '2019-05-01T21:59:58Z'
|
||||
message: Rollout does not have minimum availability
|
||||
reason: AvailableReason
|
||||
status: 'False'
|
||||
type: Available
|
||||
- lastTransitionTime: '2019-05-01T21:55:30Z'
|
||||
lastUpdateTime: '2019-05-01T22:00:05Z'
|
||||
message: ReplicaSet "guestbook-canary-567dd56d89" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: 'True'
|
||||
type: Progressing
|
||||
currentPodHash: 567dd56d89
|
||||
currentStepHash: 6c9545789c
|
||||
observedGeneration: 6886f85bff
|
||||
readyReplicas: 4
|
||||
replicas: 6
|
||||
selector: app=guestbook-canary
|
||||
updatedReplicas: 5
|
||||
69
resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml
vendored
Normal file
69
resource_customizations/argoproj.io/Rollout/testdata/canary/progressing_setWeightStep.yaml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: "2"
|
||||
clusterName: ""
|
||||
creationTimestamp: 2019-04-26T20:17:43Z
|
||||
generation: 1
|
||||
name: example-rollout-canary
|
||||
namespace: default
|
||||
resourceVersion: "696688"
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/example-rollout-canary
|
||||
uid: 58f6f1bb-6860-11e9-b8d7-025000000001
|
||||
spec:
|
||||
minReadySeconds: 30
|
||||
replicas: 5
|
||||
revisionHistoryLimit: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook
|
||||
strategy:
|
||||
canary:
|
||||
steps:
|
||||
- setWeight: 20
|
||||
- pause:
|
||||
duration: 20
|
||||
- setWeight: 40
|
||||
- pause: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: guestbook
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
name: guestbook
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 5
|
||||
availableReplicas: 5
|
||||
blueGreen: {}
|
||||
canary:
|
||||
stableRS: df986d68
|
||||
conditions:
|
||||
- lastTransitionTime: 2019-04-26T20:18:05Z
|
||||
lastUpdateTime: 2019-04-26T20:18:05Z
|
||||
message: Rollout is not serving traffic from the active service.
|
||||
reason: Available
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: 2019-04-26T20:18:58Z
|
||||
lastUpdateTime: 2019-04-26T20:19:29Z
|
||||
message: ReplicaSet "example-rollout-canary-6b566f47b7" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: "True"
|
||||
type: Progressing
|
||||
currentPodHash: 6b566f47b7
|
||||
currentStepHash: 6567fc959c
|
||||
currentStepIndex: 3
|
||||
observedGeneration: 6df79499bc
|
||||
readyReplicas: 5
|
||||
replicas: 5
|
||||
selector: app=guestbook
|
||||
updatedReplicas: 2
|
||||
71
resource_customizations/argoproj.io/Rollout/testdata/canary/suspended_pausedStep.yaml
vendored
Normal file
71
resource_customizations/argoproj.io/Rollout/testdata/canary/suspended_pausedStep.yaml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"name":"example-rollout-canary","namespace":"default"},"spec":{"minReadySeconds":30,"replicas":5,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook"}},"strategy":{"canary":{"steps":[{"setWeight":20},{"pause":{"duration":20}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: "2"
|
||||
clusterName: ""
|
||||
creationTimestamp: 2019-04-26T20:17:43Z
|
||||
generation: 1
|
||||
name: example-rollout-canary
|
||||
namespace: default
|
||||
resourceVersion: "696597"
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/example-rollout-canary
|
||||
uid: 58f6f1bb-6860-11e9-b8d7-025000000001
|
||||
spec:
|
||||
minReadySeconds: 30
|
||||
paused: true
|
||||
replicas: 5
|
||||
revisionHistoryLimit: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook
|
||||
strategy:
|
||||
canary:
|
||||
steps:
|
||||
- setWeight: 20
|
||||
- pause:
|
||||
duration: 20
|
||||
- setWeight: 40
|
||||
- pause: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: guestbook
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
name: guestbook
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 5
|
||||
availableReplicas: 5
|
||||
blueGreen: {}
|
||||
canary:
|
||||
stableRS: df986d68
|
||||
conditions:
|
||||
- lastTransitionTime: 2019-04-26T20:18:05Z
|
||||
lastUpdateTime: 2019-04-26T20:18:05Z
|
||||
message: Rollout is not serving traffic from the active service.
|
||||
reason: Available
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: 2019-04-26T20:18:38Z
|
||||
lastUpdateTime: 2019-04-26T20:18:38Z
|
||||
message: Rollout is paused
|
||||
reason: RolloutPaused
|
||||
status: Unknown
|
||||
type: Progressing
|
||||
currentPodHash: 6b566f47b7
|
||||
currentStepHash: 6567fc959c
|
||||
currentStepIndex: 1
|
||||
observedGeneration: 5c788f4484
|
||||
pauseStartTime: 2019-04-26T20:18:38Z
|
||||
readyReplicas: 5
|
||||
replicas: 5
|
||||
selector: app=guestbook
|
||||
updatedReplicas: 1
|
||||
84
resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml
vendored
Normal file
84
resource_customizations/argoproj.io/Rollout/testdata/degraded_rolloutTimeout.yaml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
rollout.argoproj.io/revision: '4'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-04-29T21:37:38Z'
|
||||
generation: 1
|
||||
labels:
|
||||
app: helm-guestbook
|
||||
app.kubernetes.io/instance: guestbook-bluegreen
|
||||
chart: helm-guestbook-0.1.0
|
||||
heritage: Tiller
|
||||
release: guestbook-bluegreen
|
||||
name: guestbook-bluegreen-helm-guestbook
|
||||
namespace: default
|
||||
selfLink: >-
|
||||
/apis/argoproj.io/v1alpha1/namespaces/default/rollouts/guestbook-bluegreen-helm-guestbook
|
||||
spec:
|
||||
minReadySeconds: 0
|
||||
progressDeadlineSeconds: 32
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: helm-guestbook
|
||||
release: guestbook-bluegreen
|
||||
strategy:
|
||||
blueGreen:
|
||||
activeService: guestbook-bluegreen-helm-guestbook
|
||||
previewReplicaCount: 1
|
||||
previewService: guestbook-bluegreen-helm-guestbook-preview
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: helm-guestbook
|
||||
release: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.3'
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
name: helm-guestbook
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources: {}
|
||||
status:
|
||||
HPAReplicas: 3
|
||||
availableReplicas: 3
|
||||
blueGreen:
|
||||
activeSelector: 8464d8564d
|
||||
canary: {}
|
||||
conditions:
|
||||
- lastTransitionTime: '2019-05-01T17:52:59Z'
|
||||
lastUpdateTime: '2019-05-01T17:52:59Z'
|
||||
message: Rollout has minimum availability
|
||||
reason: AvailableReason
|
||||
status: 'True'
|
||||
type: Available
|
||||
- lastTransitionTime: '2019-05-01T21:36:03Z'
|
||||
lastUpdateTime: '2019-05-01T21:36:03Z'
|
||||
message: >-
|
||||
ReplicaSet "guestbook-bluegreen-helm-guestbook-6b8cf6f7db" has timed out
|
||||
progressing.
|
||||
reason: ProgressDeadlineExceeded
|
||||
status: 'False'
|
||||
type: Progressing
|
||||
currentPodHash: 6b8cf6f7db
|
||||
observedGeneration: 7bcdbf7bd9
|
||||
readyReplicas: 3
|
||||
replicas: 4
|
||||
selector: >-
|
||||
app=helm-guestbook,release=guestbook-bluegreen,rollouts-pod-template-hash=8464d8564d
|
||||
updatedReplicas: 1
|
||||
56
resource_customizations/argoproj.io/Rollout/testdata/v0.2_suspended_servingPreviewService.yaml
vendored
Normal file
56
resource_customizations/argoproj.io/Rollout/testdata/v0.2_suspended_servingPreviewService.yaml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
rollout.argoproj.io/revision: "7"
|
||||
clusterName: ""
|
||||
creationTimestamp: 2019-01-22T16:52:54Z
|
||||
generation: 1
|
||||
labels:
|
||||
app.kubernetes.io/instance: guestbook-default
|
||||
name: ks-guestbook-ui
|
||||
namespace: default
|
||||
resourceVersion: "164113"
|
||||
selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/rollouts/ks-guestbook-ui
|
||||
uid: 29802403-1e66-11e9-a6a4-025000000001
|
||||
spec:
|
||||
minReadySeconds: 30
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ks-guestbook-ui
|
||||
strategy:
|
||||
blueGreen:
|
||||
activeService: ks-guestbook-ui-active
|
||||
previewService: ks-guestbook-ui-preview
|
||||
type: BlueGreenUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 83
|
||||
resources: {}
|
||||
status:
|
||||
blueGreen:
|
||||
activeSelector: 85f9884f5d
|
||||
previewSelector: 697fb9575c
|
||||
availableReplicas: 6
|
||||
conditions:
|
||||
- lastTransitionTime: 2019-01-25T07:44:26Z
|
||||
lastUpdateTime: 2019-01-25T07:44:26Z
|
||||
message: Rollout is serving traffic from the active service.
|
||||
reason: Available
|
||||
status: "True"
|
||||
type: Available
|
||||
currentPodHash: 697fb9575c
|
||||
observedGeneration: 767f98959f
|
||||
readyReplicas: 6
|
||||
replicas: 6
|
||||
updatedReplicas: 3
|
||||
verifyingPreview: true
|
||||
@@ -37,7 +37,7 @@ func (m *UpdatePasswordRequest) Reset() { *m = UpdatePasswordRequest{} }
|
||||
func (m *UpdatePasswordRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdatePasswordRequest) ProtoMessage() {}
|
||||
func (*UpdatePasswordRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_account_c12a236fbb4926f3, []int{0}
|
||||
return fileDescriptor_account_6b332ae3d6f3a375, []int{0}
|
||||
}
|
||||
func (m *UpdatePasswordRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -90,7 +90,7 @@ func (m *UpdatePasswordResponse) Reset() { *m = UpdatePasswordResponse{}
|
||||
func (m *UpdatePasswordResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdatePasswordResponse) ProtoMessage() {}
|
||||
func (*UpdatePasswordResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_account_c12a236fbb4926f3, []int{1}
|
||||
return fileDescriptor_account_6b332ae3d6f3a375, []int{1}
|
||||
}
|
||||
func (m *UpdatePasswordResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -566,10 +566,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/account/account.proto", fileDescriptor_account_c12a236fbb4926f3)
|
||||
proto.RegisterFile("server/account/account.proto", fileDescriptor_account_6b332ae3d6f3a375)
|
||||
}
|
||||
|
||||
var fileDescriptor_account_c12a236fbb4926f3 = []byte{
|
||||
var fileDescriptor_account_6b332ae3d6f3a375 = []byte{
|
||||
// 268 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0x4e, 0x2d, 0x2a,
|
||||
0x4b, 0x2d, 0xd2, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x81, 0xd1, 0x7a, 0x05, 0x45, 0xf9,
|
||||
|
||||
@@ -19,11 +19,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
|
||||
"github.com/argoproj/argo-cd/reposerver"
|
||||
"github.com/argoproj/argo-cd/reposerver/repository"
|
||||
@@ -163,8 +164,10 @@ func (s *Server) GetManifests(ctx context.Context, q *ApplicationManifestQuery)
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName(*a)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo := s.getRepo(ctx, a.Spec.Source.RepoURL)
|
||||
|
||||
repo, err := s.db.GetRepository(ctx, a.Spec.Source.RepoURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, repoClient, err := s.repoClientset.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -406,9 +409,9 @@ func (s *Server) Delete(ctx context.Context, q *ApplicationDeleteRequest) (*Appl
|
||||
}
|
||||
|
||||
if patchFinalizer {
|
||||
// Prior to v0.6, the cascaded deletion finalizer was set during app creation.
|
||||
// For backward compatibility, we always calculate the patch to see if we need to
|
||||
// set/unset the finalizer (in case we are dealing with an app created prior to v0.6)
|
||||
// Although the cascaded deletion finalizer is not set when apps are created via API,
|
||||
// they will often be set by the user as part of declarative config. As part of a delete
|
||||
// request, we always calculate the patch to see if we need to set/unset the finalizer.
|
||||
patch, err := json.Marshal(map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"finalizers": a.Finalizers,
|
||||
@@ -433,33 +436,62 @@ func (s *Server) Delete(ctx context.Context, q *ApplicationDeleteRequest) (*Appl
|
||||
}
|
||||
|
||||
func (s *Server) Watch(q *ApplicationQuery, ws ApplicationService_WatchServer) error {
|
||||
w, err := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Watch(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Stop()
|
||||
logCtx := log.NewEntry(log.New())
|
||||
if q.Name != nil {
|
||||
logCtx = logCtx.WithField("application", *q.Name)
|
||||
}
|
||||
claims := ws.Context().Value("claims")
|
||||
// sendIfPermitted is a helper to send the application to the client's streaming channel if the
|
||||
// caller has RBAC privileges permissions to view it
|
||||
sendIfPermitted := func(a appv1.Application, eventType watch.EventType) error {
|
||||
if !s.enf.Enforce(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName(a)) {
|
||||
// do not emit apps user does not have accessing
|
||||
return nil
|
||||
}
|
||||
err := ws.Send(&appv1.ApplicationWatchEvent{
|
||||
Type: eventType,
|
||||
Application: a,
|
||||
})
|
||||
if err != nil {
|
||||
logCtx.Warnf("Unable to send stream message: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var listOpts metav1.ListOptions
|
||||
if q.Name != nil && *q.Name != "" {
|
||||
listOpts.FieldSelector = fmt.Sprintf("metadata.name=%s", *q.Name)
|
||||
}
|
||||
listOpts.ResourceVersion = q.ResourceVersion
|
||||
if listOpts.ResourceVersion == "" {
|
||||
// If resourceVersion is not supplied, we need to get latest version of the apps by first
|
||||
// making a list request, which we then supply to the watch request. We always need to
|
||||
// supply a resourceVersion to watch requests since without it, the return values may return
|
||||
// stale data. See: https://github.com/argoproj/argo-cd/issues/1605
|
||||
appsList, err := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).List(listOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, a := range appsList.Items {
|
||||
err = sendIfPermitted(a, watch.Modified)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
listOpts.ResourceVersion = appsList.ResourceVersion
|
||||
}
|
||||
|
||||
w, err := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Watch(listOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Stop()
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
for next := range w.ResultChan() {
|
||||
a := *next.Object.(*appv1.Application)
|
||||
if q.Name == nil || *q.Name == "" || *q.Name == a.Name {
|
||||
if !s.enf.Enforce(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName(a)) {
|
||||
// do not emit apps user does not have accessing
|
||||
continue
|
||||
}
|
||||
err = ws.Send(&appv1.ApplicationWatchEvent{
|
||||
Type: next.Type,
|
||||
Application: a,
|
||||
})
|
||||
if err != nil {
|
||||
logCtx.Warnf("Unable to send stream message: %v", err)
|
||||
}
|
||||
}
|
||||
_ = sendIfPermitted(a, next.Type)
|
||||
}
|
||||
logCtx.Info("k8s application watch event channel closed")
|
||||
close(done)
|
||||
@@ -501,7 +533,14 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica
|
||||
}
|
||||
}
|
||||
|
||||
conditions, appSourceType, err := argo.GetSpecErrors(ctx, &app.Spec, proj, s.repoClientset, s.db)
|
||||
conditions, err := argo.ValidatePermissions(ctx, &app.Spec, proj, s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(conditions) > 0 {
|
||||
return status.Errorf(codes.InvalidArgument, "application spec is invalid: %s", argo.FormatAppConditions(conditions))
|
||||
}
|
||||
conditions, appSourceType, err := argo.ValidateRepo(ctx, &app.Spec, s.repoClientset, s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -772,15 +811,6 @@ func (s *Server) getApplicationDestination(ctx context.Context, name string) (st
|
||||
return server, namespace, nil
|
||||
}
|
||||
|
||||
func (s *Server) getRepo(ctx context.Context, repoURL string) *appv1.Repository {
|
||||
repo, err := s.db.GetRepository(ctx, repoURL)
|
||||
if err != nil {
|
||||
// If we couldn't retrieve from the repo service, assume public repositories
|
||||
repo = &appv1.Repository{Repo: repoURL}
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
// Sync syncs an application to its target state
|
||||
func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*appv1.Application, error) {
|
||||
appIf := s.appclientset.ArgoprojV1alpha1().Applications(s.ns)
|
||||
@@ -795,7 +825,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*ap
|
||||
return nil, status.Errorf(codes.FailedPrecondition, "application is deleting")
|
||||
}
|
||||
if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil {
|
||||
if syncReq.Revision != "" && syncReq.Revision != a.Spec.Source.TargetRevision {
|
||||
if syncReq.Revision != "" && syncReq.Revision != util.FirstNonEmpty(a.Spec.Source.TargetRevision, "HEAD") {
|
||||
return nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.Revision, a.Spec.Source.TargetRevision)
|
||||
}
|
||||
}
|
||||
@@ -887,8 +917,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
|
||||
}
|
||||
repo, err := s.db.GetRepository(ctx, app.Spec.Source.RepoURL)
|
||||
if err != nil {
|
||||
// If we couldn't retrieve from the repo service, assume public repositories
|
||||
repo = &appv1.Repository{Repo: app.Spec.Source.RepoURL}
|
||||
return "", "", err
|
||||
}
|
||||
gitClient, err := s.gitFactory.NewClient(repo.Repo, "", repo.Username, repo.Password, repo.SSHPrivateKey, repo.InsecureIgnoreHostKey)
|
||||
if err != nil {
|
||||
|
||||
@@ -42,6 +42,7 @@ type ApplicationQuery struct {
|
||||
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
Refresh *string `protobuf:"bytes,2,opt,name=refresh" json:"refresh,omitempty"`
|
||||
Projects []string `protobuf:"bytes,3,rep,name=project" json:"project,omitempty"`
|
||||
ResourceVersion string `protobuf:"bytes,4,opt,name=resourceVersion" json:"resourceVersion"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -51,7 +52,7 @@ func (m *ApplicationQuery) Reset() { *m = ApplicationQuery{} }
|
||||
func (m *ApplicationQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationQuery) ProtoMessage() {}
|
||||
func (*ApplicationQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{0}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{0}
|
||||
}
|
||||
func (m *ApplicationQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -101,6 +102,13 @@ func (m *ApplicationQuery) GetProjects() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ApplicationQuery) GetResourceVersion() string {
|
||||
if m != nil {
|
||||
return m.ResourceVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ApplicationEventsQuery is a query for application resource events
|
||||
type ApplicationResourceEventsQuery struct {
|
||||
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
|
||||
@@ -116,7 +124,7 @@ func (m *ApplicationResourceEventsQuery) Reset() { *m = ApplicationResou
|
||||
func (m *ApplicationResourceEventsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResourceEventsQuery) ProtoMessage() {}
|
||||
func (*ApplicationResourceEventsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{1}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{1}
|
||||
}
|
||||
func (m *ApplicationResourceEventsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -186,7 +194,7 @@ func (m *ApplicationManifestQuery) Reset() { *m = ApplicationManifestQue
|
||||
func (m *ApplicationManifestQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationManifestQuery) ProtoMessage() {}
|
||||
func (*ApplicationManifestQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{2}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{2}
|
||||
}
|
||||
func (m *ApplicationManifestQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -239,7 +247,7 @@ func (m *ApplicationResponse) Reset() { *m = ApplicationResponse{} }
|
||||
func (m *ApplicationResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResponse) ProtoMessage() {}
|
||||
func (*ApplicationResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{3}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{3}
|
||||
}
|
||||
func (m *ApplicationResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -280,7 +288,7 @@ func (m *ApplicationCreateRequest) Reset() { *m = ApplicationCreateReque
|
||||
func (m *ApplicationCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationCreateRequest) ProtoMessage() {}
|
||||
func (*ApplicationCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{4}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{4}
|
||||
}
|
||||
func (m *ApplicationCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -334,7 +342,7 @@ func (m *ApplicationUpdateRequest) Reset() { *m = ApplicationUpdateReque
|
||||
func (m *ApplicationUpdateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationUpdateRequest) ProtoMessage() {}
|
||||
func (*ApplicationUpdateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{5}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{5}
|
||||
}
|
||||
func (m *ApplicationUpdateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -382,7 +390,7 @@ func (m *ApplicationDeleteRequest) Reset() { *m = ApplicationDeleteReque
|
||||
func (m *ApplicationDeleteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationDeleteRequest) ProtoMessage() {}
|
||||
func (*ApplicationDeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{6}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{6}
|
||||
}
|
||||
func (m *ApplicationDeleteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -442,7 +450,7 @@ func (m *ApplicationSyncRequest) Reset() { *m = ApplicationSyncRequest{}
|
||||
func (m *ApplicationSyncRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationSyncRequest) ProtoMessage() {}
|
||||
func (*ApplicationSyncRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{7}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{7}
|
||||
}
|
||||
func (m *ApplicationSyncRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -526,7 +534,7 @@ func (m *ApplicationUpdateSpecRequest) Reset() { *m = ApplicationUpdateS
|
||||
func (m *ApplicationUpdateSpecRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationUpdateSpecRequest) ProtoMessage() {}
|
||||
func (*ApplicationUpdateSpecRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{8}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{8}
|
||||
}
|
||||
func (m *ApplicationUpdateSpecRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -582,7 +590,7 @@ func (m *ApplicationPatchRequest) Reset() { *m = ApplicationPatchRequest
|
||||
func (m *ApplicationPatchRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationPatchRequest) ProtoMessage() {}
|
||||
func (*ApplicationPatchRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{9}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{9}
|
||||
}
|
||||
func (m *ApplicationPatchRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -639,7 +647,7 @@ func (m *ApplicationRollbackRequest) Reset() { *m = ApplicationRollbackR
|
||||
func (m *ApplicationRollbackRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationRollbackRequest) ProtoMessage() {}
|
||||
func (*ApplicationRollbackRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{10}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{10}
|
||||
}
|
||||
func (m *ApplicationRollbackRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -712,7 +720,7 @@ func (m *ApplicationResourceRequest) Reset() { *m = ApplicationResourceR
|
||||
func (m *ApplicationResourceRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResourceRequest) ProtoMessage() {}
|
||||
func (*ApplicationResourceRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{11}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{11}
|
||||
}
|
||||
func (m *ApplicationResourceRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -801,7 +809,7 @@ func (m *ApplicationResourcePatchRequest) Reset() { *m = ApplicationReso
|
||||
func (m *ApplicationResourcePatchRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResourcePatchRequest) ProtoMessage() {}
|
||||
func (*ApplicationResourcePatchRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{12}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{12}
|
||||
}
|
||||
func (m *ApplicationResourcePatchRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -903,7 +911,7 @@ func (m *ApplicationResourceDeleteRequest) Reset() { *m = ApplicationRes
|
||||
func (m *ApplicationResourceDeleteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResourceDeleteRequest) ProtoMessage() {}
|
||||
func (*ApplicationResourceDeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{13}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{13}
|
||||
}
|
||||
func (m *ApplicationResourceDeleteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -998,7 +1006,7 @@ func (m *ResourceActionRunRequest) Reset() { *m = ResourceActionRunReque
|
||||
func (m *ResourceActionRunRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ResourceActionRunRequest) ProtoMessage() {}
|
||||
func (*ResourceActionRunRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{14}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{14}
|
||||
}
|
||||
func (m *ResourceActionRunRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1087,7 +1095,7 @@ func (m *ResourceActionsListResponse) Reset() { *m = ResourceActionsList
|
||||
func (m *ResourceActionsListResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ResourceActionsListResponse) ProtoMessage() {}
|
||||
func (*ResourceActionsListResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{15}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{15}
|
||||
}
|
||||
func (m *ResourceActionsListResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1134,7 +1142,7 @@ func (m *ApplicationResourceResponse) Reset() { *m = ApplicationResource
|
||||
func (m *ApplicationResourceResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationResourceResponse) ProtoMessage() {}
|
||||
func (*ApplicationResourceResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{16}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{16}
|
||||
}
|
||||
func (m *ApplicationResourceResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1188,7 +1196,7 @@ func (m *ApplicationPodLogsQuery) Reset() { *m = ApplicationPodLogsQuery
|
||||
func (m *ApplicationPodLogsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ApplicationPodLogsQuery) ProtoMessage() {}
|
||||
func (*ApplicationPodLogsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{17}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{17}
|
||||
}
|
||||
func (m *ApplicationPodLogsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1285,7 +1293,7 @@ func (m *LogEntry) Reset() { *m = LogEntry{} }
|
||||
func (m *LogEntry) String() string { return proto.CompactTextString(m) }
|
||||
func (*LogEntry) ProtoMessage() {}
|
||||
func (*LogEntry) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{18}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{18}
|
||||
}
|
||||
func (m *LogEntry) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1339,7 +1347,7 @@ func (m *OperationTerminateRequest) Reset() { *m = OperationTerminateReq
|
||||
func (m *OperationTerminateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*OperationTerminateRequest) ProtoMessage() {}
|
||||
func (*OperationTerminateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{19}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{19}
|
||||
}
|
||||
func (m *OperationTerminateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1385,7 +1393,7 @@ func (m *OperationTerminateResponse) Reset() { *m = OperationTerminateRe
|
||||
func (m *OperationTerminateResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*OperationTerminateResponse) ProtoMessage() {}
|
||||
func (*OperationTerminateResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{20}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{20}
|
||||
}
|
||||
func (m *OperationTerminateResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1425,7 +1433,7 @@ func (m *ResourcesQuery) Reset() { *m = ResourcesQuery{} }
|
||||
func (m *ResourcesQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ResourcesQuery) ProtoMessage() {}
|
||||
func (*ResourcesQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{21}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{21}
|
||||
}
|
||||
func (m *ResourcesQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1472,7 +1480,7 @@ func (m *ManagedResourcesResponse) Reset() { *m = ManagedResourcesRespon
|
||||
func (m *ManagedResourcesResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ManagedResourcesResponse) ProtoMessage() {}
|
||||
func (*ManagedResourcesResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_application_c1cee2c3bb672fdc, []int{22}
|
||||
return fileDescriptor_application_5178689ec7ddb110, []int{22}
|
||||
}
|
||||
func (m *ManagedResourcesResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -2397,6 +2405,10 @@ func (m *ApplicationQuery) MarshalTo(dAtA []byte) (int, error) {
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
dAtA[i] = 0x22
|
||||
i++
|
||||
i = encodeVarintApplication(dAtA, i, uint64(len(m.ResourceVersion)))
|
||||
i += copy(dAtA[i:], m.ResourceVersion)
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
@@ -3314,6 +3326,8 @@ func (m *ApplicationQuery) Size() (n int) {
|
||||
n += 1 + l + sovApplication(uint64(l))
|
||||
}
|
||||
}
|
||||
l = len(m.ResourceVersion)
|
||||
n += 1 + l + sovApplication(uint64(l))
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
@@ -3828,6 +3842,35 @@ func (m *ApplicationQuery) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
m.Projects = append(m.Projects, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ResourceVersion", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowApplication
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthApplication
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ResourceVersion = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipApplication(dAtA[iNdEx:])
|
||||
@@ -7221,121 +7264,121 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/application/application.proto", fileDescriptor_application_c1cee2c3bb672fdc)
|
||||
proto.RegisterFile("server/application/application.proto", fileDescriptor_application_5178689ec7ddb110)
|
||||
}
|
||||
|
||||
var fileDescriptor_application_c1cee2c3bb672fdc = []byte{
|
||||
// 1779 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0xdc, 0xc6,
|
||||
0x15, 0xef, 0xec, 0xae, 0x76, 0x57, 0x4f, 0xaa, 0x6b, 0x8f, 0x3f, 0x4a, 0x53, 0xb2, 0xb4, 0x18,
|
||||
0xcb, 0xb2, 0x2c, 0x5b, 0xa4, 0xa5, 0x1a, 0xad, 0x21, 0x18, 0xb0, 0xad, 0xca, 0x95, 0x55, 0xc8,
|
||||
0xaa, 0xba, 0x92, 0x51, 0xa0, 0x40, 0x51, 0xd0, 0xe4, 0x68, 0xc5, 0x6a, 0x97, 0x64, 0x49, 0xee,
|
||||
0x16, 0x5b, 0xc3, 0x87, 0x1a, 0x45, 0xd1, 0x43, 0x90, 0x20, 0x48, 0x0e, 0x4e, 0x90, 0x2f, 0xf8,
|
||||
0x9c, 0x5b, 0x90, 0x4b, 0x0e, 0xb9, 0x05, 0xf0, 0x31, 0x40, 0x72, 0x36, 0x02, 0xc5, 0x7f, 0x40,
|
||||
0x4e, 0x39, 0x07, 0x33, 0x1c, 0x72, 0x87, 0xd2, 0x2e, 0x57, 0xb2, 0x37, 0x07, 0xdf, 0xb8, 0x6f,
|
||||
0x86, 0xef, 0xfd, 0xde, 0xc7, 0xbc, 0x79, 0x3f, 0x2e, 0x4c, 0x05, 0xd4, 0x6f, 0x51, 0x5f, 0x37,
|
||||
0x3c, 0xaf, 0x6e, 0x9b, 0x46, 0x68, 0xbb, 0x8e, 0xfc, 0xac, 0x79, 0xbe, 0x1b, 0xba, 0x78, 0x44,
|
||||
0x12, 0xa9, 0xa7, 0x6a, 0x6e, 0xcd, 0xe5, 0x72, 0x9d, 0x3d, 0x45, 0x5b, 0xd4, 0xf1, 0x9a, 0xeb,
|
||||
0xd6, 0xea, 0x54, 0x37, 0x3c, 0x5b, 0x37, 0x1c, 0xc7, 0x0d, 0xf9, 0xe6, 0x40, 0xac, 0x92, 0xdd,
|
||||
0xeb, 0x81, 0x66, 0xbb, 0x7c, 0xd5, 0x74, 0x7d, 0xaa, 0xb7, 0xe6, 0xf5, 0x1a, 0x75, 0xa8, 0x6f,
|
||||
0x84, 0xd4, 0x12, 0x7b, 0xae, 0x75, 0xf6, 0x34, 0x0c, 0x73, 0xc7, 0x76, 0xa8, 0xdf, 0xd6, 0xbd,
|
||||
0xdd, 0x1a, 0x13, 0x04, 0x7a, 0x83, 0x86, 0x46, 0xb7, 0xb7, 0x56, 0x6b, 0x76, 0xb8, 0xd3, 0x7c,
|
||||
0xa0, 0x99, 0x6e, 0x43, 0x37, 0x7c, 0x0e, 0xec, 0x1f, 0xfc, 0x61, 0xce, 0xb4, 0x3a, 0x6f, 0xcb,
|
||||
0xee, 0xb5, 0xe6, 0x8d, 0xba, 0xb7, 0x63, 0x1c, 0x54, 0xb5, 0x94, 0xa5, 0xca, 0xa7, 0x9e, 0x2b,
|
||||
0x62, 0xc5, 0x1f, 0xed, 0xd0, 0xf5, 0xdb, 0xd2, 0x63, 0xa4, 0x83, 0xec, 0xc0, 0xf1, 0xdb, 0x1d,
|
||||
0x5b, 0x7f, 0x6e, 0x52, 0xbf, 0x8d, 0x31, 0x14, 0x1c, 0xa3, 0x41, 0x15, 0x54, 0x41, 0x33, 0xc3,
|
||||
0x55, 0xfe, 0x8c, 0x15, 0x28, 0xf9, 0x74, 0xdb, 0xa7, 0xc1, 0x8e, 0x92, 0xe3, 0xe2, 0xf8, 0x27,
|
||||
0x9e, 0x86, 0x12, 0x33, 0x4c, 0xcd, 0x50, 0xc9, 0x57, 0xf2, 0x33, 0xc3, 0x4b, 0xa3, 0x7b, 0xcf,
|
||||
0x27, 0xcb, 0x1b, 0x91, 0x28, 0xa8, 0xc6, 0x8b, 0xe4, 0x0b, 0x04, 0x13, 0x92, 0xa9, 0x2a, 0x0d,
|
||||
0xdc, 0xa6, 0x6f, 0xd2, 0x3b, 0x2d, 0xea, 0x84, 0xc1, 0x7e, 0xc3, 0xb9, 0xc4, 0xf0, 0x02, 0x9c,
|
||||
0xf0, 0xc5, 0xd6, 0x75, 0xa3, 0x41, 0x03, 0xcf, 0x30, 0xa9, 0x92, 0x63, 0x1b, 0x96, 0x0a, 0xcf,
|
||||
0x9e, 0x4f, 0xfe, 0xa2, 0x7a, 0x70, 0x19, 0xcf, 0xc0, 0xa8, 0x2c, 0x54, 0xf2, 0xd2, 0xf6, 0xd4,
|
||||
0x0a, 0x9e, 0x86, 0x91, 0xf8, 0xf7, 0xfd, 0xd5, 0x65, 0xa5, 0x20, 0x6d, 0x94, 0x17, 0xc8, 0x06,
|
||||
0x28, 0x12, 0xf6, 0x7b, 0x86, 0x63, 0x6f, 0xd3, 0x20, 0xec, 0x8d, 0xba, 0x02, 0x65, 0x9f, 0xb6,
|
||||
0xec, 0xc0, 0x76, 0x9d, 0x28, 0x5e, 0x42, 0x69, 0x22, 0x25, 0xa7, 0xe1, 0x64, 0x3a, 0x1a, 0x9e,
|
||||
0xeb, 0x04, 0x94, 0x3c, 0x45, 0x29, 0x4b, 0xbf, 0xf7, 0xa9, 0x11, 0xd2, 0x2a, 0xfd, 0x67, 0x93,
|
||||
0x06, 0x21, 0x76, 0x40, 0x2e, 0x6c, 0x6e, 0x70, 0x64, 0xe1, 0x0f, 0x5a, 0xa7, 0x0c, 0xb4, 0xb8,
|
||||
0x0c, 0xf8, 0xc3, 0xdf, 0x4d, 0x4b, 0xf3, 0x76, 0x6b, 0x1a, 0xab, 0x28, 0x4d, 0x3e, 0x24, 0x71,
|
||||
0x45, 0x69, 0x92, 0xa5, 0xd8, 0x6b, 0x69, 0x1f, 0x3e, 0x03, 0xc5, 0xa6, 0x17, 0x50, 0x3f, 0xe4,
|
||||
0x3e, 0x94, 0xab, 0xe2, 0x17, 0xf9, 0x6f, 0x1a, 0xe4, 0x7d, 0xcf, 0x92, 0x40, 0xee, 0xfc, 0x8c,
|
||||
0x20, 0x53, 0xf0, 0xc8, 0xdd, 0x14, 0x8a, 0x65, 0x5a, 0xa7, 0x1d, 0x14, 0xdd, 0x92, 0xa2, 0x40,
|
||||
0xc9, 0x34, 0x02, 0xd3, 0xb0, 0xa8, 0xf0, 0x27, 0xfe, 0x49, 0xbe, 0xcf, 0xc1, 0x19, 0x49, 0xd5,
|
||||
0x66, 0xdb, 0x31, 0xb3, 0x14, 0xf5, 0xcd, 0x2e, 0x1e, 0x87, 0xa2, 0xe5, 0xb7, 0xab, 0x4d, 0x47,
|
||||
0xc9, 0x33, 0x4b, 0x62, 0x5d, 0xc8, 0xb0, 0x0a, 0x43, 0x9e, 0xdf, 0x74, 0xa8, 0x52, 0x90, 0x16,
|
||||
0x23, 0x11, 0x36, 0xa1, 0x1c, 0x84, 0xec, 0x94, 0xd7, 0xda, 0xca, 0x50, 0x05, 0xcd, 0x8c, 0x2c,
|
||||
0xac, 0xbc, 0x42, 0xec, 0x98, 0x27, 0x9b, 0x42, 0x5d, 0x35, 0x51, 0x8c, 0x43, 0x18, 0x8e, 0xab,
|
||||
0x3b, 0x50, 0x4a, 0x95, 0xfc, 0xcc, 0xc8, 0xc2, 0xc6, 0x2b, 0x5a, 0xf9, 0x93, 0xc7, 0x7a, 0x93,
|
||||
0x74, 0xb0, 0x85, 0x5b, 0x1d, 0x43, 0xe4, 0x09, 0x82, 0xf1, 0x03, 0x65, 0xb3, 0xe9, 0xd1, 0xcc,
|
||||
0x58, 0x5b, 0x50, 0x08, 0x3c, 0x6a, 0xf2, 0x23, 0x3f, 0xb2, 0xf0, 0xc7, 0xc1, 0xd4, 0x11, 0x33,
|
||||
0x2a, 0xf0, 0x71, 0xed, 0x64, 0x15, 0x7e, 0x2d, 0x2d, 0x6f, 0x18, 0xa1, 0xb9, 0x93, 0x05, 0x8a,
|
||||
0x25, 0x90, 0xed, 0x49, 0x35, 0xa2, 0x48, 0x44, 0xfe, 0x87, 0x40, 0x95, 0x4b, 0xd6, 0xad, 0xd7,
|
||||
0x1f, 0x18, 0xe6, 0x6e, 0xb6, 0xba, 0x9c, 0x6d, 0x71, 0x5d, 0xf9, 0x25, 0x60, 0xba, 0xf6, 0x9e,
|
||||
0x4f, 0xe6, 0x56, 0x97, 0xab, 0x39, 0xdb, 0x7a, 0xf9, 0x4a, 0x22, 0xdf, 0xee, 0x03, 0x22, 0xf2,
|
||||
0x90, 0x05, 0x84, 0xc0, 0xb0, 0xd3, 0xb5, 0xc9, 0x76, 0xc4, 0x47, 0x68, 0xae, 0x13, 0x50, 0x6a,
|
||||
0x51, 0x9f, 0x9f, 0x12, 0xb9, 0xb1, 0xc6, 0x42, 0x06, 0xbe, 0xe6, 0xbb, 0x4d, 0x4f, 0x19, 0x92,
|
||||
0xa3, 0xc8, 0x45, 0x58, 0x81, 0xc2, 0xae, 0xed, 0x58, 0x4a, 0x51, 0x5a, 0xe2, 0x12, 0xf2, 0x5e,
|
||||
0x0e, 0x26, 0xbb, 0xb8, 0xd5, 0x37, 0x67, 0xaf, 0x81, 0x6f, 0x9d, 0xba, 0x2a, 0x1d, 0xa8, 0x2b,
|
||||
0x86, 0x9f, 0x3f, 0x6c, 0xb5, 0x3d, 0xaa, 0x94, 0x65, 0xfc, 0x89, 0x98, 0xfc, 0x88, 0xa0, 0xd2,
|
||||
0x25, 0x36, 0xfd, 0x5b, 0xe3, 0x6b, 0x12, 0x9c, 0x6d, 0xd7, 0x37, 0xa9, 0x52, 0x4a, 0x6a, 0x1d,
|
||||
0x55, 0x23, 0x11, 0xf9, 0x01, 0x81, 0x12, 0x7b, 0x7b, 0xdb, 0xe4, 0xbe, 0x37, 0x9d, 0xd7, 0xdd,
|
||||
0xe1, 0x71, 0x28, 0x1a, 0xdc, 0x97, 0x54, 0x39, 0x08, 0x19, 0xf9, 0x3f, 0x82, 0xb1, 0xb4, 0xcb,
|
||||
0xc1, 0x9a, 0x1d, 0x84, 0xf1, 0x24, 0x81, 0x6d, 0x28, 0x45, 0x3b, 0x03, 0x05, 0xf1, 0x0e, 0xbf,
|
||||
0xfa, 0x0a, 0xbd, 0x33, 0x6d, 0x28, 0x76, 0x4f, 0xe8, 0x27, 0x37, 0x61, 0xac, 0x6b, 0xa3, 0x11,
|
||||
0x48, 0x2a, 0x50, 0x6e, 0x88, 0x89, 0x29, 0xca, 0x41, 0x7c, 0x5d, 0xc6, 0x52, 0xf2, 0x55, 0x2e,
|
||||
0xdd, 0x7f, 0x5d, 0x6b, 0xcd, 0xad, 0x65, 0x0c, 0x85, 0x87, 0xc9, 0x9e, 0x02, 0x25, 0xcf, 0xb5,
|
||||
0x3a, 0x89, 0xab, 0xc6, 0x3f, 0xd9, 0xdb, 0xa6, 0xeb, 0x84, 0x06, 0x9b, 0xd8, 0x53, 0xf9, 0xea,
|
||||
0x88, 0x59, 0xee, 0x03, 0xdb, 0x31, 0xe9, 0x26, 0x35, 0x5d, 0xc7, 0x0a, 0x78, 0xe2, 0xf2, 0x71,
|
||||
0xee, 0xe5, 0x15, 0x7c, 0x17, 0x86, 0xf9, 0xef, 0x2d, 0xbb, 0x41, 0x95, 0x22, 0xbf, 0xb1, 0x67,
|
||||
0xb5, 0x88, 0x1a, 0x68, 0x32, 0x35, 0xe8, 0x44, 0x98, 0x51, 0x03, 0xad, 0x35, 0xaf, 0xb1, 0x37,
|
||||
0xaa, 0x9d, 0x97, 0x19, 0xae, 0xd0, 0xb0, 0xeb, 0x6b, 0xb6, 0xc3, 0x6f, 0xe5, 0x8e, 0xc1, 0x8e,
|
||||
0x98, 0xd5, 0xc4, 0xb6, 0x5b, 0xaf, 0xbb, 0xff, 0xe2, 0x2d, 0x20, 0xb9, 0x0e, 0x22, 0x19, 0xf9,
|
||||
0x37, 0x94, 0xd7, 0xdc, 0xda, 0x1d, 0x27, 0xf4, 0xdb, 0xac, 0x26, 0x99, 0x3b, 0xd4, 0x49, 0x07,
|
||||
0x3d, 0x16, 0xe2, 0x75, 0x18, 0x0e, 0xed, 0x06, 0xdd, 0x0c, 0x8d, 0x86, 0x27, 0x6e, 0xd7, 0x23,
|
||||
0xe0, 0x4e, 0x90, 0xc5, 0x2a, 0x88, 0x0e, 0x67, 0x93, 0x19, 0x60, 0x8b, 0xfa, 0x0d, 0xdb, 0x31,
|
||||
0x32, 0x7b, 0x0e, 0x19, 0x07, 0xb5, 0xdb, 0x0b, 0x62, 0x10, 0xbe, 0x05, 0xc7, 0xe2, 0x42, 0x12,
|
||||
0x85, 0xa0, 0xc1, 0xaf, 0xa4, 0xda, 0x5c, 0x4f, 0xd4, 0x89, 0x4e, 0xb0, 0x7f, 0x91, 0xb4, 0x41,
|
||||
0xb9, 0x67, 0x38, 0x46, 0x8d, 0x5a, 0x89, 0xa2, 0xa4, 0x24, 0xff, 0x06, 0x43, 0x76, 0x48, 0x1b,
|
||||
0xf1, 0xd1, 0x58, 0x19, 0xc0, 0xd1, 0x58, 0xb6, 0xb7, 0xb7, 0xab, 0x91, 0xd6, 0x85, 0x17, 0x67,
|
||||
0x01, 0xcb, 0xe3, 0x06, 0xf5, 0x5b, 0xb6, 0x49, 0xf1, 0x5b, 0x08, 0x0a, 0xec, 0x8c, 0xe2, 0x73,
|
||||
0x29, 0x55, 0xfb, 0x09, 0x98, 0x3a, 0xa0, 0x29, 0x87, 0x99, 0x22, 0xe3, 0x8f, 0xbf, 0x79, 0xf1,
|
||||
0x4e, 0xee, 0x0c, 0x3e, 0xc5, 0xb9, 0x6c, 0x6b, 0x5e, 0xa6, 0x96, 0x01, 0x7e, 0x03, 0x01, 0x16,
|
||||
0x5d, 0x43, 0x62, 0x63, 0xf8, 0x72, 0x2f, 0x7c, 0x5d, 0x58, 0x9b, 0x7a, 0x4e, 0xaa, 0x1a, 0x8d,
|
||||
0x91, 0x65, 0x56, 0x23, 0x7c, 0x03, 0x07, 0x30, 0xcb, 0x01, 0x4c, 0x61, 0xd2, 0x0d, 0x80, 0xfe,
|
||||
0x90, 0x95, 0xc2, 0x23, 0x9d, 0x46, 0x76, 0x3f, 0x46, 0x30, 0xf4, 0x17, 0x7e, 0xdb, 0xf5, 0x89,
|
||||
0xd0, 0xc6, 0x60, 0x22, 0xc4, 0x6d, 0x71, 0xa8, 0xe4, 0x3c, 0x87, 0x79, 0x0e, 0x8f, 0xc5, 0x30,
|
||||
0x83, 0xd0, 0xa7, 0x46, 0x23, 0x85, 0xf6, 0x2a, 0xc2, 0x4f, 0x11, 0x14, 0x23, 0x52, 0x86, 0x2f,
|
||||
0xf4, 0x82, 0x98, 0x22, 0x6d, 0xea, 0x80, 0xa8, 0x0f, 0xb9, 0xc4, 0x01, 0x9e, 0x27, 0x5d, 0x13,
|
||||
0xb9, 0x98, 0xe2, 0x6d, 0x6f, 0x23, 0xc8, 0xaf, 0xd0, 0xbe, 0x65, 0x36, 0x28, 0x64, 0x07, 0x42,
|
||||
0xd7, 0x25, 0xc3, 0xf8, 0x31, 0x82, 0xd1, 0x15, 0x1a, 0xc6, 0xd4, 0x39, 0xe8, 0x1d, 0xbe, 0x14,
|
||||
0xbb, 0x56, 0xc7, 0x35, 0xe9, 0x9b, 0x45, 0xbc, 0x94, 0x74, 0x89, 0x39, 0x6e, 0xfa, 0x22, 0xbe,
|
||||
0x90, 0x55, 0x5c, 0x8d, 0xc4, 0xe6, 0x97, 0x08, 0x8a, 0x11, 0xed, 0xe8, 0x6d, 0x3e, 0xc5, 0x66,
|
||||
0x07, 0x16, 0xa3, 0x3b, 0x1c, 0xe8, 0x4d, 0xf5, 0x6a, 0x77, 0xa0, 0xf2, 0xfb, 0xac, 0xcd, 0x5a,
|
||||
0x46, 0x68, 0x68, 0x1c, 0x7d, 0x3a, 0xb3, 0x9f, 0x21, 0x80, 0x0e, 0x6f, 0xc2, 0x97, 0xb2, 0x9d,
|
||||
0x90, 0xb8, 0x95, 0x3a, 0x40, 0xe6, 0x44, 0x34, 0xee, 0xcc, 0x8c, 0x5a, 0xc9, 0x8a, 0x3a, 0xe3,
|
||||
0x55, 0x8b, 0x9c, 0x5d, 0xe1, 0x0f, 0x11, 0x0c, 0xf1, 0xf9, 0x1c, 0x4f, 0xf5, 0x02, 0x2c, 0x8f,
|
||||
0xef, 0x03, 0x0b, 0xfa, 0x34, 0xc7, 0x59, 0x59, 0xc8, 0x2a, 0xcc, 0x45, 0x34, 0x8b, 0x5b, 0x50,
|
||||
0x8c, 0x46, 0xe4, 0xde, 0x55, 0x91, 0x1a, 0xa1, 0xd5, 0x4a, 0x46, 0x7f, 0x8c, 0x0a, 0x53, 0x9c,
|
||||
0x89, 0xd9, 0xcc, 0x33, 0xf1, 0x09, 0x82, 0x02, 0xe3, 0xce, 0xf8, 0x7c, 0x2f, 0x7d, 0xd2, 0x97,
|
||||
0x88, 0x81, 0x45, 0xe5, 0x32, 0x87, 0x76, 0x81, 0x64, 0x67, 0xaf, 0xed, 0x98, 0x2c, 0x34, 0x4f,
|
||||
0x10, 0x1c, 0xdf, 0x7f, 0x8b, 0xe2, 0xb1, 0x94, 0x91, 0xf4, 0x35, 0xad, 0xa6, 0x43, 0xd8, 0xeb,
|
||||
0x06, 0x26, 0xb7, 0x38, 0x8a, 0x45, 0x7c, 0xbd, 0xef, 0x81, 0x58, 0x8f, 0x0f, 0x31, 0x53, 0x34,
|
||||
0x97, 0x7c, 0x4e, 0xc0, 0x9f, 0x23, 0x18, 0x8d, 0xf5, 0x6e, 0xf9, 0x94, 0x66, 0xc3, 0x1a, 0x50,
|
||||
0xfd, 0x33, 0x43, 0xe4, 0x06, 0xc7, 0xfe, 0x5b, 0x7c, 0xed, 0x90, 0xd8, 0x63, 0xcc, 0x73, 0x21,
|
||||
0x83, 0xf9, 0x29, 0x82, 0x72, 0xfc, 0x55, 0x00, 0x5f, 0xec, 0x59, 0x49, 0xe9, 0xef, 0x06, 0x03,
|
||||
0xcb, 0xbe, 0xce, 0xb1, 0x5f, 0x22, 0x53, 0x59, 0xd9, 0xf7, 0x85, 0x71, 0x56, 0x01, 0xef, 0x22,
|
||||
0xc0, 0xc9, 0x78, 0x96, 0x0c, 0x6c, 0x78, 0x3a, 0x65, 0xaa, 0xe7, 0xe4, 0xa7, 0x5e, 0xec, 0xbb,
|
||||
0x2f, 0xdd, 0xca, 0x67, 0x33, 0x5b, 0xb9, 0x9b, 0xd8, 0x7f, 0x13, 0xc1, 0xc8, 0x0a, 0x4d, 0x06,
|
||||
0x97, 0x8c, 0x40, 0xa6, 0xbf, 0x7b, 0xa8, 0x33, 0xfd, 0x37, 0x0a, 0x44, 0x57, 0x38, 0xa2, 0x69,
|
||||
0x9c, 0x1d, 0xaa, 0x18, 0xc0, 0x07, 0x08, 0x7e, 0x29, 0xba, 0x98, 0x90, 0x5c, 0xe9, 0x67, 0x29,
|
||||
0xd5, 0xf4, 0x0e, 0x8f, 0xeb, 0x37, 0x1c, 0xd7, 0x1c, 0x39, 0x14, 0xae, 0x45, 0xf1, 0xf9, 0xe0,
|
||||
0x23, 0x04, 0x27, 0xe5, 0x49, 0x4f, 0x50, 0xc6, 0x97, 0x8d, 0x5b, 0x06, 0xf3, 0x24, 0xd7, 0x38,
|
||||
0x3e, 0x0d, 0x5f, 0x39, 0x0c, 0x3e, 0x5d, 0x90, 0x48, 0xfc, 0x3e, 0x82, 0x13, 0x9c, 0xb4, 0xcb,
|
||||
0x8a, 0xf7, 0x35, 0xe4, 0x5e, 0x14, 0xff, 0x10, 0x0d, 0x59, 0x9c, 0x59, 0x72, 0x24, 0x50, 0x8b,
|
||||
0x82, 0x6c, 0xb3, 0xc9, 0xfd, 0x58, 0x7c, 0x05, 0x88, 0xec, 0xce, 0xf5, 0x0b, 0xdc, 0x51, 0xaf,
|
||||
0x0c, 0x51, 0x6e, 0xb3, 0x87, 0x2b, 0xb7, 0xff, 0x20, 0x28, 0x09, 0x9e, 0x9c, 0x71, 0xab, 0x4a,
|
||||
0x44, 0x5a, 0x3d, 0x9d, 0xda, 0x15, 0xf3, 0x44, 0xf2, 0x3b, 0x6e, 0x76, 0x1e, 0xeb, 0x59, 0x66,
|
||||
0x3d, 0xd7, 0x0a, 0xf4, 0x87, 0x82, 0x40, 0x3f, 0xd2, 0xeb, 0x6e, 0x2d, 0xb8, 0x8a, 0x96, 0x6e,
|
||||
0x3c, 0xdb, 0x9b, 0x40, 0x5f, 0xef, 0x4d, 0xa0, 0xef, 0xf6, 0x26, 0xd0, 0x5f, 0xb5, 0xac, 0xbf,
|
||||
0xa3, 0x0e, 0xfe, 0x6d, 0xf7, 0x53, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5c, 0x47, 0xa4, 0xb4, 0xcb,
|
||||
0x1b, 0x00, 0x00,
|
||||
var fileDescriptor_application_5178689ec7ddb110 = []byte{
|
||||
// 1792 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0xdc, 0x5a,
|
||||
0x15, 0xe7, 0xce, 0x4c, 0x66, 0x26, 0x27, 0xe1, 0x7d, 0xdc, 0xf7, 0x5e, 0xf1, 0x73, 0xd2, 0x64,
|
||||
0x74, 0x9b, 0xa6, 0x69, 0x5e, 0x63, 0x37, 0xa1, 0x82, 0xa7, 0xe8, 0x49, 0xaf, 0x0d, 0x29, 0x69,
|
||||
0x50, 0x1a, 0xc2, 0x24, 0x05, 0x09, 0x09, 0x21, 0xd7, 0xbe, 0x99, 0x98, 0xcc, 0xd8, 0xc6, 0xf6,
|
||||
0x0c, 0x1a, 0xaa, 0x2e, 0xa8, 0x10, 0x62, 0x81, 0x40, 0x08, 0x16, 0x05, 0xf1, 0xa5, 0xae, 0xd9,
|
||||
0x21, 0x36, 0x2c, 0xd8, 0x21, 0x75, 0x89, 0x04, 0xeb, 0x0a, 0x85, 0xfe, 0x01, 0xac, 0x58, 0xa3,
|
||||
0x7b, 0x7d, 0xaf, 0x7d, 0x9d, 0xcc, 0x78, 0x92, 0x76, 0x58, 0x74, 0xe7, 0x39, 0xf7, 0xfa, 0x9c,
|
||||
0xdf, 0xf9, 0xb8, 0xe7, 0x9e, 0x9f, 0x07, 0x16, 0x22, 0x1a, 0xf6, 0x68, 0x68, 0x5a, 0x41, 0xd0,
|
||||
0x76, 0x6d, 0x2b, 0x76, 0x7d, 0x4f, 0x7d, 0x36, 0x82, 0xd0, 0x8f, 0x7d, 0x3c, 0xa5, 0x88, 0xf4,
|
||||
0xf7, 0x5b, 0x7e, 0xcb, 0xe7, 0x72, 0x93, 0x3d, 0x25, 0x5b, 0xf4, 0xd9, 0x96, 0xef, 0xb7, 0xda,
|
||||
0xd4, 0xb4, 0x02, 0xd7, 0xb4, 0x3c, 0xcf, 0x8f, 0xf9, 0xe6, 0x48, 0xac, 0x92, 0xe3, 0x8f, 0x23,
|
||||
0xc3, 0xf5, 0xf9, 0xaa, 0xed, 0x87, 0xd4, 0xec, 0xad, 0x9a, 0x2d, 0xea, 0xd1, 0xd0, 0x8a, 0xa9,
|
||||
0x23, 0xf6, 0xdc, 0xca, 0xf6, 0x74, 0x2c, 0xfb, 0xc8, 0xf5, 0x68, 0xd8, 0x37, 0x83, 0xe3, 0x16,
|
||||
0x13, 0x44, 0x66, 0x87, 0xc6, 0xd6, 0xa0, 0xb7, 0xb6, 0x5b, 0x6e, 0x7c, 0xd4, 0x7d, 0x68, 0xd8,
|
||||
0x7e, 0xc7, 0xb4, 0x42, 0x0e, 0xec, 0x3b, 0xfc, 0x61, 0xc5, 0x76, 0xb2, 0xb7, 0x55, 0xf7, 0x7a,
|
||||
0xab, 0x56, 0x3b, 0x38, 0xb2, 0xce, 0xaa, 0xda, 0x28, 0x52, 0x15, 0xd2, 0xc0, 0x17, 0xb1, 0xe2,
|
||||
0x8f, 0x6e, 0xec, 0x87, 0x7d, 0xe5, 0x31, 0xd1, 0x41, 0x9e, 0x22, 0x78, 0xe7, 0x4e, 0x66, 0xec,
|
||||
0x6b, 0x5d, 0x1a, 0xf6, 0x31, 0x86, 0x8a, 0x67, 0x75, 0xa8, 0x86, 0x1a, 0x68, 0x69, 0xb2, 0xc9,
|
||||
0x9f, 0xb1, 0x06, 0xb5, 0x90, 0x1e, 0x86, 0x34, 0x3a, 0xd2, 0x4a, 0x5c, 0x2c, 0x7f, 0xe2, 0x45,
|
||||
0xa8, 0x31, 0xcb, 0xd4, 0x8e, 0xb5, 0x72, 0xa3, 0xbc, 0x34, 0xb9, 0x31, 0x7d, 0xf2, 0x62, 0xbe,
|
||||
0xbe, 0x97, 0x88, 0xa2, 0xa6, 0x5c, 0xc4, 0x06, 0xbc, 0x1d, 0xd2, 0xc8, 0xef, 0x86, 0x36, 0xfd,
|
||||
0x3a, 0x0d, 0x23, 0xd7, 0xf7, 0xb4, 0x0a, 0xd3, 0xb4, 0x51, 0x79, 0xfe, 0x62, 0xfe, 0x33, 0xcd,
|
||||
0xd3, 0x8b, 0xe4, 0x2f, 0x08, 0xe6, 0x14, 0x68, 0x4d, 0xb1, 0x7c, 0xb7, 0x47, 0xbd, 0x38, 0x3a,
|
||||
0x0d, 0xb4, 0x94, 0x02, 0x5d, 0x83, 0x77, 0xa5, 0xa6, 0x5d, 0xab, 0x43, 0xa3, 0xc0, 0xb2, 0xa9,
|
||||
0x56, 0x62, 0x1b, 0x84, 0xa1, 0xb3, 0xcb, 0x78, 0x09, 0xa6, 0x55, 0xa1, 0x56, 0x56, 0xb6, 0xe7,
|
||||
0x56, 0xf0, 0x22, 0x4c, 0xc9, 0xdf, 0x0f, 0xb6, 0x37, 0xb5, 0x8a, 0xb2, 0x51, 0x5d, 0x20, 0x7b,
|
||||
0xa0, 0x29, 0xd8, 0xef, 0x5b, 0x9e, 0x7b, 0x48, 0xa3, 0x78, 0x38, 0xea, 0x06, 0xd4, 0x43, 0xda,
|
||||
0x73, 0x79, 0x54, 0x4a, 0x4a, 0x54, 0x52, 0x29, 0xf9, 0x00, 0xde, 0xcb, 0x47, 0x23, 0xf0, 0xbd,
|
||||
0x88, 0x92, 0x67, 0x28, 0x67, 0xe9, 0x4b, 0x21, 0xb5, 0x62, 0xda, 0xa4, 0xdf, 0xed, 0xd2, 0x28,
|
||||
0xc6, 0x1e, 0xa8, 0x27, 0x81, 0x1b, 0x9c, 0x5a, 0xfb, 0xb2, 0x91, 0xd5, 0x8d, 0x21, 0xeb, 0x86,
|
||||
0x3f, 0x7c, 0xdb, 0x76, 0x8c, 0xe0, 0xb8, 0x65, 0xb0, 0x12, 0x34, 0xd4, 0x53, 0x25, 0x4b, 0xd0,
|
||||
0x50, 0x2c, 0x49, 0xaf, 0x95, 0x7d, 0xf8, 0x12, 0x54, 0xbb, 0x41, 0x44, 0xc3, 0x98, 0xfb, 0x50,
|
||||
0x6f, 0x8a, 0x5f, 0xe4, 0x87, 0x79, 0x90, 0x0f, 0x02, 0x47, 0x01, 0x79, 0xf4, 0x7f, 0x04, 0x99,
|
||||
0x83, 0x47, 0xee, 0xe5, 0x50, 0x6c, 0xd2, 0x36, 0xcd, 0x50, 0x0c, 0x4a, 0x8a, 0x06, 0x35, 0xdb,
|
||||
0x8a, 0x6c, 0xcb, 0xa1, 0xc2, 0x1f, 0xf9, 0x93, 0xfc, 0xbb, 0x04, 0x97, 0x14, 0x55, 0xfb, 0x7d,
|
||||
0xcf, 0x2e, 0x52, 0x34, 0x32, 0xbb, 0x78, 0x16, 0xaa, 0x4e, 0xd8, 0x6f, 0x76, 0x3d, 0xad, 0xcc,
|
||||
0x2c, 0x89, 0x75, 0x21, 0xc3, 0x3a, 0x4c, 0x04, 0x61, 0xd7, 0xa3, 0xfc, 0xc0, 0xc8, 0xc5, 0x44,
|
||||
0x84, 0x6d, 0xa8, 0x47, 0x31, 0x6b, 0x0b, 0xad, 0xbe, 0x36, 0xd1, 0x40, 0x4b, 0x53, 0x6b, 0x5b,
|
||||
0xaf, 0x11, 0x3b, 0xe6, 0xc9, 0xbe, 0x50, 0xd7, 0x4c, 0x15, 0xe3, 0x18, 0x26, 0x65, 0x75, 0x47,
|
||||
0x5a, 0xad, 0x51, 0x5e, 0x9a, 0x5a, 0xdb, 0x7b, 0x4d, 0x2b, 0x5f, 0x0d, 0x58, 0x33, 0x53, 0x0e,
|
||||
0xb6, 0x70, 0x2b, 0x33, 0xc4, 0x9a, 0xd3, 0xec, 0x99, 0xb2, 0xd9, 0x0f, 0x68, 0x61, 0xac, 0x1d,
|
||||
0xa8, 0x44, 0x01, 0xb5, 0xf9, 0x91, 0x9f, 0x5a, 0xfb, 0xca, 0x78, 0xea, 0x88, 0x19, 0x15, 0xf8,
|
||||
0xb8, 0x76, 0xb2, 0x0d, 0x9f, 0x53, 0x96, 0xf7, 0xac, 0xd8, 0x3e, 0x2a, 0x02, 0xc5, 0x12, 0xc8,
|
||||
0xf6, 0xe4, 0x1a, 0x51, 0x22, 0x22, 0x3f, 0x42, 0xa0, 0xab, 0x25, 0xeb, 0xb7, 0xdb, 0x0f, 0x2d,
|
||||
0xfb, 0xb8, 0x58, 0x5d, 0xc9, 0x75, 0xb8, 0xae, 0xf2, 0x06, 0x30, 0x5d, 0x27, 0x2f, 0xe6, 0x4b,
|
||||
0xdb, 0x9b, 0xcd, 0x92, 0xeb, 0xbc, 0x7a, 0x25, 0x91, 0x7f, 0x9e, 0x02, 0x22, 0xf2, 0x50, 0x04,
|
||||
0x84, 0xc0, 0xa4, 0x37, 0xb0, 0xc9, 0x66, 0xe2, 0x0b, 0x34, 0xd7, 0x39, 0xa8, 0xf5, 0xd2, 0x9b,
|
||||
0x21, 0xdb, 0x24, 0x85, 0x0c, 0x7c, 0x2b, 0xf4, 0xbb, 0x81, 0x36, 0xa1, 0x46, 0x91, 0x8b, 0xb0,
|
||||
0x06, 0x95, 0x63, 0xd7, 0x73, 0xb4, 0xaa, 0xb2, 0xc4, 0x25, 0xe4, 0x57, 0x25, 0x98, 0x1f, 0xe0,
|
||||
0xd6, 0xc8, 0x9c, 0xbd, 0x01, 0xbe, 0x65, 0x75, 0x55, 0x3b, 0x53, 0x57, 0x0c, 0x3f, 0x7f, 0x38,
|
||||
0xe8, 0x07, 0x54, 0xab, 0xab, 0xf8, 0x53, 0x31, 0xf9, 0x2f, 0x82, 0xc6, 0x80, 0xd8, 0x8c, 0x6e,
|
||||
0x8d, 0x6f, 0x48, 0x70, 0x0e, 0xfd, 0xd0, 0xa6, 0x5a, 0x2d, 0xad, 0x75, 0xd4, 0x4c, 0x44, 0xe4,
|
||||
0x3f, 0x08, 0x34, 0xe9, 0xed, 0x1d, 0x9b, 0xfb, 0xde, 0xf5, 0xde, 0x74, 0x87, 0x67, 0xa1, 0x6a,
|
||||
0x71, 0x5f, 0x72, 0xe5, 0x20, 0x64, 0xe4, 0xc7, 0x08, 0x66, 0xf2, 0x2e, 0x47, 0x3b, 0x6e, 0x14,
|
||||
0xcb, 0x49, 0x02, 0xbb, 0x50, 0x4b, 0x76, 0x46, 0x1a, 0xe2, 0x1d, 0x7e, 0xfb, 0x35, 0x7a, 0x67,
|
||||
0xde, 0x90, 0x74, 0x4f, 0xe8, 0x27, 0x9f, 0xc2, 0xcc, 0xc0, 0x46, 0x23, 0x90, 0x34, 0xa0, 0xde,
|
||||
0x11, 0x13, 0x53, 0x92, 0x03, 0x79, 0x5d, 0x4a, 0x29, 0xf9, 0x5b, 0x29, 0xdf, 0x7f, 0x7d, 0x67,
|
||||
0xc7, 0x6f, 0x15, 0x0c, 0x85, 0xe7, 0xc9, 0x9e, 0x06, 0xb5, 0xc0, 0x77, 0xb2, 0xc4, 0x35, 0xe5,
|
||||
0x4f, 0xf6, 0xb6, 0xed, 0x7b, 0xb1, 0xc5, 0x46, 0xfc, 0x5c, 0xbe, 0x32, 0x31, 0xcb, 0x7d, 0xe4,
|
||||
0x7a, 0x36, 0xdd, 0xa7, 0xb6, 0xef, 0x39, 0x11, 0x4f, 0x5c, 0x59, 0xe6, 0x5e, 0x5d, 0xc1, 0xf7,
|
||||
0x60, 0x92, 0xff, 0x3e, 0x70, 0x3b, 0x54, 0xab, 0xf2, 0x1b, 0x7b, 0xd9, 0x48, 0xb8, 0x84, 0xa1,
|
||||
0x72, 0x89, 0x2c, 0xc2, 0x8c, 0x4b, 0x18, 0xbd, 0x55, 0x83, 0xbd, 0xd1, 0xcc, 0x5e, 0x66, 0xb8,
|
||||
0x62, 0xcb, 0x6d, 0xef, 0xb8, 0x1e, 0xbf, 0x95, 0x33, 0x83, 0x99, 0x98, 0xd5, 0xc4, 0xa1, 0xdf,
|
||||
0x6e, 0xfb, 0xdf, 0xe3, 0x2d, 0x20, 0xbd, 0x0e, 0x12, 0x19, 0xf9, 0x3e, 0xd4, 0x77, 0xfc, 0xd6,
|
||||
0x5d, 0x2f, 0x0e, 0xfb, 0xac, 0x26, 0x99, 0x3b, 0xd4, 0xcb, 0x07, 0x5d, 0x0a, 0xf1, 0x2e, 0x4c,
|
||||
0xc6, 0x6e, 0x87, 0xee, 0xc7, 0x56, 0x27, 0x10, 0xb7, 0xeb, 0x05, 0x70, 0xa7, 0xc8, 0xa4, 0x0a,
|
||||
0x62, 0xc2, 0x87, 0xe9, 0x0c, 0x70, 0x40, 0xc3, 0x8e, 0xeb, 0x59, 0x85, 0x3d, 0x87, 0xcc, 0x82,
|
||||
0x3e, 0xe8, 0x05, 0x31, 0x08, 0xdf, 0x86, 0xb7, 0x64, 0x21, 0x89, 0x42, 0x30, 0xe0, 0x6d, 0xa5,
|
||||
0x36, 0x77, 0x53, 0x75, 0xa2, 0x13, 0x9c, 0x5e, 0x24, 0x7d, 0xd0, 0xee, 0x5b, 0x9e, 0xd5, 0xa2,
|
||||
0x4e, 0xaa, 0x28, 0x2d, 0xc9, 0x6f, 0xc1, 0x84, 0x1b, 0xd3, 0x8e, 0x3c, 0x1a, 0x5b, 0x63, 0x38,
|
||||
0x1a, 0x9b, 0xee, 0xe1, 0x61, 0x33, 0xd1, 0xba, 0xf6, 0xf2, 0x43, 0xc0, 0xea, 0xb8, 0x41, 0xc3,
|
||||
0x9e, 0x6b, 0x53, 0xfc, 0x33, 0x04, 0x15, 0x76, 0x46, 0xf1, 0xe5, 0x9c, 0xaa, 0xd3, 0x84, 0x4d,
|
||||
0x1f, 0xd3, 0x94, 0xc3, 0x4c, 0x91, 0xd9, 0x27, 0xff, 0x78, 0xf9, 0x8b, 0xd2, 0x25, 0xfc, 0x3e,
|
||||
0x27, 0xbf, 0xbd, 0x55, 0x95, 0x8b, 0x46, 0xf8, 0x27, 0x08, 0xb0, 0xe8, 0x1a, 0x0a, 0x1b, 0xc3,
|
||||
0x1f, 0x0d, 0xc3, 0x37, 0x80, 0xb5, 0xe9, 0x97, 0x95, 0xaa, 0x31, 0x18, 0xbb, 0x66, 0x35, 0xc2,
|
||||
0x37, 0x70, 0x00, 0xcb, 0x1c, 0xc0, 0x02, 0x26, 0x83, 0x00, 0x98, 0x8f, 0x58, 0x29, 0x3c, 0x36,
|
||||
0x69, 0x62, 0xf7, 0xf7, 0x08, 0x26, 0xbe, 0xc1, 0x6f, 0xbb, 0x11, 0x11, 0xda, 0x1b, 0x4f, 0x84,
|
||||
0xb8, 0x2d, 0x0e, 0x95, 0x5c, 0xe1, 0x30, 0x2f, 0xe3, 0x19, 0x09, 0x33, 0x8a, 0x43, 0x6a, 0x75,
|
||||
0x72, 0x68, 0x6f, 0x22, 0xfc, 0x0c, 0x41, 0x35, 0x21, 0x65, 0xf8, 0xea, 0x30, 0x88, 0x39, 0xd2,
|
||||
0xa6, 0x8f, 0x89, 0xfa, 0x90, 0xeb, 0x1c, 0xe0, 0x15, 0x32, 0x30, 0x91, 0xeb, 0x39, 0xde, 0xf6,
|
||||
0x73, 0x04, 0xe5, 0x2d, 0x3a, 0xb2, 0xcc, 0xc6, 0x85, 0xec, 0x4c, 0xe8, 0x06, 0x64, 0x18, 0x3f,
|
||||
0x41, 0x30, 0xbd, 0x45, 0x63, 0x49, 0x9d, 0xa3, 0xe1, 0xe1, 0xcb, 0xb1, 0x6b, 0x7d, 0xd6, 0x50,
|
||||
0x3e, 0x72, 0xc8, 0xa5, 0xb4, 0x4b, 0xac, 0x70, 0xd3, 0xd7, 0xf0, 0xd5, 0xa2, 0xe2, 0xea, 0xa4,
|
||||
0x36, 0xff, 0x8a, 0xa0, 0x9a, 0xd0, 0x8e, 0xe1, 0xe6, 0x73, 0x6c, 0x76, 0x6c, 0x31, 0xba, 0xcb,
|
||||
0x81, 0x7e, 0xaa, 0xdf, 0x1c, 0x0c, 0x54, 0x7d, 0x9f, 0xb5, 0x59, 0xc7, 0x8a, 0x2d, 0x83, 0xa3,
|
||||
0xcf, 0x67, 0xf6, 0x4f, 0x08, 0x20, 0xe3, 0x4d, 0xf8, 0x7a, 0xb1, 0x13, 0x0a, 0xb7, 0xd2, 0xc7,
|
||||
0xc8, 0x9c, 0x88, 0xc1, 0x9d, 0x59, 0xd2, 0x1b, 0x45, 0x51, 0x67, 0xbc, 0x6a, 0x9d, 0xb3, 0x2b,
|
||||
0xfc, 0x5b, 0x04, 0x13, 0x7c, 0x3e, 0xc7, 0x0b, 0xc3, 0x00, 0xab, 0xe3, 0xfb, 0xd8, 0x82, 0xbe,
|
||||
0xc8, 0x71, 0x36, 0xd6, 0x8a, 0x0a, 0x73, 0x1d, 0x2d, 0xe3, 0x1e, 0x54, 0x93, 0x11, 0x79, 0x78,
|
||||
0x55, 0xe4, 0x46, 0x68, 0xbd, 0x51, 0xd0, 0x1f, 0x93, 0xc2, 0x14, 0x67, 0x62, 0xb9, 0xf0, 0x4c,
|
||||
0xfc, 0x01, 0x41, 0x85, 0x71, 0x67, 0x7c, 0x65, 0x98, 0x3e, 0xe5, 0x4b, 0xc4, 0xd8, 0xa2, 0xf2,
|
||||
0x11, 0x87, 0x76, 0x95, 0x14, 0x67, 0xaf, 0xef, 0xd9, 0x2c, 0x34, 0x4f, 0x11, 0xbc, 0x73, 0xfa,
|
||||
0x16, 0xc5, 0x33, 0x39, 0x23, 0xf9, 0x6b, 0x5a, 0xcf, 0x87, 0x70, 0xd8, 0x0d, 0x4c, 0x6e, 0x73,
|
||||
0x14, 0xeb, 0xf8, 0xe3, 0x91, 0x07, 0x62, 0x57, 0x1e, 0x62, 0xa6, 0x68, 0x25, 0xfd, 0x9c, 0x80,
|
||||
0xff, 0x8c, 0x60, 0x5a, 0xea, 0x3d, 0x08, 0x29, 0x2d, 0x86, 0x35, 0xa6, 0xfa, 0x67, 0x86, 0xc8,
|
||||
0x27, 0x1c, 0xfb, 0x17, 0xf0, 0xad, 0x73, 0x62, 0x97, 0x98, 0x57, 0x62, 0x06, 0xf3, 0x8f, 0x08,
|
||||
0xea, 0xf2, 0xab, 0x00, 0xbe, 0x36, 0xb4, 0x92, 0xf2, 0xdf, 0x0d, 0xc6, 0x96, 0x7d, 0x93, 0x63,
|
||||
0xbf, 0x4e, 0x16, 0x8a, 0xb2, 0x1f, 0x0a, 0xe3, 0xac, 0x02, 0x7e, 0x89, 0x00, 0xa7, 0xe3, 0x59,
|
||||
0x3a, 0xb0, 0xe1, 0xc5, 0x9c, 0xa9, 0xa1, 0x93, 0x9f, 0x7e, 0x6d, 0xe4, 0xbe, 0x7c, 0x2b, 0x5f,
|
||||
0x2e, 0x6c, 0xe5, 0x7e, 0x6a, 0xff, 0xa7, 0x08, 0xa6, 0xb6, 0x68, 0x3a, 0xb8, 0x14, 0x04, 0x32,
|
||||
0xff, 0xdd, 0x43, 0x5f, 0x1a, 0xbd, 0x51, 0x20, 0xba, 0xc1, 0x11, 0x2d, 0xe2, 0xe2, 0x50, 0x49,
|
||||
0x00, 0xbf, 0x41, 0xf0, 0x59, 0xd1, 0xc5, 0x84, 0xe4, 0xc6, 0x28, 0x4b, 0xb9, 0xa6, 0x77, 0x7e,
|
||||
0x5c, 0x9f, 0xe7, 0xb8, 0x56, 0xc8, 0xb9, 0x70, 0xad, 0x8b, 0xcf, 0x07, 0xbf, 0x43, 0xf0, 0x9e,
|
||||
0x3a, 0xe9, 0x09, 0xca, 0xf8, 0xaa, 0x71, 0x2b, 0x60, 0x9e, 0xe4, 0x16, 0xc7, 0x67, 0xe0, 0x1b,
|
||||
0xe7, 0xc1, 0x67, 0x0a, 0x12, 0x89, 0x7f, 0x8d, 0xe0, 0x5d, 0x4e, 0xda, 0x55, 0xc5, 0xa7, 0x1a,
|
||||
0xf2, 0x30, 0x8a, 0x7f, 0x8e, 0x86, 0x2c, 0xce, 0x2c, 0xb9, 0x10, 0xa8, 0x75, 0x41, 0xb6, 0xd9,
|
||||
0xe4, 0xfe, 0x96, 0xbc, 0x02, 0x44, 0x76, 0x57, 0x46, 0x05, 0xee, 0xa2, 0x57, 0x86, 0x28, 0xb7,
|
||||
0xe5, 0xf3, 0x95, 0xdb, 0x0f, 0x10, 0xd4, 0x04, 0x4f, 0x2e, 0xb8, 0x55, 0x15, 0x22, 0xad, 0x7f,
|
||||
0x90, 0xdb, 0x25, 0x79, 0x22, 0xf9, 0x22, 0x37, 0xbb, 0x8a, 0xcd, 0x22, 0xb3, 0x81, 0xef, 0x44,
|
||||
0xe6, 0x23, 0x41, 0xa0, 0x1f, 0x9b, 0x6d, 0xbf, 0x15, 0xdd, 0x44, 0x1b, 0x9f, 0x3c, 0x3f, 0x99,
|
||||
0x43, 0x7f, 0x3f, 0x99, 0x43, 0xff, 0x3a, 0x99, 0x43, 0xdf, 0x34, 0x8a, 0xfe, 0xbf, 0x3a, 0xfb,
|
||||
0x3f, 0xdf, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xba, 0x1f, 0x43, 0xcd, 0xfc, 0x1b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ message ApplicationQuery {
|
||||
optional string name = 1;
|
||||
optional string refresh = 2;
|
||||
repeated string project = 3 [(gogoproto.customname) = "Projects"];
|
||||
optional string resourceVersion = 4 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// ApplicationEventsQuery is a query for application resource events
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@@ -166,7 +166,7 @@ metadata:
|
||||
spec:
|
||||
source:
|
||||
path: some/path
|
||||
repoURL: https://git.com/repo.git
|
||||
repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||
targetRevision: HEAD
|
||||
ksonnet:
|
||||
environment: default
|
||||
|
||||
@@ -11,9 +11,7 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/server/rbacpolicy"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
@@ -144,53 +142,6 @@ func (s *Server) Create(ctx context.Context, q *ClusterCreateRequest) (*appv1.Cl
|
||||
return redact(clust), err
|
||||
}
|
||||
|
||||
// Create creates a cluster
|
||||
func (s *Server) CreateFromKubeConfig(ctx context.Context, q *ClusterCreateFromKubeConfigRequest) (*appv1.Cluster, error) {
|
||||
kubeconfig, err := clientcmd.Load([]byte(q.Kubeconfig))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not unmarshal kubeconfig: %v", err)
|
||||
}
|
||||
|
||||
var clusterServer string
|
||||
var clusterInsecure bool
|
||||
if q.InCluster {
|
||||
clusterServer = common.KubernetesInternalAPIServerAddr
|
||||
} else if cluster, ok := kubeconfig.Clusters[q.Context]; ok {
|
||||
clusterServer = cluster.Server
|
||||
clusterInsecure = cluster.InsecureSkipTLSVerify
|
||||
} else {
|
||||
return nil, status.Errorf(codes.Internal, "Context %s does not exist in kubeconfig", q.Context)
|
||||
}
|
||||
|
||||
c := &appv1.Cluster{
|
||||
Server: clusterServer,
|
||||
Name: q.Context,
|
||||
Config: appv1.ClusterConfig{
|
||||
TLSClientConfig: appv1.TLSClientConfig{
|
||||
Insecure: clusterInsecure,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Temporarily install RBAC resources for managing the cluster
|
||||
clientset, err := kubernetes.NewForConfig(c.RESTConfig())
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not create Kubernetes clientset: %v", err)
|
||||
}
|
||||
|
||||
bearerToken, err := common.InstallClusterManagerRBAC(clientset)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not install cluster manager RBAC: %v", err)
|
||||
}
|
||||
|
||||
c.Config.BearerToken = bearerToken
|
||||
|
||||
return s.Create(ctx, &ClusterCreateRequest{
|
||||
Cluster: c,
|
||||
Upsert: q.Upsert,
|
||||
})
|
||||
}
|
||||
|
||||
// Get returns a cluster from a query
|
||||
func (s *Server) Get(ctx context.Context, q *ClusterQuery) (*appv1.Cluster, error) {
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionGet, q.Server); err != nil {
|
||||
|
||||
@@ -45,7 +45,7 @@ func (m *ClusterQuery) Reset() { *m = ClusterQuery{} }
|
||||
func (m *ClusterQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClusterQuery) ProtoMessage() {}
|
||||
func (*ClusterQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cluster_0875510a34378ea0, []int{0}
|
||||
return fileDescriptor_cluster_96df59157dc2259c, []int{0}
|
||||
}
|
||||
func (m *ClusterQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -91,7 +91,7 @@ func (m *ClusterResponse) Reset() { *m = ClusterResponse{} }
|
||||
func (m *ClusterResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClusterResponse) ProtoMessage() {}
|
||||
func (*ClusterResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cluster_0875510a34378ea0, []int{1}
|
||||
return fileDescriptor_cluster_96df59157dc2259c, []int{1}
|
||||
}
|
||||
func (m *ClusterResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -132,7 +132,7 @@ func (m *ClusterCreateRequest) Reset() { *m = ClusterCreateRequest{} }
|
||||
func (m *ClusterCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClusterCreateRequest) ProtoMessage() {}
|
||||
func (*ClusterCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cluster_0875510a34378ea0, []int{2}
|
||||
return fileDescriptor_cluster_96df59157dc2259c, []int{2}
|
||||
}
|
||||
func (m *ClusterCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -175,77 +175,6 @@ func (m *ClusterCreateRequest) GetUpsert() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type ClusterCreateFromKubeConfigRequest struct {
|
||||
Kubeconfig string `protobuf:"bytes,1,opt,name=kubeconfig,proto3" json:"kubeconfig,omitempty"`
|
||||
Context string `protobuf:"bytes,2,opt,name=context,proto3" json:"context,omitempty"`
|
||||
Upsert bool `protobuf:"varint,3,opt,name=upsert,proto3" json:"upsert,omitempty"`
|
||||
InCluster bool `protobuf:"varint,4,opt,name=inCluster,proto3" json:"inCluster,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) Reset() { *m = ClusterCreateFromKubeConfigRequest{} }
|
||||
func (m *ClusterCreateFromKubeConfigRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClusterCreateFromKubeConfigRequest) ProtoMessage() {}
|
||||
func (*ClusterCreateFromKubeConfigRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cluster_0875510a34378ea0, []int{3}
|
||||
}
|
||||
func (m *ClusterCreateFromKubeConfigRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ClusterCreateFromKubeConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_ClusterCreateFromKubeConfigRequest.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalTo(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (dst *ClusterCreateFromKubeConfigRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ClusterCreateFromKubeConfigRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *ClusterCreateFromKubeConfigRequest) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ClusterCreateFromKubeConfigRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ClusterCreateFromKubeConfigRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ClusterCreateFromKubeConfigRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) GetKubeconfig() string {
|
||||
if m != nil {
|
||||
return m.Kubeconfig
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) GetContext() string {
|
||||
if m != nil {
|
||||
return m.Context
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) GetUpsert() bool {
|
||||
if m != nil {
|
||||
return m.Upsert
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) GetInCluster() bool {
|
||||
if m != nil {
|
||||
return m.InCluster
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ClusterUpdateRequest struct {
|
||||
Cluster *v1alpha1.Cluster `protobuf:"bytes,1,opt,name=cluster" json:"cluster,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
@@ -257,7 +186,7 @@ func (m *ClusterUpdateRequest) Reset() { *m = ClusterUpdateRequest{} }
|
||||
func (m *ClusterUpdateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClusterUpdateRequest) ProtoMessage() {}
|
||||
func (*ClusterUpdateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cluster_0875510a34378ea0, []int{4}
|
||||
return fileDescriptor_cluster_96df59157dc2259c, []int{3}
|
||||
}
|
||||
func (m *ClusterUpdateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -297,7 +226,6 @@ func init() {
|
||||
proto.RegisterType((*ClusterQuery)(nil), "cluster.ClusterQuery")
|
||||
proto.RegisterType((*ClusterResponse)(nil), "cluster.ClusterResponse")
|
||||
proto.RegisterType((*ClusterCreateRequest)(nil), "cluster.ClusterCreateRequest")
|
||||
proto.RegisterType((*ClusterCreateFromKubeConfigRequest)(nil), "cluster.ClusterCreateFromKubeConfigRequest")
|
||||
proto.RegisterType((*ClusterUpdateRequest)(nil), "cluster.ClusterUpdateRequest")
|
||||
}
|
||||
|
||||
@@ -316,8 +244,6 @@ type ClusterServiceClient interface {
|
||||
List(ctx context.Context, in *ClusterQuery, opts ...grpc.CallOption) (*v1alpha1.ClusterList, error)
|
||||
// Create creates a cluster
|
||||
Create(ctx context.Context, in *ClusterCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Cluster, error)
|
||||
// CreateFromKubeConfig installs the argocd-manager service account into the cluster specified in the given kubeconfig and context
|
||||
CreateFromKubeConfig(ctx context.Context, in *ClusterCreateFromKubeConfigRequest, opts ...grpc.CallOption) (*v1alpha1.Cluster, error)
|
||||
// Get returns a cluster by server address
|
||||
Get(ctx context.Context, in *ClusterQuery, opts ...grpc.CallOption) (*v1alpha1.Cluster, error)
|
||||
// Update updates a cluster
|
||||
@@ -352,15 +278,6 @@ func (c *clusterServiceClient) Create(ctx context.Context, in *ClusterCreateRequ
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clusterServiceClient) CreateFromKubeConfig(ctx context.Context, in *ClusterCreateFromKubeConfigRequest, opts ...grpc.CallOption) (*v1alpha1.Cluster, error) {
|
||||
out := new(v1alpha1.Cluster)
|
||||
err := c.cc.Invoke(ctx, "/cluster.ClusterService/CreateFromKubeConfig", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clusterServiceClient) Get(ctx context.Context, in *ClusterQuery, opts ...grpc.CallOption) (*v1alpha1.Cluster, error) {
|
||||
out := new(v1alpha1.Cluster)
|
||||
err := c.cc.Invoke(ctx, "/cluster.ClusterService/Get", in, out, opts...)
|
||||
@@ -395,8 +312,6 @@ type ClusterServiceServer interface {
|
||||
List(context.Context, *ClusterQuery) (*v1alpha1.ClusterList, error)
|
||||
// Create creates a cluster
|
||||
Create(context.Context, *ClusterCreateRequest) (*v1alpha1.Cluster, error)
|
||||
// CreateFromKubeConfig installs the argocd-manager service account into the cluster specified in the given kubeconfig and context
|
||||
CreateFromKubeConfig(context.Context, *ClusterCreateFromKubeConfigRequest) (*v1alpha1.Cluster, error)
|
||||
// Get returns a cluster by server address
|
||||
Get(context.Context, *ClusterQuery) (*v1alpha1.Cluster, error)
|
||||
// Update updates a cluster
|
||||
@@ -445,24 +360,6 @@ func _ClusterService_Create_Handler(srv interface{}, ctx context.Context, dec fu
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClusterService_CreateFromKubeConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ClusterCreateFromKubeConfigRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClusterServiceServer).CreateFromKubeConfig(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/cluster.ClusterService/CreateFromKubeConfig",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClusterServiceServer).CreateFromKubeConfig(ctx, req.(*ClusterCreateFromKubeConfigRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClusterService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ClusterQuery)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -529,10 +426,6 @@ var _ClusterService_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Create",
|
||||
Handler: _ClusterService_Create_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateFromKubeConfig",
|
||||
Handler: _ClusterService_CreateFromKubeConfig_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Get",
|
||||
Handler: _ClusterService_Get_Handler,
|
||||
@@ -639,59 +532,6 @@ func (m *ClusterCreateRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Kubeconfig) > 0 {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintCluster(dAtA, i, uint64(len(m.Kubeconfig)))
|
||||
i += copy(dAtA[i:], m.Kubeconfig)
|
||||
}
|
||||
if len(m.Context) > 0 {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintCluster(dAtA, i, uint64(len(m.Context)))
|
||||
i += copy(dAtA[i:], m.Context)
|
||||
}
|
||||
if m.Upsert {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
if m.Upsert {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.InCluster {
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
if m.InCluster {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ClusterUpdateRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
@@ -770,29 +610,6 @@ func (m *ClusterCreateRequest) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ClusterCreateFromKubeConfigRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Kubeconfig)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovCluster(uint64(l))
|
||||
}
|
||||
l = len(m.Context)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovCluster(uint64(l))
|
||||
}
|
||||
if m.Upsert {
|
||||
n += 2
|
||||
}
|
||||
if m.InCluster {
|
||||
n += 2
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ClusterUpdateRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
@@ -1054,155 +871,6 @@ func (m *ClusterCreateRequest) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ClusterCreateFromKubeConfigRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCluster
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ClusterCreateFromKubeConfigRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ClusterCreateFromKubeConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Kubeconfig", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCluster
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthCluster
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Kubeconfig = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Context", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCluster
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthCluster
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Context = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Upsert", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCluster
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Upsert = bool(v != 0)
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field InCluster", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowCluster
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.InCluster = bool(v != 0)
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipCluster(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthCluster
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ClusterUpdateRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
@@ -1393,45 +1061,39 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/cluster/cluster.proto", fileDescriptor_cluster_0875510a34378ea0)
|
||||
proto.RegisterFile("server/cluster/cluster.proto", fileDescriptor_cluster_96df59157dc2259c)
|
||||
}
|
||||
|
||||
var fileDescriptor_cluster_0875510a34378ea0 = []byte{
|
||||
// 564 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcd, 0x6e, 0x13, 0x31,
|
||||
0x10, 0xc7, 0xe5, 0xb6, 0xda, 0x12, 0x83, 0xf8, 0xb0, 0x0a, 0x5a, 0xd2, 0x10, 0xa5, 0x3e, 0x54,
|
||||
0x55, 0xa0, 0xb6, 0x12, 0x2e, 0x55, 0x8f, 0x0d, 0x2a, 0x42, 0x70, 0x21, 0x88, 0x0b, 0xaa, 0x84,
|
||||
0x36, 0x9b, 0x61, 0xbb, 0x24, 0x5d, 0x2f, 0xb6, 0x37, 0x02, 0x21, 0x84, 0x04, 0x57, 0xc4, 0x05,
|
||||
0xee, 0x3c, 0x02, 0xaf, 0xc1, 0x11, 0x89, 0x1b, 0x27, 0x14, 0xf1, 0x20, 0x68, 0xbd, 0x76, 0xbe,
|
||||
0xc3, 0x85, 0x88, 0x53, 0xec, 0x19, 0x67, 0xe6, 0x37, 0x33, 0xff, 0x4c, 0x70, 0x45, 0x81, 0x1c,
|
||||
0x80, 0xe4, 0x61, 0x3f, 0x53, 0x7a, 0xfc, 0xc9, 0x52, 0x29, 0xb4, 0x20, 0x9b, 0xf6, 0x5a, 0xde,
|
||||
0x8a, 0x44, 0x24, 0x8c, 0x8d, 0xe7, 0xa7, 0xc2, 0x5d, 0xae, 0x44, 0x42, 0x44, 0x7d, 0xe0, 0x41,
|
||||
0x1a, 0xf3, 0x20, 0x49, 0x84, 0x0e, 0x74, 0x2c, 0x12, 0x65, 0xbd, 0xb4, 0x77, 0xa0, 0x58, 0x2c,
|
||||
0x8c, 0x37, 0x14, 0x12, 0xf8, 0xa0, 0xc1, 0x23, 0x48, 0x40, 0x06, 0x1a, 0xba, 0xf6, 0xcd, 0xbd,
|
||||
0x28, 0xd6, 0xa7, 0x59, 0x87, 0x85, 0xe2, 0x8c, 0x07, 0xd2, 0xa4, 0x78, 0x6e, 0x0e, 0xfb, 0x61,
|
||||
0x97, 0xa7, 0xbd, 0x28, 0xff, 0xb2, 0xe2, 0x41, 0x9a, 0xf6, 0xe3, 0xd0, 0x04, 0xe7, 0x83, 0x46,
|
||||
0xd0, 0x4f, 0x4f, 0x83, 0xb9, 0x50, 0x74, 0x17, 0x5f, 0x68, 0x15, 0xb4, 0x0f, 0x33, 0x90, 0xaf,
|
||||
0xc8, 0x35, 0xec, 0x15, 0xb5, 0xf9, 0xa8, 0x86, 0xf6, 0x4a, 0x6d, 0x7b, 0xa3, 0x57, 0xf0, 0x25,
|
||||
0xfb, 0xae, 0x0d, 0x2a, 0x15, 0x89, 0x02, 0xfa, 0x01, 0xe1, 0x2d, 0x6b, 0x6b, 0x49, 0x08, 0x34,
|
||||
0xb4, 0xe1, 0x45, 0x06, 0x4a, 0x93, 0x13, 0xec, 0x3a, 0x60, 0x82, 0x9c, 0x6f, 0x1e, 0xb1, 0x31,
|
||||
0x30, 0x73, 0xc0, 0xe6, 0xf0, 0x34, 0xec, 0xb2, 0xb4, 0x17, 0xb1, 0x1c, 0x98, 0x4d, 0x00, 0x33,
|
||||
0x07, 0xcc, 0x5c, 0x56, 0x17, 0x32, 0x27, 0xcc, 0x52, 0x05, 0x52, 0xfb, 0x6b, 0x35, 0xb4, 0x77,
|
||||
0xae, 0x6d, 0x6f, 0xf4, 0x33, 0xc2, 0x74, 0x0a, 0xe7, 0x58, 0x8a, 0xb3, 0xfb, 0x59, 0x07, 0x5a,
|
||||
0x22, 0x79, 0x16, 0x47, 0x0e, 0xae, 0x8a, 0x71, 0x2f, 0xeb, 0x40, 0x68, 0x8c, 0xb6, 0xc8, 0x09,
|
||||
0x0b, 0xf1, 0xf1, 0x66, 0x28, 0x12, 0x0d, 0x2f, 0x8b, 0xf8, 0xa5, 0xb6, 0xbb, 0x4e, 0x24, 0x5e,
|
||||
0x9f, 0x4c, 0x4c, 0x2a, 0xb8, 0x14, 0x27, 0x36, 0xb3, 0xbf, 0x61, 0x5c, 0x63, 0x03, 0xd5, 0xa3,
|
||||
0x26, 0x3d, 0x4e, 0xbb, 0xff, 0xab, 0x49, 0xcd, 0x9f, 0x1e, 0xbe, 0x68, 0x8d, 0x8f, 0x40, 0x0e,
|
||||
0xe2, 0x10, 0xc8, 0x5b, 0xbc, 0xf1, 0x20, 0x56, 0x9a, 0x5c, 0x65, 0x4e, 0xad, 0x93, 0x83, 0x2f,
|
||||
0x1f, 0xff, 0x7b, 0xfa, 0x3c, 0x3c, 0xf5, 0xdf, 0xfd, 0xf8, 0xfd, 0x69, 0x8d, 0x90, 0xcb, 0x46,
|
||||
0xc1, 0x83, 0x86, 0xfb, 0x6d, 0x28, 0xf2, 0x11, 0x61, 0xaf, 0x98, 0x0c, 0xb9, 0x31, 0xcb, 0x30,
|
||||
0x25, 0xa0, 0xf2, 0x0a, 0x5a, 0x41, 0x77, 0x0c, 0xc7, 0x36, 0x9d, 0xe3, 0x38, 0x1c, 0x29, 0xe9,
|
||||
0x6b, 0x2e, 0xe0, 0x05, 0x52, 0x21, 0x37, 0x17, 0xe3, 0x2d, 0x14, 0xd4, 0x4a, 0x60, 0x77, 0x0d,
|
||||
0x6c, 0x8d, 0x6e, 0xcf, 0xc2, 0xee, 0x8f, 0x95, 0x79, 0x88, 0xea, 0xe4, 0x3d, 0xc2, 0xeb, 0x77,
|
||||
0x61, 0xe9, 0x0c, 0x57, 0xd8, 0x37, 0x72, 0x7d, 0x16, 0x85, 0xbf, 0x2e, 0x56, 0xc1, 0x1b, 0xf2,
|
||||
0x05, 0x61, 0xaf, 0x10, 0xf3, 0xfc, 0x20, 0xa7, 0x44, 0xbe, 0x12, 0xa0, 0xa6, 0x01, 0xba, 0x55,
|
||||
0xde, 0x99, 0x07, 0x72, 0xb9, 0x2d, 0xd8, 0x78, 0xb2, 0x27, 0xd8, 0xbb, 0x03, 0x7d, 0xd0, 0xb0,
|
||||
0xac, 0x53, 0xfe, 0xac, 0x79, 0xb4, 0xd5, 0x6c, 0xfd, 0xf5, 0xe5, 0xf5, 0x1f, 0x1d, 0x7c, 0x1b,
|
||||
0x56, 0xd1, 0xf7, 0x61, 0x15, 0xfd, 0x1a, 0x56, 0xd1, 0x93, 0xfa, 0xdf, 0x96, 0xf1, 0xf4, 0xff,
|
||||
0x44, 0xc7, 0x33, 0x4b, 0xf7, 0xf6, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x23, 0xc4, 0x8d, 0xa4,
|
||||
0x40, 0x06, 0x00, 0x00,
|
||||
var fileDescriptor_cluster_96df59157dc2259c = []byte{
|
||||
// 472 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0xcf, 0x8b, 0x13, 0x31,
|
||||
0x14, 0xc7, 0xc9, 0xaa, 0xa3, 0x46, 0xf1, 0x47, 0x58, 0xa5, 0x8e, 0x6b, 0xd9, 0xcd, 0x41, 0x96,
|
||||
0x45, 0x13, 0x5a, 0x2f, 0x8b, 0xc7, 0x5d, 0x51, 0x04, 0x2f, 0x56, 0xbc, 0xc8, 0x82, 0x64, 0xa7,
|
||||
0x8f, 0xec, 0xd8, 0x71, 0x12, 0x93, 0xcc, 0x80, 0x88, 0x08, 0x7a, 0x15, 0x2f, 0xfe, 0x01, 0x5e,
|
||||
0xfd, 0x53, 0x3c, 0x0a, 0xfe, 0x03, 0x52, 0xfc, 0x43, 0x64, 0x32, 0x49, 0xbb, 0x6d, 0xa9, 0x17,
|
||||
0xcb, 0x9e, 0x9a, 0xbc, 0xa4, 0xef, 0x7d, 0xf2, 0x7d, 0xdf, 0x79, 0x78, 0xc3, 0x82, 0xa9, 0xc1,
|
||||
0xf0, 0xac, 0xa8, 0xac, 0x9b, 0xfe, 0x32, 0x6d, 0x94, 0x53, 0xe4, 0x6c, 0xd8, 0xa6, 0xeb, 0x52,
|
||||
0x49, 0xe5, 0x63, 0xbc, 0x59, 0xb5, 0xc7, 0xe9, 0x86, 0x54, 0x4a, 0x16, 0xc0, 0x85, 0xce, 0xb9,
|
||||
0x28, 0x4b, 0xe5, 0x84, 0xcb, 0x55, 0x69, 0xc3, 0x29, 0x1d, 0xed, 0x5a, 0x96, 0x2b, 0x7f, 0x9a,
|
||||
0x29, 0x03, 0xbc, 0xee, 0x71, 0x09, 0x25, 0x18, 0xe1, 0x60, 0x18, 0xee, 0x3c, 0x96, 0xb9, 0x3b,
|
||||
0xaa, 0x0e, 0x59, 0xa6, 0x5e, 0x73, 0x61, 0x7c, 0x89, 0x57, 0x7e, 0x71, 0x37, 0x1b, 0x72, 0x3d,
|
||||
0x92, 0xcd, 0x9f, 0x2d, 0x17, 0x5a, 0x17, 0x79, 0xe6, 0x93, 0xf3, 0xba, 0x27, 0x0a, 0x7d, 0x24,
|
||||
0x16, 0x52, 0xd1, 0xdb, 0xf8, 0xe2, 0x7e, 0x4b, 0xfb, 0xb4, 0x02, 0xf3, 0x96, 0x5c, 0xc7, 0x49,
|
||||
0xfb, 0xb6, 0x0e, 0xda, 0x44, 0xdb, 0xe7, 0x07, 0x61, 0x47, 0xaf, 0xe2, 0xcb, 0xe1, 0xde, 0x00,
|
||||
0xac, 0x56, 0xa5, 0x05, 0xfa, 0x19, 0xe1, 0xf5, 0x10, 0xdb, 0x37, 0x20, 0x1c, 0x0c, 0xe0, 0x4d,
|
||||
0x05, 0xd6, 0x91, 0x03, 0x1c, 0x15, 0xf0, 0x49, 0x2e, 0xf4, 0xf7, 0xd8, 0x14, 0x98, 0x45, 0x60,
|
||||
0xbf, 0x78, 0x99, 0x0d, 0x99, 0x1e, 0x49, 0xd6, 0x00, 0xb3, 0x63, 0xc0, 0x2c, 0x02, 0xb3, 0x58,
|
||||
0x35, 0xa6, 0x6c, 0x08, 0x2b, 0x6d, 0xc1, 0xb8, 0xce, 0xda, 0x26, 0xda, 0x3e, 0x37, 0x08, 0x3b,
|
||||
0xea, 0x26, 0x34, 0xcf, 0xf5, 0xf0, 0xa4, 0x68, 0xfa, 0xdf, 0xcf, 0xe0, 0x4b, 0x21, 0xf8, 0x0c,
|
||||
0x4c, 0x9d, 0x67, 0x40, 0x3e, 0xe0, 0xd3, 0x4f, 0x72, 0xeb, 0xc8, 0x35, 0x16, 0x6d, 0x71, 0x5c,
|
||||
0xe1, 0xf4, 0xe1, 0xff, 0x97, 0x6f, 0xd2, 0xd3, 0xce, 0xc7, 0x5f, 0x7f, 0xbe, 0xae, 0x11, 0x72,
|
||||
0xc5, 0x5b, 0xa5, 0xee, 0x45, 0x13, 0x5a, 0xf2, 0x05, 0xe1, 0xa4, 0xed, 0x08, 0xb9, 0x35, 0xcf,
|
||||
0x30, 0xd3, 0xa9, 0x74, 0x05, 0x52, 0xd0, 0x2d, 0xcf, 0x71, 0x93, 0x2e, 0x70, 0xdc, 0x9f, 0xb4,
|
||||
0xec, 0x13, 0xc2, 0xa7, 0x1e, 0xc1, 0x52, 0x45, 0x56, 0x48, 0x41, 0x6e, 0xcc, 0x53, 0xf0, 0x77,
|
||||
0xad, 0x83, 0xdf, 0x93, 0x6f, 0x08, 0x27, 0xad, 0x35, 0x16, 0x65, 0x99, 0xb1, 0xcc, 0x4a, 0x80,
|
||||
0xfa, 0x1e, 0xe8, 0x4e, 0xba, 0xb5, 0x08, 0x14, 0x6b, 0x07, 0xb0, 0xa9, 0x4e, 0x07, 0x38, 0x79,
|
||||
0x00, 0x05, 0x38, 0x58, 0xa6, 0x54, 0x67, 0x3e, 0x3c, 0xf9, 0x18, 0xc3, 0xfb, 0x77, 0x96, 0xbf,
|
||||
0x7f, 0x6f, 0xf7, 0xc7, 0xb8, 0x8b, 0x7e, 0x8e, 0xbb, 0xe8, 0xf7, 0xb8, 0x8b, 0x5e, 0xec, 0xfc,
|
||||
0x6b, 0x86, 0xcc, 0x8e, 0xb7, 0xc3, 0xc4, 0xcf, 0x8a, 0x7b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
|
||||
0x2c, 0xae, 0x46, 0x1e, 0xf7, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -66,19 +66,6 @@ func request_ClusterService_Create_0(ctx context.Context, marshaler runtime.Mars
|
||||
|
||||
}
|
||||
|
||||
func request_ClusterService_CreateFromKubeConfig_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ClusterCreateFromKubeConfigRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.CreateFromKubeConfig(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_ClusterService_Get_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ClusterQuery
|
||||
var metadata runtime.ServerMetadata
|
||||
@@ -260,35 +247,6 @@ func RegisterClusterServiceHandlerClient(ctx context.Context, mux *runtime.Serve
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ClusterService_CreateFromKubeConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_ClusterService_CreateFromKubeConfig_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ClusterService_CreateFromKubeConfig_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_ClusterService_Get_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -384,8 +342,6 @@ var (
|
||||
|
||||
pattern_ClusterService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "clusters"}, ""))
|
||||
|
||||
pattern_ClusterService_CreateFromKubeConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "clusters-kubeconfig"}, ""))
|
||||
|
||||
pattern_ClusterService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "clusters", "server"}, ""))
|
||||
|
||||
pattern_ClusterService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "clusters", "cluster.server"}, ""))
|
||||
@@ -398,8 +354,6 @@ var (
|
||||
|
||||
forward_ClusterService_Create_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ClusterService_CreateFromKubeConfig_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ClusterService_Get_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ClusterService_Update_0 = runtime.ForwardResponseMessage
|
||||
|
||||
@@ -24,13 +24,6 @@ message ClusterCreateRequest {
|
||||
bool upsert = 2;
|
||||
}
|
||||
|
||||
message ClusterCreateFromKubeConfigRequest {
|
||||
string kubeconfig = 1;
|
||||
string context = 2;
|
||||
bool upsert = 3;
|
||||
bool inCluster = 4;
|
||||
}
|
||||
|
||||
message ClusterUpdateRequest {
|
||||
github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Cluster cluster = 1;
|
||||
}
|
||||
@@ -51,14 +44,6 @@ service ClusterService {
|
||||
};
|
||||
}
|
||||
|
||||
// CreateFromKubeConfig installs the argocd-manager service account into the cluster specified in the given kubeconfig and context
|
||||
rpc CreateFromKubeConfig(ClusterCreateFromKubeConfigRequest) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Cluster) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/clusters-kubeconfig"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// Get returns a cluster by server address
|
||||
rpc Get(ClusterQuery) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Cluster) {
|
||||
option (google.api.http).get = "/api/v1/clusters/{server}";
|
||||
|
||||
@@ -46,7 +46,7 @@ func (m *ProjectCreateRequest) Reset() { *m = ProjectCreateRequest{} }
|
||||
func (m *ProjectCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectCreateRequest) ProtoMessage() {}
|
||||
func (*ProjectCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{0}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{0}
|
||||
}
|
||||
func (m *ProjectCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -96,7 +96,7 @@ func (m *ProjectTokenDeleteRequest) Reset() { *m = ProjectTokenDeleteReq
|
||||
func (m *ProjectTokenDeleteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectTokenDeleteRequest) ProtoMessage() {}
|
||||
func (*ProjectTokenDeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{1}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{1}
|
||||
}
|
||||
func (m *ProjectTokenDeleteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -162,7 +162,7 @@ func (m *ProjectTokenCreateRequest) Reset() { *m = ProjectTokenCreateReq
|
||||
func (m *ProjectTokenCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectTokenCreateRequest) ProtoMessage() {}
|
||||
func (*ProjectTokenCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{2}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{2}
|
||||
}
|
||||
func (m *ProjectTokenCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -231,7 +231,7 @@ func (m *ProjectTokenResponse) Reset() { *m = ProjectTokenResponse{} }
|
||||
func (m *ProjectTokenResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectTokenResponse) ProtoMessage() {}
|
||||
func (*ProjectTokenResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{3}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{3}
|
||||
}
|
||||
func (m *ProjectTokenResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -279,7 +279,7 @@ func (m *ProjectQuery) Reset() { *m = ProjectQuery{} }
|
||||
func (m *ProjectQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectQuery) ProtoMessage() {}
|
||||
func (*ProjectQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{4}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{4}
|
||||
}
|
||||
func (m *ProjectQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -326,7 +326,7 @@ func (m *ProjectUpdateRequest) Reset() { *m = ProjectUpdateRequest{} }
|
||||
func (m *ProjectUpdateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProjectUpdateRequest) ProtoMessage() {}
|
||||
func (*ProjectUpdateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{5}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{5}
|
||||
}
|
||||
func (m *ProjectUpdateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -372,7 +372,7 @@ func (m *EmptyResponse) Reset() { *m = EmptyResponse{} }
|
||||
func (m *EmptyResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*EmptyResponse) ProtoMessage() {}
|
||||
func (*EmptyResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_project_082822b5d17b8c4e, []int{6}
|
||||
return fileDescriptor_project_579f5f5e657aac5a, []int{6}
|
||||
}
|
||||
func (m *EmptyResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1846,10 +1846,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/project/project.proto", fileDescriptor_project_082822b5d17b8c4e)
|
||||
proto.RegisterFile("server/project/project.proto", fileDescriptor_project_579f5f5e657aac5a)
|
||||
}
|
||||
|
||||
var fileDescriptor_project_082822b5d17b8c4e = []byte{
|
||||
var fileDescriptor_project_579f5f5e657aac5a = []byte{
|
||||
// 697 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x5d, 0x6b, 0x13, 0x4d,
|
||||
0x14, 0x66, 0x9a, 0xbe, 0x79, 0xdf, 0x4e, 0x5e, 0xb5, 0x0c, 0xad, 0xa6, 0xb1, 0x8d, 0x61, 0x2e,
|
||||
|
||||
@@ -26,12 +26,17 @@ const (
|
||||
ActionSync = "sync"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultScopes = []string{"groups"}
|
||||
)
|
||||
|
||||
// RBACPolicyEnforcer provides an RBAC Claims Enforcer which additionally consults AppProject
|
||||
// roles, jwt tokens, and groups. It is backed by a AppProject informer/lister cache and does not
|
||||
// make any API calls during enforcement.
|
||||
type RBACPolicyEnforcer struct {
|
||||
enf *rbac.Enforcer
|
||||
projLister applister.AppProjectNamespaceLister
|
||||
scopes []string
|
||||
}
|
||||
|
||||
// NewRBACPolicyEnforcer returns a new RBAC Enforcer for the Argo CD API Server
|
||||
@@ -39,9 +44,14 @@ func NewRBACPolicyEnforcer(enf *rbac.Enforcer, projLister applister.AppProjectNa
|
||||
return &RBACPolicyEnforcer{
|
||||
enf: enf,
|
||||
projLister: projLister,
|
||||
scopes: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *RBACPolicyEnforcer) SetScopes(scopes []string) {
|
||||
p.scopes = scopes
|
||||
}
|
||||
|
||||
// EnforceClaims is an RBAC claims enforcer specific to the Argo CD API server
|
||||
func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...interface{}) bool {
|
||||
mapClaims, err := jwtutil.MapClaims(claims)
|
||||
@@ -68,8 +78,12 @@ func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...interface
|
||||
return true
|
||||
}
|
||||
|
||||
scopes := p.scopes
|
||||
if scopes == nil {
|
||||
scopes = defaultScopes
|
||||
}
|
||||
// Finally check if any of the user's groups grant them permissions
|
||||
groups := jwtutil.GetGroups(mapClaims)
|
||||
groups := jwtutil.GetScopeValues(mapClaims, scopes)
|
||||
for _, group := range groups {
|
||||
vals := append([]interface{}{group}, rvals[1:]...)
|
||||
if p.enf.EnforceRuntimePolicy(runtimePolicy, vals...) {
|
||||
|
||||
@@ -68,4 +68,9 @@ func TestEnforceAllPolicies(t *testing.T) {
|
||||
assert.False(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app"))
|
||||
claims = jwt.MapClaims{"groups": []string{"my-org:other-group"}}
|
||||
assert.False(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app"))
|
||||
|
||||
// AWS cognito returns its groups in cognito:groups
|
||||
rbacEnf.SetScopes([]string{"cognito:groups"})
|
||||
claims = jwt.MapClaims{"cognito:groups": []string{"my-org:my-team"}}
|
||||
assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app"))
|
||||
}
|
||||
|
||||
@@ -164,13 +164,7 @@ func (s *Server) ListApps(ctx context.Context, q *RepoAppsQuery) (*RepoAppsRespo
|
||||
}
|
||||
repo, err := s.db.GetRepository(ctx, q.Repo)
|
||||
if err != nil {
|
||||
if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound {
|
||||
repo = &appsv1.Repository{
|
||||
Repo: q.Repo,
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Test the repo
|
||||
@@ -202,13 +196,7 @@ func (s *Server) GetAppDetails(ctx context.Context, q *RepoAppDetailsQuery) (*re
|
||||
}
|
||||
repo, err := s.db.GetRepository(ctx, q.Repo)
|
||||
if err != nil {
|
||||
if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound {
|
||||
repo = &appsv1.Repository{
|
||||
Repo: q.Repo,
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
conn, repoClient, err := s.repoClientset.NewRepoServerClient()
|
||||
if err != nil {
|
||||
|
||||
@@ -47,7 +47,7 @@ func (m *RepoAppsQuery) Reset() { *m = RepoAppsQuery{} }
|
||||
func (m *RepoAppsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoAppsQuery) ProtoMessage() {}
|
||||
func (*RepoAppsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{0}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{0}
|
||||
}
|
||||
func (m *RepoAppsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -103,7 +103,7 @@ func (m *AppInfo) Reset() { *m = AppInfo{} }
|
||||
func (m *AppInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*AppInfo) ProtoMessage() {}
|
||||
func (*AppInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{1}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{1}
|
||||
}
|
||||
func (m *AppInfo) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -162,7 +162,7 @@ func (m *RepoAppDetailsQuery) Reset() { *m = RepoAppDetailsQuery{} }
|
||||
func (m *RepoAppDetailsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoAppDetailsQuery) ProtoMessage() {}
|
||||
func (*RepoAppDetailsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{2}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{2}
|
||||
}
|
||||
func (m *RepoAppDetailsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -238,7 +238,7 @@ func (m *RepoAppsResponse) Reset() { *m = RepoAppsResponse{} }
|
||||
func (m *RepoAppsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoAppsResponse) ProtoMessage() {}
|
||||
func (*RepoAppsResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{3}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{3}
|
||||
}
|
||||
func (m *RepoAppsResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -286,7 +286,7 @@ func (m *RepoQuery) Reset() { *m = RepoQuery{} }
|
||||
func (m *RepoQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoQuery) ProtoMessage() {}
|
||||
func (*RepoQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{4}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{4}
|
||||
}
|
||||
func (m *RepoQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -332,7 +332,7 @@ func (m *RepoResponse) Reset() { *m = RepoResponse{} }
|
||||
func (m *RepoResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoResponse) ProtoMessage() {}
|
||||
func (*RepoResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{5}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{5}
|
||||
}
|
||||
func (m *RepoResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -373,7 +373,7 @@ func (m *RepoCreateRequest) Reset() { *m = RepoCreateRequest{} }
|
||||
func (m *RepoCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoCreateRequest) ProtoMessage() {}
|
||||
func (*RepoCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{6}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{6}
|
||||
}
|
||||
func (m *RepoCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -427,7 +427,7 @@ func (m *RepoUpdateRequest) Reset() { *m = RepoUpdateRequest{} }
|
||||
func (m *RepoUpdateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*RepoUpdateRequest) ProtoMessage() {}
|
||||
func (*RepoUpdateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_repository_8a59358b1a9ab690, []int{7}
|
||||
return fileDescriptor_repository_40c78d186a0140db, []int{7}
|
||||
}
|
||||
func (m *RepoUpdateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -2081,10 +2081,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/repository/repository.proto", fileDescriptor_repository_8a59358b1a9ab690)
|
||||
proto.RegisterFile("server/repository/repository.proto", fileDescriptor_repository_40c78d186a0140db)
|
||||
}
|
||||
|
||||
var fileDescriptor_repository_8a59358b1a9ab690 = []byte{
|
||||
var fileDescriptor_repository_40c78d186a0140db = []byte{
|
||||
// 675 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcd, 0x6e, 0x13, 0x3d,
|
||||
0x14, 0xd5, 0xb4, 0x69, 0xda, 0xba, 0x5f, 0x3f, 0x81, 0x5b, 0xaa, 0x30, 0xa4, 0x6d, 0x64, 0x16,
|
||||
|
||||
@@ -15,6 +15,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
||||
golang_proto "github.com/golang/protobuf/proto"
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
||||
@@ -103,13 +106,14 @@ var (
|
||||
type ArgoCDServer struct {
|
||||
ArgoCDServerOpts
|
||||
|
||||
ssoClientApp *oidc.ClientApp
|
||||
settings *settings_util.ArgoCDSettings
|
||||
log *log.Entry
|
||||
sessionMgr *util_session.SessionManager
|
||||
settingsMgr *settings_util.SettingsManager
|
||||
enf *rbac.Enforcer
|
||||
projInformer cache.SharedIndexInformer
|
||||
ssoClientApp *oidc.ClientApp
|
||||
settings *settings_util.ArgoCDSettings
|
||||
log *log.Entry
|
||||
sessionMgr *util_session.SessionManager
|
||||
settingsMgr *settings_util.SettingsManager
|
||||
enf *rbac.Enforcer
|
||||
projInformer cache.SharedIndexInformer
|
||||
policyEnforcer *rbacpolicy.RBACPolicyEnforcer
|
||||
|
||||
// stopCh is the channel which when closed, will shutdown the Argo CD server
|
||||
stopCh chan struct{}
|
||||
@@ -177,6 +181,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
|
||||
settingsMgr: settingsMgr,
|
||||
enf: enf,
|
||||
projInformer: projInformer,
|
||||
policyEnforcer: policyEnf,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +355,19 @@ func (a *ArgoCDServer) watchSettings(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) {
|
||||
err := a.enf.RunPolicyLoader(ctx)
|
||||
err := a.enf.RunPolicyLoader(ctx, func(cm *v1.ConfigMap) error {
|
||||
var scopes []string
|
||||
if scopesStr, ok := cm.Data[rbac.ConfigMapScopesKey]; len(scopesStr) > 0 && ok {
|
||||
scopes = make([]string, 0)
|
||||
err := yaml.Unmarshal([]byte(scopesStr), &scopes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a.policyEnforcer.SetScopes(scopes)
|
||||
return nil
|
||||
})
|
||||
errors.CheckError(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ func (m *SessionCreateRequest) Reset() { *m = SessionCreateRequest{} }
|
||||
func (m *SessionCreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SessionCreateRequest) ProtoMessage() {}
|
||||
func (*SessionCreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_session_8e535ce77fc5e082, []int{0}
|
||||
return fileDescriptor_session_ce4750ea85292617, []int{0}
|
||||
}
|
||||
func (m *SessionCreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -108,7 +108,7 @@ func (m *SessionDeleteRequest) Reset() { *m = SessionDeleteRequest{} }
|
||||
func (m *SessionDeleteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SessionDeleteRequest) ProtoMessage() {}
|
||||
func (*SessionDeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_session_8e535ce77fc5e082, []int{1}
|
||||
return fileDescriptor_session_ce4750ea85292617, []int{1}
|
||||
}
|
||||
func (m *SessionDeleteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -149,7 +149,7 @@ func (m *SessionResponse) Reset() { *m = SessionResponse{} }
|
||||
func (m *SessionResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SessionResponse) ProtoMessage() {}
|
||||
func (*SessionResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_session_8e535ce77fc5e082, []int{2}
|
||||
return fileDescriptor_session_ce4750ea85292617, []int{2}
|
||||
}
|
||||
func (m *SessionResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -827,10 +827,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/session/session.proto", fileDescriptor_session_8e535ce77fc5e082)
|
||||
proto.RegisterFile("server/session/session.proto", fileDescriptor_session_ce4750ea85292617)
|
||||
}
|
||||
|
||||
var fileDescriptor_session_8e535ce77fc5e082 = []byte{
|
||||
var fileDescriptor_session_ce4750ea85292617 = []byte{
|
||||
// 356 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xb1, 0x4e, 0xeb, 0x30,
|
||||
0x14, 0x86, 0xe5, 0x5e, 0xdd, 0xde, 0x7b, 0x3d, 0xdc, 0x8a, 0x28, 0x82, 0x28, 0x2a, 0x15, 0xca,
|
||||
|
||||
@@ -50,6 +50,7 @@ func (s *Server) Get(ctx context.Context, q *SettingsQuery) (*Settings, error) {
|
||||
Issuer: oidcConfig.Issuer,
|
||||
ClientID: oidcConfig.ClientID,
|
||||
CLIClientID: oidcConfig.CLIClientID,
|
||||
Scopes: oidcConfig.RequestedScopes,
|
||||
}
|
||||
}
|
||||
return &set, nil
|
||||
|
||||
@@ -43,7 +43,7 @@ func (m *SettingsQuery) Reset() { *m = SettingsQuery{} }
|
||||
func (m *SettingsQuery) String() string { return proto.CompactTextString(m) }
|
||||
func (*SettingsQuery) ProtoMessage() {}
|
||||
func (*SettingsQuery) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_settings_f96c7d59ef70e4fa, []int{0}
|
||||
return fileDescriptor_settings_e1e5490ce99485a2, []int{0}
|
||||
}
|
||||
func (m *SettingsQuery) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -87,7 +87,7 @@ func (m *Settings) Reset() { *m = Settings{} }
|
||||
func (m *Settings) String() string { return proto.CompactTextString(m) }
|
||||
func (*Settings) ProtoMessage() {}
|
||||
func (*Settings) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_settings_f96c7d59ef70e4fa, []int{1}
|
||||
return fileDescriptor_settings_e1e5490ce99485a2, []int{1}
|
||||
}
|
||||
func (m *Settings) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -162,7 +162,7 @@ func (m *DexConfig) Reset() { *m = DexConfig{} }
|
||||
func (m *DexConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*DexConfig) ProtoMessage() {}
|
||||
func (*DexConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_settings_f96c7d59ef70e4fa, []int{2}
|
||||
return fileDescriptor_settings_e1e5490ce99485a2, []int{2}
|
||||
}
|
||||
func (m *DexConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -210,7 +210,7 @@ func (m *Connector) Reset() { *m = Connector{} }
|
||||
func (m *Connector) String() string { return proto.CompactTextString(m) }
|
||||
func (*Connector) ProtoMessage() {}
|
||||
func (*Connector) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_settings_f96c7d59ef70e4fa, []int{3}
|
||||
return fileDescriptor_settings_e1e5490ce99485a2, []int{3}
|
||||
}
|
||||
func (m *Connector) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -258,6 +258,7 @@ type OIDCConfig struct {
|
||||
Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"`
|
||||
ClientID string `protobuf:"bytes,3,opt,name=clientID,proto3" json:"clientID,omitempty"`
|
||||
CLIClientID string `protobuf:"bytes,4,opt,name=cliClientID,proto3" json:"cliClientID,omitempty"`
|
||||
Scopes []string `protobuf:"bytes,5,rep,name=scopes" json:"scopes,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -267,7 +268,7 @@ func (m *OIDCConfig) Reset() { *m = OIDCConfig{} }
|
||||
func (m *OIDCConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*OIDCConfig) ProtoMessage() {}
|
||||
func (*OIDCConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_settings_f96c7d59ef70e4fa, []int{4}
|
||||
return fileDescriptor_settings_e1e5490ce99485a2, []int{4}
|
||||
}
|
||||
func (m *OIDCConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -324,6 +325,13 @@ func (m *OIDCConfig) GetCLIClientID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *OIDCConfig) GetScopes() []string {
|
||||
if m != nil {
|
||||
return m.Scopes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*SettingsQuery)(nil), "cluster.SettingsQuery")
|
||||
proto.RegisterType((*Settings)(nil), "cluster.Settings")
|
||||
@@ -614,6 +622,21 @@ func (m *OIDCConfig) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintSettings(dAtA, i, uint64(len(m.CLIClientID)))
|
||||
i += copy(dAtA[i:], m.CLIClientID)
|
||||
}
|
||||
if len(m.Scopes) > 0 {
|
||||
for _, s := range m.Scopes {
|
||||
dAtA[i] = 0x2a
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
dAtA[i] = uint8(l)
|
||||
i++
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
@@ -727,6 +750,12 @@ func (m *OIDCConfig) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovSettings(uint64(l))
|
||||
}
|
||||
if len(m.Scopes) > 0 {
|
||||
for _, s := range m.Scopes {
|
||||
l = len(s)
|
||||
n += 1 + l + sovSettings(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
@@ -1431,6 +1460,35 @@ func (m *OIDCConfig) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
m.CLIClientID = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Scopes", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSettings
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthSettings
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Scopes = append(m.Scopes, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipSettings(dAtA[iNdEx:])
|
||||
@@ -1559,45 +1617,46 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/settings/settings.proto", fileDescriptor_settings_f96c7d59ef70e4fa)
|
||||
proto.RegisterFile("server/settings/settings.proto", fileDescriptor_settings_e1e5490ce99485a2)
|
||||
}
|
||||
|
||||
var fileDescriptor_settings_f96c7d59ef70e4fa = []byte{
|
||||
// 566 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x5d, 0x6b, 0x13, 0x41,
|
||||
0x14, 0x65, 0xbb, 0xfd, 0xca, 0x8d, 0xda, 0x76, 0x94, 0x12, 0x83, 0x24, 0x21, 0x4f, 0x01, 0x71,
|
||||
0xd7, 0xa4, 0x2f, 0xea, 0x8b, 0x90, 0x54, 0x24, 0xb6, 0x50, 0x9c, 0xa2, 0x0f, 0x82, 0xc8, 0x74,
|
||||
0x72, 0xdd, 0x8e, 0xd9, 0xee, 0x2c, 0xb3, 0xb3, 0x8b, 0x79, 0xf5, 0x1f, 0x88, 0xf8, 0x27, 0xfc,
|
||||
0x25, 0x3e, 0x0a, 0xbe, 0x07, 0x59, 0xfc, 0x21, 0xb2, 0xb3, 0x1f, 0x59, 0x9a, 0xe2, 0xdb, 0xd9,
|
||||
0x73, 0xee, 0x99, 0x9d, 0x7b, 0xcf, 0x5c, 0xe8, 0x44, 0xa8, 0x12, 0x54, 0x6e, 0x84, 0x5a, 0x8b,
|
||||
0xc0, 0x8b, 0x2a, 0xe0, 0x84, 0x4a, 0x6a, 0x49, 0x76, 0xb8, 0x1f, 0x47, 0x1a, 0x55, 0xfb, 0x9e,
|
||||
0x27, 0x3d, 0x69, 0x38, 0x37, 0x43, 0xb9, 0xdc, 0x7e, 0xe0, 0x49, 0xe9, 0xf9, 0xe8, 0xb2, 0x50,
|
||||
0xb8, 0x2c, 0x08, 0xa4, 0x66, 0x5a, 0xc8, 0xa0, 0x30, 0xb7, 0xa7, 0x9e, 0xd0, 0x97, 0xf1, 0x85,
|
||||
0xc3, 0xe5, 0x95, 0xcb, 0x94, 0xb1, 0x7f, 0x32, 0xe0, 0x11, 0x9f, 0xb9, 0xe1, 0xdc, 0xcb, 0x6c,
|
||||
0x91, 0xcb, 0xc2, 0xd0, 0x17, 0xdc, 0x18, 0xdd, 0x64, 0xc8, 0xfc, 0xf0, 0x92, 0x0d, 0x5d, 0x0f,
|
||||
0x03, 0x54, 0x4c, 0xe3, 0x2c, 0x3f, 0xaa, 0xbf, 0x07, 0xb7, 0xcf, 0x8b, 0x9b, 0xbd, 0x8e, 0x51,
|
||||
0x2d, 0xfa, 0x3f, 0x6c, 0xd8, 0x2d, 0x19, 0x72, 0x1f, 0xec, 0x58, 0xf9, 0x2d, 0xab, 0x67, 0x0d,
|
||||
0x1a, 0xe3, 0x9d, 0x74, 0xd9, 0xb5, 0xdf, 0xd0, 0x53, 0x9a, 0x71, 0xe4, 0x31, 0x34, 0x66, 0xf8,
|
||||
0x79, 0x22, 0x83, 0x8f, 0xc2, 0x6b, 0x6d, 0xf4, 0xac, 0x41, 0x73, 0x44, 0x9c, 0xa2, 0x29, 0xe7,
|
||||
0xb8, 0x54, 0xe8, 0xaa, 0x88, 0x4c, 0x00, 0xa4, 0x98, 0xf1, 0xc2, 0x62, 0x1b, 0xcb, 0xdd, 0xca,
|
||||
0x72, 0x36, 0x3d, 0x9e, 0xe4, 0xd2, 0xf8, 0x4e, 0xba, 0xec, 0xc2, 0xea, 0x9b, 0xd6, 0x6c, 0xa4,
|
||||
0x07, 0x4d, 0x16, 0x86, 0xa7, 0xec, 0x02, 0xfd, 0x13, 0x5c, 0xb4, 0x36, 0xb3, 0x9b, 0xd1, 0x3a,
|
||||
0x45, 0xde, 0xc2, 0x81, 0xc2, 0x48, 0xc6, 0x8a, 0xe3, 0x59, 0x82, 0x4a, 0x89, 0x19, 0x46, 0xad,
|
||||
0xad, 0x9e, 0x3d, 0x68, 0x8e, 0x06, 0xd5, 0xdf, 0xca, 0x0e, 0x1d, 0x7a, 0xbd, 0xf4, 0x45, 0xa0,
|
||||
0xd5, 0x82, 0xae, 0x1f, 0xd1, 0xfe, 0x6a, 0xc1, 0xe1, 0xcd, 0xd5, 0x64, 0x1f, 0xec, 0x39, 0x2e,
|
||||
0xf2, 0x31, 0xd1, 0x0c, 0x12, 0x06, 0x5b, 0x09, 0xf3, 0x63, 0x2c, 0x26, 0x73, 0xe2, 0xac, 0x12,
|
||||
0x73, 0xca, 0xc4, 0x0c, 0xf8, 0xc0, 0x67, 0x4e, 0x38, 0xf7, 0x9c, 0x2c, 0x31, 0xa7, 0x96, 0x98,
|
||||
0x53, 0x26, 0xb6, 0x76, 0x43, 0x9a, 0x9f, 0xfc, 0x6c, 0xe3, 0x89, 0xd5, 0x7f, 0x0e, 0x8d, 0x6a,
|
||||
0xd4, 0x64, 0x04, 0xc0, 0x65, 0x10, 0x20, 0xd7, 0x52, 0x45, 0x2d, 0xcb, 0x74, 0xbc, 0x8a, 0x64,
|
||||
0x52, 0x4a, 0xb4, 0x56, 0xd5, 0x3f, 0x82, 0x46, 0x25, 0x10, 0x02, 0x9b, 0x01, 0xbb, 0xc2, 0xa2,
|
||||
0x0f, 0x83, 0x33, 0x4e, 0x2f, 0xc2, 0xbc, 0x8f, 0x06, 0x35, 0xb8, 0xff, 0xdd, 0x82, 0x5a, 0x3c,
|
||||
0x37, 0xda, 0x0e, 0x61, 0x5b, 0x44, 0x51, 0x8c, 0xaa, 0x30, 0x16, 0x5f, 0x64, 0x00, 0xbb, 0xdc,
|
||||
0x17, 0x18, 0xe8, 0xe9, 0xb1, 0x79, 0x01, 0x8d, 0xf1, 0xad, 0x74, 0xd9, 0xdd, 0x9d, 0x14, 0x1c,
|
||||
0xad, 0x54, 0x32, 0x84, 0x26, 0xf7, 0x45, 0x29, 0xe4, 0x41, 0x8f, 0xf7, 0xd2, 0x65, 0xb7, 0x39,
|
||||
0x39, 0x9d, 0x56, 0xf5, 0xf5, 0x9a, 0xd1, 0x7b, 0xd8, 0x2b, 0x73, 0x3d, 0x47, 0x95, 0x08, 0x8e,
|
||||
0xe4, 0x15, 0xd8, 0x2f, 0x51, 0x93, 0xc3, 0xb5, 0xe0, 0xcd, 0x63, 0x6f, 0x1f, 0xac, 0xf1, 0xfd,
|
||||
0xd6, 0x97, 0xdf, 0x7f, 0xbf, 0x6d, 0x10, 0xb2, 0x6f, 0x76, 0x2f, 0x19, 0x56, 0x8b, 0x3b, 0x7e,
|
||||
0xfa, 0x33, 0xed, 0x58, 0xbf, 0xd2, 0x8e, 0xf5, 0x27, 0xed, 0x58, 0xef, 0x1e, 0xfe, 0x6f, 0x07,
|
||||
0xaf, 0x2d, 0xff, 0xc5, 0xb6, 0x59, 0xb6, 0xa3, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0x4c,
|
||||
0x68, 0x20, 0x16, 0x04, 0x00, 0x00,
|
||||
var fileDescriptor_settings_e1e5490ce99485a2 = []byte{
|
||||
// 577 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0x5d, 0x6b, 0x13, 0x41,
|
||||
0x14, 0x65, 0xbb, 0xfd, 0xda, 0x1b, 0xb5, 0xed, 0x28, 0x25, 0x06, 0x49, 0x42, 0x9e, 0x02, 0xe2,
|
||||
0xae, 0x49, 0x5f, 0xd4, 0x17, 0x21, 0xa9, 0x48, 0x6c, 0xa1, 0x38, 0x45, 0x1f, 0x04, 0x91, 0xe9,
|
||||
0xe4, 0xba, 0x1d, 0xb3, 0xdd, 0x59, 0x66, 0x67, 0x83, 0x79, 0xf5, 0x1f, 0x88, 0xff, 0x42, 0xf0,
|
||||
0x7f, 0xf8, 0x28, 0xf8, 0x1e, 0x64, 0xf1, 0x87, 0xc8, 0xce, 0x7e, 0x64, 0x69, 0x8a, 0x6f, 0x67,
|
||||
0xce, 0xb9, 0x67, 0x76, 0xee, 0x9c, 0xb9, 0x0b, 0xed, 0x18, 0xd5, 0x1c, 0x95, 0x17, 0xa3, 0xd6,
|
||||
0x22, 0xf4, 0xe3, 0x0a, 0xb8, 0x91, 0x92, 0x5a, 0x92, 0x1d, 0x1e, 0x24, 0xb1, 0x46, 0xd5, 0xba,
|
||||
0xe7, 0x4b, 0x5f, 0x1a, 0xce, 0xcb, 0x50, 0x2e, 0xb7, 0x1e, 0xf8, 0x52, 0xfa, 0x01, 0x7a, 0x2c,
|
||||
0x12, 0x1e, 0x0b, 0x43, 0xa9, 0x99, 0x16, 0x32, 0x2c, 0xcc, 0xad, 0x89, 0x2f, 0xf4, 0x65, 0x72,
|
||||
0xe1, 0x72, 0x79, 0xe5, 0x31, 0x65, 0xec, 0x9f, 0x0c, 0x78, 0xc4, 0xa7, 0x5e, 0x34, 0xf3, 0x33,
|
||||
0x5b, 0xec, 0xb1, 0x28, 0x0a, 0x04, 0x37, 0x46, 0x6f, 0x3e, 0x60, 0x41, 0x74, 0xc9, 0x06, 0x9e,
|
||||
0x8f, 0x21, 0x2a, 0xa6, 0x71, 0x9a, 0x6f, 0xd5, 0xdb, 0x83, 0xdb, 0xe7, 0xc5, 0xc9, 0x5e, 0x27,
|
||||
0xa8, 0x16, 0xbd, 0xef, 0x36, 0xec, 0x96, 0x0c, 0xb9, 0x0f, 0x76, 0xa2, 0x82, 0xa6, 0xd5, 0xb5,
|
||||
0xfa, 0xce, 0x68, 0x27, 0x5d, 0x76, 0xec, 0x37, 0xf4, 0x94, 0x66, 0x1c, 0x79, 0x0c, 0xce, 0x14,
|
||||
0x3f, 0x8f, 0x65, 0xf8, 0x51, 0xf8, 0xcd, 0x8d, 0xae, 0xd5, 0x6f, 0x0c, 0x89, 0x5b, 0x34, 0xe5,
|
||||
0x1e, 0x97, 0x0a, 0x5d, 0x15, 0x91, 0x31, 0x80, 0x14, 0x53, 0x5e, 0x58, 0x6c, 0x63, 0xb9, 0x5b,
|
||||
0x59, 0xce, 0x26, 0xc7, 0xe3, 0x5c, 0x1a, 0xdd, 0x49, 0x97, 0x1d, 0x58, 0xad, 0x69, 0xcd, 0x46,
|
||||
0xba, 0xd0, 0x60, 0x51, 0x74, 0xca, 0x2e, 0x30, 0x38, 0xc1, 0x45, 0x73, 0x33, 0x3b, 0x19, 0xad,
|
||||
0x53, 0xe4, 0x2d, 0x1c, 0x28, 0x8c, 0x65, 0xa2, 0x38, 0x9e, 0xcd, 0x51, 0x29, 0x31, 0xc5, 0xb8,
|
||||
0xb9, 0xd5, 0xb5, 0xfb, 0x8d, 0x61, 0xbf, 0xfa, 0x5a, 0xd9, 0xa1, 0x4b, 0xaf, 0x97, 0xbe, 0x08,
|
||||
0xb5, 0x5a, 0xd0, 0xf5, 0x2d, 0x5a, 0x5f, 0x2d, 0x38, 0xbc, 0xb9, 0x9a, 0xec, 0x83, 0x3d, 0xc3,
|
||||
0x45, 0x7e, 0x4d, 0x34, 0x83, 0x84, 0xc1, 0xd6, 0x9c, 0x05, 0x09, 0x16, 0x37, 0x73, 0xe2, 0xae,
|
||||
0x12, 0x73, 0xcb, 0xc4, 0x0c, 0xf8, 0xc0, 0xa7, 0x6e, 0x34, 0xf3, 0xdd, 0x2c, 0x31, 0xb7, 0x96,
|
||||
0x98, 0x5b, 0x26, 0xb6, 0x76, 0x42, 0x9a, 0xef, 0xfc, 0x6c, 0xe3, 0x89, 0xd5, 0x7b, 0x0e, 0x4e,
|
||||
0x75, 0xd5, 0x64, 0x08, 0xc0, 0x65, 0x18, 0x22, 0xd7, 0x52, 0xc5, 0x4d, 0xcb, 0x74, 0xbc, 0x8a,
|
||||
0x64, 0x5c, 0x4a, 0xb4, 0x56, 0xd5, 0x3b, 0x02, 0xa7, 0x12, 0x08, 0x81, 0xcd, 0x90, 0x5d, 0x61,
|
||||
0xd1, 0x87, 0xc1, 0x19, 0xa7, 0x17, 0x51, 0xde, 0x87, 0x43, 0x0d, 0xee, 0xfd, 0xb0, 0xa0, 0x16,
|
||||
0xcf, 0x8d, 0xb6, 0x43, 0xd8, 0x16, 0x71, 0x9c, 0xa0, 0x2a, 0x8c, 0xc5, 0x8a, 0xf4, 0x61, 0x97,
|
||||
0x07, 0x02, 0x43, 0x3d, 0x39, 0x36, 0x2f, 0xc0, 0x19, 0xdd, 0x4a, 0x97, 0x9d, 0xdd, 0x71, 0xc1,
|
||||
0xd1, 0x4a, 0x25, 0x03, 0x68, 0xf0, 0x40, 0x94, 0x42, 0x1e, 0xf4, 0x68, 0x2f, 0x5d, 0x76, 0x1a,
|
||||
0xe3, 0xd3, 0x49, 0x55, 0x5f, 0xaf, 0xc9, 0x3e, 0x1a, 0x73, 0x19, 0x15, 0x71, 0x3b, 0xb4, 0x58,
|
||||
0x0d, 0xdf, 0xc3, 0x5e, 0x99, 0xf7, 0x39, 0xaa, 0xb9, 0xe0, 0x48, 0x5e, 0x81, 0xfd, 0x12, 0x35,
|
||||
0x39, 0x5c, 0x7b, 0x10, 0x66, 0x08, 0x5a, 0x07, 0x6b, 0x7c, 0xaf, 0xf9, 0xe5, 0xf7, 0xdf, 0x6f,
|
||||
0x1b, 0x84, 0xec, 0x9b, 0x99, 0x9c, 0x0f, 0xaa, 0x81, 0x1e, 0x3d, 0xfd, 0x99, 0xb6, 0xad, 0x5f,
|
||||
0x69, 0xdb, 0xfa, 0x93, 0xb6, 0xad, 0x77, 0x0f, 0xff, 0x37, 0x9b, 0xd7, 0x7e, 0x0a, 0x17, 0xdb,
|
||||
0x66, 0x08, 0x8f, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x66, 0xd0, 0x3d, 0x2e, 0x04, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ message OIDCConfig {
|
||||
string issuer = 2;
|
||||
string clientID = 3 [(gogoproto.customname) = "ClientID"];
|
||||
string cliClientID = 4 [(gogoproto.customname) = "CLIClientID"];
|
||||
repeated string scopes = 5;
|
||||
}
|
||||
|
||||
// SettingsService
|
||||
|
||||
@@ -51,7 +51,7 @@ func (m *VersionMessage) Reset() { *m = VersionMessage{} }
|
||||
func (m *VersionMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*VersionMessage) ProtoMessage() {}
|
||||
func (*VersionMessage) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_version_9a67e1897074bbcc, []int{0}
|
||||
return fileDescriptor_version_d7990ce5151ca1a0, []int{0}
|
||||
}
|
||||
func (m *VersionMessage) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -781,10 +781,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("server/version/version.proto", fileDescriptor_version_9a67e1897074bbcc)
|
||||
proto.RegisterFile("server/version/version.proto", fileDescriptor_version_d7990ce5151ca1a0)
|
||||
}
|
||||
|
||||
var fileDescriptor_version_9a67e1897074bbcc = []byte{
|
||||
var fileDescriptor_version_d7990ce5151ca1a0 = []byte{
|
||||
// 343 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xcf, 0x4a, 0xc3, 0x40,
|
||||
0x10, 0xc6, 0x49, 0xd5, 0xfe, 0x59, 0x4a, 0x0f, 0x8b, 0xd4, 0x25, 0x96, 0x22, 0x3d, 0x88, 0x08,
|
||||
|
||||
@@ -406,6 +406,7 @@ func TestEdgeCasesApplicationResources(t *testing.T) {
|
||||
"DeprecatedExtensions": "deprecated-extensions",
|
||||
"CRDs": "crd-creation",
|
||||
"DuplicatedResources": "duplicated-resources",
|
||||
"FailedConversion": "failed-conversion",
|
||||
}
|
||||
|
||||
for name, appPath := range apps {
|
||||
@@ -516,3 +517,75 @@ func TestResourceAction(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "test", deployment.Labels["sample"])
|
||||
}
|
||||
|
||||
func TestSyncResourceByLabel(t *testing.T) {
|
||||
fixture.EnsureCleanState()
|
||||
|
||||
app := createAndSyncDefault(t)
|
||||
|
||||
res, _ := fixture.RunCli("app", "sync", app.Name, "--label",
|
||||
fmt.Sprintf("app.kubernetes.io/instance=test-%s", strings.Split(app.Name, "-")[1]))
|
||||
assert.Contains(t, res, "guestbook-ui Synced Healthy")
|
||||
|
||||
res, _ = fixture.RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist")
|
||||
assert.Contains(t, res, "level=fatal")
|
||||
}
|
||||
|
||||
func TestPermissions(t *testing.T) {
|
||||
fixture.EnsureCleanState()
|
||||
appName := "test-app"
|
||||
_, err := fixture.RunCli("proj", "create", "test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// make sure app cannot be created without permissions in project
|
||||
output, err := fixture.RunCli("app", "create", appName, "--repo", fixture.RepoURL(),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace)
|
||||
assert.Error(t, err)
|
||||
sourceError := fmt.Sprintf("application repo %s is not permitted in project 'test'", fixture.RepoURL())
|
||||
destinationError := fmt.Sprintf("application destination {%s %s} is not permitted in project 'test'", common.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace)
|
||||
|
||||
assert.Contains(t, output, sourceError)
|
||||
assert.Contains(t, output, destinationError)
|
||||
|
||||
proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get("test", metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
proj.Spec.Destinations = []v1alpha1.ApplicationDestination{{Server: "*", Namespace: "*"}}
|
||||
proj.Spec.SourceRepos = []string{"*"}
|
||||
proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(proj)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// make sure controller report permissions issues in conditions
|
||||
_, err = fixture.RunCli("app", "create", "test-app", "--repo", fixture.RepoURL(),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Delete(appName, &metav1.DeleteOptions{})
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
proj.Spec.Destinations = []v1alpha1.ApplicationDestination{}
|
||||
proj.Spec.SourceRepos = []string{}
|
||||
_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(proj)
|
||||
assert.NoError(t, err)
|
||||
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
refresh := string(v1alpha1.RefreshTypeNormal)
|
||||
app, err := client.Get(context.Background(), &application.ApplicationQuery{Name: &appName, Refresh: &refresh})
|
||||
assert.NoError(t, err)
|
||||
|
||||
destinationErrorExist := false
|
||||
sourceErrorExist := false
|
||||
for i := range app.Status.Conditions {
|
||||
if strings.Contains(app.Status.Conditions[i].Message, destinationError) {
|
||||
destinationErrorExist = true
|
||||
}
|
||||
if strings.Contains(app.Status.Conditions[i].Message, sourceError) {
|
||||
sourceErrorExist = true
|
||||
}
|
||||
}
|
||||
assert.True(t, destinationErrorExist)
|
||||
assert.True(t, sourceErrorExist)
|
||||
}
|
||||
|
||||
16
test/e2e/testdata/failed-conversion/apiservice.yaml
vendored
Normal file
16
test/e2e/testdata/failed-conversion/apiservice.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: apiregistration.k8s.io/v1beta1
|
||||
kind: APIService
|
||||
metadata:
|
||||
name: v1beta1.metrics.k8s.io
|
||||
labels:
|
||||
app: metrics-server
|
||||
chart: metrics-server
|
||||
spec:
|
||||
service:
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
group: metrics.k8s.io
|
||||
version: v1beta1
|
||||
insecureSkipTLSVerify: true
|
||||
groupPriorityMinimum: 100
|
||||
versionPriority: 100
|
||||
@@ -127,28 +127,13 @@ func WaitForRefresh(ctx context.Context, appIf v1alpha1.ApplicationInterface, na
|
||||
return nil, fmt.Errorf("application refresh deadline exceeded")
|
||||
}
|
||||
|
||||
// GetSpecErrors returns list of conditions which indicates that app spec is invalid. Following is checked:
|
||||
// ValidateRepo validates the repository specified in application spec. Following is checked:
|
||||
// * the git repository is accessible
|
||||
// * the git path contains valid manifests
|
||||
// * the referenced cluster has been added to Argo CD
|
||||
// * the app source repo and destination namespace/cluster are permitted in app project
|
||||
// * there are parameters of only one app source type
|
||||
// * ksonnet: the specified environment exists
|
||||
func GetSpecErrors(
|
||||
ctx context.Context,
|
||||
spec *argoappv1.ApplicationSpec,
|
||||
proj *argoappv1.AppProject,
|
||||
repoClientset reposerver.Clientset,
|
||||
db db.ArgoDB,
|
||||
) ([]argoappv1.ApplicationCondition, argoappv1.ApplicationSourceType, error) {
|
||||
func ValidateRepo(ctx context.Context, spec *argoappv1.ApplicationSpec, repoClientset reposerver.Clientset, db db.ArgoDB) ([]argoappv1.ApplicationCondition, argoappv1.ApplicationSourceType, error) {
|
||||
conditions := make([]argoappv1.ApplicationCondition, 0)
|
||||
if spec.Source.RepoURL == "" || spec.Source.Path == "" {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
Type: argoappv1.ApplicationConditionInvalidSpecError,
|
||||
Message: "spec.source.repoURL and spec.source.path are required",
|
||||
})
|
||||
return conditions, "", nil
|
||||
}
|
||||
|
||||
// Test the repo
|
||||
conn, repoClient, err := repoClientset.NewRepoServerClient()
|
||||
@@ -158,24 +143,16 @@ func GetSpecErrors(
|
||||
defer util.Close(conn)
|
||||
repoAccessable := false
|
||||
repoRes, err := db.GetRepository(ctx, spec.Source.RepoURL)
|
||||
|
||||
if err != nil {
|
||||
if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound {
|
||||
// The repo has not been added to Argo CD so we do not have credentials to access it.
|
||||
// We support the mode where apps can be created from public repositories. Test the
|
||||
// repo to make sure it is publicly accessible
|
||||
err = git.TestRepo(spec.Source.RepoURL, "", "", "", false)
|
||||
if err != nil {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
Type: argoappv1.ApplicationConditionInvalidSpecError,
|
||||
Message: fmt.Sprintf("No credentials available for source repository and repository is not publicly accessible: %v", err),
|
||||
})
|
||||
} else {
|
||||
repoAccessable = true
|
||||
}
|
||||
} else {
|
||||
return nil, "", err
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
err = git.TestRepo(repoRes.Repo, repoRes.Username, repoRes.Password, repoRes.SSHPrivateKey, repoRes.InsecureIgnoreHostKey)
|
||||
if err != nil {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
Type: argoappv1.ApplicationConditionInvalidSpecError,
|
||||
Message: fmt.Sprintf("repository not accessible: %v", err),
|
||||
})
|
||||
} else {
|
||||
repoAccessable = true
|
||||
}
|
||||
@@ -218,18 +195,31 @@ func GetSpecErrors(
|
||||
conditions = append(conditions, helmConditions...)
|
||||
}
|
||||
case argoappv1.ApplicationSourceTypeDirectory, argoappv1.ApplicationSourceTypeKustomize:
|
||||
maniDirConditions := verifyGenerateManifests(ctx, repoRes, []*argoappv1.HelmRepository{}, spec, repoClient)
|
||||
if len(maniDirConditions) > 0 {
|
||||
conditions = append(conditions, maniDirConditions...)
|
||||
mainDirConditions := verifyGenerateManifests(ctx, repoRes, []*argoappv1.HelmRepository{}, spec, repoClient)
|
||||
if len(mainDirConditions) > 0 {
|
||||
conditions = append(conditions, mainDirConditions...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return conditions, appSourceType, nil
|
||||
}
|
||||
|
||||
// ValidatePermissions ensures that the referenced cluster has been added to Argo CD and the app source repo and destination namespace/cluster are permitted in app project
|
||||
func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, proj *argoappv1.AppProject, db db.ArgoDB) ([]argoappv1.ApplicationCondition, error) {
|
||||
conditions := make([]argoappv1.ApplicationCondition, 0)
|
||||
if spec.Source.RepoURL == "" || spec.Source.Path == "" {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
Type: argoappv1.ApplicationConditionInvalidSpecError,
|
||||
Message: "spec.source.repoURL and spec.source.path are required",
|
||||
})
|
||||
return conditions, nil
|
||||
}
|
||||
|
||||
if !proj.IsSourcePermitted(spec.Source) {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
Type: argoappv1.ApplicationConditionInvalidSpecError,
|
||||
Message: fmt.Sprintf("application source %v is not permitted in project '%s'", spec.Source, spec.Project),
|
||||
Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.Source.RepoURL, spec.Project),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -241,7 +231,7 @@ func GetSpecErrors(
|
||||
})
|
||||
}
|
||||
// Ensure the k8s cluster the app is referencing, is configured in Argo CD
|
||||
_, err = db.GetCluster(ctx, spec.Destination.Server)
|
||||
_, err := db.GetCluster(ctx, spec.Destination.Server)
|
||||
if err != nil {
|
||||
if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound {
|
||||
conditions = append(conditions, argoappv1.ApplicationCondition{
|
||||
@@ -249,11 +239,11 @@ func GetSpecErrors(
|
||||
Message: fmt.Sprintf("cluster '%s' has not been configured", spec.Destination.Server),
|
||||
})
|
||||
} else {
|
||||
return nil, "", err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return conditions, appSourceType, nil
|
||||
return conditions, nil
|
||||
}
|
||||
|
||||
// GetAppProject returns a project from an application
|
||||
@@ -340,6 +330,7 @@ func verifyAppYAML(ctx context.Context, repoRes *argoappv1.Repository, spec *arg
|
||||
return nil
|
||||
}
|
||||
|
||||
// verifyHelmChart verifies a helm chart is functional
|
||||
// verifyHelmChart verifies a helm chart is functional
|
||||
func verifyHelmChart(ctx context.Context, repoRes *argoappv1.Repository, spec *argoappv1.ApplicationSpec, repoClient repository.RepoServerServiceClient) []argoappv1.ApplicationCondition {
|
||||
var conditions []argoappv1.ApplicationCondition
|
||||
|
||||
@@ -4,20 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/diff"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
noMatchingPathError = "Unable to remove nonexistent key: not-matching-path"
|
||||
)
|
||||
|
||||
type normalizerPatch struct {
|
||||
groupKind schema.GroupKind
|
||||
namespace string
|
||||
@@ -103,10 +99,8 @@ func (n *normalizer) Normalize(un *unstructured.Unstructured) error {
|
||||
for _, patch := range matched {
|
||||
patchedData, err := patch.patch.Apply(docData)
|
||||
if err != nil {
|
||||
if err.Error() == noMatchingPathError {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
log.Debugf("Failed to apply normalization: %v", err)
|
||||
continue
|
||||
}
|
||||
docData = patchedData
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package argo
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
@@ -73,3 +74,45 @@ func TestNormalizeMatchedResourceOverrides(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, has)
|
||||
}
|
||||
|
||||
const testCRDYAML = `
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: certificates.certmanager.k8s.io
|
||||
spec:
|
||||
group: certmanager.k8s.io
|
||||
names:
|
||||
kind: Certificate
|
||||
listKind: CertificateList
|
||||
plural: certificates
|
||||
shortNames:
|
||||
- cert
|
||||
- certs
|
||||
singular: certificate
|
||||
scope: Namespaced
|
||||
version: v1alpha1`
|
||||
|
||||
func TestNormalizeMissingJsonPointer(t *testing.T) {
|
||||
normalizer, err := NewDiffNormalizer([]v1alpha1.ResourceIgnoreDifferences{}, map[string]v1alpha1.ResourceOverride{
|
||||
"apps/Deployment": {
|
||||
IgnoreDifferences: `jsonPointers: ["/garbage"]`,
|
||||
},
|
||||
"apiextensions.k8s.io/CustomResourceDefinition": {
|
||||
IgnoreDifferences: `jsonPointers: ["/spec/additionalPrinterColumns/0/priority"]`,
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
deployment := kube.MustToUnstructured(test.DemoDeployment())
|
||||
|
||||
err = normalizer.Normalize(deployment)
|
||||
assert.NoError(t, err)
|
||||
|
||||
crd := unstructured.Unstructured{}
|
||||
err = yaml.Unmarshal([]byte(testCRDYAML), &crd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = normalizer.Normalize(&crd)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -80,10 +80,14 @@ func TestCreateExistingRepository(t *testing.T) {
|
||||
assert.Equal(t, codes.AlreadyExists, status.Convert(err).Code())
|
||||
}
|
||||
|
||||
func TestDeleteRepositoryManagedSecrets(t *testing.T) {
|
||||
func TestGetRepository(t *testing.T) {
|
||||
config := map[string]string{
|
||||
"repositories": `
|
||||
- url: https://github.com/argoproj/argocd-example-apps
|
||||
- url: https://known/repo
|
||||
- url: https://secured/repo
|
||||
`,
|
||||
"repository.credentials": `
|
||||
- url: https://secured
|
||||
usernameSecret:
|
||||
name: managed-secret
|
||||
key: username
|
||||
@@ -91,7 +95,41 @@ func TestDeleteRepositoryManagedSecrets(t *testing.T) {
|
||||
name: managed-secret
|
||||
key: password
|
||||
`}
|
||||
clientset := getClientset(config, &v1.Secret{
|
||||
clientset := getClientset(config, newManagedSecret())
|
||||
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
repoURL string
|
||||
want *v1alpha1.Repository
|
||||
}{
|
||||
{
|
||||
name: "TestUnknownRepo",
|
||||
repoURL: "https://unknown/repo",
|
||||
want: &v1alpha1.Repository{Repo: "https://unknown/repo"},
|
||||
},
|
||||
{
|
||||
name: "TestKnownRepo",
|
||||
repoURL: "https://known/repo",
|
||||
want: &v1alpha1.Repository{Repo: "https://known/repo"},
|
||||
},
|
||||
{
|
||||
name: "TestSecuredRepo",
|
||||
repoURL: "https://secured/repo",
|
||||
want: &v1alpha1.Repository{Repo: "https://secured/repo", Username: "test-username", Password: "test-password"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := db.GetRepository(context.TODO(), tt.repoURL)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newManagedSecret() *v1.Secret {
|
||||
return &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "managed-secret",
|
||||
Namespace: testNamespace,
|
||||
@@ -103,7 +141,21 @@ func TestDeleteRepositoryManagedSecrets(t *testing.T) {
|
||||
username: []byte("test-username"),
|
||||
password: []byte("test-password"),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteRepositoryManagedSecrets(t *testing.T) {
|
||||
config := map[string]string{
|
||||
"repositories": `
|
||||
- url: https://github.com/argoproj/argocd-example-apps
|
||||
usernameSecret:
|
||||
name: managed-secret
|
||||
key: username
|
||||
passwordSecret:
|
||||
name: managed-secret
|
||||
key: password
|
||||
`}
|
||||
clientset := getClientset(config, newManagedSecret())
|
||||
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
|
||||
|
||||
err := db.DeleteRepository(context.Background(), "https://github.com/argoproj/argocd-example-apps")
|
||||
|
||||
262
util/db/mocks/ArgoDB.go
Normal file
262
util/db/mocks/ArgoDB.go
Normal file
@@ -0,0 +1,262 @@
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import context "context"
|
||||
import db "github.com/argoproj/argo-cd/util/db"
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
|
||||
// ArgoDB is an autogenerated mock type for the ArgoDB type
|
||||
type ArgoDB struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CreateCluster provides a mock function with given fields: ctx, c
|
||||
func (_m *ArgoDB) CreateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) {
|
||||
ret := _m.Called(ctx, c)
|
||||
|
||||
var r0 *v1alpha1.Cluster
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok {
|
||||
r0 = rf(ctx, c)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Cluster)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok {
|
||||
r1 = rf(ctx, c)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CreateRepository provides a mock function with given fields: ctx, r
|
||||
func (_m *ArgoDB) CreateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) {
|
||||
ret := _m.Called(ctx, r)
|
||||
|
||||
var r0 *v1alpha1.Repository
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok {
|
||||
r0 = rf(ctx, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Repository)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok {
|
||||
r1 = rf(ctx, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DeleteCluster provides a mock function with given fields: ctx, name
|
||||
func (_m *ArgoDB) DeleteCluster(ctx context.Context, name string) error {
|
||||
ret := _m.Called(ctx, name)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, name)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteRepository provides a mock function with given fields: ctx, name
|
||||
func (_m *ArgoDB) DeleteRepository(ctx context.Context, name string) error {
|
||||
ret := _m.Called(ctx, name)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, name)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetCluster provides a mock function with given fields: ctx, name
|
||||
func (_m *ArgoDB) GetCluster(ctx context.Context, name string) (*v1alpha1.Cluster, error) {
|
||||
ret := _m.Called(ctx, name)
|
||||
|
||||
var r0 *v1alpha1.Cluster
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Cluster); ok {
|
||||
r0 = rf(ctx, name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Cluster)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, name)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetRepository provides a mock function with given fields: ctx, repoURL
|
||||
func (_m *ArgoDB) GetRepository(ctx context.Context, repoURL string) (*v1alpha1.Repository, error) {
|
||||
ret := _m.Called(ctx, repoURL)
|
||||
|
||||
var r0 *v1alpha1.Repository
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Repository); ok {
|
||||
r0 = rf(ctx, repoURL)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Repository)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, repoURL)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListClusters provides a mock function with given fields: ctx
|
||||
func (_m *ArgoDB) ListClusters(ctx context.Context) (*v1alpha1.ClusterList, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
var r0 *v1alpha1.ClusterList
|
||||
if rf, ok := ret.Get(0).(func(context.Context) *v1alpha1.ClusterList); ok {
|
||||
r0 = rf(ctx)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.ClusterList)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
|
||||
r1 = rf(ctx)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListHelmRepos provides a mock function with given fields: ctx
|
||||
func (_m *ArgoDB) ListHelmRepos(ctx context.Context) ([]*v1alpha1.HelmRepository, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
var r0 []*v1alpha1.HelmRepository
|
||||
if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.HelmRepository); ok {
|
||||
r0 = rf(ctx)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*v1alpha1.HelmRepository)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
|
||||
r1 = rf(ctx)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListRepoURLs provides a mock function with given fields: ctx
|
||||
func (_m *ArgoDB) ListRepoURLs(ctx context.Context) ([]string, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(context.Context) []string); ok {
|
||||
r0 = rf(ctx)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
|
||||
r1 = rf(ctx)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateCluster provides a mock function with given fields: ctx, c
|
||||
func (_m *ArgoDB) UpdateCluster(ctx context.Context, c *v1alpha1.Cluster) (*v1alpha1.Cluster, error) {
|
||||
ret := _m.Called(ctx, c)
|
||||
|
||||
var r0 *v1alpha1.Cluster
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Cluster) *v1alpha1.Cluster); ok {
|
||||
r0 = rf(ctx, c)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Cluster)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Cluster) error); ok {
|
||||
r1 = rf(ctx, c)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateRepository provides a mock function with given fields: ctx, r
|
||||
func (_m *ArgoDB) UpdateRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) {
|
||||
ret := _m.Called(ctx, r)
|
||||
|
||||
var r0 *v1alpha1.Repository
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok {
|
||||
r0 = rf(ctx, r)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.Repository)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok {
|
||||
r1 = rf(ctx, r)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// WatchClusters provides a mock function with given fields: ctx, callback
|
||||
func (_m *ArgoDB) WatchClusters(ctx context.Context, callback func(*db.ClusterEvent)) error {
|
||||
ret := _m.Called(ctx, callback)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, func(*db.ClusterEvent)) error); ok {
|
||||
r0 = rf(ctx, callback)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
@@ -5,17 +5,18 @@ import (
|
||||
"hash/fnv"
|
||||
"strings"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/git"
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/git"
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,7 +46,7 @@ func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*apps
|
||||
return nil, err
|
||||
}
|
||||
|
||||
index := getRepoCredIndex(s, r.Repo)
|
||||
index := getRepositoryIndex(s, r.Repo)
|
||||
if index > -1 {
|
||||
return nil, status.Errorf(codes.AlreadyExists, "repository '%s' already exists", r.Repo)
|
||||
}
|
||||
@@ -85,25 +86,45 @@ func (db *db) GetRepository(ctx context.Context, repoURL string) (*appsv1.Reposi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
index := getRepoCredIndex(s, repoURL)
|
||||
if index < 0 {
|
||||
return nil, status.Errorf(codes.NotFound, "repo '%s' not found", repoURL)
|
||||
repo := &appsv1.Repository{Repo: repoURL}
|
||||
index := getRepositoryIndex(s, repoURL)
|
||||
if index >= 0 {
|
||||
repo, err = db.credentialsToRepository(s.Repositories[index])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
repoInfo := s.Repositories[index]
|
||||
|
||||
if !repo.HasCredentials() {
|
||||
index := getRepositoryCredentialIndex(s, repoURL)
|
||||
if index >= 0 {
|
||||
|
||||
credential, err := db.credentialsToRepository(s.RepositoryCredentials[index])
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
log.WithFields(log.Fields{"repoURL": repo.Repo, "credUrl": credential.Repo}).Info("copying credentials")
|
||||
repo.CopyCredentialsFrom(*credential)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return repo, err
|
||||
}
|
||||
|
||||
func (db *db) credentialsToRepository(repoInfo settings.RepoCredentials) (*appsv1.Repository, error) {
|
||||
repo := &appsv1.Repository{
|
||||
Repo: repoInfo.URL,
|
||||
InsecureIgnoreHostKey: repoInfo.InsecureIgnoreHostKey,
|
||||
}
|
||||
|
||||
err = db.unmarshalFromSecretsStr(map[*string]*apiv1.SecretKeySelector{
|
||||
err := db.unmarshalFromSecretsStr(map[*string]*apiv1.SecretKeySelector{
|
||||
&repo.Username: repoInfo.UsernameSecret,
|
||||
&repo.Password: repoInfo.PasswordSecret,
|
||||
&repo.SSHPrivateKey: repoInfo.SSHPrivateKeySecret,
|
||||
}, make(map[string]*apiv1.Secret))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo, nil
|
||||
|
||||
return repo, err
|
||||
}
|
||||
|
||||
// UpdateRepository updates a repository
|
||||
@@ -113,7 +134,7 @@ func (db *db) UpdateRepository(ctx context.Context, r *appsv1.Repository) (*apps
|
||||
return nil, err
|
||||
}
|
||||
|
||||
index := getRepoCredIndex(s, r.Repo)
|
||||
index := getRepositoryIndex(s, r.Repo)
|
||||
if index < 0 {
|
||||
return nil, status.Errorf(codes.NotFound, "repo '%s' not found", r.Repo)
|
||||
}
|
||||
@@ -138,7 +159,7 @@ func (db *db) DeleteRepository(ctx context.Context, repoURL string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
index := getRepoCredIndex(s, repoURL)
|
||||
index := getRepositoryIndex(s, repoURL)
|
||||
if index < 0 {
|
||||
return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL)
|
||||
}
|
||||
@@ -243,9 +264,20 @@ func (db *db) upsertSecret(name string, data map[string][]byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRepoCredIndex(s *settings.ArgoCDSettings, repoURL string) int {
|
||||
for i, cred := range s.Repositories {
|
||||
if git.SameURL(cred.URL, repoURL) {
|
||||
func getRepositoryIndex(s *settings.ArgoCDSettings, repoURL string) int {
|
||||
for i, repo := range s.Repositories {
|
||||
if git.SameURL(repo.URL, repoURL) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func getRepositoryCredentialIndex(s *settings.ArgoCDSettings, repoURL string) int {
|
||||
repoURL = git.NormalizeGitURL(repoURL)
|
||||
for i, cred := range s.RepositoryCredentials {
|
||||
credUrl := git.NormalizeGitURL(cred.URL)
|
||||
if strings.HasPrefix(repoURL, credUrl) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package db
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
|
||||
func TestRepoURLToSecretName(t *testing.T) {
|
||||
tables := map[string]string{
|
||||
@@ -18,3 +22,24 @@ func TestRepoURLToSecretName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getRepositoryCredentialIndex(t *testing.T) {
|
||||
argoCDSettings := settings.ArgoCDSettings{
|
||||
RepositoryCredentials: []settings.RepoCredentials{{URL: "http://known"}},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
repoURL string
|
||||
want int
|
||||
}{
|
||||
{"TestNotFound", "", -1},
|
||||
{"TestFoundFound", "http://known/repo", 0},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getRepositoryCredentialIndex(&argoCDSettings, tt.repoURL); got != tt.want {
|
||||
t.Errorf("getRepositoryCredentialIndex() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
git "gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/config"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport"
|
||||
@@ -47,9 +47,14 @@ func NewFactory() ClientFactory {
|
||||
return &factory{}
|
||||
}
|
||||
|
||||
func (f *factory) NewClient(repoURL, path, username, password, sshPrivateKey string, insecureIgnoreHostKey bool) (Client, error) {
|
||||
func (f *factory) NewClient(rawRepoURL, path, username, password, sshPrivateKey string, insecureIgnoreHostKey bool) (Client, error) {
|
||||
var sshUser string
|
||||
if isSSH, user := IsSSHURL(rawRepoURL); isSSH {
|
||||
sshUser = user
|
||||
}
|
||||
|
||||
clnt := nativeGitClient{
|
||||
repoURL: repoURL,
|
||||
repoURL: rawRepoURL,
|
||||
root: path,
|
||||
}
|
||||
if sshPrivateKey != "" {
|
||||
@@ -57,7 +62,7 @@ func (f *factory) NewClient(repoURL, path, username, password, sshPrivateKey str
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auth := &ssh2.PublicKeys{User: "git", Signer: signer}
|
||||
auth := &ssh2.PublicKeys{User: sshUser, Signer: signer}
|
||||
if insecureIgnoreHostKey {
|
||||
auth.HostKeyCallback = ssh.InsecureIgnoreHostKey()
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ func removeSuffix(s, suffix string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
var commitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{40}$")
|
||||
var (
|
||||
commitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{40}$")
|
||||
sshURLRegex = regexp.MustCompile("^(ssh://)?([^/@:]*?)@.*")
|
||||
)
|
||||
|
||||
// IsCommitSHA returns whether or not a string is a 40 character SHA-1
|
||||
func IsCommitSHA(sha string) bool {
|
||||
@@ -47,7 +50,7 @@ func SameURL(leftRepo, rightRepo string) bool {
|
||||
// and should not be considered stable from release to release
|
||||
func NormalizeGitURL(repo string) string {
|
||||
repo = strings.ToLower(strings.TrimSpace(repo))
|
||||
if IsSSHURL(repo) {
|
||||
if yes, _ := IsSSHURL(repo); yes {
|
||||
repo = ensurePrefix(repo, "ssh://")
|
||||
}
|
||||
repo = removeSuffix(repo, ".git")
|
||||
@@ -60,8 +63,12 @@ func NormalizeGitURL(repo string) string {
|
||||
}
|
||||
|
||||
// IsSSHURL returns true if supplied URL is SSH URL
|
||||
func IsSSHURL(url string) bool {
|
||||
return strings.HasPrefix(url, "git@") || strings.HasPrefix(url, "ssh://")
|
||||
func IsSSHURL(url string) (bool, string) {
|
||||
matches := sshURLRegex.FindStringSubmatch(url)
|
||||
if len(matches) > 2 {
|
||||
return true, matches[2]
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// TestRepo tests if a repo exists and is accessible with the given credentials
|
||||
|
||||
@@ -73,10 +73,21 @@ func TestIsSSHURL(t *testing.T) {
|
||||
"ssh://git@github.com:test.git": true,
|
||||
}
|
||||
for k, v := range data {
|
||||
assert.Equal(t, v, IsSSHURL(k))
|
||||
isSSH, _ := IsSSHURL(k)
|
||||
assert.Equal(t, v, isSSH)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSSHURLUserName(t *testing.T) {
|
||||
isSSH, user := IsSSHURL("ssh://john@john-server.org:29418/project")
|
||||
assert.True(t, isSSH)
|
||||
assert.Equal(t, "john", user)
|
||||
|
||||
isSSH, user = IsSSHURL("john@john-server.org:29418/project")
|
||||
assert.True(t, isSSH)
|
||||
assert.Equal(t, "john", user)
|
||||
}
|
||||
|
||||
func TestSameURL(t *testing.T) {
|
||||
data := map[string]string{
|
||||
"git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git",
|
||||
|
||||
@@ -149,3 +149,12 @@ func TestTLS(address string) (*TLSTestResult, error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func WithTimeout(duration time.Duration) grpc.UnaryClientInterceptor {
|
||||
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||
clientDeadline := time.Now().Add(duration)
|
||||
ctx, cancel := context.WithDeadline(ctx, clientDeadline)
|
||||
defer cancel()
|
||||
return invoker(ctx, method, req, reply, cc, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
// SetApplicationHealth updates the health statuses of all resources performed in the comparison
|
||||
func SetApplicationHealth(resStatuses []appv1.ResourceStatus, liveObjs []*unstructured.Unstructured, resourceOverrides map[string]appv1.ResourceOverride) (*appv1.HealthStatus, error) {
|
||||
func SetApplicationHealth(resStatuses []appv1.ResourceStatus, liveObjs []*unstructured.Unstructured, resourceOverrides map[string]appv1.ResourceOverride, filter func(obj *unstructured.Unstructured) bool) (*appv1.HealthStatus, error) {
|
||||
var savedErr error
|
||||
appHealth := appv1.HealthStatus{Status: appv1.HealthStatusHealthy}
|
||||
for i, liveObj := range liveObjs {
|
||||
@@ -30,9 +30,11 @@ func SetApplicationHealth(resStatuses []appv1.ResourceStatus, liveObjs []*unstru
|
||||
if liveObj == nil {
|
||||
resHealth = &appv1.HealthStatus{Status: appv1.HealthStatusMissing}
|
||||
} else {
|
||||
resHealth, err = GetResourceHealth(liveObj, resourceOverrides)
|
||||
if err != nil && savedErr == nil {
|
||||
savedErr = err
|
||||
if filter(liveObj) {
|
||||
resHealth, err = GetResourceHealth(liveObj, resourceOverrides)
|
||||
if err != nil && savedErr == nil {
|
||||
savedErr = err
|
||||
}
|
||||
}
|
||||
}
|
||||
if resHealth != nil {
|
||||
|
||||
@@ -118,13 +118,17 @@ func TestSetApplicationHealth(t *testing.T) {
|
||||
&runningPod,
|
||||
&failedJob,
|
||||
}
|
||||
healthStatus, err := SetApplicationHealth(resources, liveObjs, nil)
|
||||
healthStatus, err := SetApplicationHealth(resources, liveObjs, nil, func(obj *unstructured.Unstructured) bool {
|
||||
return true
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, appv1.HealthStatusDegraded, healthStatus.Status)
|
||||
|
||||
// now mark the job as a hook and retry. it should ignore the hook and consider the app healthy
|
||||
failedJob.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"})
|
||||
healthStatus, err = SetApplicationHealth(resources, liveObjs, nil)
|
||||
healthStatus, err = SetApplicationHealth(resources, liveObjs, nil, func(obj *unstructured.Unstructured) bool {
|
||||
return true
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user