mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 09:38:49 +01:00
Compare commits
26 Commits
master
...
v1.3.0-rc4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
593715038c | ||
|
|
4f84498265 | ||
|
|
8186ff0bb9 | ||
|
|
0432a85832 | ||
|
|
a0d37654b4 | ||
|
|
fe3b17322a | ||
|
|
59623b85fe | ||
|
|
905a8b0d75 | ||
|
|
30935e2019 | ||
|
|
f3e0e097de | ||
|
|
e1ff01cb56 | ||
|
|
e0de3300d2 | ||
|
|
40cb6fa9ce | ||
|
|
11de95cbac | ||
|
|
c7cd2e92bb | ||
|
|
a4f13f5f29 | ||
|
|
6460de9d03 | ||
|
|
6f6b03f74c | ||
|
|
36775ae1bb | ||
|
|
4a360cf9f4 | ||
|
|
6e56302fa4 | ||
|
|
3d82d5aab7 | ||
|
|
7df03b3c89 | ||
|
|
e059760906 | ||
|
|
8925b52bc8 | ||
|
|
8a43840f0b |
@@ -8,6 +8,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"syscall"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -108,7 +109,7 @@ func NewRunDexCommand() *cobra.Command {
|
||||
} else {
|
||||
err = ioutil.WriteFile("/tmp/dex.yaml", dexCfgBytes, 0644)
|
||||
errors.CheckError(err)
|
||||
log.Info(string(dexCfgBytes))
|
||||
log.Info(redactor(string(dexCfgBytes)))
|
||||
cmd = exec.Command("dex", "serve", "/tmp/dex.yaml")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
@@ -532,6 +533,11 @@ func NewClusterConfig() *cobra.Command {
|
||||
return command
|
||||
}
|
||||
|
||||
func redactor(dirtyString string) string {
|
||||
dirtyString = regexp.MustCompile("(clientSecret: )[^ \n]*").ReplaceAllString(dirtyString, "$1********")
|
||||
return regexp.MustCompile("(secret: )[^ \n]*").ReplaceAllString(dirtyString, "$1********")
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := NewCommand().Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
73
cmd/argocd-util/main_test.go
Normal file
73
cmd/argocd-util/main_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var textToRedact = `
|
||||
- config:
|
||||
clientID: aabbccddeeff00112233
|
||||
clientSecret: $dex.github.clientSecret
|
||||
orgs:
|
||||
- name: your-github-org
|
||||
redirectURI: https://argocd.example.com/api/dex/callback
|
||||
id: github
|
||||
name: GitHub
|
||||
type: github
|
||||
grpc:
|
||||
addr: 0.0.0.0:5557
|
||||
issuer: https://argocd.example.com/api/dex
|
||||
oauth2:
|
||||
skipApprovalScreen: true
|
||||
staticClients:
|
||||
- id: argo-cd
|
||||
name: Argo CD
|
||||
redirectURIs:
|
||||
- https://argocd.example.com/auth/callback
|
||||
secret: Dis9M-GA11oTwZVQQWdDklPQw-sWXZkWJFyyEhMs
|
||||
- id: argo-cd-cli
|
||||
name: Argo CD CLI
|
||||
public: true
|
||||
redirectURIs:
|
||||
- http://localhost
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556`
|
||||
|
||||
var expectedRedaction = `
|
||||
- config:
|
||||
clientID: aabbccddeeff00112233
|
||||
clientSecret: ********
|
||||
orgs:
|
||||
- name: your-github-org
|
||||
redirectURI: https://argocd.example.com/api/dex/callback
|
||||
id: github
|
||||
name: GitHub
|
||||
type: github
|
||||
grpc:
|
||||
addr: 0.0.0.0:5557
|
||||
issuer: https://argocd.example.com/api/dex
|
||||
oauth2:
|
||||
skipApprovalScreen: true
|
||||
staticClients:
|
||||
- id: argo-cd
|
||||
name: Argo CD
|
||||
redirectURIs:
|
||||
- https://argocd.example.com/auth/callback
|
||||
secret: ********
|
||||
- id: argo-cd-cli
|
||||
name: Argo CD CLI
|
||||
public: true
|
||||
redirectURIs:
|
||||
- http://localhost
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556`
|
||||
|
||||
func TestSecretsRedactor(t *testing.T) {
|
||||
assert.Equal(t, expectedRedaction, redactor(textToRedact))
|
||||
}
|
||||
@@ -972,8 +972,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
}
|
||||
|
||||
foundDiffs = true
|
||||
err = diff.PrintDiff(item.key.Name, target, live)
|
||||
errors.CheckError(err)
|
||||
_ = diff.PrintDiff(item.key.Name, target, live)
|
||||
}
|
||||
}
|
||||
if foundDiffs {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/errors"
|
||||
argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
|
||||
repositorypkg "github.com/argoproj/argo-cd/pkg/apiclient/repository"
|
||||
@@ -50,13 +51,20 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
)
|
||||
|
||||
// For better readability and easier formatting
|
||||
var repoAddExamples = `
|
||||
Add a SSH repository using a private key for authentication, ignoring the server's host key:",
|
||||
$ argocd repo add git@git.example.com --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa",
|
||||
Add a HTTPS repository using username/password and TLS client certificates:",
|
||||
$ argocd repo add https://git.example.com --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key",
|
||||
Add a HTTPS repository using username/password without verifying the server's TLS certificate:",
|
||||
$ argocd repo add https://git.example.com --username git --password secret --insecure-skip-server-verification",
|
||||
var repoAddExamples = ` # Add a Git repository via SSH using a private key for authentication, ignoring the server's host key:
|
||||
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
|
||||
|
||||
# Add a private Git repository via HTTPS using username/password and TLS client certificates:
|
||||
argocd repo add https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key
|
||||
|
||||
# Add a private Git repository via HTTPS using username/password without verifying the server's TLS certificate
|
||||
argocd repo add https://git.example.com/repos/repo --username git --password secret --insecure-skip-server-verification
|
||||
|
||||
# Add a public Helm repository named 'stable' via HTTPS
|
||||
argocd repo add https://kubernetes-charts.storage.googleapis.com --type helm --name stable
|
||||
|
||||
# Add a private Helm repository named 'stable' via HTTPS
|
||||
argocd repo add https://kubernetes-charts.storage.googleapis.com --type helm --name stable --username test --password test
|
||||
`
|
||||
|
||||
var command = &cobra.Command{
|
||||
@@ -113,6 +121,10 @@ Add a HTTPS repository using username/password without verifying the server's TL
|
||||
repo.Insecure = insecureSkipServerVerification
|
||||
repo.EnableLFS = enableLfs
|
||||
|
||||
if repo.Type == "helm" && repo.Name == "" {
|
||||
errors.CheckError(fmt.Errorf("Must specify --name for repos of type 'helm'"))
|
||||
}
|
||||
|
||||
conn, repoIf := argocdclient.NewClientOrDie(clientOpts).NewRepoClientOrDie()
|
||||
defer util.Close(conn)
|
||||
|
||||
@@ -148,8 +160,8 @@ Add a HTTPS repository using username/password without verifying the server's TL
|
||||
fmt.Printf("repository '%s' added\n", createdRepo.Repo)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&repo.Type, "type", "", "type of the repository, \"git\" or \"helm\"")
|
||||
command.Flags().StringVar(&repo.Name, "name", "", "name of the repository")
|
||||
command.Flags().StringVar(&repo.Type, "type", common.DefaultRepoType, "type of the repository, \"git\" or \"helm\"")
|
||||
command.Flags().StringVar(&repo.Name, "name", "", "name of the repository, mandatory for repositories of type helm")
|
||||
command.Flags().StringVar(&repo.Username, "username", "", "username to the repository")
|
||||
command.Flags().StringVar(&repo.Password, "password", "", "password to the repository")
|
||||
command.Flags().StringVar(&sshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")
|
||||
|
||||
@@ -21,9 +21,10 @@ const (
|
||||
ArgoCDTLSCertsConfigMapName = "argocd-tls-certs-cm"
|
||||
)
|
||||
|
||||
// Default system namespace
|
||||
// Some default configurables
|
||||
const (
|
||||
DefaultSystemNamespace = "kube-system"
|
||||
DefaultRepoType = "git"
|
||||
)
|
||||
|
||||
// Default listener ports for ArgoCD components
|
||||
|
||||
@@ -803,6 +803,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
revision = app.Status.Sync.Revision
|
||||
}
|
||||
|
||||
observedAt := metav1.Now()
|
||||
compareResult := ctrl.appStateManager.CompareAppState(app, revision, app.Spec.Source, refreshType == appv1.RefreshTypeHard, localManifests)
|
||||
|
||||
ctrl.normalizeApplication(origApp, app)
|
||||
@@ -830,8 +831,10 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
}
|
||||
}
|
||||
|
||||
app.Status.ObservedAt = &compareResult.reconciledAt
|
||||
app.Status.ReconciledAt = &compareResult.reconciledAt
|
||||
if app.Status.ReconciledAt == nil || comparisonLevel == CompareWithLatest {
|
||||
app.Status.ReconciledAt = &observedAt
|
||||
}
|
||||
app.Status.ObservedAt = &observedAt
|
||||
app.Status.Sync = *compareResult.syncStatus
|
||||
app.Status.Health = *compareResult.healthStatus
|
||||
app.Status.Resources = compareResult.resources
|
||||
@@ -850,23 +853,22 @@ func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application,
|
||||
compareWith := CompareWithLatest
|
||||
refreshType := appv1.RefreshTypeNormal
|
||||
expired := app.Status.ReconciledAt == nil || app.Status.ReconciledAt.Add(statusRefreshTimeout).Before(time.Now().UTC())
|
||||
if requestedType, ok := app.IsRefreshRequested(); ok || expired {
|
||||
if ok {
|
||||
refreshType = requestedType
|
||||
reason = fmt.Sprintf("%s refresh requested", refreshType)
|
||||
} else if expired {
|
||||
reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout)
|
||||
}
|
||||
} else if requested, level := ctrl.isRefreshRequested(app.Name); requested {
|
||||
compareWith = level
|
||||
reason = fmt.Sprintf("controller refresh requested")
|
||||
} else if app.Status.Sync.Status == appv1.SyncStatusCodeUnknown && expired {
|
||||
reason = "comparison status unknown"
|
||||
|
||||
if requestedType, ok := app.IsRefreshRequested(); ok {
|
||||
// user requested app refresh.
|
||||
refreshType = requestedType
|
||||
reason = fmt.Sprintf("%s refresh requested", refreshType)
|
||||
} else if expired {
|
||||
reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout)
|
||||
} else if !app.Spec.Source.Equals(app.Status.Sync.ComparedTo.Source) {
|
||||
reason = "spec.source differs"
|
||||
} else if !app.Spec.Destination.Equals(app.Status.Sync.ComparedTo.Destination) {
|
||||
reason = "spec.destination differs"
|
||||
} else if requested, level := ctrl.isRefreshRequested(app.Name); requested {
|
||||
compareWith = level
|
||||
reason = fmt.Sprintf("controller refresh requested")
|
||||
}
|
||||
|
||||
if reason != "" {
|
||||
logCtx.Infof("Refreshing app status (%s), level (%d)", reason, compareWith)
|
||||
return true, refreshType, compareWith
|
||||
|
||||
@@ -2,6 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -597,6 +598,24 @@ func TestNeedRefreshAppStatus(t *testing.T) {
|
||||
assert.Equal(t, argoappv1.RefreshTypeHard, refreshType)
|
||||
assert.Equal(t, CompareWithLatest, compareWith)
|
||||
}
|
||||
|
||||
{
|
||||
app := app.DeepCopy()
|
||||
// ensure that CompareWithLatest level is used if application source has changed
|
||||
ctrl.requestAppRefresh(app.Name, ComparisonWithNothing)
|
||||
// sample app source change
|
||||
app.Spec.Source.Helm = &argoappv1.ApplicationSourceHelm{
|
||||
Parameters: []argoappv1.HelmParameter{{
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}},
|
||||
}
|
||||
|
||||
needRefresh, refreshType, compareWith = ctrl.needRefreshAppStatus(app, 1*time.Hour)
|
||||
assert.True(t, needRefresh)
|
||||
assert.Equal(t, argoappv1.RefreshTypeNormal, refreshType)
|
||||
assert.Equal(t, CompareWithLatest, compareWith)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshAppConditions(t *testing.T) {
|
||||
@@ -651,3 +670,63 @@ func TestRefreshAppConditions(t *testing.T) {
|
||||
assert.Equal(t, "Application referencing project wrong project which does not exist", app.Status.Conditions[0].Message)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateReconciledAt(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
reconciledAt := metav1.NewTime(time.Now().Add(-1 * time.Second))
|
||||
app.Status = argoappv1.ApplicationStatus{ReconciledAt: &reconciledAt}
|
||||
app.Status.Sync = argoappv1.SyncStatus{ComparedTo: argoappv1.ComparedTo{Source: app.Spec.Source, Destination: app.Spec.Destination}}
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
|
||||
})
|
||||
key, _ := cache.MetaNamespaceKeyFunc(app)
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
fakeAppCs.ReactionChain = nil
|
||||
receivedPatch := map[string]interface{}{}
|
||||
fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if patchAction, ok := action.(kubetesting.PatchAction); ok {
|
||||
assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch))
|
||||
}
|
||||
return true, nil, nil
|
||||
})
|
||||
|
||||
t.Run("UpdatedOnFullReconciliation", func(t *testing.T) {
|
||||
receivedPatch = map[string]interface{}{}
|
||||
ctrl.requestAppRefresh(app.Name, CompareWithLatest)
|
||||
ctrl.appRefreshQueue.Add(key)
|
||||
|
||||
ctrl.processAppRefreshQueueItem()
|
||||
|
||||
_, updated, err := unstructured.NestedString(receivedPatch, "status", "reconciledAt")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, updated)
|
||||
|
||||
_, updated, err = unstructured.NestedString(receivedPatch, "status", "observedAt")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, updated)
|
||||
})
|
||||
|
||||
t.Run("NotUpdatedOnPartialReconciliation", func(t *testing.T) {
|
||||
receivedPatch = map[string]interface{}{}
|
||||
ctrl.appRefreshQueue.Add(key)
|
||||
ctrl.requestAppRefresh(app.Name, CompareWithRecent)
|
||||
|
||||
ctrl.processAppRefreshQueueItem()
|
||||
|
||||
_, updated, err := unstructured.NestedString(receivedPatch, "status", "reconciledAt")
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, updated)
|
||||
|
||||
_, updated, err = unstructured.NestedString(receivedPatch, "status", "observedAt")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, updated)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ type AppStateManager interface {
|
||||
}
|
||||
|
||||
type comparisonResult struct {
|
||||
reconciledAt metav1.Time
|
||||
syncStatus *v1alpha1.SyncStatus
|
||||
healthStatus *v1alpha1.HealthStatus
|
||||
resources []v1alpha1.ResourceStatus
|
||||
@@ -275,13 +274,11 @@ func (m *appStateManager) getComparisonSettings(app *appv1.Application) (string,
|
||||
// revision and supplied source. If revision or overrides are empty, then compares against
|
||||
// revision and overrides in the app spec.
|
||||
func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, noCache bool, localManifests []string) *comparisonResult {
|
||||
reconciledAt := metav1.Now()
|
||||
appLabelKey, resourceOverrides, diffNormalizer, err := m.getComparisonSettings(app)
|
||||
|
||||
// return unknown comparison result if basic comparison settings cannot be loaded
|
||||
if err != nil {
|
||||
return &comparisonResult{
|
||||
reconciledAt: reconciledAt,
|
||||
syncStatus: &v1alpha1.SyncStatus{
|
||||
ComparedTo: appv1.ComparedTo{Source: source, Destination: app.Spec.Destination},
|
||||
Status: appv1.SyncStatusCodeUnknown,
|
||||
@@ -435,6 +432,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision st
|
||||
} else {
|
||||
resState.Status = v1alpha1.SyncStatusCodeSynced
|
||||
}
|
||||
// we can't say anything about the status if we were unable to get the target objects
|
||||
if failedToLoadObjs {
|
||||
resState.Status = v1alpha1.SyncStatusCodeUnknown
|
||||
}
|
||||
managedResources[i] = managedResource{
|
||||
Name: resState.Name,
|
||||
Namespace: resState.Namespace,
|
||||
@@ -472,7 +473,6 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision st
|
||||
}
|
||||
|
||||
compRes := comparisonResult{
|
||||
reconciledAt: reconciledAt,
|
||||
syncStatus: &syncStatus,
|
||||
healthStatus: healthStatus,
|
||||
resources: resourceSummaries,
|
||||
|
||||
@@ -354,7 +354,6 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) {
|
||||
|
||||
assert.Equal(t, argoappv1.HealthStatusUnknown, compRes.healthStatus.Status)
|
||||
assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status)
|
||||
assert.NotNil(t, compRes.reconciledAt)
|
||||
}
|
||||
|
||||
func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -eux -o pipefail
|
||||
|
||||
[ -e $DOWNLOADS/helm.tar.gz ] || curl -sLf --retry 3 -o $DOWNLOADS/helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz
|
||||
[ -e $DOWNLOADS/helm.tar.gz ] || curl -sLf --retry 3 -o $DOWNLOADS/helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v2.15.2-linux-amd64.tar.gz
|
||||
tar -C /tmp/ -xf $DOWNLOADS/helm.tar.gz
|
||||
cp /tmp/linux-amd64/helm $BIN/helm
|
||||
helm version --client
|
||||
|
||||
@@ -12,7 +12,7 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.3.0-rc4
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: latest
|
||||
newTag: v1.3.0-rc4
|
||||
|
||||
@@ -1032,6 +1032,8 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
observedAt:
|
||||
description: ObservedAt indicates when the application state was updated
|
||||
without querying latest git state
|
||||
format: date-time
|
||||
type: string
|
||||
operationState:
|
||||
@@ -1509,6 +1511,8 @@ spec:
|
||||
- startedAt
|
||||
type: object
|
||||
reconciledAt:
|
||||
description: ReconciledAt indicates when the application state was reconciled
|
||||
using the latest git version
|
||||
format: date-time
|
||||
type: string
|
||||
resources:
|
||||
|
||||
@@ -18,7 +18,7 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v1.3.0-rc4
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: latest
|
||||
newTag: v1.3.0-rc4
|
||||
|
||||
@@ -1033,6 +1033,8 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
observedAt:
|
||||
description: ObservedAt indicates when the application state was updated
|
||||
without querying latest git state
|
||||
format: date-time
|
||||
type: string
|
||||
operationState:
|
||||
@@ -1510,6 +1512,8 @@ spec:
|
||||
- startedAt
|
||||
type: object
|
||||
reconciledAt:
|
||||
description: ReconciledAt indicates when the application state was reconciled
|
||||
using the latest git version
|
||||
format: date-time
|
||||
type: string
|
||||
resources:
|
||||
@@ -2978,7 +2982,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3032,7 +3036,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3088,7 +3092,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3162,7 +3166,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1033,6 +1033,8 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
observedAt:
|
||||
description: ObservedAt indicates when the application state was updated
|
||||
without querying latest git state
|
||||
format: date-time
|
||||
type: string
|
||||
operationState:
|
||||
@@ -1510,6 +1512,8 @@ spec:
|
||||
- startedAt
|
||||
type: object
|
||||
reconciledAt:
|
||||
description: ReconciledAt indicates when the application state was reconciled
|
||||
using the latest git version
|
||||
format: date-time
|
||||
type: string
|
||||
resources:
|
||||
@@ -2893,7 +2897,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2947,7 +2951,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3003,7 +3007,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3077,7 +3081,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1033,6 +1033,8 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
observedAt:
|
||||
description: ObservedAt indicates when the application state was updated
|
||||
without querying latest git state
|
||||
format: date-time
|
||||
type: string
|
||||
operationState:
|
||||
@@ -1510,6 +1512,8 @@ spec:
|
||||
- startedAt
|
||||
type: object
|
||||
reconciledAt:
|
||||
description: ReconciledAt indicates when the application state was reconciled
|
||||
using the latest git version
|
||||
format: date-time
|
||||
type: string
|
||||
resources:
|
||||
@@ -2742,7 +2746,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2796,7 +2800,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2860,7 +2864,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2911,7 +2915,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1033,6 +1033,8 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
observedAt:
|
||||
description: ObservedAt indicates when the application state was updated
|
||||
without querying latest git state
|
||||
format: date-time
|
||||
type: string
|
||||
operationState:
|
||||
@@ -1510,6 +1512,8 @@ spec:
|
||||
- startedAt
|
||||
type: object
|
||||
reconciledAt:
|
||||
description: ReconciledAt indicates when the application state was reconciled
|
||||
using the latest git version
|
||||
format: date-time
|
||||
type: string
|
||||
resources:
|
||||
@@ -2657,7 +2661,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2711,7 +2715,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2775,7 +2779,7 @@ spec:
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2826,7 +2830,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:latest
|
||||
image: argoproj/argocd:v1.3.0-rc4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -33,7 +33,7 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
func (m *AWSAuthConfig) Reset() { *m = AWSAuthConfig{} }
|
||||
func (*AWSAuthConfig) ProtoMessage() {}
|
||||
func (*AWSAuthConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{0}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{0}
|
||||
}
|
||||
func (m *AWSAuthConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -61,7 +61,7 @@ var xxx_messageInfo_AWSAuthConfig proto.InternalMessageInfo
|
||||
func (m *AppProject) Reset() { *m = AppProject{} }
|
||||
func (*AppProject) ProtoMessage() {}
|
||||
func (*AppProject) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{1}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{1}
|
||||
}
|
||||
func (m *AppProject) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -89,7 +89,7 @@ var xxx_messageInfo_AppProject proto.InternalMessageInfo
|
||||
func (m *AppProjectList) Reset() { *m = AppProjectList{} }
|
||||
func (*AppProjectList) ProtoMessage() {}
|
||||
func (*AppProjectList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{2}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{2}
|
||||
}
|
||||
func (m *AppProjectList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -117,7 +117,7 @@ var xxx_messageInfo_AppProjectList proto.InternalMessageInfo
|
||||
func (m *AppProjectSpec) Reset() { *m = AppProjectSpec{} }
|
||||
func (*AppProjectSpec) ProtoMessage() {}
|
||||
func (*AppProjectSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{3}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{3}
|
||||
}
|
||||
func (m *AppProjectSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -145,7 +145,7 @@ var xxx_messageInfo_AppProjectSpec proto.InternalMessageInfo
|
||||
func (m *Application) Reset() { *m = Application{} }
|
||||
func (*Application) ProtoMessage() {}
|
||||
func (*Application) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{4}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{4}
|
||||
}
|
||||
func (m *Application) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -173,7 +173,7 @@ var xxx_messageInfo_Application proto.InternalMessageInfo
|
||||
func (m *ApplicationCondition) Reset() { *m = ApplicationCondition{} }
|
||||
func (*ApplicationCondition) ProtoMessage() {}
|
||||
func (*ApplicationCondition) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{5}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{5}
|
||||
}
|
||||
func (m *ApplicationCondition) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -201,7 +201,7 @@ var xxx_messageInfo_ApplicationCondition proto.InternalMessageInfo
|
||||
func (m *ApplicationDestination) Reset() { *m = ApplicationDestination{} }
|
||||
func (*ApplicationDestination) ProtoMessage() {}
|
||||
func (*ApplicationDestination) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{6}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{6}
|
||||
}
|
||||
func (m *ApplicationDestination) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -229,7 +229,7 @@ var xxx_messageInfo_ApplicationDestination proto.InternalMessageInfo
|
||||
func (m *ApplicationList) Reset() { *m = ApplicationList{} }
|
||||
func (*ApplicationList) ProtoMessage() {}
|
||||
func (*ApplicationList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{7}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{7}
|
||||
}
|
||||
func (m *ApplicationList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -257,7 +257,7 @@ var xxx_messageInfo_ApplicationList proto.InternalMessageInfo
|
||||
func (m *ApplicationSource) Reset() { *m = ApplicationSource{} }
|
||||
func (*ApplicationSource) ProtoMessage() {}
|
||||
func (*ApplicationSource) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{8}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{8}
|
||||
}
|
||||
func (m *ApplicationSource) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -285,7 +285,7 @@ var xxx_messageInfo_ApplicationSource proto.InternalMessageInfo
|
||||
func (m *ApplicationSourceDirectory) Reset() { *m = ApplicationSourceDirectory{} }
|
||||
func (*ApplicationSourceDirectory) ProtoMessage() {}
|
||||
func (*ApplicationSourceDirectory) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{9}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{9}
|
||||
}
|
||||
func (m *ApplicationSourceDirectory) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -313,7 +313,7 @@ var xxx_messageInfo_ApplicationSourceDirectory proto.InternalMessageInfo
|
||||
func (m *ApplicationSourceHelm) Reset() { *m = ApplicationSourceHelm{} }
|
||||
func (*ApplicationSourceHelm) ProtoMessage() {}
|
||||
func (*ApplicationSourceHelm) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{10}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{10}
|
||||
}
|
||||
func (m *ApplicationSourceHelm) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -341,7 +341,7 @@ var xxx_messageInfo_ApplicationSourceHelm proto.InternalMessageInfo
|
||||
func (m *ApplicationSourceJsonnet) Reset() { *m = ApplicationSourceJsonnet{} }
|
||||
func (*ApplicationSourceJsonnet) ProtoMessage() {}
|
||||
func (*ApplicationSourceJsonnet) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{11}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{11}
|
||||
}
|
||||
func (m *ApplicationSourceJsonnet) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -369,7 +369,7 @@ var xxx_messageInfo_ApplicationSourceJsonnet proto.InternalMessageInfo
|
||||
func (m *ApplicationSourceKsonnet) Reset() { *m = ApplicationSourceKsonnet{} }
|
||||
func (*ApplicationSourceKsonnet) ProtoMessage() {}
|
||||
func (*ApplicationSourceKsonnet) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{12}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{12}
|
||||
}
|
||||
func (m *ApplicationSourceKsonnet) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -397,7 +397,7 @@ var xxx_messageInfo_ApplicationSourceKsonnet proto.InternalMessageInfo
|
||||
func (m *ApplicationSourceKustomize) Reset() { *m = ApplicationSourceKustomize{} }
|
||||
func (*ApplicationSourceKustomize) ProtoMessage() {}
|
||||
func (*ApplicationSourceKustomize) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{13}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{13}
|
||||
}
|
||||
func (m *ApplicationSourceKustomize) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -425,7 +425,7 @@ var xxx_messageInfo_ApplicationSourceKustomize proto.InternalMessageInfo
|
||||
func (m *ApplicationSourcePlugin) Reset() { *m = ApplicationSourcePlugin{} }
|
||||
func (*ApplicationSourcePlugin) ProtoMessage() {}
|
||||
func (*ApplicationSourcePlugin) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{14}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{14}
|
||||
}
|
||||
func (m *ApplicationSourcePlugin) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -453,7 +453,7 @@ var xxx_messageInfo_ApplicationSourcePlugin proto.InternalMessageInfo
|
||||
func (m *ApplicationSpec) Reset() { *m = ApplicationSpec{} }
|
||||
func (*ApplicationSpec) ProtoMessage() {}
|
||||
func (*ApplicationSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{15}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{15}
|
||||
}
|
||||
func (m *ApplicationSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -481,7 +481,7 @@ var xxx_messageInfo_ApplicationSpec proto.InternalMessageInfo
|
||||
func (m *ApplicationStatus) Reset() { *m = ApplicationStatus{} }
|
||||
func (*ApplicationStatus) ProtoMessage() {}
|
||||
func (*ApplicationStatus) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{16}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{16}
|
||||
}
|
||||
func (m *ApplicationStatus) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -509,7 +509,7 @@ var xxx_messageInfo_ApplicationStatus proto.InternalMessageInfo
|
||||
func (m *ApplicationSummary) Reset() { *m = ApplicationSummary{} }
|
||||
func (*ApplicationSummary) ProtoMessage() {}
|
||||
func (*ApplicationSummary) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{17}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{17}
|
||||
}
|
||||
func (m *ApplicationSummary) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -537,7 +537,7 @@ var xxx_messageInfo_ApplicationSummary proto.InternalMessageInfo
|
||||
func (m *ApplicationTree) Reset() { *m = ApplicationTree{} }
|
||||
func (*ApplicationTree) ProtoMessage() {}
|
||||
func (*ApplicationTree) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{18}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{18}
|
||||
}
|
||||
func (m *ApplicationTree) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -565,7 +565,7 @@ var xxx_messageInfo_ApplicationTree proto.InternalMessageInfo
|
||||
func (m *ApplicationWatchEvent) Reset() { *m = ApplicationWatchEvent{} }
|
||||
func (*ApplicationWatchEvent) ProtoMessage() {}
|
||||
func (*ApplicationWatchEvent) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{19}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{19}
|
||||
}
|
||||
func (m *ApplicationWatchEvent) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -593,7 +593,7 @@ var xxx_messageInfo_ApplicationWatchEvent proto.InternalMessageInfo
|
||||
func (m *Cluster) Reset() { *m = Cluster{} }
|
||||
func (*Cluster) ProtoMessage() {}
|
||||
func (*Cluster) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{20}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{20}
|
||||
}
|
||||
func (m *Cluster) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -621,7 +621,7 @@ var xxx_messageInfo_Cluster proto.InternalMessageInfo
|
||||
func (m *ClusterConfig) Reset() { *m = ClusterConfig{} }
|
||||
func (*ClusterConfig) ProtoMessage() {}
|
||||
func (*ClusterConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{21}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{21}
|
||||
}
|
||||
func (m *ClusterConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -649,7 +649,7 @@ var xxx_messageInfo_ClusterConfig proto.InternalMessageInfo
|
||||
func (m *ClusterList) Reset() { *m = ClusterList{} }
|
||||
func (*ClusterList) ProtoMessage() {}
|
||||
func (*ClusterList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{22}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{22}
|
||||
}
|
||||
func (m *ClusterList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -677,7 +677,7 @@ var xxx_messageInfo_ClusterList proto.InternalMessageInfo
|
||||
func (m *Command) Reset() { *m = Command{} }
|
||||
func (*Command) ProtoMessage() {}
|
||||
func (*Command) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{23}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{23}
|
||||
}
|
||||
func (m *Command) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -705,7 +705,7 @@ var xxx_messageInfo_Command proto.InternalMessageInfo
|
||||
func (m *ComparedTo) Reset() { *m = ComparedTo{} }
|
||||
func (*ComparedTo) ProtoMessage() {}
|
||||
func (*ComparedTo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{24}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{24}
|
||||
}
|
||||
func (m *ComparedTo) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -733,7 +733,7 @@ var xxx_messageInfo_ComparedTo proto.InternalMessageInfo
|
||||
func (m *ComponentParameter) Reset() { *m = ComponentParameter{} }
|
||||
func (*ComponentParameter) ProtoMessage() {}
|
||||
func (*ComponentParameter) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{25}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{25}
|
||||
}
|
||||
func (m *ComponentParameter) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -761,7 +761,7 @@ var xxx_messageInfo_ComponentParameter proto.InternalMessageInfo
|
||||
func (m *ConfigManagementPlugin) Reset() { *m = ConfigManagementPlugin{} }
|
||||
func (*ConfigManagementPlugin) ProtoMessage() {}
|
||||
func (*ConfigManagementPlugin) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{26}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{26}
|
||||
}
|
||||
func (m *ConfigManagementPlugin) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -789,7 +789,7 @@ var xxx_messageInfo_ConfigManagementPlugin proto.InternalMessageInfo
|
||||
func (m *ConnectionState) Reset() { *m = ConnectionState{} }
|
||||
func (*ConnectionState) ProtoMessage() {}
|
||||
func (*ConnectionState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{27}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{27}
|
||||
}
|
||||
func (m *ConnectionState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -817,7 +817,7 @@ var xxx_messageInfo_ConnectionState proto.InternalMessageInfo
|
||||
func (m *EnvEntry) Reset() { *m = EnvEntry{} }
|
||||
func (*EnvEntry) ProtoMessage() {}
|
||||
func (*EnvEntry) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{28}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{28}
|
||||
}
|
||||
func (m *EnvEntry) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -845,7 +845,7 @@ var xxx_messageInfo_EnvEntry proto.InternalMessageInfo
|
||||
func (m *HealthStatus) Reset() { *m = HealthStatus{} }
|
||||
func (*HealthStatus) ProtoMessage() {}
|
||||
func (*HealthStatus) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{29}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{29}
|
||||
}
|
||||
func (m *HealthStatus) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -873,7 +873,7 @@ var xxx_messageInfo_HealthStatus proto.InternalMessageInfo
|
||||
func (m *HelmParameter) Reset() { *m = HelmParameter{} }
|
||||
func (*HelmParameter) ProtoMessage() {}
|
||||
func (*HelmParameter) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{30}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{30}
|
||||
}
|
||||
func (m *HelmParameter) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -901,7 +901,7 @@ var xxx_messageInfo_HelmParameter proto.InternalMessageInfo
|
||||
func (m *Info) Reset() { *m = Info{} }
|
||||
func (*Info) ProtoMessage() {}
|
||||
func (*Info) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{31}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{31}
|
||||
}
|
||||
func (m *Info) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -929,7 +929,7 @@ var xxx_messageInfo_Info proto.InternalMessageInfo
|
||||
func (m *InfoItem) Reset() { *m = InfoItem{} }
|
||||
func (*InfoItem) ProtoMessage() {}
|
||||
func (*InfoItem) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{32}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{32}
|
||||
}
|
||||
func (m *InfoItem) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -957,7 +957,7 @@ var xxx_messageInfo_InfoItem proto.InternalMessageInfo
|
||||
func (m *JWTToken) Reset() { *m = JWTToken{} }
|
||||
func (*JWTToken) ProtoMessage() {}
|
||||
func (*JWTToken) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{33}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{33}
|
||||
}
|
||||
func (m *JWTToken) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -985,7 +985,7 @@ var xxx_messageInfo_JWTToken proto.InternalMessageInfo
|
||||
func (m *JsonnetVar) Reset() { *m = JsonnetVar{} }
|
||||
func (*JsonnetVar) ProtoMessage() {}
|
||||
func (*JsonnetVar) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{34}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{34}
|
||||
}
|
||||
func (m *JsonnetVar) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1013,7 +1013,7 @@ var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo
|
||||
func (m *KsonnetParameter) Reset() { *m = KsonnetParameter{} }
|
||||
func (*KsonnetParameter) ProtoMessage() {}
|
||||
func (*KsonnetParameter) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{35}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{35}
|
||||
}
|
||||
func (m *KsonnetParameter) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1041,7 +1041,7 @@ var xxx_messageInfo_KsonnetParameter proto.InternalMessageInfo
|
||||
func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} }
|
||||
func (*KustomizeOptions) ProtoMessage() {}
|
||||
func (*KustomizeOptions) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{36}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{36}
|
||||
}
|
||||
func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1069,7 +1069,7 @@ var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo
|
||||
func (m *Operation) Reset() { *m = Operation{} }
|
||||
func (*Operation) ProtoMessage() {}
|
||||
func (*Operation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{37}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{37}
|
||||
}
|
||||
func (m *Operation) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1097,7 +1097,7 @@ var xxx_messageInfo_Operation proto.InternalMessageInfo
|
||||
func (m *OperationState) Reset() { *m = OperationState{} }
|
||||
func (*OperationState) ProtoMessage() {}
|
||||
func (*OperationState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{38}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{38}
|
||||
}
|
||||
func (m *OperationState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1125,7 +1125,7 @@ var xxx_messageInfo_OperationState proto.InternalMessageInfo
|
||||
func (m *OrphanedResourcesMonitorSettings) Reset() { *m = OrphanedResourcesMonitorSettings{} }
|
||||
func (*OrphanedResourcesMonitorSettings) ProtoMessage() {}
|
||||
func (*OrphanedResourcesMonitorSettings) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{39}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{39}
|
||||
}
|
||||
func (m *OrphanedResourcesMonitorSettings) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1153,7 +1153,7 @@ var xxx_messageInfo_OrphanedResourcesMonitorSettings proto.InternalMessageInfo
|
||||
func (m *ProjectRole) Reset() { *m = ProjectRole{} }
|
||||
func (*ProjectRole) ProtoMessage() {}
|
||||
func (*ProjectRole) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{40}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{40}
|
||||
}
|
||||
func (m *ProjectRole) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1181,7 +1181,7 @@ var xxx_messageInfo_ProjectRole proto.InternalMessageInfo
|
||||
func (m *Repository) Reset() { *m = Repository{} }
|
||||
func (*Repository) ProtoMessage() {}
|
||||
func (*Repository) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{41}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{41}
|
||||
}
|
||||
func (m *Repository) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1209,7 +1209,7 @@ var xxx_messageInfo_Repository proto.InternalMessageInfo
|
||||
func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} }
|
||||
func (*RepositoryCertificate) ProtoMessage() {}
|
||||
func (*RepositoryCertificate) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{42}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{42}
|
||||
}
|
||||
func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1237,7 +1237,7 @@ var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo
|
||||
func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} }
|
||||
func (*RepositoryCertificateList) ProtoMessage() {}
|
||||
func (*RepositoryCertificateList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{43}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{43}
|
||||
}
|
||||
func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1265,7 +1265,7 @@ var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo
|
||||
func (m *RepositoryList) Reset() { *m = RepositoryList{} }
|
||||
func (*RepositoryList) ProtoMessage() {}
|
||||
func (*RepositoryList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{44}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{44}
|
||||
}
|
||||
func (m *RepositoryList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1293,7 +1293,7 @@ var xxx_messageInfo_RepositoryList proto.InternalMessageInfo
|
||||
func (m *ResourceAction) Reset() { *m = ResourceAction{} }
|
||||
func (*ResourceAction) ProtoMessage() {}
|
||||
func (*ResourceAction) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{45}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{45}
|
||||
}
|
||||
func (m *ResourceAction) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1321,7 +1321,7 @@ var xxx_messageInfo_ResourceAction proto.InternalMessageInfo
|
||||
func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} }
|
||||
func (*ResourceActionDefinition) ProtoMessage() {}
|
||||
func (*ResourceActionDefinition) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{46}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{46}
|
||||
}
|
||||
func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1349,7 +1349,7 @@ var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo
|
||||
func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} }
|
||||
func (*ResourceActionParam) ProtoMessage() {}
|
||||
func (*ResourceActionParam) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{47}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{47}
|
||||
}
|
||||
func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1377,7 +1377,7 @@ var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo
|
||||
func (m *ResourceActions) Reset() { *m = ResourceActions{} }
|
||||
func (*ResourceActions) ProtoMessage() {}
|
||||
func (*ResourceActions) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{48}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{48}
|
||||
}
|
||||
func (m *ResourceActions) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1405,7 +1405,7 @@ var xxx_messageInfo_ResourceActions proto.InternalMessageInfo
|
||||
func (m *ResourceDiff) Reset() { *m = ResourceDiff{} }
|
||||
func (*ResourceDiff) ProtoMessage() {}
|
||||
func (*ResourceDiff) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{49}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{49}
|
||||
}
|
||||
func (m *ResourceDiff) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1433,7 +1433,7 @@ var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo
|
||||
func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} }
|
||||
func (*ResourceIgnoreDifferences) ProtoMessage() {}
|
||||
func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{50}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{50}
|
||||
}
|
||||
func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1461,7 +1461,7 @@ var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo
|
||||
func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} }
|
||||
func (*ResourceNetworkingInfo) ProtoMessage() {}
|
||||
func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{51}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{51}
|
||||
}
|
||||
func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1489,7 +1489,7 @@ var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo
|
||||
func (m *ResourceNode) Reset() { *m = ResourceNode{} }
|
||||
func (*ResourceNode) ProtoMessage() {}
|
||||
func (*ResourceNode) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{52}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{52}
|
||||
}
|
||||
func (m *ResourceNode) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1517,7 +1517,7 @@ var xxx_messageInfo_ResourceNode proto.InternalMessageInfo
|
||||
func (m *ResourceOverride) Reset() { *m = ResourceOverride{} }
|
||||
func (*ResourceOverride) ProtoMessage() {}
|
||||
func (*ResourceOverride) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{53}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{53}
|
||||
}
|
||||
func (m *ResourceOverride) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1545,7 +1545,7 @@ var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo
|
||||
func (m *ResourceRef) Reset() { *m = ResourceRef{} }
|
||||
func (*ResourceRef) ProtoMessage() {}
|
||||
func (*ResourceRef) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{54}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{54}
|
||||
}
|
||||
func (m *ResourceRef) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1573,7 +1573,7 @@ var xxx_messageInfo_ResourceRef proto.InternalMessageInfo
|
||||
func (m *ResourceResult) Reset() { *m = ResourceResult{} }
|
||||
func (*ResourceResult) ProtoMessage() {}
|
||||
func (*ResourceResult) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{55}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{55}
|
||||
}
|
||||
func (m *ResourceResult) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1601,7 +1601,7 @@ var xxx_messageInfo_ResourceResult proto.InternalMessageInfo
|
||||
func (m *ResourceStatus) Reset() { *m = ResourceStatus{} }
|
||||
func (*ResourceStatus) ProtoMessage() {}
|
||||
func (*ResourceStatus) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{56}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{56}
|
||||
}
|
||||
func (m *ResourceStatus) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1629,7 +1629,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo
|
||||
func (m *RevisionHistory) Reset() { *m = RevisionHistory{} }
|
||||
func (*RevisionHistory) ProtoMessage() {}
|
||||
func (*RevisionHistory) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{57}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{57}
|
||||
}
|
||||
func (m *RevisionHistory) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1657,7 +1657,7 @@ var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo
|
||||
func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} }
|
||||
func (*RevisionMetadata) ProtoMessage() {}
|
||||
func (*RevisionMetadata) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{58}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{58}
|
||||
}
|
||||
func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1685,7 +1685,7 @@ var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo
|
||||
func (m *SyncOperation) Reset() { *m = SyncOperation{} }
|
||||
func (*SyncOperation) ProtoMessage() {}
|
||||
func (*SyncOperation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{59}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{59}
|
||||
}
|
||||
func (m *SyncOperation) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1713,7 +1713,7 @@ var xxx_messageInfo_SyncOperation proto.InternalMessageInfo
|
||||
func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} }
|
||||
func (*SyncOperationResource) ProtoMessage() {}
|
||||
func (*SyncOperationResource) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{60}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{60}
|
||||
}
|
||||
func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1741,7 +1741,7 @@ var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo
|
||||
func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} }
|
||||
func (*SyncOperationResult) ProtoMessage() {}
|
||||
func (*SyncOperationResult) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{61}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{61}
|
||||
}
|
||||
func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1769,7 +1769,7 @@ var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo
|
||||
func (m *SyncPolicy) Reset() { *m = SyncPolicy{} }
|
||||
func (*SyncPolicy) ProtoMessage() {}
|
||||
func (*SyncPolicy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{62}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{62}
|
||||
}
|
||||
func (m *SyncPolicy) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1797,7 +1797,7 @@ var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo
|
||||
func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} }
|
||||
func (*SyncPolicyAutomated) ProtoMessage() {}
|
||||
func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{63}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{63}
|
||||
}
|
||||
func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1825,7 +1825,7 @@ var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo
|
||||
func (m *SyncStatus) Reset() { *m = SyncStatus{} }
|
||||
func (*SyncStatus) ProtoMessage() {}
|
||||
func (*SyncStatus) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{64}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{64}
|
||||
}
|
||||
func (m *SyncStatus) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1853,7 +1853,7 @@ var xxx_messageInfo_SyncStatus proto.InternalMessageInfo
|
||||
func (m *SyncStrategy) Reset() { *m = SyncStrategy{} }
|
||||
func (*SyncStrategy) ProtoMessage() {}
|
||||
func (*SyncStrategy) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{65}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{65}
|
||||
}
|
||||
func (m *SyncStrategy) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1881,7 +1881,7 @@ var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo
|
||||
func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} }
|
||||
func (*SyncStrategyApply) ProtoMessage() {}
|
||||
func (*SyncStrategyApply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{66}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{66}
|
||||
}
|
||||
func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1909,7 +1909,7 @@ var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo
|
||||
func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} }
|
||||
func (*SyncStrategyHook) ProtoMessage() {}
|
||||
func (*SyncStrategyHook) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{67}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{67}
|
||||
}
|
||||
func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1937,7 +1937,7 @@ var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo
|
||||
func (m *SyncWindow) Reset() { *m = SyncWindow{} }
|
||||
func (*SyncWindow) ProtoMessage() {}
|
||||
func (*SyncWindow) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{68}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{68}
|
||||
}
|
||||
func (m *SyncWindow) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1965,7 +1965,7 @@ var xxx_messageInfo_SyncWindow proto.InternalMessageInfo
|
||||
func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} }
|
||||
func (*TLSClientConfig) ProtoMessage() {}
|
||||
func (*TLSClientConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_622b11e42e23cc72, []int{69}
|
||||
return fileDescriptor_generated_b34c2064a02cfa33, []int{69}
|
||||
}
|
||||
func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -18635,10 +18635,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_generated_622b11e42e23cc72)
|
||||
proto.RegisterFile("github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_generated_b34c2064a02cfa33)
|
||||
}
|
||||
|
||||
var fileDescriptor_generated_622b11e42e23cc72 = []byte{
|
||||
var fileDescriptor_generated_b34c2064a02cfa33 = []byte{
|
||||
// 4679 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3c, 0x5b, 0x8c, 0x1c, 0xd9,
|
||||
0x55, 0xae, 0x7e, 0xcf, 0x99, 0x87, 0x3d, 0x77, 0xd7, 0x9b, 0xce, 0x68, 0xe3, 0xb1, 0xca, 0x4a,
|
||||
|
||||
@@ -236,10 +236,12 @@ message ApplicationStatus {
|
||||
|
||||
repeated ApplicationCondition conditions = 5;
|
||||
|
||||
// ReconciledAt indicates when the application state was reconciled using the latest git version
|
||||
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time reconciledAt = 6;
|
||||
|
||||
optional OperationState operationState = 7;
|
||||
|
||||
// ObservedAt indicates when the application state was updated without querying latest git state
|
||||
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time observedAt = 8;
|
||||
|
||||
optional string sourceType = 9;
|
||||
|
||||
@@ -895,7 +895,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference
|
||||
},
|
||||
"reconciledAt": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
||||
Description: "ReconciledAt indicates when the application state was reconciled using the latest git version",
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
||||
},
|
||||
},
|
||||
"operationState": {
|
||||
@@ -905,7 +906,8 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference
|
||||
},
|
||||
"observedAt": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
||||
Description: "ObservedAt indicates when the application state was updated without querying latest git state",
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
||||
},
|
||||
},
|
||||
"sourceType": {
|
||||
|
||||
@@ -331,16 +331,18 @@ type ApplicationDestination struct {
|
||||
|
||||
// ApplicationStatus contains information about application sync, health status
|
||||
type ApplicationStatus struct {
|
||||
Resources []ResourceStatus `json:"resources,omitempty" protobuf:"bytes,1,opt,name=resources"`
|
||||
Sync SyncStatus `json:"sync,omitempty" protobuf:"bytes,2,opt,name=sync"`
|
||||
Health HealthStatus `json:"health,omitempty" protobuf:"bytes,3,opt,name=health"`
|
||||
History []RevisionHistory `json:"history,omitempty" protobuf:"bytes,4,opt,name=history"`
|
||||
Conditions []ApplicationCondition `json:"conditions,omitempty" protobuf:"bytes,5,opt,name=conditions"`
|
||||
ReconciledAt *metav1.Time `json:"reconciledAt,omitempty" protobuf:"bytes,6,opt,name=reconciledAt"`
|
||||
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"`
|
||||
Summary ApplicationSummary `json:"summary,omitempty" protobuf:"bytes,10,opt,name=summary"`
|
||||
Resources []ResourceStatus `json:"resources,omitempty" protobuf:"bytes,1,opt,name=resources"`
|
||||
Sync SyncStatus `json:"sync,omitempty" protobuf:"bytes,2,opt,name=sync"`
|
||||
Health HealthStatus `json:"health,omitempty" protobuf:"bytes,3,opt,name=health"`
|
||||
History []RevisionHistory `json:"history,omitempty" protobuf:"bytes,4,opt,name=history"`
|
||||
Conditions []ApplicationCondition `json:"conditions,omitempty" protobuf:"bytes,5,opt,name=conditions"`
|
||||
// ReconciledAt indicates when the application state was reconciled using the latest git version
|
||||
ReconciledAt *metav1.Time `json:"reconciledAt,omitempty" protobuf:"bytes,6,opt,name=reconciledAt"`
|
||||
OperationState *OperationState `json:"operationState,omitempty" protobuf:"bytes,7,opt,name=operationState"`
|
||||
// ObservedAt indicates when the application state was updated without querying latest git state
|
||||
ObservedAt *metav1.Time `json:"observedAt,omitempty" protobuf:"bytes,8,opt,name=observedAt"`
|
||||
SourceType ApplicationSourceType `json:"sourceType,omitempty" protobuf:"bytes,9,opt,name=sourceType"`
|
||||
Summary ApplicationSummary `json:"summary,omitempty" protobuf:"bytes,10,opt,name=summary"`
|
||||
}
|
||||
|
||||
// Operation contains requested operation parameters.
|
||||
|
||||
@@ -257,8 +257,6 @@ func TestAppProject_InvalidPolicyRules(t *testing.T) {
|
||||
errmsg string
|
||||
}
|
||||
badPolicies := []badPolicy{
|
||||
// should have spaces
|
||||
{"p,proj:my-proj:my-role,applications,get,my-proj/*,allow", "syntax"},
|
||||
// incorrect form
|
||||
{"g, proj:my-proj:my-role, applications, get, my-proj/*, allow", "must be of the form: 'p, sub, res, act, obj, eft'"},
|
||||
{"p, not, enough, parts", "must be of the form: 'p, sub, res, act, obj, eft'"},
|
||||
|
||||
@@ -111,6 +111,7 @@ type operationSettings struct {
|
||||
// runRepoOperation downloads either git folder or helm chart and executes specified operation
|
||||
func (s *Service) runRepoOperation(
|
||||
c context.Context,
|
||||
revision string,
|
||||
repo *v1alpha1.Repository,
|
||||
source *v1alpha1.ApplicationSource,
|
||||
getCached func(revision string) bool,
|
||||
@@ -119,9 +120,9 @@ func (s *Service) runRepoOperation(
|
||||
|
||||
var gitClient git.Client
|
||||
var err error
|
||||
revision := source.TargetRevision
|
||||
revision = util.FirstNonEmpty(revision, source.TargetRevision)
|
||||
if !source.IsHelm() {
|
||||
gitClient, revision, err = s.newClientResolveRevision(repo, source.TargetRevision)
|
||||
gitClient, revision, err = s.newClientResolveRevision(repo, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -188,7 +189,7 @@ func (s *Service) GenerateManifest(c context.Context, q *apiclient.ManifestReque
|
||||
}
|
||||
return false
|
||||
}
|
||||
err := s.runRepoOperation(c, q.Repo, q.ApplicationSource, getCached, func(appPath string, revision string) error {
|
||||
err := s.runRepoOperation(c, q.Revision, q.Repo, q.ApplicationSource, getCached, func(appPath string, revision string) error {
|
||||
var err error
|
||||
res, err = GenerateManifests(appPath, q)
|
||||
if err != nil {
|
||||
@@ -584,7 +585,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
||||
return false
|
||||
}
|
||||
|
||||
err := s.runRepoOperation(ctx, q.Repo, q.Source, getCached, func(appPath string, revision string) error {
|
||||
err := s.runRepoOperation(ctx, q.Source.TargetRevision, q.Repo, q.Source, getCached, func(appPath string, revision string) error {
|
||||
appSourceType, err := GetAppSourceType(q.Source, appPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -88,6 +88,19 @@ func TestGenerateYamlManifestInDir(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateManifestsUseExactRevision(t *testing.T) {
|
||||
service, gitClient, _ := newServiceWithMocks(".")
|
||||
|
||||
src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}}
|
||||
|
||||
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Revision: "abc"}
|
||||
|
||||
res1, err := service.GenerateManifest(context.Background(), &q)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res1.Manifests))
|
||||
assert.Equal(t, gitClient.Calls[0].Arguments[0], "abc")
|
||||
}
|
||||
|
||||
func TestRecurseManifestsInDir(t *testing.T) {
|
||||
service := newService(".")
|
||||
|
||||
|
||||
@@ -41,37 +41,38 @@ func NewServer(db db.ArgoDB, enf *rbac.Enforcer, cache *cache.Cache, kubectl kub
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) getConnectionState(cluster appv1.Cluster, errorMessage string) appv1.ConnectionState {
|
||||
if connectionState, err := s.cache.GetClusterConnectionState(cluster.Server); err == nil {
|
||||
return connectionState
|
||||
func (s *Server) getConnectionState(cluster appv1.Cluster, errorMessage string) (appv1.ConnectionState, string) {
|
||||
if clusterInfo, err := s.cache.GetClusterInfo(cluster.Server); err == nil {
|
||||
return clusterInfo.ConnectionState, clusterInfo.Version
|
||||
}
|
||||
now := v1.Now()
|
||||
connectionState := appv1.ConnectionState{
|
||||
Status: appv1.ConnectionStatusSuccessful,
|
||||
ModifiedAt: &now,
|
||||
clusterInfo := cache.ClusterInfo{
|
||||
ConnectionState: appv1.ConnectionState{
|
||||
Status: appv1.ConnectionStatusSuccessful,
|
||||
ModifiedAt: &now,
|
||||
},
|
||||
}
|
||||
|
||||
config := cluster.RESTConfig()
|
||||
config.Timeout = time.Second
|
||||
kubeClientset, err := kubernetes.NewForConfig(config)
|
||||
if err == nil {
|
||||
_, err = kubeClientset.Discovery().ServerVersion()
|
||||
}
|
||||
version, err := s.kubectl.GetServerVersion(config)
|
||||
if err != nil {
|
||||
connectionState.Status = appv1.ConnectionStatusFailed
|
||||
connectionState.Message = fmt.Sprintf("Unable to connect to cluster: %v", err)
|
||||
clusterInfo.Status = appv1.ConnectionStatusFailed
|
||||
clusterInfo.Message = fmt.Sprintf("Unable to connect to cluster: %v", err)
|
||||
} else {
|
||||
clusterInfo.Version = version
|
||||
}
|
||||
|
||||
if errorMessage != "" {
|
||||
connectionState.Status = appv1.ConnectionStatusFailed
|
||||
connectionState.Message = fmt.Sprintf("%s %s", errorMessage, connectionState.Message)
|
||||
clusterInfo.Status = appv1.ConnectionStatusFailed
|
||||
clusterInfo.Message = fmt.Sprintf("%s %s", errorMessage, clusterInfo.Message)
|
||||
}
|
||||
|
||||
err = s.cache.SetClusterConnectionState(cluster.Server, &connectionState)
|
||||
err = s.cache.SetClusterInfo(cluster.Server, &clusterInfo)
|
||||
if err != nil {
|
||||
log.Warnf("getConnectionState cache set error %s: %v", cluster.Server, err)
|
||||
log.Warnf("getClusterInfo cache set error %s: %v", cluster.Server, err)
|
||||
}
|
||||
return connectionState
|
||||
return clusterInfo.ConnectionState, clusterInfo.Version
|
||||
}
|
||||
|
||||
// List returns list of clusters
|
||||
@@ -100,11 +101,9 @@ func (s *Server) List(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Clus
|
||||
warningMessage = fmt.Sprintf("There are %d credentials configured this cluster.", len(clusters))
|
||||
}
|
||||
if clust.ConnectionState.Status == "" {
|
||||
clust.ConnectionState = s.getConnectionState(clust, warningMessage)
|
||||
}
|
||||
clust.ServerVersion, err = s.kubectl.GetServerVersion(clust.RESTConfig())
|
||||
if err != nil {
|
||||
return err
|
||||
state, serverVersion := s.getConnectionState(clust, warningMessage)
|
||||
clust.ConnectionState = state
|
||||
clust.ServerVersion = serverVersion
|
||||
}
|
||||
items[i] = *redact(&clust)
|
||||
return nil
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
repositorypkg "github.com/argoproj/argo-cd/pkg/apiclient/repository"
|
||||
appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||
@@ -82,10 +83,15 @@ func (s *Server) List(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.
|
||||
items := appsv1.Repositories{}
|
||||
for _, repo := range repos {
|
||||
if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, repo.Repo) {
|
||||
// For backwards compatibility, if we have no repo type set assume a default
|
||||
rType := repo.Type
|
||||
if rType == "" {
|
||||
rType = common.DefaultRepoType
|
||||
}
|
||||
// remove secrets
|
||||
items = append(items, &appsv1.Repository{
|
||||
Repo: repo.Repo,
|
||||
Type: repo.Type,
|
||||
Type: rType,
|
||||
Name: repo.Name,
|
||||
Username: repo.Username,
|
||||
Insecure: repo.IsInsecure(),
|
||||
@@ -222,7 +228,10 @@ func (s *Server) Create(ctx context.Context, q *repositorypkg.RepoCreateRequest)
|
||||
return nil, status.Errorf(codes.InvalidArgument, "existing repository spec is different; use upsert flag to force update")
|
||||
}
|
||||
}
|
||||
return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil
|
||||
}
|
||||
|
||||
// Update updates a repository
|
||||
|
||||
@@ -478,7 +478,7 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
|
||||
// TranslateGrpcCookieHeader conditionally sets a cookie on the response.
|
||||
func (a *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.ResponseWriter, resp golang_proto.Message) error {
|
||||
if sessionResp, ok := resp.(*sessionpkg.SessionResponse); ok {
|
||||
flags := []string{"path=/"}
|
||||
flags := []string{"path=/", "SameSite=lax", "httpOnly"}
|
||||
if !a.Insecure {
|
||||
flags = append(flags, "Secure")
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func TestDeclarativeHelmInvalidValuesFile(t *testing.T) {
|
||||
func TestHelmRepo(t *testing.T) {
|
||||
Given(t).
|
||||
CustomCACertAdded().
|
||||
HelmRepoAdded("").
|
||||
HelmRepoAdded("custom-repo").
|
||||
RepoURLType(RepoURLTypeHelm).
|
||||
Chart("helm").
|
||||
Revision("1.0.0").
|
||||
|
||||
9
ui/.prettierrc
Normal file
9
ui/.prettierrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"bracketSpacing": false,
|
||||
"jsxSingleQuote": true,
|
||||
"printWidth": 180,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 4,
|
||||
"jsxBracketSameLine": true,
|
||||
"quoteProps": "consistent"
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
import { ErrorNotification, MockupList, NotificationType, SlidingPanel } from 'argo-ui';
|
||||
import {ErrorNotification, MockupList, NotificationType, SlidingPanel} from 'argo-ui';
|
||||
import * as classNames from 'classnames';
|
||||
import * as minimatch from 'minimatch';
|
||||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import { Observable } from 'rxjs';
|
||||
import {RouteComponentProps} from 'react-router';
|
||||
import {Observable} from 'rxjs';
|
||||
|
||||
import { Autocomplete, ClusterCtx, DataLoader, EmptyState, ObservableQuery, Page, Paginate, Query } from '../../../shared/components';
|
||||
import { Consumer } from '../../../shared/context';
|
||||
import {Autocomplete, ClusterCtx, DataLoader, EmptyState, ObservableQuery, Page, Paginate, Query} from '../../../shared/components';
|
||||
import {Consumer} from '../../../shared/context';
|
||||
import * as models from '../../../shared/models';
|
||||
import { AppsListPreferences, AppsListViewType, services } from '../../../shared/services';
|
||||
import { ApplicationCreatePanel } from '../application-create-panel/application-create-panel';
|
||||
import { ApplicationSyncPanel } from '../application-sync-panel/application-sync-panel';
|
||||
import {AppsListPreferences, AppsListViewType, services} from '../../../shared/services';
|
||||
import {ApplicationCreatePanel} from '../application-create-panel/application-create-panel';
|
||||
import {ApplicationSyncPanel} from '../application-sync-panel/application-sync-panel';
|
||||
import {ApplicationsSyncPanel} from '../applications-sync-panel/applications-sync-panel';
|
||||
import * as LabelSelector from '../label-selector';
|
||||
import * as AppUtils from '../utils';
|
||||
import { ApplicationsFilter } from './applications-filter';
|
||||
import { ApplicationsSummary } from './applications-summary';
|
||||
import { ApplicationsTable } from './applications-table';
|
||||
import { ApplicationTiles } from './applications-tiles';
|
||||
import {ApplicationsFilter} from './applications-filter';
|
||||
import {ApplicationsSummary} from './applications-summary';
|
||||
import {ApplicationsTable} from './applications-table';
|
||||
import {ApplicationTiles} from './applications-tiles';
|
||||
|
||||
require('./applications-list.scss');
|
||||
|
||||
@@ -25,93 +27,125 @@ const APP_FIELDS = [
|
||||
'metadata.labels',
|
||||
'metadata.resourceVersion',
|
||||
'metadata.creationTimestamp',
|
||||
'metadata.deletionTimestamp',
|
||||
'spec',
|
||||
'operation.sync',
|
||||
'status.sync.status',
|
||||
'status.health',
|
||||
'status.summary'];
|
||||
'status.operationState.phase',
|
||||
'status.operationState.operation.sync',
|
||||
'status.summary',
|
||||
];
|
||||
const APP_LIST_FIELDS = APP_FIELDS.map((field) => `items.${field}`);
|
||||
const APP_WATCH_FIELDS = ['result.type', ...APP_FIELDS.map((field) => `result.application.${field}`)];
|
||||
|
||||
function loadApplications(selector: string): Observable<models.Application[]> {
|
||||
return Observable.fromPromise(services.applications.list([], { fields: APP_LIST_FIELDS, selector })).flatMap((applications) =>
|
||||
function loadApplications(): Observable<models.Application[]> {
|
||||
return Observable.fromPromise(services.applications.list([], {fields: APP_LIST_FIELDS})).flatMap((applications) =>
|
||||
Observable.merge(
|
||||
Observable.from([applications]),
|
||||
services.applications.watch(null, { fields: APP_WATCH_FIELDS, selector }).map((appChange) => {
|
||||
const index = applications.findIndex((item) => item.metadata.name === appChange.application.metadata.name);
|
||||
if (index > -1 && appChange.application.metadata.resourceVersion === applications[index].metadata.resourceVersion) {
|
||||
return {applications, updated: false};
|
||||
}
|
||||
switch (appChange.type) {
|
||||
case 'DELETED':
|
||||
if (index > -1) {
|
||||
applications.splice(index, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (index > -1) {
|
||||
applications[index] = appChange.application;
|
||||
} else {
|
||||
applications.unshift(appChange.application);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return {applications, updated: true};
|
||||
}).filter((item) => item.updated).map((item) => item.applications),
|
||||
services.applications
|
||||
.watch(null, {fields: APP_WATCH_FIELDS})
|
||||
.map((appChange) => {
|
||||
const index = applications.findIndex((item) => item.metadata.name === appChange.application.metadata.name);
|
||||
if (index > -1 && appChange.application.metadata.resourceVersion === applications[index].metadata.resourceVersion) {
|
||||
return {applications, updated: false};
|
||||
}
|
||||
switch (appChange.type) {
|
||||
case 'DELETED':
|
||||
if (index > -1) {
|
||||
applications.splice(index, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (index > -1) {
|
||||
applications[index] = appChange.application;
|
||||
} else {
|
||||
applications.unshift(appChange.application);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return {applications, updated: true};
|
||||
})
|
||||
.filter((item) => item.updated)
|
||||
.map((item) => item.applications),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const ViewPref = ({children}: { children: (pref: AppsListPreferences & { page: number, search: string }) => React.ReactNode }) => (
|
||||
const ViewPref = ({children}: {children: (pref: AppsListPreferences & {page: number; search: string}) => React.ReactNode}) => (
|
||||
<ObservableQuery>
|
||||
{(q) => (
|
||||
<DataLoader load={() => Observable.combineLatest(
|
||||
services.viewPreferences.getPreferences().map((item) => item.appList), q).map((items) => {
|
||||
const params = items[1];
|
||||
const viewPref: AppsListPreferences = {...items[0]};
|
||||
if (params.get('proj') != null) {
|
||||
viewPref.projectsFilter = params.get('proj').split(',').filter((item) => !!item);
|
||||
}
|
||||
if (params.get('sync') != null) {
|
||||
viewPref.syncFilter = params.get('sync').split(',').filter((item) => !!item);
|
||||
}
|
||||
if (params.get('health') != null) {
|
||||
viewPref.healthFilter = params.get('health').split(',').filter((item) => !!item);
|
||||
}
|
||||
if (params.get('namespace') != null) {
|
||||
viewPref.namespacesFilter = params.get('namespace').split(',').filter((item) => !!item);
|
||||
}
|
||||
if (params.get('cluster') != null) {
|
||||
viewPref.clustersFilter = params.get('cluster').split(',').filter((item) => !!item);
|
||||
}
|
||||
if (params.get('view') != null) {
|
||||
viewPref.view = params.get('view') as AppsListViewType;
|
||||
}
|
||||
if (params.get('labels') != null) {
|
||||
viewPref.labelsFilter = params.get('labels').split(',').filter((item) => !!item);
|
||||
}
|
||||
return {...viewPref, page: parseInt(params.get('page') || '0', 10), search: params.get('search') || ''};
|
||||
})}>
|
||||
{(pref) => children(pref)}
|
||||
<DataLoader
|
||||
load={() =>
|
||||
Observable.combineLatest(services.viewPreferences.getPreferences().map((item) => item.appList), q).map((items) => {
|
||||
const params = items[1];
|
||||
const viewPref: AppsListPreferences = {...items[0]};
|
||||
if (params.get('proj') != null) {
|
||||
viewPref.projectsFilter = params
|
||||
.get('proj')
|
||||
.split(',')
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
if (params.get('sync') != null) {
|
||||
viewPref.syncFilter = params
|
||||
.get('sync')
|
||||
.split(',')
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
if (params.get('health') != null) {
|
||||
viewPref.healthFilter = params
|
||||
.get('health')
|
||||
.split(',')
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
if (params.get('namespace') != null) {
|
||||
viewPref.namespacesFilter = params
|
||||
.get('namespace')
|
||||
.split(',')
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
if (params.get('cluster') != null) {
|
||||
viewPref.clustersFilter = params
|
||||
.get('cluster')
|
||||
.split(',')
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
if (params.get('view') != null) {
|
||||
viewPref.view = params.get('view') as AppsListViewType;
|
||||
}
|
||||
if (params.get('labels') != null) {
|
||||
viewPref.labelsFilter = params
|
||||
.get('labels')
|
||||
.split(',')
|
||||
.map(decodeURIComponent)
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
return {...viewPref, page: parseInt(params.get('page') || '0', 10), search: params.get('search') || ''};
|
||||
})
|
||||
}>
|
||||
{(pref) => children(pref)}
|
||||
</DataLoader>
|
||||
)}
|
||||
</ObservableQuery>
|
||||
);
|
||||
|
||||
function filterApps(applications: models.Application[], pref: AppsListPreferences, search: string) {
|
||||
return applications.filter((app) =>
|
||||
(search === '' || app.metadata.name.includes(search)) &&
|
||||
(pref.projectsFilter.length === 0 || pref.projectsFilter.includes(app.spec.project)) &&
|
||||
(pref.reposFilter.length === 0 || pref.reposFilter.includes(app.spec.source.repoURL)) &&
|
||||
(pref.syncFilter.length === 0 || pref.syncFilter.includes(app.status.sync.status)) &&
|
||||
(pref.healthFilter.length === 0 || pref.healthFilter.includes(app.status.health.status)) &&
|
||||
(pref.namespacesFilter.length === 0 || pref.namespacesFilter.some((ns) => minimatch(app.spec.destination.namespace, ns))) &&
|
||||
(pref.clustersFilter.length === 0 || pref.clustersFilter.some((server) => minimatch(app.spec.destination.server, server))),
|
||||
return applications.filter(
|
||||
(app) =>
|
||||
(search === '' || app.metadata.name.includes(search)) &&
|
||||
(pref.projectsFilter.length === 0 || pref.projectsFilter.includes(app.spec.project)) &&
|
||||
(pref.reposFilter.length === 0 || pref.reposFilter.includes(app.spec.source.repoURL)) &&
|
||||
(pref.syncFilter.length === 0 || pref.syncFilter.includes(app.status.sync.status)) &&
|
||||
(pref.healthFilter.length === 0 || pref.healthFilter.includes(app.status.health.status)) &&
|
||||
(pref.namespacesFilter.length === 0 || pref.namespacesFilter.some((ns) => minimatch(app.spec.destination.namespace, ns))) &&
|
||||
(pref.clustersFilter.length === 0 || pref.clustersFilter.some((server) => minimatch(app.spec.destination.server, server))) &&
|
||||
(pref.labelsFilter.length === 0 || pref.labelsFilter.every((selector) => LabelSelector.match(selector, app.metadata.labels))),
|
||||
);
|
||||
}
|
||||
|
||||
function tryJsonParse(input: string) {
|
||||
try {
|
||||
return input && JSON.parse(input) || null;
|
||||
return (input && JSON.parse(input)) || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
@@ -120,179 +154,234 @@ function tryJsonParse(input: string) {
|
||||
export const ApplicationsList = (props: RouteComponentProps<{}>) => {
|
||||
const query = new URLSearchParams(props.location.search);
|
||||
const appInput = tryJsonParse(query.get('new'));
|
||||
const syncAppsInput = tryJsonParse(query.get('syncApps'));
|
||||
const [createApi, setCreateApi] = React.useState(null);
|
||||
const clusters = React.useMemo(() => services.clusters.list(), []);
|
||||
|
||||
return (
|
||||
<ClusterCtx.Provider value={clusters}>
|
||||
<Consumer>{
|
||||
(ctx) => (
|
||||
<Page title='Applications' toolbar={services.viewPreferences.getPreferences().map((pref) => ({
|
||||
breadcrumbs: [{ title: 'Applications', path: '/applications' }],
|
||||
tools: (
|
||||
<React.Fragment key='app-list-tools'>
|
||||
<span className='applications-list__view-type'>
|
||||
<i className={classNames('fa fa-th', {selected: pref.appList.view === 'tiles'})} onClick={() => {
|
||||
ctx.navigation.goto('.', { view: 'tiles'});
|
||||
services.viewPreferences.updatePreferences({ appList: {...pref.appList, view: 'tiles'} });
|
||||
}} />
|
||||
<i className={classNames('fa fa-th-list', {selected: pref.appList.view === 'list'})} onClick={() => {
|
||||
ctx.navigation.goto('.', { view: 'list'});
|
||||
services.viewPreferences.updatePreferences({ appList: {...pref.appList, view: 'list'} });
|
||||
}} />
|
||||
<i className={classNames('fa fa-chart-pie', {selected: pref.appList.view === 'summary'})} onClick={() => {
|
||||
ctx.navigation.goto('.', { view: 'summary'});
|
||||
services.viewPreferences.updatePreferences({ appList: {...pref.appList, view: 'summary'} });
|
||||
}} />
|
||||
</span>
|
||||
</React.Fragment>
|
||||
),
|
||||
actionMenu: {
|
||||
className: 'fa fa-plus',
|
||||
items: [{
|
||||
title: 'New Application',
|
||||
action: () => ctx.navigation.goto('.', { new: '{}' }),
|
||||
}],
|
||||
},
|
||||
}))}>
|
||||
<div className='applications-list'>
|
||||
<ViewPref>
|
||||
{(pref) =>
|
||||
<DataLoader
|
||||
input={(pref.labelsFilter || []).join(',')}
|
||||
load={(selector) => loadApplications(selector)}
|
||||
loadingRenderer={() => (<div className='argo-container'><MockupList height={100} marginTop={30}/></div>)}>
|
||||
{(applications: models.Application[]) => (
|
||||
applications.length === 0 && (pref.labelsFilter || []).length === 0 ? (
|
||||
<EmptyState icon='argo-icon-application'>
|
||||
<h4>No applications yet</h4>
|
||||
<h5>Create new application to start managing resources in your cluster</h5>
|
||||
<button className='argo-button argo-button--base' onClick={() => ctx.navigation.goto('.', { new: JSON.stringify({}) })}>Create application</button>
|
||||
</EmptyState>
|
||||
) : (
|
||||
<div className='row'>
|
||||
<div className='columns small-12 xxlarge-2'>
|
||||
<Query>
|
||||
{(q) => (
|
||||
<div className='applications-list__search'>
|
||||
<i className='fa fa-search'/>
|
||||
{q.get('search') && (
|
||||
<i className='fa fa-times' onClick={() => ctx.navigation.goto('.', { search: null }, { replace: true })}/>
|
||||
)}
|
||||
<Autocomplete
|
||||
filterSuggestions={true}
|
||||
renderInput={(inputProps) => (
|
||||
<input {...inputProps} onFocus={(e) => {
|
||||
e.target.select();
|
||||
if (inputProps.onFocus) {
|
||||
inputProps.onFocus(e);
|
||||
}
|
||||
}} className='argo-field' />
|
||||
)}
|
||||
renderItem={(item) => (
|
||||
<React.Fragment>
|
||||
<i className='icon argo-icon-application'/> {item.label}
|
||||
</React.Fragment>
|
||||
)}
|
||||
onSelect={(val) => {
|
||||
ctx.navigation.goto(`./${val}`);
|
||||
<ClusterCtx.Provider value={clusters}>
|
||||
<Consumer>
|
||||
{(ctx) => (
|
||||
<Page
|
||||
title='Applications'
|
||||
toolbar={services.viewPreferences.getPreferences().map((pref) => ({
|
||||
breadcrumbs: [{title: 'Applications', path: '/applications'}],
|
||||
tools: (
|
||||
<React.Fragment key='app-list-tools'>
|
||||
<span className='applications-list__view-type'>
|
||||
<i
|
||||
className={classNames('fa fa-th', {selected: pref.appList.view === 'tiles'})}
|
||||
onClick={() => {
|
||||
ctx.navigation.goto('.', {view: 'tiles'});
|
||||
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'tiles'}});
|
||||
}}
|
||||
onChange={(e) => ctx.navigation.goto('.', { search: e.target.value }, { replace: true })}
|
||||
value={q.get('search') || ''} items={applications.map((app) => app.metadata.name)}/>
|
||||
</div>
|
||||
)}
|
||||
</Query>
|
||||
<ApplicationsFilter applications={applications} pref={pref} onChange={(newPref) => {
|
||||
services.viewPreferences.updatePreferences({appList: newPref});
|
||||
ctx.navigation.goto('.', {
|
||||
proj: newPref.projectsFilter.join(','),
|
||||
sync: newPref.syncFilter.join(','),
|
||||
health: newPref.healthFilter.join(','),
|
||||
namespace: newPref.namespacesFilter.join(','),
|
||||
cluster: newPref.clustersFilter.join(','),
|
||||
labels: newPref.labelsFilter.join(','),
|
||||
});
|
||||
}} />
|
||||
</div>
|
||||
<div className='columns small-12 xxlarge-10'>
|
||||
{pref.view === 'summary' && (
|
||||
<ApplicationsSummary applications={filterApps(applications, pref, pref.search)} />
|
||||
) || (
|
||||
<Paginate
|
||||
preferencesKey='applications-list'
|
||||
page={pref.page}
|
||||
emptyState={() => (
|
||||
<EmptyState icon='fa fa-search'>
|
||||
<h4>No applications found</h4>
|
||||
<h5>Try to change filter criteria</h5>
|
||||
</EmptyState>
|
||||
)}
|
||||
data={filterApps(applications, pref, pref.search)} onPageChange={(page) => ctx.navigation.goto('.', { page })} >
|
||||
{(data) => (
|
||||
pref.view === 'tiles' && (
|
||||
<ApplicationTiles
|
||||
applications={data}
|
||||
syncApplication={(appName) => ctx.navigation.goto('.', { syncApp: appName })}
|
||||
refreshApplication={(appName) => services.applications.get(appName, 'normal')}
|
||||
deleteApplication={(appName) => AppUtils.deleteApplication(appName, ctx)}
|
||||
/>
|
||||
) || (
|
||||
<ApplicationsTable applications={data}
|
||||
syncApplication={(appName) => ctx.navigation.goto('.', { syncApp: appName })}
|
||||
refreshApplication={(appName) => services.applications.get(appName, 'normal')}
|
||||
deleteApplication={(appName) => AppUtils.deleteApplication(appName, ctx)}
|
||||
<i
|
||||
className={classNames('fa fa-th-list', {selected: pref.appList.view === 'list'})}
|
||||
onClick={() => {
|
||||
ctx.navigation.goto('.', {view: 'list'});
|
||||
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'list'}});
|
||||
}}
|
||||
/>
|
||||
)
|
||||
<i
|
||||
className={classNames('fa fa-chart-pie', {selected: pref.appList.view === 'summary'})}
|
||||
onClick={() => {
|
||||
ctx.navigation.goto('.', {view: 'summary'});
|
||||
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'summary'}});
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</React.Fragment>
|
||||
),
|
||||
actionMenu: {
|
||||
items: [
|
||||
{
|
||||
title: 'New App',
|
||||
iconClassName: 'fa fa-plus',
|
||||
action: () => ctx.navigation.goto('.', {new: '{}'}),
|
||||
},
|
||||
{
|
||||
title: 'Sync Apps',
|
||||
iconClassName: 'fa fa-sync',
|
||||
action: () => ctx.navigation.goto('.', {syncApps: true}),
|
||||
},
|
||||
],
|
||||
},
|
||||
}))}>
|
||||
<div className='applications-list'>
|
||||
<ViewPref>
|
||||
{(pref) => (
|
||||
<DataLoader
|
||||
load={() => loadApplications()}
|
||||
loadingRenderer={() => (
|
||||
<div className='argo-container'>
|
||||
<MockupList height={100} marginTop={30} />
|
||||
</div>
|
||||
)}>
|
||||
{(applications: models.Application[]) =>
|
||||
applications.length === 0 && (pref.labelsFilter || []).length === 0 ? (
|
||||
<EmptyState icon='argo-icon-application'>
|
||||
<h4>No applications yet</h4>
|
||||
<h5>Create new application to start managing resources in your cluster</h5>
|
||||
<button className='argo-button argo-button--base' onClick={() => ctx.navigation.goto('.', {new: JSON.stringify({})})}>
|
||||
Create application
|
||||
</button>
|
||||
</EmptyState>
|
||||
) : (
|
||||
<div className='row'>
|
||||
<div className='columns small-12 xxlarge-2'>
|
||||
<Query>
|
||||
{(q) => (
|
||||
<div className='applications-list__search'>
|
||||
<i className='fa fa-search' />
|
||||
{q.get('search') && (
|
||||
<i className='fa fa-times' onClick={() => ctx.navigation.goto('.', {search: null}, {replace: true})} />
|
||||
)}
|
||||
<Autocomplete
|
||||
filterSuggestions={true}
|
||||
renderInput={(inputProps) => (
|
||||
<input
|
||||
{...inputProps}
|
||||
onFocus={(e) => {
|
||||
e.target.select();
|
||||
if (inputProps.onFocus) {
|
||||
inputProps.onFocus(e);
|
||||
}
|
||||
}}
|
||||
className='argo-field'
|
||||
/>
|
||||
)}
|
||||
renderItem={(item) => (
|
||||
<React.Fragment>
|
||||
<i className='icon argo-icon-application' /> {item.label}
|
||||
</React.Fragment>
|
||||
)}
|
||||
onSelect={(val) => {
|
||||
ctx.navigation.goto(`./${val}`);
|
||||
}}
|
||||
onChange={(e) => ctx.navigation.goto('.', {search: e.target.value}, {replace: true})}
|
||||
value={q.get('search') || ''}
|
||||
items={applications.map((app) => app.metadata.name)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Query>
|
||||
<ApplicationsFilter
|
||||
applications={applications}
|
||||
pref={pref}
|
||||
onChange={(newPref) => {
|
||||
services.viewPreferences.updatePreferences({appList: newPref});
|
||||
ctx.navigation.goto('.', {
|
||||
proj: newPref.projectsFilter.join(','),
|
||||
sync: newPref.syncFilter.join(','),
|
||||
health: newPref.healthFilter.join(','),
|
||||
namespace: newPref.namespacesFilter.join(','),
|
||||
cluster: newPref.clustersFilter.join(','),
|
||||
labels: newPref.labelsFilter.map(encodeURIComponent).join(','),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{syncAppsInput && (
|
||||
<ApplicationsSyncPanel
|
||||
key='syncsPanel'
|
||||
show={syncAppsInput}
|
||||
hide={() => ctx.navigation.goto('.', {syncApps: null})}
|
||||
apps={filterApps(applications, pref, pref.search)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className='columns small-12 xxlarge-10'>
|
||||
{(pref.view === 'summary' && <ApplicationsSummary applications={filterApps(applications, pref, pref.search)} />) || (
|
||||
<Paginate
|
||||
preferencesKey='applications-list'
|
||||
page={pref.page}
|
||||
emptyState={() => (
|
||||
<EmptyState icon='fa fa-search'>
|
||||
<h4>No applications found</h4>
|
||||
<h5>Try to change filter criteria</h5>
|
||||
</EmptyState>
|
||||
)}
|
||||
data={filterApps(applications, pref, pref.search)}
|
||||
onPageChange={(page) => ctx.navigation.goto('.', {page})}>
|
||||
{(data) =>
|
||||
(pref.view === 'tiles' && (
|
||||
<ApplicationTiles
|
||||
applications={data}
|
||||
syncApplication={(appName) => ctx.navigation.goto('.', {syncApp: appName})}
|
||||
refreshApplication={(appName) => services.applications.get(appName, 'normal')}
|
||||
deleteApplication={(appName) => AppUtils.deleteApplication(appName, ctx)}
|
||||
/>
|
||||
)) || (
|
||||
<ApplicationsTable
|
||||
applications={data}
|
||||
syncApplication={(appName) => ctx.navigation.goto('.', {syncApp: appName})}
|
||||
refreshApplication={(appName) => services.applications.get(appName, 'normal')}
|
||||
deleteApplication={(appName) => AppUtils.deleteApplication(appName, ctx)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Paginate>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</DataLoader>
|
||||
)}
|
||||
</Paginate>
|
||||
)}
|
||||
</div>
|
||||
</ViewPref>
|
||||
</div>
|
||||
)
|
||||
<ObservableQuery>
|
||||
{(q) => (
|
||||
<DataLoader
|
||||
load={() =>
|
||||
q.flatMap((params) => {
|
||||
const syncApp = params.get('syncApp');
|
||||
return (syncApp && Observable.fromPromise(services.applications.get(syncApp))) || Observable.from([null]);
|
||||
})
|
||||
}>
|
||||
{(app) => (
|
||||
<ApplicationSyncPanel key='syncPanel' application={app} selectedResource={'all'} hide={() => ctx.navigation.goto('.', {syncApp: null})} />
|
||||
)}
|
||||
</DataLoader>
|
||||
)}
|
||||
</ObservableQuery>
|
||||
<SlidingPanel
|
||||
isShown={!!appInput}
|
||||
onClose={() => ctx.navigation.goto('.', {new: null})}
|
||||
header={
|
||||
<div>
|
||||
<button className='argo-button argo-button--base' onClick={() => createApi && createApi.submitForm(null)}>
|
||||
Create
|
||||
</button>{' '}
|
||||
<button onClick={() => ctx.navigation.goto('.', {new: null})} className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
}>
|
||||
{appInput && (
|
||||
<ApplicationCreatePanel
|
||||
getFormApi={(api) => {
|
||||
setCreateApi(api);
|
||||
}}
|
||||
createApp={async (app) => {
|
||||
try {
|
||||
await services.applications.create(app);
|
||||
ctx.navigation.goto('.', {new: null});
|
||||
} catch (e) {
|
||||
ctx.notifications.show({
|
||||
content: <ErrorNotification title='Unable to create application' e={e} />,
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
}}
|
||||
app={appInput}
|
||||
onAppChanged={(app) => ctx.navigation.goto('.', {new: JSON.stringify(app)}, {replace: true})}
|
||||
/>
|
||||
)}
|
||||
</SlidingPanel>
|
||||
</Page>
|
||||
)}
|
||||
</DataLoader>
|
||||
}</ViewPref>
|
||||
</div>
|
||||
<ObservableQuery>
|
||||
{(q) => (
|
||||
<DataLoader load={() => q.flatMap((params) => {
|
||||
const syncApp = params.get('syncApp');
|
||||
return syncApp && Observable.fromPromise(services.applications.get(syncApp)) || Observable.from([null]);
|
||||
}) }>
|
||||
{(app) => (
|
||||
<ApplicationSyncPanel key='syncPanel' application={app} selectedResource={'all'} hide={() => ctx.navigation.goto('.', { syncApp: null })} />
|
||||
)}
|
||||
</DataLoader>
|
||||
)}
|
||||
</ObservableQuery>
|
||||
<SlidingPanel isShown={!!appInput} onClose={() => ctx.navigation.goto('.', { new: null })} header={
|
||||
<div>
|
||||
<button className='argo-button argo-button--base'
|
||||
onClick={() => createApi && createApi.submitForm(null)}>
|
||||
Create
|
||||
</button> <button onClick={() => ctx.navigation.goto('.', { new: null })} className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
}>
|
||||
{appInput && <ApplicationCreatePanel getFormApi={(api) => {
|
||||
setCreateApi(api);
|
||||
}} createApp={ async (app) => {
|
||||
try {
|
||||
await services.applications.create(app);
|
||||
ctx.navigation.goto('.', { new: null });
|
||||
} catch (e) {
|
||||
ctx.notifications.show({
|
||||
content: <ErrorNotification title='Unable to create application' e={e}/>,
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
}}
|
||||
app={appInput}
|
||||
onAppChanged={(app) => ctx.navigation.goto('.', { new: JSON.stringify(app) }, { replace: true })} />}
|
||||
</SlidingPanel>
|
||||
</Page>
|
||||
)}
|
||||
</Consumer>
|
||||
</ClusterCtx.Provider>);
|
||||
</Consumer>
|
||||
</ClusterCtx.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
import {ErrorNotification, NotificationType, SlidingPanel} from 'argo-ui';
|
||||
import * as React from 'react';
|
||||
import {Checkbox, Form, FormApi} from 'react-form';
|
||||
import {Consumer} from '../../../shared/context';
|
||||
import * as models from '../../../shared/models';
|
||||
import {services} from '../../../shared/services';
|
||||
import {ComparisonStatusIcon, HealthStatusIcon} from '../utils';
|
||||
|
||||
export const ApplicationsSyncPanel = ({show, apps, hide}: {show: boolean; apps: models.Application[]; hide: () => void}) => {
|
||||
const [form, setForm] = React.useState<FormApi>(null);
|
||||
const getSelectedApps = (params: any) => apps.filter((app) => params['app/' + app.metadata.name]);
|
||||
return (
|
||||
<Consumer>
|
||||
{(ctx) => (
|
||||
<SlidingPanel
|
||||
isMiddle={true}
|
||||
isShown={show}
|
||||
onClose={() => hide()}
|
||||
header={
|
||||
<div>
|
||||
<button className='argo-button argo-button--base' onClick={() => form.submitForm(null)}>
|
||||
Sync
|
||||
</button>{' '}
|
||||
<button onClick={() => hide()} className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
}>
|
||||
<Form
|
||||
onSubmit={async (params: any) => {
|
||||
const selectedApps = getSelectedApps(params);
|
||||
if (selectedApps.length === 0) {
|
||||
ctx.notifications.show({content: `No apps selected`, type: NotificationType.Error});
|
||||
return;
|
||||
}
|
||||
ctx.notifications.show({
|
||||
content: `Syncing ${selectedApps.length} app(s)`,
|
||||
type: NotificationType.Success,
|
||||
});
|
||||
const syncStrategy = (params.applyOnly ? {apply: {force: params.force}} : {hook: {force: params.force}}) as models.SyncStrategy;
|
||||
for (const app of selectedApps) {
|
||||
await services.applications.sync(app.metadata.name, app.spec.source.targetRevision, params.prune, params.dryRun, syncStrategy, null).catch((e) => {
|
||||
ctx.notifications.show({
|
||||
content: <ErrorNotification title={`Unable to sync ${app.metadata.name}`} e={e} />,
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
});
|
||||
}
|
||||
hide();
|
||||
}}
|
||||
getApi={setForm}>
|
||||
{(formApi) => (
|
||||
<React.Fragment>
|
||||
<div className='argo-form-row'>
|
||||
<h4>Sync app(s)</h4>
|
||||
<label>Options:</label>
|
||||
<div style={{paddingLeft: '1em'}}>
|
||||
<label>
|
||||
<Checkbox field='prune' /> Prune
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<Checkbox field='dryRun' /> Dry Run
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<Checkbox field='applyOnly' /> Apply Only
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<Checkbox field='force' /> Force
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
Apps (<a
|
||||
onClick={() => apps.forEach((app) => formApi.setValue('app/' + app.metadata.name, true))}>all</a>/
|
||||
<a
|
||||
onClick={() =>
|
||||
apps.forEach((app) => formApi.setValue('app/' + app.metadata.name, app.status.sync.status === models.SyncStatuses.OutOfSync))
|
||||
}>
|
||||
out of sync
|
||||
</a>
|
||||
/<a
|
||||
onClick={() => apps.forEach((app) => formApi.setValue('app/' + app.metadata.name, false))}>none</a>
|
||||
):
|
||||
</label>
|
||||
<div style={{paddingLeft: '1em'}}>
|
||||
{apps.map((app) => (
|
||||
<label key={app.metadata.name}>
|
||||
<Checkbox field={`app/${app.metadata.name}`} />
|
||||
|
||||
{app.metadata.name}
|
||||
|
||||
<ComparisonStatusIcon status={app.status.sync.status} />
|
||||
|
||||
<HealthStatusIcon state={app.status.health} />
|
||||
<br />
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Form>
|
||||
</SlidingPanel>
|
||||
)}
|
||||
</Consumer>
|
||||
);
|
||||
};
|
||||
44
ui/src/app/applications/components/label-selector.test.ts
Normal file
44
ui/src/app/applications/components/label-selector.test.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import * as LabelSelector from './label-selector';
|
||||
|
||||
test('exists', () => {
|
||||
expect(LabelSelector.match('test', {test: 'hello'})).toBeTruthy();
|
||||
expect(LabelSelector.match('test1', {test: 'hello'})).toBeFalsy();
|
||||
});
|
||||
|
||||
test('not exists', () => {
|
||||
expect(LabelSelector.match('!test', {test: 'hello'})).toBeFalsy();
|
||||
expect(LabelSelector.match('!test1', {test: 'hello'})).toBeTruthy();
|
||||
});
|
||||
|
||||
test('in', () => {
|
||||
expect(LabelSelector.match('test in 1, 2, 3', {test: '1'})).toBeTruthy();
|
||||
expect(LabelSelector.match('test in 1, 2, 3', {test: '4'})).toBeFalsy();
|
||||
expect(LabelSelector.match('test in 1, 2, 3', {test1: '1'})).toBeFalsy();
|
||||
});
|
||||
|
||||
test('notIn', () => {
|
||||
expect(LabelSelector.match('test notin 1, 2, 3', {test: '1'})).toBeFalsy();
|
||||
expect(LabelSelector.match('test notin 1, 2, 3', {test: '4'})).toBeTruthy();
|
||||
expect(LabelSelector.match('test notin 1, 2, 3', {test1: '1'})).toBeTruthy();
|
||||
});
|
||||
|
||||
test('equal', () => {
|
||||
expect(LabelSelector.match('test=hello', {test: 'hello'})).toBeTruthy();
|
||||
expect(LabelSelector.match('test=world', {test: 'hello'})).toBeFalsy();
|
||||
expect(LabelSelector.match('test==hello', {test: 'hello'})).toBeTruthy();
|
||||
});
|
||||
|
||||
test('notEqual', () => {
|
||||
expect(LabelSelector.match('test!=hello', {test: 'hello'})).toBeFalsy();
|
||||
expect(LabelSelector.match('test!=world', {test: 'hello'})).toBeTruthy();
|
||||
});
|
||||
|
||||
test('greaterThen', () => {
|
||||
expect(LabelSelector.match('test gt 1', {test: '2'})).toBeTruthy();
|
||||
expect(LabelSelector.match('test gt 3', {test: '2'})).toBeFalsy();
|
||||
});
|
||||
|
||||
test('lessThen', () => {
|
||||
expect(LabelSelector.match('test lt 1', {test: '2'})).toBeFalsy();
|
||||
expect(LabelSelector.match('test lt 3', {test: '2'})).toBeTruthy();
|
||||
});
|
||||
39
ui/src/app/applications/components/label-selector.ts
Normal file
39
ui/src/app/applications/components/label-selector.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
type operatorFn = (labels: {[name: string]: string}, key: string, values: string[]) => boolean;
|
||||
|
||||
const operators: {[type: string]: operatorFn} = {
|
||||
'!=': (labels, key, values) => labels[key] !== values[0],
|
||||
'==': (labels, key, values) => labels[key] === values[0],
|
||||
'=': (labels, key, values) => labels[key] === values[0],
|
||||
'notin': (labels, key, values) => !values.includes(labels[key]),
|
||||
'in': (labels, key, values) => values.includes(labels[key]),
|
||||
'gt': (labels, key, values) => parseFloat(labels[key]) > parseFloat(values[0]),
|
||||
'lt': (labels, key, values) => parseFloat(labels[key]) < parseFloat(values[0]),
|
||||
};
|
||||
|
||||
function split(input: string, delimiter: string): string[] {
|
||||
return input
|
||||
.split(delimiter)
|
||||
.map((part) => part.trim())
|
||||
.filter((part) => part !== '');
|
||||
}
|
||||
|
||||
export type LabelSelector = (labels: {[name: string]: string}) => boolean;
|
||||
|
||||
export function parse(selector: string): LabelSelector {
|
||||
for (const type of Object.keys(operators)) {
|
||||
const operator = operators[type];
|
||||
const parts = split(selector, type);
|
||||
if (parts.length > 1) {
|
||||
const values = split(parts[1], ',');
|
||||
return (labels) => operator(labels, parts[0], values);
|
||||
}
|
||||
}
|
||||
if (selector.startsWith('!')) {
|
||||
return (labels) => !labels.hasOwnProperty(selector.slice(1));
|
||||
}
|
||||
return (labels) => labels.hasOwnProperty(selector);
|
||||
}
|
||||
|
||||
export function match(selector: string, labels: {[name: string]: string}): boolean {
|
||||
return parse(selector)(labels || {});
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export interface ViewPreferences {
|
||||
|
||||
const VIEW_PREFERENCES_KEY = 'view_preferences';
|
||||
|
||||
const minVer = 3;
|
||||
const minVer = 4;
|
||||
|
||||
const DEFAULT_PREFERENCES: ViewPreferences = {
|
||||
version: 1,
|
||||
|
||||
11
util/cache/cache.go
vendored
11
util/cache/cache.go
vendored
@@ -30,6 +30,11 @@ type OIDCState struct {
|
||||
ReturnURL string `json:"returnURL"`
|
||||
}
|
||||
|
||||
type ClusterInfo struct {
|
||||
appv1.ConnectionState
|
||||
Version string
|
||||
}
|
||||
|
||||
// NewCache creates new instance of Cache
|
||||
func NewCache(cacheClient CacheClient) *Cache {
|
||||
return &Cache{client: cacheClient}
|
||||
@@ -153,13 +158,13 @@ func (c *Cache) SetAppResourcesTree(appName string, resourcesTree *appv1.Applica
|
||||
return c.setItem(appResourcesTreeKey(appName), resourcesTree, appStateCacheExpiration, resourcesTree == nil)
|
||||
}
|
||||
|
||||
func (c *Cache) GetClusterConnectionState(server string) (appv1.ConnectionState, error) {
|
||||
res := appv1.ConnectionState{}
|
||||
func (c *Cache) GetClusterInfo(server string) (ClusterInfo, error) {
|
||||
res := ClusterInfo{}
|
||||
err := c.getItem(clusterConnectionStateKey(server), &res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (c *Cache) SetClusterConnectionState(server string, state *appv1.ConnectionState) error {
|
||||
func (c *Cache) SetClusterInfo(server string, state *ClusterInfo) error {
|
||||
return c.setItem(clusterConnectionStateKey(server), &state, connectionStatusCacheExpiration, state == nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func ignoreLiveObjectHealth(liveObj *unstructured.Unstructured, resHealth appv1.
|
||||
return true
|
||||
}
|
||||
gvk := liveObj.GroupVersionKind()
|
||||
if gvk.Group == "argoproj.io" && gvk.Kind == "Application" && resHealth.Status == appv1.HealthStatusMissing {
|
||||
if gvk.Group == "argoproj.io" && gvk.Kind == "Application" && (resHealth.Status == appv1.HealthStatusMissing || resHealth.Status == appv1.HealthStatusUnknown) {
|
||||
// Covers the app-of-apps corner case where child app is deployed but that app itself
|
||||
// has a status of 'Missing', which we don't want to cause the parent's health status
|
||||
// to also be Missing
|
||||
|
||||
@@ -115,6 +115,7 @@ func TestAppOfAppsHealth(t *testing.T) {
|
||||
}
|
||||
|
||||
missingApp, missingStatus := newAppLiveObj("foo", appv1.HealthStatusMissing)
|
||||
unknownApp, unknownStatus := newAppLiveObj("fooz", appv1.HealthStatusUnknown)
|
||||
healthyApp, healthyStatus := newAppLiveObj("bar", appv1.HealthStatusHealthy)
|
||||
degradedApp, degradedStatus := newAppLiveObj("baz", appv1.HealthStatusDegraded)
|
||||
|
||||
@@ -127,6 +128,15 @@ func TestAppOfAppsHealth(t *testing.T) {
|
||||
assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status)
|
||||
}
|
||||
|
||||
// verify unknown child app does not affect app health
|
||||
{
|
||||
unknownAndHealthyStatuses := []appv1.ResourceStatus{unknownStatus, healthyStatus}
|
||||
unknownAndHealthyLiveObjects := []*unstructured.Unstructured{unknownApp, healthyApp}
|
||||
healthStatus, err := SetApplicationHealth(unknownAndHealthyStatuses, unknownAndHealthyLiveObjects, nil, noFilter)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status)
|
||||
}
|
||||
|
||||
// verify degraded does affect
|
||||
{
|
||||
degradedAndHealthyStatuses := []appv1.ResourceStatus{degradedStatus, healthyStatus}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
"github.com/argoproj/argo-cd/util/config"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -128,22 +129,41 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string) (string, ut
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
// download chart tar file into persistent helm repository directory
|
||||
_, err = helmCmd.Fetch(c.repoURL, chart, version, c.creds)
|
||||
// (1) because `helm fetch` downloads an arbitrary file name, we download to an empty temp directory
|
||||
tempDest, err := ioutil.TempDir("", "helm")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(tempDest) }()
|
||||
_, err = helmCmd.Fetch(c.repoURL, chart, version, tempDest, c.creds)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
// (2) then we assume that the only file downloaded into the directory is the tgz file
|
||||
// and we move that to where we want it
|
||||
infos, err := ioutil.ReadDir(tempDest)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if len(infos) != 1 {
|
||||
return "", nil, fmt.Errorf("expected 1 file, found %v", len(infos))
|
||||
}
|
||||
err = os.Rename(filepath.Join(tempDest, infos[0].Name()), chartPath)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
// untar helm chart into throw away temp directory which should be deleted as soon as no longer needed
|
||||
tempDir, err := ioutil.TempDir("", "")
|
||||
tempDir, err := ioutil.TempDir("", "helm")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
cmd := exec.Command("tar", "-zxvf", chartPath)
|
||||
cmd.Dir = tempDir
|
||||
_, err = argoexec.RunCommandExt(cmd, argoexec.CmdOpts{})
|
||||
_, err = argoexec.RunCommandExt(cmd, config.CmdOpts())
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(tempDir)
|
||||
return "", nil, err
|
||||
}
|
||||
return path.Join(tempDir, chart), util.NewCloser(func() error {
|
||||
return os.RemoveAll(tempDir)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
package helm
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
)
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
_, err := NewClient("", Creds{}).GetIndex()
|
||||
client := NewClient("", Creds{})
|
||||
_, err := client.GetIndex()
|
||||
assert.Error(t, err)
|
||||
})
|
||||
t.Run("Stable", func(t *testing.T) {
|
||||
index, err := NewClient("https://kubernetes-charts.storage.googleapis.com", Creds{}).GetIndex()
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{})
|
||||
index, err := client.GetIndex()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, index)
|
||||
})
|
||||
t.Run("BasicAuth", func(t *testing.T) {
|
||||
index, err := NewClient("https://kubernetes-charts.storage.googleapis.com", Creds{
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{
|
||||
Username: "my-password",
|
||||
Password: "my-username",
|
||||
}).GetIndex()
|
||||
})
|
||||
index, err := client.GetIndex()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, index)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_nativeHelmChart_ExtractChart(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", Creds{})
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1")
|
||||
defer util.Close(closer)
|
||||
assert.NoError(t, err)
|
||||
info, err := os.Stat(path)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, info.IsDir())
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
argoexec "github.com/argoproj/pkg/exec"
|
||||
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
"github.com/argoproj/argo-cd/util/config"
|
||||
"github.com/argoproj/argo-cd/util/security"
|
||||
)
|
||||
|
||||
@@ -39,6 +40,7 @@ func (c Cmd) run(args ...string) (string, error) {
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("HELM_HOME=%s", c.helmHome))
|
||||
return argoexec.RunCommandExt(cmd, argoexec.CmdOpts{
|
||||
Timeout: config.CmdOpts().Timeout,
|
||||
Redactor: redactor,
|
||||
})
|
||||
}
|
||||
@@ -117,31 +119,31 @@ func writeToTmp(data []byte) (string, io.Closer, error) {
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (c *Cmd) Fetch(repo, chartName string, version string, opts Creds) (string, error) {
|
||||
args := []string{"fetch"}
|
||||
func (c *Cmd) Fetch(repo, chartName, version, destination string, creds Creds) (string, error) {
|
||||
args := []string{"fetch", "--destination", destination}
|
||||
|
||||
if version != "" {
|
||||
args = append(args, "--version", version)
|
||||
}
|
||||
if opts.Username != "" {
|
||||
args = append(args, "--username", opts.Username)
|
||||
if creds.Username != "" {
|
||||
args = append(args, "--username", creds.Username)
|
||||
}
|
||||
if opts.Password != "" {
|
||||
args = append(args, "--password", opts.Password)
|
||||
if creds.Password != "" {
|
||||
args = append(args, "--password", creds.Password)
|
||||
}
|
||||
if opts.CAPath != "" {
|
||||
args = append(args, "--ca-file", opts.CAPath)
|
||||
if creds.CAPath != "" {
|
||||
args = append(args, "--ca-file", creds.CAPath)
|
||||
}
|
||||
if len(opts.CertData) > 0 {
|
||||
filePath, closer, err := writeToTmp(opts.CertData)
|
||||
if len(creds.CertData) > 0 {
|
||||
filePath, closer, err := writeToTmp(creds.CertData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer util.Close(closer)
|
||||
args = append(args, "--cert-file", filePath)
|
||||
}
|
||||
if len(opts.KeyData) > 0 {
|
||||
filePath, closer, err := writeToTmp(opts.KeyData)
|
||||
if len(creds.KeyData) > 0 {
|
||||
filePath, closer, err := writeToTmp(creds.KeyData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
argoexec "github.com/argoproj/pkg/exec"
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
"github.com/argoproj/argo-cd/util/config"
|
||||
)
|
||||
@@ -89,6 +88,7 @@ func (h *helm) Dispose() {
|
||||
func Version() (string, error) {
|
||||
cmd := exec.Command("helm", "version", "--client")
|
||||
out, err := argoexec.RunCommandExt(cmd, argoexec.CmdOpts{
|
||||
Timeout: config.CmdOpts().Timeout,
|
||||
Redactor: redactor,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -138,12 +138,17 @@ func (h *helm) GetParameters(valuesFiles []string) (map[string]string, error) {
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func flatVals(input map[string]interface{}, output map[string]string, prefixes ...string) {
|
||||
for key, val := range input {
|
||||
if subMap, ok := val.(map[string]interface{}); ok {
|
||||
flatVals(subMap, output, append(prefixes, fmt.Sprintf("%v", key))...)
|
||||
} else {
|
||||
output[strings.Join(append(prefixes, fmt.Sprintf("%v", key)), ".")] = fmt.Sprintf("%v", val)
|
||||
func flatVals(input interface{}, output map[string]string, prefixes ...string) {
|
||||
switch i := input.(type) {
|
||||
case map[string]interface{}:
|
||||
for k, v := range i {
|
||||
flatVals(v, output, append(prefixes, k)...)
|
||||
}
|
||||
case []interface{}:
|
||||
for j, v := range i {
|
||||
flatVals(v, output, append(prefixes[0:len(prefixes)-1], fmt.Sprintf("%s[%v]", prefixes[len(prefixes)-1], j))...)
|
||||
}
|
||||
default:
|
||||
output[strings.Join(prefixes, ".")] = fmt.Sprintf("%v", i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,3 +164,27 @@ func TestVersion(t *testing.T) {
|
||||
re := regexp.MustCompile(SemverRegexValidation)
|
||||
assert.True(t, re.MatchString(ver))
|
||||
}
|
||||
|
||||
func Test_flatVals(t *testing.T) {
|
||||
t.Run("Map", func(t *testing.T) {
|
||||
output := map[string]string{}
|
||||
|
||||
flatVals(map[string]interface{}{"foo": map[string]interface{}{"bar": "baz"}}, output)
|
||||
|
||||
assert.Equal(t, map[string]string{"foo.bar": "baz"}, output)
|
||||
})
|
||||
t.Run("Array", func(t *testing.T) {
|
||||
output := map[string]string{}
|
||||
|
||||
flatVals(map[string]interface{}{"foo": []interface{}{"bar"}}, output)
|
||||
|
||||
assert.Equal(t, map[string]string{"foo[0]": "bar"}, output)
|
||||
})
|
||||
t.Run("Val", func(t *testing.T) {
|
||||
output := map[string]string{}
|
||||
|
||||
flatVals(map[string]interface{}{"foo": 1}, output)
|
||||
|
||||
assert.Equal(t, map[string]string{"foo": "1"}, output)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user