mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-28 21:48:46 +01:00
Compare commits
32 Commits
v1.2.0
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aaca0bbe8 | ||
|
|
85f62dff9e | ||
|
|
97f08aaf4c | ||
|
|
ad7a69a798 | ||
|
|
fc588538bc | ||
|
|
675ae6a991 | ||
|
|
6cc0fd8b8c | ||
|
|
26e1cf0438 | ||
|
|
30d3fcb84a | ||
|
|
3a3a7f5044 | ||
|
|
6c34dd828f | ||
|
|
de7003f530 | ||
|
|
8981903603 | ||
|
|
509c567a40 | ||
|
|
c722a71820 | ||
|
|
1aaf76f230 | ||
|
|
71ad60e89f | ||
|
|
9c46f77bb1 | ||
|
|
b6256aae9f | ||
|
|
f802190a24 | ||
|
|
e07c1edece | ||
|
|
ed15da5271 | ||
|
|
d34dbeac0d | ||
|
|
c4d3a54126 | ||
|
|
622671ece4 | ||
|
|
cf6a7abd30 | ||
|
|
a6a394ba93 | ||
|
|
d315814020 | ||
|
|
d46872d7e8 | ||
|
|
ba7f0fcb47 | ||
|
|
5fcfc22298 | ||
|
|
9e486dfad4 |
@@ -60,10 +60,8 @@ commands:
|
||||
name: Install Go deps
|
||||
command: |
|
||||
set -x
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
go get github.com/jstemmer/go-junit-report
|
||||
go get github.com/mattn/goreman
|
||||
go get golang.org/x/tools/cmd/goimports
|
||||
install_tools:
|
||||
steps:
|
||||
- run:
|
||||
@@ -71,7 +69,14 @@ commands:
|
||||
command: mkdir -p /tmp/dl
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dl-v6
|
||||
- dl-v7
|
||||
- run:
|
||||
name: Install Kubectl v1.14.0
|
||||
command: |
|
||||
set -x
|
||||
[ -e /tmp/dl/kubectl ] || curl -sLf -C - -o /tmp/dl/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.14.0/bin/linux/amd64/kubectl
|
||||
sudo cp /tmp/dl/kubectl /usr/local/bin/kubectl
|
||||
sudo chmod +x /usr/local/bin/kubectl
|
||||
- run:
|
||||
name: Install Kubectx v0.6.3
|
||||
command: |
|
||||
@@ -119,7 +124,7 @@ commands:
|
||||
sudo chmod +x /usr/local/go/bin/kustomize
|
||||
kustomize version
|
||||
- save_cache:
|
||||
key: dl-v6
|
||||
key: dl-v7
|
||||
paths:
|
||||
- /tmp/dl
|
||||
save_go_cache:
|
||||
@@ -208,14 +213,13 @@ jobs:
|
||||
name: Create namespace
|
||||
command: |
|
||||
set -x
|
||||
cat /etc/rancher/k3s/k3s.yaml | sed "s/localhost/`hostname`/" | tee ~/.kube/config
|
||||
echo "127.0.0.1 `hostname`" | sudo tee -a /etc/hosts
|
||||
kubectl create ns argocd-e2e
|
||||
kubens argocd-e2e
|
||||
# install the certificates (not 100% sure we need this)
|
||||
sudo cp /var/lib/rancher/k3s/server/tls/token-ca.crt /usr/local/share/ca-certificates/k3s.crt
|
||||
sudo update-ca-certificates
|
||||
# create the kubecfg, again - not sure we need this
|
||||
cat /etc/rancher/k3s/k3s.yaml | sed "s/localhost/`hostname`/" | tee ~/.kube/config
|
||||
echo "127.0.0.1 `hostname`" | sudo tee -a /etc/hosts
|
||||
- run:
|
||||
name: Apply manifests
|
||||
command: kustomize build test/manifests/base | kubectl apply -f -
|
||||
|
||||
@@ -77,7 +77,9 @@ RUN echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/s
|
||||
RUN groupadd -g 999 argocd && \
|
||||
useradd -r -u 999 -g argocd argocd && \
|
||||
mkdir -p /home/argocd && \
|
||||
chown argocd:argocd /home/argocd && \
|
||||
chown argocd:0 /home/argocd && \
|
||||
chmod g=u /home/argocd && \
|
||||
chmod g=u /etc/passwd && \
|
||||
apt-get update && \
|
||||
apt-get install -y git git-lfs && \
|
||||
apt-get clean && \
|
||||
@@ -89,6 +91,9 @@ COPY --from=builder /usr/local/bin/helm /usr/local/bin/helm
|
||||
COPY --from=builder /usr/local/bin/kubectl /usr/local/bin/kubectl
|
||||
COPY --from=builder /usr/local/bin/kustomize /usr/local/bin/kustomize
|
||||
COPY --from=builder /usr/local/bin/aws-iam-authenticator /usr/local/bin/aws-iam-authenticator
|
||||
# script to add current (possibly arbitrary) user to /etc/passwd at runtime
|
||||
# (if it's not already there, to be openshift friendly)
|
||||
COPY uid_entrypoint.sh /usr/local/bin/uid_entrypoint.sh
|
||||
|
||||
# support for mounting configuration from a configmap
|
||||
RUN mkdir -p /app/config/ssh && \
|
||||
|
||||
9
Gopkg.lock
generated
9
Gopkg.lock
generated
@@ -89,6 +89,14 @@
|
||||
pruneopts = ""
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a6ee710e45210bafe11f2f28963571be2ac8809f9a7b675a6d2c02302a1ce1a9"
|
||||
name = "github.com/bouk/monkey"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5df1f207ff77e025801505ae4d903133a0b4353f"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e04162bd6a6d4950541bae744c968108e14913b1cebccf29f7650b573f44adb3"
|
||||
name = "github.com/casbin/casbin"
|
||||
@@ -1589,6 +1597,7 @@
|
||||
"github.com/argoproj/pkg/errors",
|
||||
"github.com/argoproj/pkg/exec",
|
||||
"github.com/argoproj/pkg/time",
|
||||
"github.com/bouk/monkey",
|
||||
"github.com/casbin/casbin",
|
||||
"github.com/casbin/casbin/model",
|
||||
"github.com/casbin/casbin/persist",
|
||||
|
||||
16
Makefile
16
Makefile
@@ -27,7 +27,9 @@ DEV_IMAGE?=false
|
||||
LINT_GOGC?=off
|
||||
LINT_CONCURRENCY?=8
|
||||
# Set timeout for linter
|
||||
LINT_DEADLINE?=1m0s
|
||||
LINT_DEADLINE?=4m0s
|
||||
CODEGEN=true
|
||||
LINT=true
|
||||
|
||||
override LDFLAGS += \
|
||||
-X ${PACKAGE}.version=${VERSION} \
|
||||
@@ -74,7 +76,7 @@ codegen-local: protogen clientgen openapigen manifests-local
|
||||
|
||||
.PHONY: codegen
|
||||
codegen: dev-tools-image
|
||||
$(call run-in-dev-tool,make codegen-local)
|
||||
@if [ "$(CODGEN)" = "true" ]; then $(call run-in-dev-tool,make codegen-local) ; fi
|
||||
|
||||
.PHONY: cli
|
||||
cli: clean-debug
|
||||
@@ -153,12 +155,16 @@ builder-image:
|
||||
dep-ensure:
|
||||
dep ensure -no-vendor
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
.PHONY: lint-local
|
||||
lint-local: build
|
||||
# golangci-lint does not do a good job of formatting imports
|
||||
goimports -local github.com/argoproj/argo-cd -w `find . ! -path './vendor/*' ! -path './pkg/client/*' -type f -name '*.go'`
|
||||
goimports -local github.com/argoproj/argo-cd -w `find . ! -path './vendor/*' ! -path './pkg/client/*' ! -path '*.pb.go' ! -path '*.gw.go' -type f -name '*.go'`
|
||||
GOGC=$(LINT_GOGC) golangci-lint run --fix --verbose --concurrency $(LINT_CONCURRENCY) --deadline $(LINT_DEADLINE)
|
||||
|
||||
.PHONY: lint
|
||||
lint: dev-tools-image
|
||||
@if [ "$(LINT)" = "true" ]; then $(call run-in-dev-tool,make lint-local LINT_CONCURRENCY=$(LINT_CONCURRENCY) LINT_DEADLINE=$(LINT_DEADLINE) LINT_GOGC=$(LINT_GOGC)); fi
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -v `go list ./... | grep -v 'resource_customizations\|test/e2e'`
|
||||
|
||||
@@ -46,6 +46,7 @@ func newCommand() *cobra.Command {
|
||||
logLevel string
|
||||
glogLevel int
|
||||
metricsPort int
|
||||
kubectlParallelismLimit int64
|
||||
cacheSrc func() (*cache.Cache, error)
|
||||
)
|
||||
var command = cobra.Command{
|
||||
@@ -84,7 +85,8 @@ func newCommand() *cobra.Command {
|
||||
cache,
|
||||
resyncDuration,
|
||||
time.Duration(selfHealTimeoutSeconds)*time.Second,
|
||||
metricsPort)
|
||||
metricsPort,
|
||||
kubectlParallelismLimit)
|
||||
errors.CheckError(err)
|
||||
|
||||
log.Infof("Application Controller (version: %s) starting (namespace: %s)", common.GetVersion(), namespace)
|
||||
@@ -109,6 +111,7 @@ func newCommand() *cobra.Command {
|
||||
command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level")
|
||||
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortArgoCDMetrics, "Start metrics server on given port")
|
||||
command.Flags().IntVar(&selfHealTimeoutSeconds, "self-heal-timeout-seconds", 5, "Specifies timeout between application self heal attempts")
|
||||
command.Flags().Int64Var(&kubectlParallelismLimit, "kubectl-parallelism-limit", 0, "Number of allowed concurrent kubectl fork/execs.")
|
||||
|
||||
cacheSrc = cache.AddCacheFlagsToCmd(&command)
|
||||
return &command
|
||||
|
||||
@@ -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
|
||||
@@ -554,6 +555,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))
|
||||
}
|
||||
@@ -5,11 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
@@ -20,7 +17,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/google/shlex"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@@ -444,6 +440,12 @@ func setAppOptions(flags *pflag.FlagSet, app *argoappv1.Application, appOpts *ap
|
||||
}
|
||||
app.Spec.SyncPolicy.Automated.Prune = appOpts.autoPrune
|
||||
}
|
||||
if flags.Changed("self-heal") {
|
||||
if app.Spec.SyncPolicy == nil || app.Spec.SyncPolicy.Automated == nil {
|
||||
log.Fatal("Cannot set --self-helf: application not configured with automatic sync")
|
||||
}
|
||||
app.Spec.SyncPolicy.Automated.SelfHeal = appOpts.selfHeal
|
||||
}
|
||||
|
||||
return visited
|
||||
}
|
||||
@@ -544,6 +546,7 @@ type appOptions struct {
|
||||
project string
|
||||
syncPolicy string
|
||||
autoPrune bool
|
||||
selfHeal bool
|
||||
namePrefix string
|
||||
directoryRecurse bool
|
||||
configManagementPlugin string
|
||||
@@ -565,6 +568,7 @@ func addAppFlags(command *cobra.Command, opts *appOptions) {
|
||||
command.Flags().StringVar(&opts.project, "project", "", "Application project name")
|
||||
command.Flags().StringVar(&opts.syncPolicy, "sync-policy", "", "Set the sync policy (one of: automated, none)")
|
||||
command.Flags().BoolVar(&opts.autoPrune, "auto-prune", false, "Set automatic pruning when sync is automated")
|
||||
command.Flags().BoolVar(&opts.selfHeal, "self-heal", false, "Set self healing when sync is automated")
|
||||
command.Flags().StringVar(&opts.namePrefix, "nameprefix", "", "Kustomize nameprefix")
|
||||
command.Flags().BoolVar(&opts.directoryRecurse, "directory-recurse", false, "Recurse directory")
|
||||
command.Flags().StringVar(&opts.configManagementPlugin, "config-management-plugin", "", "Config management plugin name")
|
||||
@@ -871,7 +875,8 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
}
|
||||
|
||||
foundDiffs = true
|
||||
printDiff(item.key.Name, target, live)
|
||||
err = diff.PrintDiff(item.key.Name, target, live)
|
||||
errors.CheckError(err)
|
||||
}
|
||||
}
|
||||
if foundDiffs {
|
||||
@@ -886,43 +891,6 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
|
||||
return command
|
||||
}
|
||||
|
||||
func printDiff(name string, live *unstructured.Unstructured, target *unstructured.Unstructured) {
|
||||
tempDir, err := ioutil.TempDir("", "argocd-diff")
|
||||
errors.CheckError(err)
|
||||
|
||||
targetFile := path.Join(tempDir, name)
|
||||
targetData := []byte("")
|
||||
if target != nil {
|
||||
targetData, err = yaml.Marshal(target)
|
||||
errors.CheckError(err)
|
||||
}
|
||||
err = ioutil.WriteFile(targetFile, targetData, 0644)
|
||||
errors.CheckError(err)
|
||||
|
||||
liveFile := path.Join(tempDir, fmt.Sprintf("%s-live.yaml", name))
|
||||
liveData := []byte("")
|
||||
if live != nil {
|
||||
liveData, err = yaml.Marshal(live)
|
||||
errors.CheckError(err)
|
||||
}
|
||||
err = ioutil.WriteFile(liveFile, liveData, 0644)
|
||||
errors.CheckError(err)
|
||||
|
||||
cmdBinary := "diff"
|
||||
var args []string
|
||||
if envDiff := os.Getenv("KUBECTL_EXTERNAL_DIFF"); envDiff != "" {
|
||||
parts, err := shlex.Split(envDiff)
|
||||
errors.CheckError(err)
|
||||
cmdBinary = parts[0]
|
||||
args = parts[1:]
|
||||
}
|
||||
|
||||
cmd := exec.Command(cmdBinary, append(args, liveFile, targetFile)...)
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
_ = cmd.Run()
|
||||
}
|
||||
|
||||
// NewApplicationDeleteCommand returns a new instance of an `argocd app delete` command
|
||||
func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
var (
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/semaphore"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -85,6 +86,7 @@ type ApplicationController struct {
|
||||
refreshRequestedApps map[string]CompareWith
|
||||
refreshRequestedAppsMutex *sync.Mutex
|
||||
metricsServer *metrics.MetricsServer
|
||||
kubectlSemaphore *semaphore.Weighted
|
||||
}
|
||||
|
||||
type ApplicationControllerConfig struct {
|
||||
@@ -103,6 +105,7 @@ func NewApplicationController(
|
||||
appResyncPeriod time.Duration,
|
||||
selfHealTimeout time.Duration,
|
||||
metricsPort int,
|
||||
kubectlParallelismLimit int64,
|
||||
) (*ApplicationController, error) {
|
||||
db := db.NewDB(namespace, settingsMgr, kubeClientset)
|
||||
kubectlCmd := kube.KubectlCmd{}
|
||||
@@ -123,7 +126,12 @@ func NewApplicationController(
|
||||
settingsMgr: settingsMgr,
|
||||
selfHealTimeout: selfHealTimeout,
|
||||
}
|
||||
if kubectlParallelismLimit > 0 {
|
||||
ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit)
|
||||
}
|
||||
kubectlCmd.OnKubectlRun = ctrl.onKubectlRun
|
||||
appInformer, appLister := ctrl.newApplicationInformerAndLister()
|
||||
|
||||
projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, cache.Indexers{})
|
||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort)
|
||||
ctrl.metricsServer = metrics.NewMetricsServer(metricsAddr, appLister, func() error {
|
||||
@@ -141,6 +149,23 @@ func NewApplicationController(
|
||||
return &ctrl, nil
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) onKubectlRun(command string) (util.Closer, error) {
|
||||
ctrl.metricsServer.IncKubectlExec(command)
|
||||
if ctrl.kubectlSemaphore != nil {
|
||||
if err := ctrl.kubectlSemaphore.Acquire(context.Background(), 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrl.metricsServer.IncKubectlExecPending(command)
|
||||
}
|
||||
return util.NewCloser(func() error {
|
||||
if ctrl.kubectlSemaphore != nil {
|
||||
ctrl.kubectlSemaphore.Release(1)
|
||||
ctrl.metricsServer.DecKubectlExecPending(command)
|
||||
}
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func isSelfReferencedApp(app *appv1.Application, ref v1.ObjectReference) bool {
|
||||
gvk := ref.GroupVersionKind()
|
||||
return ref.UID == app.UID &&
|
||||
@@ -647,7 +672,13 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
defer func() {
|
||||
reconcileDuration := time.Since(startTime)
|
||||
ctrl.metricsServer.IncReconcile(origApp, reconcileDuration)
|
||||
logCtx := log.WithFields(log.Fields{"application": origApp.Name, "time_ms": reconcileDuration.Seconds() * 1e3, "level": comparisonLevel})
|
||||
logCtx := log.WithFields(log.Fields{
|
||||
"application": origApp.Name,
|
||||
"time_ms": reconcileDuration.Seconds() * 1e3,
|
||||
"level": comparisonLevel,
|
||||
"dest-server": origApp.Spec.Destination.Server,
|
||||
"dest-namespace": origApp.Spec.Destination.Namespace,
|
||||
})
|
||||
logCtx.Info("Reconciliation completed")
|
||||
}()
|
||||
|
||||
@@ -683,7 +714,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
}
|
||||
|
||||
var localManifests []string
|
||||
if opState := app.Status.OperationState; opState != nil {
|
||||
if opState := app.Status.OperationState; opState != nil && opState.Operation.Sync != nil {
|
||||
localManifests = opState.Operation.Sync.Manifests
|
||||
}
|
||||
|
||||
@@ -692,6 +723,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, compareResult.appSourceType)
|
||||
@@ -710,8 +742,10 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
conditions = append(conditions, *syncErrCond)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -731,21 +765,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 {
|
||||
// user requested app refresh.
|
||||
refreshType = requestedType
|
||||
reason = fmt.Sprintf("%s refresh requested", refreshType)
|
||||
} 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"
|
||||
} 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 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")
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
@@ -83,6 +84,7 @@ func newFakeController(data *fakeData) *ApplicationController {
|
||||
time.Minute,
|
||||
time.Minute,
|
||||
common.DefaultPortArgoCDMetrics,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -524,13 +526,107 @@ func TestNeedRefreshAppStatus(t *testing.T) {
|
||||
assert.Equal(t, argoappv1.RefreshTypeNormal, refreshType)
|
||||
assert.Equal(t, CompareWithLatest, compareWith)
|
||||
|
||||
// execute hard refresh if app has refresh annotation
|
||||
app.Annotations = map[string]string{
|
||||
common.AnnotationKeyRefresh: string(argoappv1.RefreshTypeHard),
|
||||
{
|
||||
// refresh app using the 'latest' level if comparison expired
|
||||
app := app.DeepCopy()
|
||||
ctrl.requestAppRefresh(app.Name, CompareWithRecent)
|
||||
reconciledAt := metav1.NewTime(time.Now().UTC().Add(-1 * time.Hour))
|
||||
app.Status.ReconciledAt = &reconciledAt
|
||||
needRefresh, refreshType, compareWith = ctrl.needRefreshAppStatus(app, 1*time.Minute)
|
||||
assert.True(t, needRefresh)
|
||||
assert.Equal(t, argoappv1.RefreshTypeNormal, refreshType)
|
||||
assert.Equal(t, CompareWithLatest, compareWith)
|
||||
}
|
||||
needRefresh, refreshType, compareWith = ctrl.needRefreshAppStatus(app, 1*time.Hour)
|
||||
assert.True(t, needRefresh)
|
||||
assert.Equal(t, argoappv1.RefreshTypeHard, refreshType)
|
||||
assert.Equal(t, CompareWithLatest, compareWith)
|
||||
|
||||
{
|
||||
app := app.DeepCopy()
|
||||
// execute hard refresh if app has refresh annotation
|
||||
reconciledAt := metav1.NewTime(time.Now().UTC().Add(-1 * time.Hour))
|
||||
app.Status.ReconciledAt = &reconciledAt
|
||||
app.Annotations = map[string]string{
|
||||
common.AnnotationKeyRefresh: string(argoappv1.RefreshTypeHard),
|
||||
}
|
||||
needRefresh, refreshType, compareWith = ctrl.needRefreshAppStatus(app, 1*time.Hour)
|
||||
assert.True(t, needRefresh)
|
||||
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 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)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ import (
|
||||
|
||||
type MetricsServer struct {
|
||||
*http.Server
|
||||
syncCounter *prometheus.CounterVec
|
||||
k8sRequestCounter *prometheus.CounterVec
|
||||
reconcileHistogram *prometheus.HistogramVec
|
||||
syncCounter *prometheus.CounterVec
|
||||
k8sRequestCounter *prometheus.CounterVec
|
||||
kubectlExecCounter *prometheus.CounterVec
|
||||
kubectlExecPendingGauge *prometheus.GaugeVec
|
||||
reconcileHistogram *prometheus.HistogramVec
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -76,6 +78,16 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, health
|
||||
append(descAppDefaultLabels, "phase"),
|
||||
)
|
||||
appRegistry.MustRegister(syncCounter)
|
||||
kubectlExecCounter := prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "argocd_kubectl_exec_total",
|
||||
Help: "Number of kubectl executions",
|
||||
}, []string{"command"})
|
||||
appRegistry.MustRegister(kubectlExecCounter)
|
||||
kubectlExecPendingGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "argocd_kubectl_exec_pending",
|
||||
Help: "Number of pending kubectl executions",
|
||||
}, []string{"command"})
|
||||
appRegistry.MustRegister(kubectlExecPendingGauge)
|
||||
k8sRequestCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "argocd_app_k8s_request_total",
|
||||
@@ -102,9 +114,11 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, health
|
||||
Addr: addr,
|
||||
Handler: mux,
|
||||
},
|
||||
syncCounter: syncCounter,
|
||||
k8sRequestCounter: k8sRequestCounter,
|
||||
reconcileHistogram: reconcileHistogram,
|
||||
syncCounter: syncCounter,
|
||||
k8sRequestCounter: k8sRequestCounter,
|
||||
reconcileHistogram: reconcileHistogram,
|
||||
kubectlExecCounter: kubectlExecCounter,
|
||||
kubectlExecPendingGauge: kubectlExecPendingGauge,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +140,18 @@ func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.D
|
||||
m.reconcileHistogram.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject()).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
func (m *MetricsServer) IncKubectlExec(command string) {
|
||||
m.kubectlExecCounter.WithLabelValues(command).Inc()
|
||||
}
|
||||
|
||||
func (m *MetricsServer) IncKubectlExecPending(command string) {
|
||||
m.kubectlExecPendingGauge.WithLabelValues(command).Inc()
|
||||
}
|
||||
|
||||
func (m *MetricsServer) DecKubectlExecPending(command string) {
|
||||
m.kubectlExecPendingGauge.WithLabelValues(command).Dec()
|
||||
}
|
||||
|
||||
type appCollector struct {
|
||||
store applister.ApplicationLister
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ type AppStateManager interface {
|
||||
}
|
||||
|
||||
type comparisonResult struct {
|
||||
reconciledAt metav1.Time
|
||||
syncStatus *v1alpha1.SyncStatus
|
||||
healthStatus *v1alpha1.HealthStatus
|
||||
resources []v1alpha1.ResourceStatus
|
||||
@@ -255,13 +254,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,
|
||||
@@ -415,6 +412,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,
|
||||
@@ -452,7 +453,6 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, revision st
|
||||
}
|
||||
|
||||
compRes := comparisonResult{
|
||||
reconciledAt: reconciledAt,
|
||||
syncStatus: &syncStatus,
|
||||
healthStatus: healthStatus,
|
||||
resources: resourceSummaries,
|
||||
|
||||
@@ -11,6 +11,10 @@ func CheckError(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func FailOnErr(_ interface{}, err error) {
|
||||
// panics if there is an error.
|
||||
// This returns the first value so you can use it if you cast it:
|
||||
// text := FailOrErr(Foo)).(string)
|
||||
func FailOnErr(v interface{}, err error) interface{} {
|
||||
CheckError(err)
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ bases:
|
||||
images:
|
||||
- name: argoproj/argocd
|
||||
newName: argoproj/argocd
|
||||
newTag: v1.2.0
|
||||
newTag: v1.2.5
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.2.0
|
||||
newTag: v1.2.5
|
||||
|
||||
@@ -21,6 +21,7 @@ spec:
|
||||
image: argoproj/argocd:latest
|
||||
imagePullPolicy: Always
|
||||
command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
|
||||
@@ -1020,6 +1020,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:
|
||||
@@ -1486,6 +1488,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: v1.2.0
|
||||
newTag: v1.2.5
|
||||
- name: argoproj/argocd-ui
|
||||
newName: argoproj/argocd-ui
|
||||
newTag: v1.2.0
|
||||
newTag: v1.2.5
|
||||
|
||||
@@ -23,6 +23,7 @@ spec:
|
||||
containers:
|
||||
- name: argocd-repo-server
|
||||
command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --sentinel
|
||||
- argocd-redis-ha-announce-0:26379
|
||||
|
||||
@@ -1021,6 +1021,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:
|
||||
@@ -1487,6 +1489,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:
|
||||
@@ -2901,7 +2905,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2955,7 +2959,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -3001,6 +3005,7 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --sentinel
|
||||
- argocd-redis-ha-announce-0:26379
|
||||
@@ -3010,7 +3015,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -3084,7 +3089,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1021,6 +1021,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:
|
||||
@@ -1487,6 +1489,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:
|
||||
@@ -2816,7 +2820,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2870,7 +2874,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2916,6 +2920,7 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --sentinel
|
||||
- argocd-redis-ha-announce-0:26379
|
||||
@@ -2925,7 +2930,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2999,7 +3004,7 @@ spec:
|
||||
- argocd-redis-ha-announce-2:26379
|
||||
- --sentinelmaster
|
||||
- argocd
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1021,6 +1021,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:
|
||||
@@ -1487,6 +1489,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:
|
||||
@@ -2665,7 +2669,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2719,7 +2723,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2779,10 +2783,11 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2833,7 +2838,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1021,6 +1021,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:
|
||||
@@ -1487,6 +1489,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:
|
||||
@@ -2580,7 +2584,7 @@ spec:
|
||||
- "20"
|
||||
- --operation-processors
|
||||
- "10"
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2634,7 +2638,7 @@ spec:
|
||||
- cp
|
||||
- /usr/local/bin/argocd-util
|
||||
- /shared
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
volumeMounts:
|
||||
@@ -2694,10 +2698,11 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- command:
|
||||
- uid_entrypoint.sh
|
||||
- argocd-repo-server
|
||||
- --redis
|
||||
- argocd-redis:6379
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 5
|
||||
@@ -2748,7 +2753,7 @@ spec:
|
||||
- argocd-server
|
||||
- --staticassets
|
||||
- /shared/app
|
||||
image: argoproj/argocd:v1.2.0
|
||||
image: argoproj/argocd:v1.2.5
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
versionpkg "github.com/argoproj/argo-cd/pkg/apiclient/version"
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
grpc_util "github.com/argoproj/argo-cd/util/grpc"
|
||||
"github.com/argoproj/argo-cd/util/localconfig"
|
||||
oidcutil "github.com/argoproj/argo-cd/util/oidc"
|
||||
@@ -387,7 +388,7 @@ func (c *client) newConn() (*grpc.ClientConn, io.Closer, error) {
|
||||
}
|
||||
conn, e := grpc_util.BlockingDial(context.Background(), network, serverAddr, creds, dialOpts...)
|
||||
closers = append(closers, conn)
|
||||
return conn, &inlineCloser{close: func() error {
|
||||
return conn, util.NewCloser(func() error {
|
||||
var firstErr error
|
||||
for i := range closers {
|
||||
err := closers[i].Close()
|
||||
@@ -396,7 +397,7 @@ func (c *client) newConn() (*grpc.ClientConn, io.Closer, error) {
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
}}, e
|
||||
}), e
|
||||
}
|
||||
|
||||
func (c *client) tlsConfig() (*tls.Config, error) {
|
||||
|
||||
@@ -43,14 +43,6 @@ func (noopCodec) String() string {
|
||||
return "bytes"
|
||||
}
|
||||
|
||||
type inlineCloser struct {
|
||||
close func() error
|
||||
}
|
||||
|
||||
func (c *inlineCloser) Close() error {
|
||||
return c.close()
|
||||
}
|
||||
|
||||
func toFrame(msg []byte) []byte {
|
||||
frame := append([]byte{0, 0, 0, 0}, msg...)
|
||||
binary.BigEndian.PutUint32(frame, uint32(len(msg)))
|
||||
@@ -185,7 +177,7 @@ func (c *client) useGRPCProxy() (net.Addr, io.Closer, error) {
|
||||
}
|
||||
c.proxyUsersCount = c.proxyUsersCount + 1
|
||||
|
||||
return c.proxyListener.Addr(), &inlineCloser{close: func() error {
|
||||
return c.proxyListener.Addr(), util.NewCloser(func() error {
|
||||
c.proxyMutex.Lock()
|
||||
defer c.proxyMutex.Unlock()
|
||||
c.proxyUsersCount = c.proxyUsersCount - 1
|
||||
@@ -196,5 +188,5 @@ func (c *client) useGRPCProxy() (net.Addr, io.Closer, error) {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}}, nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
@@ -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_5166844f4e566460, []int{0}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{1}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{2}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{3}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{4}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{5}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{6}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{7}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{8}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{9}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{10}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{11}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{12}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{13}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{14}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{15}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{16}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{17}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{18}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{19}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{20}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{21}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{22}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{23}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{24}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{25}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{26}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{27}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{28}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{29}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{30}
|
||||
return fileDescriptor_generated_438690de2f872566, []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 *HelmRepository) Reset() { *m = HelmRepository{} }
|
||||
func (*HelmRepository) ProtoMessage() {}
|
||||
func (*HelmRepository) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{31}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{31}
|
||||
}
|
||||
func (m *HelmRepository) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -929,7 +929,7 @@ var xxx_messageInfo_HelmRepository proto.InternalMessageInfo
|
||||
func (m *Info) Reset() { *m = Info{} }
|
||||
func (*Info) ProtoMessage() {}
|
||||
func (*Info) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{32}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{32}
|
||||
}
|
||||
func (m *Info) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -957,7 +957,7 @@ var xxx_messageInfo_Info proto.InternalMessageInfo
|
||||
func (m *InfoItem) Reset() { *m = InfoItem{} }
|
||||
func (*InfoItem) ProtoMessage() {}
|
||||
func (*InfoItem) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{33}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{33}
|
||||
}
|
||||
func (m *InfoItem) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -985,7 +985,7 @@ var xxx_messageInfo_InfoItem proto.InternalMessageInfo
|
||||
func (m *JWTToken) Reset() { *m = JWTToken{} }
|
||||
func (*JWTToken) ProtoMessage() {}
|
||||
func (*JWTToken) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{34}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{34}
|
||||
}
|
||||
func (m *JWTToken) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1013,7 +1013,7 @@ var xxx_messageInfo_JWTToken proto.InternalMessageInfo
|
||||
func (m *JsonnetVar) Reset() { *m = JsonnetVar{} }
|
||||
func (*JsonnetVar) ProtoMessage() {}
|
||||
func (*JsonnetVar) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{35}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{35}
|
||||
}
|
||||
func (m *JsonnetVar) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1041,7 +1041,7 @@ var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo
|
||||
func (m *KsonnetParameter) Reset() { *m = KsonnetParameter{} }
|
||||
func (*KsonnetParameter) ProtoMessage() {}
|
||||
func (*KsonnetParameter) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{36}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{36}
|
||||
}
|
||||
func (m *KsonnetParameter) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1069,7 +1069,7 @@ var xxx_messageInfo_KsonnetParameter proto.InternalMessageInfo
|
||||
func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} }
|
||||
func (*KustomizeOptions) ProtoMessage() {}
|
||||
func (*KustomizeOptions) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{37}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{37}
|
||||
}
|
||||
func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1097,7 +1097,7 @@ var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo
|
||||
func (m *Operation) Reset() { *m = Operation{} }
|
||||
func (*Operation) ProtoMessage() {}
|
||||
func (*Operation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{38}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{38}
|
||||
}
|
||||
func (m *Operation) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1125,7 +1125,7 @@ var xxx_messageInfo_Operation proto.InternalMessageInfo
|
||||
func (m *OperationState) Reset() { *m = OperationState{} }
|
||||
func (*OperationState) ProtoMessage() {}
|
||||
func (*OperationState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{39}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{39}
|
||||
}
|
||||
func (m *OperationState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -1153,7 +1153,7 @@ var xxx_messageInfo_OperationState proto.InternalMessageInfo
|
||||
func (m *ProjectRole) Reset() { *m = ProjectRole{} }
|
||||
func (*ProjectRole) ProtoMessage() {}
|
||||
func (*ProjectRole) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{40}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{41}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{42}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{43}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{44}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{45}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{46}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{47}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{48}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{49}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{50}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{51}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{52}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{53}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{54}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{55}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{56}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{57}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{58}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{59}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{60}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{61}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{62}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{63}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{64}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{65}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{66}
|
||||
return fileDescriptor_generated_438690de2f872566, []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_5166844f4e566460, []int{67}
|
||||
return fileDescriptor_generated_438690de2f872566, []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 *TLSClientConfig) Reset() { *m = TLSClientConfig{} }
|
||||
func (*TLSClientConfig) ProtoMessage() {}
|
||||
func (*TLSClientConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_generated_5166844f4e566460, []int{68}
|
||||
return fileDescriptor_generated_438690de2f872566, []int{68}
|
||||
}
|
||||
func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -18109,10 +18109,10 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_generated_5166844f4e566460)
|
||||
proto.RegisterFile("github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_generated_438690de2f872566)
|
||||
}
|
||||
|
||||
var fileDescriptor_generated_5166844f4e566460 = []byte{
|
||||
var fileDescriptor_generated_438690de2f872566 = []byte{
|
||||
// 4429 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4b, 0x8c, 0x1c, 0xc7,
|
||||
0x75, 0xec, 0xf9, 0xef, 0xdb, 0x0f, 0xb9, 0x25, 0x51, 0x1e, 0x2f, 0x24, 0x2e, 0xd1, 0x44, 0x6c,
|
||||
|
||||
@@ -224,10 +224,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;
|
||||
|
||||
@@ -861,7 +861,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": {
|
||||
@@ -871,7 +872,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": {
|
||||
|
||||
@@ -288,16 +288,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.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
actionTests:
|
||||
- action: restart
|
||||
inputPath: testdata/daemonset.yaml
|
||||
expectedOutputPath: testdata/daemonset-restarted.yaml
|
||||
@@ -0,0 +1,3 @@
|
||||
actions = {}
|
||||
actions["restart"] = {}
|
||||
return actions
|
||||
@@ -0,0 +1,9 @@
|
||||
local os = require("os")
|
||||
if obj.spec.template.metadata == nil then
|
||||
obj.spec.template.metadata = {}
|
||||
end
|
||||
if obj.spec.template.metadata.annotations == nil then
|
||||
obj.spec.template.metadata.annotations = {}
|
||||
end
|
||||
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
50
resource_customizations/apps/DaemonSet/actions/testdata/daemonset-restarted.yaml
vendored
Normal file
50
resource_customizations/apps/DaemonSet/actions/testdata/daemonset-restarted.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
annotations:
|
||||
deprecated.daemonset.template.generation: "3"
|
||||
creationTimestamp: "2019-09-13T08:52:50Z"
|
||||
generation: 3
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: daemonset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7472656"
|
||||
selfLink: /apis/apps/v1/namespaces/statefulset/daemonsets/daemonset
|
||||
uid: de04d075-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
name: daemonset
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "0001-01-01T00:00:00Z"
|
||||
labels:
|
||||
name: daemonset
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
status:
|
||||
currentNumberScheduled: 4
|
||||
desiredNumberScheduled: 4
|
||||
numberAvailable: 4
|
||||
numberMisscheduled: 0
|
||||
numberReady: 4
|
||||
observedGeneration: 3
|
||||
updatedNumberScheduled: 4
|
||||
48
resource_customizations/apps/DaemonSet/actions/testdata/daemonset.yaml
vendored
Normal file
48
resource_customizations/apps/DaemonSet/actions/testdata/daemonset.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
annotations:
|
||||
deprecated.daemonset.template.generation: "3"
|
||||
creationTimestamp: "2019-09-13T08:52:50Z"
|
||||
generation: 3
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: daemonset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7472656"
|
||||
selfLink: /apis/apps/v1/namespaces/statefulset/daemonsets/daemonset
|
||||
uid: de04d075-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
name: daemonset
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: daemonset
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
status:
|
||||
currentNumberScheduled: 4
|
||||
desiredNumberScheduled: 4
|
||||
numberAvailable: 4
|
||||
numberMisscheduled: 0
|
||||
numberReady: 4
|
||||
observedGeneration: 3
|
||||
updatedNumberScheduled: 4
|
||||
@@ -0,0 +1,4 @@
|
||||
actionTests:
|
||||
- action: restart
|
||||
inputPath: testdata/deployment.yaml
|
||||
expectedOutputPath: testdata/deployment-restarted.yaml
|
||||
@@ -0,0 +1,3 @@
|
||||
actions = {}
|
||||
actions["restart"] = {}
|
||||
return actions
|
||||
@@ -0,0 +1,9 @@
|
||||
local os = require("os")
|
||||
if obj.spec.template.metadata == nil then
|
||||
obj.spec.template.metadata = {}
|
||||
end
|
||||
if obj.spec.template.metadata.annotations == nil then
|
||||
obj.spec.template.metadata.annotations = {}
|
||||
end
|
||||
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
63
resource_customizations/apps/Deployment/actions/testdata/deployment-restarted.yaml
vendored
Normal file
63
resource_customizations/apps/Deployment/actions/testdata/deployment-restarted.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
creationTimestamp: "2019-09-12T01:33:53Z"
|
||||
generation: 1
|
||||
name: nginx-deploy
|
||||
namespace: default
|
||||
resourceVersion: "6897444"
|
||||
selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deploy
|
||||
uid: 61689d6d-d4fd-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "0001-01-01T00:00:00Z"
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
status:
|
||||
availableReplicas: 2
|
||||
conditions:
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:33:53Z"
|
||||
message: Deployment does not have minimum availability.
|
||||
reason: MinimumReplicasUnavailable
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:34:05Z"
|
||||
message: ReplicaSet "nginx-deploy-9cb4784bd" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 2
|
||||
replicas: 3
|
||||
unavailableReplicas: 1
|
||||
updatedReplicas: 3
|
||||
61
resource_customizations/apps/Deployment/actions/testdata/deployment.yaml
vendored
Normal file
61
resource_customizations/apps/Deployment/actions/testdata/deployment.yaml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
creationTimestamp: "2019-09-12T01:33:53Z"
|
||||
generation: 1
|
||||
name: nginx-deploy
|
||||
namespace: default
|
||||
resourceVersion: "6897444"
|
||||
selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deploy
|
||||
uid: 61689d6d-d4fd-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
status:
|
||||
availableReplicas: 2
|
||||
conditions:
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:33:53Z"
|
||||
message: Deployment does not have minimum availability.
|
||||
reason: MinimumReplicasUnavailable
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:34:05Z"
|
||||
message: ReplicaSet "nginx-deploy-9cb4784bd" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 2
|
||||
replicas: 3
|
||||
unavailableReplicas: 1
|
||||
updatedReplicas: 3
|
||||
@@ -0,0 +1,4 @@
|
||||
actionTests:
|
||||
- action: restart
|
||||
inputPath: testdata/statefulset.yaml
|
||||
expectedOutputPath: testdata/statefulset-restarted.yaml
|
||||
@@ -0,0 +1,3 @@
|
||||
actions = {}
|
||||
actions["restart"] = {}
|
||||
return actions
|
||||
@@ -0,0 +1,9 @@
|
||||
local os = require("os")
|
||||
if obj.spec.template.metadata == nil then
|
||||
obj.spec.template.metadata = {}
|
||||
end
|
||||
if obj.spec.template.metadata.annotations == nil then
|
||||
obj.spec.template.metadata.annotations = {}
|
||||
end
|
||||
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
52
resource_customizations/apps/StatefulSet/actions/testdata/statefulset-restarted.yaml
vendored
Normal file
52
resource_customizations/apps/StatefulSet/actions/testdata/statefulset-restarted.yaml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
creationTimestamp: "2019-09-13T08:52:54Z"
|
||||
generation: 2
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: statefulset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7471813"
|
||||
selfLink: /apis/apps/v1/namespaces/statefulset/statefulsets/statefulset
|
||||
uid: dfe8fadf-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
podManagementPolicy: OrderedReady
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: statefulset
|
||||
serviceName: statefulset
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: statefulset
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "0001-01-01T00:00:00Z"
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
partition: 0
|
||||
type: RollingUpdate
|
||||
status:
|
||||
collisionCount: 0
|
||||
currentReplicas: 3
|
||||
currentRevision: statefulset-85b7f767c6
|
||||
observedGeneration: 2
|
||||
readyReplicas: 3
|
||||
replicas: 3
|
||||
updateRevision: statefulset-85b7f767c6
|
||||
updatedReplicas: 3
|
||||
50
resource_customizations/apps/StatefulSet/actions/testdata/statefulset.yaml
vendored
Normal file
50
resource_customizations/apps/StatefulSet/actions/testdata/statefulset.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
creationTimestamp: "2019-09-13T08:52:54Z"
|
||||
generation: 2
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: statefulset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7471813"
|
||||
selfLink: /apis/apps/v1/namespaces/statefulset/statefulsets/statefulset
|
||||
uid: dfe8fadf-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
podManagementPolicy: OrderedReady
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: statefulset
|
||||
serviceName: statefulset
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: statefulset
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
partition: 0
|
||||
type: RollingUpdate
|
||||
status:
|
||||
collisionCount: 0
|
||||
currentReplicas: 3
|
||||
currentRevision: statefulset-85b7f767c6
|
||||
observedGeneration: 2
|
||||
readyReplicas: 3
|
||||
replicas: 3
|
||||
updateRevision: statefulset-85b7f767c6
|
||||
updatedReplicas: 3
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/bouk/monkey"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yudai/gojsondiff/formatter"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/argoproj/argo-cd/errors"
|
||||
appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/diff"
|
||||
"github.com/argoproj/argo-cd/util/lua"
|
||||
@@ -47,14 +47,14 @@ func TestLuaResourceActionsScript(t *testing.T) {
|
||||
if !strings.Contains(path, "action_test.yaml") {
|
||||
return nil
|
||||
}
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
dir := filepath.Dir(path)
|
||||
//TODO: Change to path
|
||||
yamlBytes, err := ioutil.ReadFile(dir + "/action_test.yaml")
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
var resourceTest ActionTestStructure
|
||||
err = yaml.Unmarshal(yamlBytes, &resourceTest)
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
for i := range resourceTest.DiscoveryTests {
|
||||
test := resourceTest.DiscoveryTests[i]
|
||||
testName := fmt.Sprintf("discovery/%s", test.InputPath)
|
||||
@@ -64,9 +64,9 @@ func TestLuaResourceActionsScript(t *testing.T) {
|
||||
}
|
||||
obj := getObj(filepath.Join(dir, test.InputPath))
|
||||
discoveryLua, err := vm.GetResourceActionDiscovery(obj)
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
result, err := vm.ExecuteResourceActionDiscovery(obj, discoveryLua)
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.Result, result)
|
||||
})
|
||||
}
|
||||
@@ -75,20 +75,28 @@ func TestLuaResourceActionsScript(t *testing.T) {
|
||||
testName := fmt.Sprintf("actions/%s/%s", test.Action, test.InputPath)
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
vm := lua.VM{
|
||||
UseOpenLibs: true,
|
||||
// Uncomment the following line if you need to use lua libraries debugging
|
||||
// purposes. Otherwise, leave this false to ensure tests reflect the same
|
||||
// privileges that API server has.
|
||||
//UseOpenLibs: true,
|
||||
}
|
||||
obj := getObj(filepath.Join(dir, test.InputPath))
|
||||
action, err := vm.GetResourceAction(obj, test.Action)
|
||||
errors.CheckError(err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// freeze time so that lua test has predictable time output (will return 0001-01-01T00:00:00Z)
|
||||
patch := monkey.Patch(time.Now, func() time.Time { return time.Time{} })
|
||||
result, err := vm.ExecuteResourceAction(obj, action.ActionLua)
|
||||
errors.CheckError(err)
|
||||
patch.Unpatch()
|
||||
|
||||
assert.NoError(t, err)
|
||||
expectedObj := getObj(filepath.Join(dir, test.ExpectedOutputPath))
|
||||
// Ideally, we would use a assert.Equal to detect the difference, but the Lua VM returns a object with float64 instead of the originial int32. As a result, the assert.Equal is never true despite that the change has been applied.
|
||||
// Ideally, we would use a assert.Equal to detect the difference, but the Lua VM returns a object with float64 instead of the original int32. As a result, the assert.Equal is never true despite that the change has been applied.
|
||||
diffResult := diff.Diff(expectedObj, result, testNormalizer{})
|
||||
if diffResult.Modified {
|
||||
output, err := diffResult.ASCIIFormat(expectedObj, formatter.AsciiFormatterConfig{})
|
||||
errors.CheckError(err)
|
||||
assert.Fail(t, "Output does not match input:", output)
|
||||
t.Error("Output does not match input:")
|
||||
err = diff.PrintDiff(test.Action, expectedObj, result)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
actionTests:
|
||||
- action: restart
|
||||
inputPath: testdata/daemonset.yaml
|
||||
expectedOutputPath: testdata/daemonset-restarted.yaml
|
||||
@@ -0,0 +1,3 @@
|
||||
actions = {}
|
||||
actions["restart"] = {}
|
||||
return actions
|
||||
@@ -0,0 +1,9 @@
|
||||
local os = require("os")
|
||||
if obj.spec.template.metadata == nil then
|
||||
obj.spec.template.metadata = {}
|
||||
end
|
||||
if obj.spec.template.metadata.annotations == nil then
|
||||
obj.spec.template.metadata.annotations = {}
|
||||
end
|
||||
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
47
resource_customizations/extensions/DaemonSet/actions/testdata/daemonset-restarted.yaml
vendored
Normal file
47
resource_customizations/extensions/DaemonSet/actions/testdata/daemonset-restarted.yaml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
annotations:
|
||||
creationTimestamp: "2019-09-13T08:52:50Z"
|
||||
generation: 2
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: extensions-daemonset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7471358"
|
||||
selfLink: /apis/extensions/v1beta1/namespaces/statefulset/daemonsets/extensions-daemonset
|
||||
uid: de09964a-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
name: extensions-daemonset
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "0001-01-01T00:00:00Z"
|
||||
labels:
|
||||
name: extensions-daemonset
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
templateGeneration: 2
|
||||
updateStrategy:
|
||||
type: OnDelete
|
||||
status:
|
||||
currentNumberScheduled: 4
|
||||
desiredNumberScheduled: 4
|
||||
numberAvailable: 4
|
||||
numberMisscheduled: 0
|
||||
numberReady: 4
|
||||
observedGeneration: 2
|
||||
45
resource_customizations/extensions/DaemonSet/actions/testdata/daemonset.yaml
vendored
Normal file
45
resource_customizations/extensions/DaemonSet/actions/testdata/daemonset.yaml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
annotations:
|
||||
creationTimestamp: "2019-09-13T08:52:50Z"
|
||||
generation: 2
|
||||
labels:
|
||||
app.kubernetes.io/instance: extensions
|
||||
name: extensions-daemonset
|
||||
namespace: statefulset
|
||||
resourceVersion: "7471358"
|
||||
selfLink: /apis/extensions/v1beta1/namespaces/statefulset/daemonsets/extensions-daemonset
|
||||
uid: de09964a-d603-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
name: extensions-daemonset
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: extensions-daemonset
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
templateGeneration: 2
|
||||
updateStrategy:
|
||||
type: OnDelete
|
||||
status:
|
||||
currentNumberScheduled: 4
|
||||
desiredNumberScheduled: 4
|
||||
numberAvailable: 4
|
||||
numberMisscheduled: 0
|
||||
numberReady: 4
|
||||
observedGeneration: 2
|
||||
@@ -0,0 +1,4 @@
|
||||
actionTests:
|
||||
- action: restart
|
||||
inputPath: testdata/deployment.yaml
|
||||
expectedOutputPath: testdata/deployment-restarted.yaml
|
||||
@@ -0,0 +1,3 @@
|
||||
actions = {}
|
||||
actions["restart"] = {}
|
||||
return actions
|
||||
@@ -0,0 +1,9 @@
|
||||
local os = require("os")
|
||||
if obj.spec.template.metadata == nil then
|
||||
obj.spec.template.metadata = {}
|
||||
end
|
||||
if obj.spec.template.metadata.annotations == nil then
|
||||
obj.spec.template.metadata.annotations = {}
|
||||
end
|
||||
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%XZ")
|
||||
return obj
|
||||
63
resource_customizations/extensions/Deployment/actions/testdata/deployment-restarted.yaml
vendored
Normal file
63
resource_customizations/extensions/Deployment/actions/testdata/deployment-restarted.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
creationTimestamp: "2019-09-12T01:33:53Z"
|
||||
generation: 1
|
||||
name: nginx-deploy
|
||||
namespace: default
|
||||
resourceVersion: "6897444"
|
||||
selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deploy
|
||||
uid: 61689d6d-d4fd-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "0001-01-01T00:00:00Z"
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
status:
|
||||
availableReplicas: 2
|
||||
conditions:
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:33:53Z"
|
||||
message: Deployment does not have minimum availability.
|
||||
reason: MinimumReplicasUnavailable
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:34:05Z"
|
||||
message: ReplicaSet "nginx-deploy-9cb4784bd" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 2
|
||||
replicas: 3
|
||||
unavailableReplicas: 1
|
||||
updatedReplicas: 3
|
||||
61
resource_customizations/extensions/Deployment/actions/testdata/deployment.yaml
vendored
Normal file
61
resource_customizations/extensions/Deployment/actions/testdata/deployment.yaml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
creationTimestamp: "2019-09-12T01:33:53Z"
|
||||
generation: 1
|
||||
name: nginx-deploy
|
||||
namespace: default
|
||||
resourceVersion: "6897444"
|
||||
selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deploy
|
||||
uid: 61689d6d-d4fd-11e9-9e69-42010aa8005f
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
status:
|
||||
availableReplicas: 2
|
||||
conditions:
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:33:53Z"
|
||||
message: Deployment does not have minimum availability.
|
||||
reason: MinimumReplicasUnavailable
|
||||
status: "False"
|
||||
type: Available
|
||||
- lastTransitionTime: "2019-09-12T01:33:53Z"
|
||||
lastUpdateTime: "2019-09-12T01:34:05Z"
|
||||
message: ReplicaSet "nginx-deploy-9cb4784bd" is progressing.
|
||||
reason: ReplicaSetUpdated
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 2
|
||||
replicas: 3
|
||||
unavailableReplicas: 1
|
||||
updatedReplicas: 3
|
||||
@@ -121,6 +121,9 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
badge = replaceFirstGroupSubMatch(rightText1Pattern, badge, rightText)
|
||||
badge = replaceFirstGroupSubMatch(rightText2Pattern, badge, rightText)
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
|
||||
//Ask cache's to not cache the contents in order prevent the badge from becoming stale
|
||||
w.Header().Set("Cache-Control", "private, no-store")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte(badge))
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ func TestHandlerFeatureIsEnabled(t *testing.T) {
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, "private, no-store", rr.Header().Get("Cache-Control"))
|
||||
|
||||
response := rr.Body.String()
|
||||
assert.Equal(t, success, leftPathColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, success, rightPathColorPattern.FindStringSubmatch(response)[1])
|
||||
@@ -74,6 +76,8 @@ func TestHandlerFeatureIsDisabled(t *testing.T) {
|
||||
rr := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, "private, no-store", rr.Header().Get("Cache-Control"))
|
||||
|
||||
response := rr.Body.String()
|
||||
assert.Equal(t, unknown, leftPathColorPattern.FindStringSubmatch(response)[1])
|
||||
assert.Equal(t, unknown, rightPathColorPattern.FindStringSubmatch(response)[1])
|
||||
|
||||
@@ -419,6 +419,7 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
|
||||
"/account.AccountService/UpdatePassword": true,
|
||||
"/repository.RepositoryService/Create": true,
|
||||
"/repository.RepositoryService/Update": true,
|
||||
"/repository.RepositoryService/ValidateAccess": true,
|
||||
"/application.ApplicationService/PatchResource": true,
|
||||
}
|
||||
// NOTE: notice we do not configure the gRPC server here with TLS (e.g. grpc.Creds(creds))
|
||||
|
||||
@@ -17,12 +17,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/errors"
|
||||
. "github.com/argoproj/argo-cd/errors"
|
||||
applicationpkg "github.com/argoproj/argo-cd/pkg/apiclient/application"
|
||||
repositorypkg "github.com/argoproj/argo-cd/pkg/apiclient/repository"
|
||||
. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/test/e2e/fixture"
|
||||
. "github.com/argoproj/argo-cd/test/e2e/fixture"
|
||||
. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
. "github.com/argoproj/argo-cd/util/argo"
|
||||
@@ -44,18 +44,18 @@ func TestAppCreation(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
And(func(app *Application) {
|
||||
assert.Equal(t, fixture.Name(), app.Name)
|
||||
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.Source.RepoURL)
|
||||
assert.Equal(t, Name(), app.Name)
|
||||
assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL)
|
||||
assert.Equal(t, guestbookPath, app.Spec.Source.Path)
|
||||
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
|
||||
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
|
||||
assert.Equal(t, common.KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
|
||||
}).
|
||||
Expect(Event(EventReasonResourceCreated, "create")).
|
||||
And(func(_ *Application) {
|
||||
// app should be listed
|
||||
output, err := fixture.RunCli("app", "list")
|
||||
output, err := RunCli("app", "list")
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, output, fixture.Name())
|
||||
assert.Contains(t, output, Name())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ func TestAppDeletion(t *testing.T) {
|
||||
Expect(DoesNotExist()).
|
||||
Expect(Event(EventReasonResourceDeleted, "delete"))
|
||||
|
||||
output, err := fixture.RunCli("app", "list")
|
||||
output, err := RunCli("app", "list")
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, output, fixture.Name())
|
||||
assert.NotContains(t, output, Name())
|
||||
}
|
||||
|
||||
func TestTrackAppStateAndSyncApp(t *testing.T) {
|
||||
@@ -95,10 +95,10 @@ func TestTrackAppStateAndSyncApp(t *testing.T) {
|
||||
Create().
|
||||
Sync().
|
||||
Then().
|
||||
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui OutOfSync Missing", fixture.DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("Service %s guestbook-ui OutOfSync Missing", fixture.DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced Healthy service/guestbook-ui created", fixture.DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced Healthy deployment.apps/guestbook-ui created", fixture.DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui OutOfSync Missing", DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("Service %s guestbook-ui OutOfSync Missing", DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced Healthy service/guestbook-ui created", DeploymentNamespace()))).
|
||||
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced Healthy deployment.apps/guestbook-ui created", DeploymentNamespace()))).
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(Event(EventReasonResourceUpdated, "sync")).
|
||||
@@ -134,11 +134,11 @@ func TestAppRollbackSuccessful(t *testing.T) {
|
||||
patch, _, err := diff.CreateTwoWayMergePatch(app, appWithHistory, &Application{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
app, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Patch(app.Name, types.MergePatchType, patch)
|
||||
app, err = AppClientset.ArgoprojV1alpha1().Applications(ArgoCDNamespace).Patch(app.Name, types.MergePatchType, patch)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// sync app and make sure it reaches InSync state
|
||||
_, err = fixture.RunCli("app", "rollback", app.Name, "1")
|
||||
_, err = RunCli("app", "rollback", app.Name, "1")
|
||||
assert.NoError(t, err)
|
||||
|
||||
}).
|
||||
@@ -184,7 +184,7 @@ func TestManipulateApplicationResources(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
manifests, err := fixture.RunCli("app", "manifests", app.Name, "--source", "live")
|
||||
manifests, err := RunCli("app", "manifests", app.Name, "--source", "live")
|
||||
assert.NoError(t, err)
|
||||
resources, err := kube.SplitYAML(manifests)
|
||||
assert.NoError(t, err)
|
||||
@@ -201,7 +201,7 @@ func TestManipulateApplicationResources(t *testing.T) {
|
||||
|
||||
deployment := resources[index]
|
||||
|
||||
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
|
||||
closer, client, err := ArgoCDClientset.NewApplicationClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
@@ -243,7 +243,7 @@ func assetSecretDataHidden(t *testing.T, manifest string) {
|
||||
}
|
||||
|
||||
func TestAppWithSecrets(t *testing.T) {
|
||||
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
|
||||
closer, client, err := ArgoCDClientset.NewApplicationClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
@@ -255,49 +255,45 @@ func TestAppWithSecrets(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
res, err := client.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{
|
||||
res := FailOnErr(client.GetResource(context.Background(), &applicationpkg.ApplicationResourceRequest{
|
||||
Namespace: app.Spec.Destination.Namespace,
|
||||
Kind: kube.SecretKind,
|
||||
Group: "",
|
||||
Name: &app.Name,
|
||||
Version: "v1",
|
||||
ResourceName: "test-secret",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
})).(*applicationpkg.ApplicationResourceResponse)
|
||||
assetSecretDataHidden(t, res.Manifest)
|
||||
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name)
|
||||
assert.NoError(t, err)
|
||||
diffOutput := FailOnErr(RunCli("app", "diff", app.Name)).(string)
|
||||
assert.Empty(t, diffOutput)
|
||||
|
||||
// patch secret and make sure app is out of sync and diff detects the change
|
||||
_, err = fixture.KubeClientset.CoreV1().Secrets(fixture.DeploymentNamespace()).Patch(
|
||||
"test-secret", types.JSONPatchType, []byte(`[{"op": "remove", "path": "/data/username"}]`))
|
||||
assert.NoError(t, err)
|
||||
FailOnErr(KubeClientset.CoreV1().Secrets(DeploymentNamespace()).Patch(
|
||||
"test-secret", types.JSONPatchType, []byte(`[
|
||||
{"op": "remove", "path": "/data/username"},
|
||||
{"op": "add", "path": "/stringData", "value": {"password": "foo"}}
|
||||
]`)))
|
||||
}).
|
||||
When().
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
And(func(app *Application) {
|
||||
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name)
|
||||
diffOutput, err := RunCli("app", "diff", app.Name)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, diffOutput, "username: +++++++++")
|
||||
assert.Contains(t, diffOutput, "username: ++++++++")
|
||||
assert.Contains(t, diffOutput, "password: ++++++++++++")
|
||||
|
||||
// local diff should ignore secrets
|
||||
diffOutput, err = fixture.RunCli("app", "diff", app.Name, "--local", "testdata/secrets")
|
||||
assert.NoError(t, err)
|
||||
diffOutput = FailOnErr(RunCli("app", "diff", app.Name, "--local", "testdata/secrets")).(string)
|
||||
assert.Empty(t, diffOutput)
|
||||
|
||||
// ignore missing field and make sure diff shows no difference
|
||||
app.Spec.IgnoreDifferences = []ResourceIgnoreDifferences{{
|
||||
Kind: kube.SecretKind, JSONPointers: []string{"/data/username"},
|
||||
Kind: kube.SecretKind, JSONPointers: []string{"/data/username", "/data/password"},
|
||||
}}
|
||||
_, err = client.UpdateSpec(context.Background(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, Spec: app.Spec})
|
||||
|
||||
assert.NoError(t, err)
|
||||
FailOnErr(client.UpdateSpec(context.Background(), &applicationpkg.ApplicationUpdateSpecRequest{Name: &app.Name, Spec: app.Spec}))
|
||||
}).
|
||||
When().
|
||||
Refresh(RefreshTypeNormal).
|
||||
@@ -305,8 +301,7 @@ func TestAppWithSecrets(t *testing.T) {
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name)
|
||||
assert.NoError(t, err)
|
||||
diffOutput := FailOnErr(RunCli("app", "diff", app.Name)).(string)
|
||||
assert.Empty(t, diffOutput)
|
||||
})
|
||||
}
|
||||
@@ -321,7 +316,7 @@ func TestResourceDiffing(t *testing.T) {
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
// Patch deployment
|
||||
_, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(
|
||||
_, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Patch(
|
||||
"guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "test" }]`))
|
||||
assert.NoError(t, err)
|
||||
}).
|
||||
@@ -330,9 +325,9 @@ func TestResourceDiffing(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
And(func(app *Application) {
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata/guestbook")
|
||||
diffOutput, err := RunCli("app", "diff", app.Name, "--local", "testdata/guestbook")
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", fixture.DeploymentNamespace()))
|
||||
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", DeploymentNamespace()))
|
||||
}).
|
||||
Given().
|
||||
ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {IgnoreDifferences: ` jsonPointers: ["/spec/template/spec/containers/0/image"]`}}).
|
||||
@@ -341,7 +336,7 @@ func TestResourceDiffing(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata/guestbook")
|
||||
diffOutput, err := RunCli("app", "diff", app.Name, "--local", "testdata/guestbook")
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, diffOutput)
|
||||
})
|
||||
@@ -366,7 +361,7 @@ func TestConfigMap(t *testing.T) {
|
||||
func TestFailedConversion(t *testing.T) {
|
||||
|
||||
defer func() {
|
||||
errors.FailOnErr(fixture.Run("", "kubectl", "delete", "apiservice", "v1beta1.metrics.k8s.io"))
|
||||
FailOnErr(Run("", "kubectl", "delete", "apiservice", "v1beta1.metrics.k8s.io"))
|
||||
}()
|
||||
|
||||
testEdgeCasesApplicationResources(t, "failed-conversion", HealthStatusProgressing)
|
||||
@@ -383,7 +378,7 @@ func testEdgeCasesApplicationResources(t *testing.T, appPath string, statusCode
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(statusCode)).
|
||||
And(func(app *Application) {
|
||||
diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", path.Join("testdata", appPath))
|
||||
diffOutput, err := RunCli("app", "diff", app.Name, "--local", path.Join("testdata", appPath))
|
||||
assert.Empty(t, diffOutput)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
@@ -401,7 +396,7 @@ func TestKsonnetApp(t *testing.T) {
|
||||
Sync().
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
closer, client, err := fixture.ArgoCDClientset.NewRepoClient()
|
||||
closer, client, err := ArgoCDClientset.NewRepoClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
@@ -440,7 +435,7 @@ func TestResourceAction(t *testing.T) {
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
|
||||
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
|
||||
closer, client, err := ArgoCDClientset.NewApplicationClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
@@ -449,7 +444,7 @@ func TestResourceAction(t *testing.T) {
|
||||
Group: "apps",
|
||||
Kind: "Deployment",
|
||||
Version: "v1",
|
||||
Namespace: fixture.DeploymentNamespace(),
|
||||
Namespace: DeploymentNamespace(),
|
||||
ResourceName: "guestbook-ui",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
@@ -459,13 +454,13 @@ func TestResourceAction(t *testing.T) {
|
||||
Group: "apps",
|
||||
Kind: "Deployment",
|
||||
Version: "v1",
|
||||
Namespace: fixture.DeploymentNamespace(),
|
||||
Namespace: DeploymentNamespace(),
|
||||
ResourceName: "guestbook-ui",
|
||||
Action: "sample",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get("guestbook-ui", metav1.GetOptions{})
|
||||
deployment, err := KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get("guestbook-ui", metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "test", deployment.Labels["sample"])
|
||||
@@ -480,11 +475,11 @@ func TestSyncResourceByLabel(t *testing.T) {
|
||||
Sync().
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
_, _ = fixture.RunCli("app", "sync", app.Name, "--label", fmt.Sprintf("app.kubernetes.io/instance=%s", app.Name))
|
||||
_, _ = RunCli("app", "sync", app.Name, "--label", fmt.Sprintf("app.kubernetes.io/instance=%s", app.Name))
|
||||
}).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
_, err := fixture.RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist")
|
||||
_, err := RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist")
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "level=fatal")
|
||||
})
|
||||
@@ -498,7 +493,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
Sync().
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
res, _ := fixture.RunCli("app", "manifests", app.Name)
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 80")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.2")
|
||||
}).
|
||||
@@ -509,7 +504,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
res, _ := fixture.RunCli("app", "manifests", app.Name)
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 81")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.3")
|
||||
}).
|
||||
@@ -520,7 +515,7 @@ func TestLocalManifestSync(t *testing.T) {
|
||||
Then().
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
And(func(app *Application) {
|
||||
res, _ := fixture.RunCli("app", "manifests", app.Name)
|
||||
res, _ := RunCli("app", "manifests", app.Name)
|
||||
assert.Contains(t, res, "containerPort: 80")
|
||||
assert.Contains(t, res, "image: gcr.io/heptio-images/ks-guestbook-demo:0.2")
|
||||
})
|
||||
@@ -534,10 +529,10 @@ func TestNoLocalSyncWithAutosyncEnabled(t *testing.T) {
|
||||
Sync().
|
||||
Then().
|
||||
And(func(app *Application) {
|
||||
_, err := fixture.RunCli("app", "set", app.Name, "--sync-policy", "automated")
|
||||
_, err := RunCli("app", "set", app.Name, "--sync-policy", "automated")
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = fixture.RunCli("app", "sync", app.Name, "--local", guestbookPathLocal)
|
||||
_, err = RunCli("app", "sync", app.Name, "--local", guestbookPathLocal)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
@@ -556,44 +551,44 @@ func TestSyncAsync(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPermissions(t *testing.T) {
|
||||
fixture.EnsureCleanState(t)
|
||||
appName := fixture.Name()
|
||||
_, err := fixture.RunCli("proj", "create", "test")
|
||||
EnsureCleanState(t)
|
||||
appName := Name()
|
||||
_, err := RunCli("proj", "create", "test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// make sure app cannot be created without permissions in project
|
||||
_, err = fixture.RunCli("app", "create", appName, "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
|
||||
_, err = RunCli("app", "create", appName, "--repo", RepoURL(RepoURLTypeFile),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", DeploymentNamespace())
|
||||
assert.Error(t, err)
|
||||
sourceError := fmt.Sprintf("application repo %s is not permitted in project 'test'", fixture.RepoURL(fixture.RepoURLTypeFile))
|
||||
destinationError := fmt.Sprintf("application destination {%s %s} is not permitted in project 'test'", common.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace())
|
||||
sourceError := fmt.Sprintf("application repo %s is not permitted in project 'test'", RepoURL(RepoURLTypeFile))
|
||||
destinationError := fmt.Sprintf("application destination {%s %s} is not permitted in project 'test'", common.KubernetesInternalAPIServerAddr, DeploymentNamespace())
|
||||
|
||||
assert.Contains(t, err.Error(), sourceError)
|
||||
assert.Contains(t, err.Error(), destinationError)
|
||||
|
||||
proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get("test", metav1.GetOptions{})
|
||||
proj, err := AppClientset.ArgoprojV1alpha1().AppProjects(ArgoCDNamespace).Get("test", metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
proj.Spec.Destinations = []ApplicationDestination{{Server: "*", Namespace: "*"}}
|
||||
proj.Spec.SourceRepos = []string{"*"}
|
||||
proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(proj)
|
||||
proj, err = AppClientset.ArgoprojV1alpha1().AppProjects(ArgoCDNamespace).Update(proj)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// make sure controller report permissions issues in conditions
|
||||
_, err = fixture.RunCli("app", "create", appName, "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
|
||||
_, err = RunCli("app", "create", appName, "--repo", RepoURL(RepoURLTypeFile),
|
||||
"--path", guestbookPath, "--project", "test", "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", DeploymentNamespace())
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Delete(appName, &metav1.DeleteOptions{})
|
||||
err = AppClientset.ArgoprojV1alpha1().Applications(ArgoCDNamespace).Delete(appName, &metav1.DeleteOptions{})
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
proj.Spec.Destinations = []ApplicationDestination{}
|
||||
proj.Spec.SourceRepos = []string{}
|
||||
_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(proj)
|
||||
_, err = AppClientset.ArgoprojV1alpha1().AppProjects(ArgoCDNamespace).Update(proj)
|
||||
assert.NoError(t, err)
|
||||
time.Sleep(1 * time.Second)
|
||||
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
|
||||
closer, client, err := ArgoCDClientset.NewApplicationClient()
|
||||
assert.NoError(t, err)
|
||||
defer util.Close(closer)
|
||||
|
||||
@@ -697,7 +692,7 @@ func TestSelfManagedApps(t *testing.T) {
|
||||
Given(t).
|
||||
Path("self-managed-app").
|
||||
When().
|
||||
PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, fixture.RepoURL(fixture.RepoURLTypeFile))).
|
||||
PatchFile("resources.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/spec/source/repoURL", "value": "%s"}]`, RepoURL(RepoURLTypeFile))).
|
||||
Create().
|
||||
Sync().
|
||||
Then().
|
||||
@@ -709,7 +704,7 @@ func TestSelfManagedApps(t *testing.T) {
|
||||
|
||||
reconciledCount := 0
|
||||
var lastReconciledAt *metav1.Time
|
||||
for event := range fixture.ArgoCDClientset.WatchApplicationWithRetry(ctx, a.Name) {
|
||||
for event := range ArgoCDClientset.WatchApplicationWithRetry(ctx, a.Name) {
|
||||
reconciledAt := event.Application.Status.ReconciledAt
|
||||
if reconciledAt == nil {
|
||||
reconciledAt = &metav1.Time{}
|
||||
|
||||
@@ -35,7 +35,7 @@ type Context struct {
|
||||
|
||||
func Given(t *testing.T) *Context {
|
||||
fixture.EnsureCleanState(t)
|
||||
return &Context{t: t, destServer: KubernetesInternalAPIServerAddr, repoURLType: fixture.RepoURLTypeFile, name: fixture.Name(), timeout: 5, project: "default", prune: true}
|
||||
return &Context{t: t, destServer: KubernetesInternalAPIServerAddr, repoURLType: fixture.RepoURLTypeFile, name: fixture.Name(), timeout: 10, project: "default", prune: true}
|
||||
}
|
||||
|
||||
func (c *Context) CustomCACertAdded() *Context {
|
||||
|
||||
@@ -29,6 +29,7 @@ func TestPostSyncHookSuccessful(t *testing.T) {
|
||||
// make sure we can run a standard sync hook
|
||||
func testHookSuccessful(t *testing.T, hookType HookType, podHookPhase OperationPhase) {
|
||||
Given(t).
|
||||
Timeout(10).
|
||||
Path("hook").
|
||||
When().
|
||||
PatchFile("hook.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/hook": "%s"}}]`, hookType)).
|
||||
|
||||
@@ -16,7 +16,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {
|
||||
const [form, setForm] = React.useState<FormApi>(null);
|
||||
const isVisible = !!(selectedResource && application);
|
||||
const appResources = (application && selectedResource && application.status && application.status.resources || []).sort(
|
||||
(first, second) => nodeKey(first).localeCompare(nodeKey(second)));
|
||||
(first, second) => nodeKey(first).localeCompare(nodeKey(second))).filter((item) => !item.hook);
|
||||
const syncResIndex = appResources.findIndex((item) => nodeKey(item) === selectedResource);
|
||||
const syncStrategy = {} as models.SyncStrategy;
|
||||
|
||||
@@ -36,7 +36,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {
|
||||
<Form
|
||||
defaultValues={{
|
||||
revision: application.spec.source.targetRevision || 'HEAD',
|
||||
resources: appResources.filter((item) => !item.hook).map((_, i) => i === syncResIndex || syncResIndex === -1),
|
||||
resources: appResources.map((_, i) => i === syncResIndex || syncResIndex === -1),
|
||||
}}
|
||||
validateError={(values) => ({
|
||||
resources: values.resources.every((item: boolean) => !item) && 'Select at least one resource',
|
||||
|
||||
@@ -2,9 +2,12 @@ import {repoUrl, revisionUrl} from './urls';
|
||||
|
||||
function testExample(http: string, ssl: string, revision: string, expectedRepoUrl: string, expectedRevisionUrl: string) {
|
||||
expect(repoUrl(http)).toBe(expectedRepoUrl);
|
||||
expect(repoUrl(ssl)).toBe(expectedRepoUrl);
|
||||
expect(revisionUrl(http, revision)).toBe(expectedRevisionUrl);
|
||||
expect(revisionUrl(ssl, revision)).toBe(expectedRevisionUrl);
|
||||
expect(repoUrl(http)).toBe(expectedRepoUrl);
|
||||
expect(revisionUrl(http, revision)).toBe(expectedRevisionUrl);
|
||||
expect(revisionUrl(ssl, revision)).toBe(expectedRevisionUrl);
|
||||
}
|
||||
|
||||
test('github.com', () => {
|
||||
@@ -16,6 +19,15 @@ test('github.com', () => {
|
||||
'https://github.com/argoproj/argo-cd/commit/024dee09f543ce7bb5af7ca50260504d89dfda94');
|
||||
});
|
||||
|
||||
// for enterprise github installations
|
||||
test('github.my-enterprise.com', () => {
|
||||
testExample(
|
||||
'https://github.my-enterprise.com/my-org/my-repo.git',
|
||||
'git@github.my-enterprise.com:my-org/my-repo.git',
|
||||
'a06f2be80a4da89abb8ced904beab75b3ec6db0e',
|
||||
'https://github.my-enterprise.com/my-org/my-repo',
|
||||
'https://github.my-enterprise.com/my-org/my-repo/commit/a06f2be80a4da89abb8ced904beab75b3ec6db0e');
|
||||
});
|
||||
|
||||
test('gitlab.com', () => {
|
||||
testExample(
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import {GitUrl} from 'git-url-parse';
|
||||
|
||||
const GitUrlParse = require('git-url-parse');
|
||||
|
||||
function supportedSource(source: string): boolean {
|
||||
return ['github.com', 'gitlab.com', 'bitbucket.org'].indexOf(source) >= 0;
|
||||
function supportedSource(parsed: GitUrl): boolean {
|
||||
return parsed.resource.startsWith('github') || ['gitlab.com', 'bitbucket.org'].indexOf(parsed.source) >= 0;
|
||||
}
|
||||
|
||||
function protocol(proto: string): string {
|
||||
@@ -11,7 +13,7 @@ function protocol(proto: string): string {
|
||||
export function repoUrl(url: string): string {
|
||||
const parsed = GitUrlParse(url);
|
||||
|
||||
if (!supportedSource(parsed.source)) {
|
||||
if (!supportedSource(parsed)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -22,7 +24,7 @@ export function revisionUrl(url: string, revision: string): string {
|
||||
|
||||
const parsed = GitUrlParse(url);
|
||||
|
||||
if (!supportedSource(parsed.source)) {
|
||||
if (!supportedSource(parsed)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
12
uid_entrypoint.sh
Executable file
12
uid_entrypoint.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Make sure that if we are using an arbitrary UID that it appears in /etc/passwd,
|
||||
# otherwise this will cause issues with things like cloning with git+ssh
|
||||
# reference: https://access.redhat.com/documentation/en-us/openshift_container_platform/3.11/html/creating_images/creating-images-guidelines#use-uid
|
||||
if ! whoami &> /dev/null; then
|
||||
if [ -w /etc/passwd ]; then
|
||||
echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:/home/argocd:/sbin/nologin" >> /etc/passwd
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
@@ -141,8 +142,12 @@ func (db *db) WatchClusters(ctx context.Context, callback func(*ClusterEvent)) e
|
||||
next.Type = watch.Modified
|
||||
cluster = &localCluster
|
||||
} else if next.Type == watch.Added {
|
||||
localCls = cluster
|
||||
next.Type = watch.Modified
|
||||
if !reflect.DeepEqual(localCls.Config, cluster.Config) {
|
||||
localCls = cluster
|
||||
next.Type = watch.Modified
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
localCls = cluster
|
||||
}
|
||||
|
||||
@@ -4,8 +4,14 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"reflect"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/google/shlex"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/yudai/gojsondiff"
|
||||
"github.com/yudai/gojsondiff/formatter"
|
||||
@@ -388,7 +394,7 @@ func HideSecretData(target *unstructured.Unstructured, live *unstructured.Unstru
|
||||
|
||||
for k := range keys {
|
||||
// we use "+" rather than the more common "*"
|
||||
nextReplacement := "+++++++++"
|
||||
nextReplacement := "++++++++"
|
||||
valToReplacement := make(map[string]string)
|
||||
for _, obj := range []*unstructured.Unstructured{target, live, orig} {
|
||||
var data map[string]interface{}
|
||||
@@ -410,7 +416,7 @@ func HideSecretData(target *unstructured.Unstructured, live *unstructured.Unstru
|
||||
replacement, ok := valToReplacement[val]
|
||||
if !ok {
|
||||
replacement = nextReplacement
|
||||
nextReplacement = nextReplacement + "+"
|
||||
nextReplacement = nextReplacement + "++++"
|
||||
valToReplacement[val] = replacement
|
||||
}
|
||||
data[k] = replacement
|
||||
@@ -477,3 +483,50 @@ func remarshal(obj *unstructured.Unstructured) *unstructured.Unstructured {
|
||||
unstrBody = jsonutil.RemoveMapFields(obj.Object, unstrBody)
|
||||
return &unstructured.Unstructured{Object: unstrBody}
|
||||
}
|
||||
|
||||
// PrintDiff prints a diff between two unstructured objects to stdout using an external diff utility
|
||||
// Honors the diff utility set in the KUBECTL_EXTERNAL_DIFF environment variable
|
||||
func PrintDiff(name string, live *unstructured.Unstructured, target *unstructured.Unstructured) error {
|
||||
tempDir, err := ioutil.TempDir("", "argocd-diff")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetFile := path.Join(tempDir, name)
|
||||
targetData := []byte("")
|
||||
if target != nil {
|
||||
targetData, err = yaml.Marshal(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = ioutil.WriteFile(targetFile, targetData, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
liveFile := path.Join(tempDir, fmt.Sprintf("%s-live.yaml", name))
|
||||
liveData := []byte("")
|
||||
if live != nil {
|
||||
liveData, err = yaml.Marshal(live)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = ioutil.WriteFile(liveFile, liveData, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmdBinary := "diff"
|
||||
var args []string
|
||||
if envDiff := os.Getenv("KUBECTL_EXTERNAL_DIFF"); envDiff != "" {
|
||||
parts, err := shlex.Split(envDiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmdBinary = parts[0]
|
||||
args = parts[1:]
|
||||
}
|
||||
cmd := exec.Command(cmdBinary, append(args, liveFile, targetFile)...)
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
@@ -533,10 +533,10 @@ func secretData(obj *unstructured.Unstructured) map[string]interface{} {
|
||||
return data
|
||||
}
|
||||
|
||||
const (
|
||||
replacement1 = "+++++++++"
|
||||
replacement2 = "++++++++++"
|
||||
replacement3 = "+++++++++++"
|
||||
var (
|
||||
replacement1 = strings.Repeat("+", 8)
|
||||
replacement2 = strings.Repeat("+", 12)
|
||||
replacement3 = strings.Repeat("+", 16)
|
||||
)
|
||||
|
||||
func TestHideSecretDataSameKeysDifferentValues(t *testing.T) {
|
||||
|
||||
@@ -94,7 +94,14 @@ func (f *factory) NewClient(rawRepoURL string, path string, creds Creds, insecur
|
||||
// - Otherwise (and on non-fatal errors), a default HTTP client is returned.
|
||||
func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds) *http.Client {
|
||||
// Default HTTP client
|
||||
var customHTTPClient *http.Client = &http.Client{}
|
||||
var customHTTPClient *http.Client = &http.Client{
|
||||
// 15 second timeout
|
||||
Timeout: 15 * time.Second,
|
||||
// don't follow redirect
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
// Callback function to return any configured client certificate
|
||||
// We never return err, but an empty cert instead.
|
||||
@@ -122,19 +129,11 @@ func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds) *http.Client
|
||||
}
|
||||
|
||||
if insecure {
|
||||
customHTTPClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
},
|
||||
// 15 second timeout
|
||||
Timeout: 15 * time.Second,
|
||||
|
||||
// don't follow redirect
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
customHTTPClient.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
@@ -147,33 +146,19 @@ func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds) *http.Client
|
||||
return customHTTPClient
|
||||
} else if len(serverCertificatePem) > 0 {
|
||||
certPool := certutil.GetCertPoolFromPEMData(serverCertificatePem)
|
||||
customHTTPClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: certPool,
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
},
|
||||
// 15 second timeout
|
||||
Timeout: 15 * time.Second,
|
||||
// don't follow redirect
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
customHTTPClient.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: certPool,
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// else no custom certificate stored.
|
||||
customHTTPClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
},
|
||||
// 15 second timeout
|
||||
Timeout: 15 * time.Second,
|
||||
// don't follow redirect
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
customHTTPClient.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
GetClientCertificate: clientCertFunc,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,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}
|
||||
|
||||
@@ -33,7 +33,9 @@ type Kubectl interface {
|
||||
GetAPIResources(config *rest.Config, resourceFilter ResourceFilter) ([]APIResourceInfo, error)
|
||||
}
|
||||
|
||||
type KubectlCmd struct{}
|
||||
type KubectlCmd struct {
|
||||
OnKubectlRun func(command string) (util.Closer, error)
|
||||
}
|
||||
|
||||
type APIResourceInfo struct {
|
||||
GroupKind schema.GroupKind
|
||||
@@ -214,7 +216,7 @@ func (k KubectlCmd) ApplyResource(config *rest.Config, obj *unstructured.Unstruc
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
outReconcile, err := runKubectl(f.Name(), namespace, []string{"auth", "reconcile"}, manifestBytes, dryRun)
|
||||
outReconcile, err := k.runKubectl(f.Name(), namespace, []string{"auth", "reconcile"}, manifestBytes, dryRun)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -231,7 +233,7 @@ func (k KubectlCmd) ApplyResource(config *rest.Config, obj *unstructured.Unstruc
|
||||
if !validate {
|
||||
applyArgs = append(applyArgs, "--validate=false")
|
||||
}
|
||||
outApply, err := runKubectl(f.Name(), namespace, applyArgs, manifestBytes, dryRun)
|
||||
outApply, err := k.runKubectl(f.Name(), namespace, applyArgs, manifestBytes, dryRun)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -251,7 +253,27 @@ func convertKubectlError(err error) error {
|
||||
return fmt.Errorf(errorStr)
|
||||
}
|
||||
|
||||
func runKubectl(kubeconfigPath string, namespace string, args []string, manifestBytes []byte, dryRun bool) (string, error) {
|
||||
func (k *KubectlCmd) processKubectlRun(args []string) (util.Closer, error) {
|
||||
if k.OnKubectlRun != nil {
|
||||
cmd := "unknown"
|
||||
if len(args) > 0 {
|
||||
cmd = args[0]
|
||||
}
|
||||
return k.OnKubectlRun(cmd)
|
||||
}
|
||||
return util.NewCloser(func() error {
|
||||
return nil
|
||||
// do nothing
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (k *KubectlCmd) runKubectl(kubeconfigPath string, namespace string, args []string, manifestBytes []byte, dryRun bool) (string, error) {
|
||||
closer, err := k.processKubectlRun(args)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer util.Close(closer)
|
||||
|
||||
cmdArgs := append([]string{"--kubeconfig", kubeconfigPath, "-f", "-"}, args...)
|
||||
if namespace != "" {
|
||||
cmdArgs = append(cmdArgs, "-n", namespace)
|
||||
@@ -304,6 +326,13 @@ func (k KubectlCmd) ConvertToVersion(obj *unstructured.Unstructured, group strin
|
||||
return nil, err
|
||||
}
|
||||
defer util.DeleteFile(f.Name())
|
||||
|
||||
closer, err := k.processKubectlRun([]string{"convert"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer util.Close(closer)
|
||||
|
||||
outputVersion := fmt.Sprintf("%s/%s", group, version)
|
||||
cmd := exec.Command("kubectl", "convert", "--output-version", outputVersion, "-o", "json", "--local=true", "-f", f.Name())
|
||||
cmd.Stdin = bytes.NewReader(manifestBytes)
|
||||
|
||||
@@ -2,34 +2,28 @@ package kube
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/argo-cd/util"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func TestConvertToVersion(t *testing.T) {
|
||||
/*
|
||||
ctl_test.go:22:
|
||||
Error Trace: ctl_test.go:22
|
||||
Error: Expected nil, but got: &errors.errorString{s:"failed to convert Deployment/nginx-deployment to apps/v1"}
|
||||
Test: TestConvertToVersion
|
||||
panic: runtime error: invalid memory address or nil pointer dereference
|
||||
/home/circleci/sdk/go1.11.4/src/testing/testing.go:792 +0x387
|
||||
/home/circleci/sdk/go1.11.4/src/runtime/panic.go:513 +0x1b9
|
||||
/home/circleci/.go_workspace/src/github.com/argoproj/argo-cd/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go:200 +0x3a
|
||||
/home/circleci/.go_workspace/src/github.com/argoproj/argo-cd/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go:396 +0x5b
|
||||
/home/circleci/.go_workspace/src/github.com/argoproj/argo-cd/util/kube/ctl_test.go:23 +0x1e4
|
||||
/home/circleci/sdk/go1.11.4/src/testing/testing.go:827 +0xbf
|
||||
/home/circleci/sdk/go1.11.4/src/testing/testing.go:878 +0x35c
|
||||
*/
|
||||
if os.Getenv("CIRCLECI") == "true" {
|
||||
t.SkipNow()
|
||||
callbackExecuted := false
|
||||
closerExecuted := false
|
||||
kubectl := KubectlCmd{
|
||||
func(command string) (util.Closer, error) {
|
||||
callbackExecuted = true
|
||||
return util.NewCloser(func() error {
|
||||
closerExecuted = true
|
||||
return nil
|
||||
}), nil
|
||||
},
|
||||
}
|
||||
|
||||
kubectl := KubectlCmd{}
|
||||
yamlBytes, err := ioutil.ReadFile("testdata/nginx.yaml")
|
||||
assert.Nil(t, err)
|
||||
var obj unstructured.Unstructured
|
||||
@@ -42,6 +36,8 @@ func TestConvertToVersion(t *testing.T) {
|
||||
gvk := newObj.GroupVersionKind()
|
||||
assert.Equal(t, "apps", gvk.Group)
|
||||
assert.Equal(t, "v1", gvk.Version)
|
||||
assert.True(t, callbackExecuted)
|
||||
assert.True(t, closerExecuted)
|
||||
|
||||
// converting it again should not have any affect
|
||||
newObj, err = kubectl.ConvertToVersion(&obj, "apps", "v1")
|
||||
@@ -50,3 +46,21 @@ func TestConvertToVersion(t *testing.T) {
|
||||
assert.Equal(t, "apps", gvk.Group)
|
||||
assert.Equal(t, "v1", gvk.Version)
|
||||
}
|
||||
|
||||
func TestRunKubectl(t *testing.T) {
|
||||
callbackExecuted := false
|
||||
closerExecuted := false
|
||||
kubectl := KubectlCmd{
|
||||
func(command string) (util.Closer, error) {
|
||||
callbackExecuted = true
|
||||
return util.NewCloser(func() error {
|
||||
closerExecuted = true
|
||||
return nil
|
||||
}), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, _ = kubectl.runKubectl("/dev/null", "default", []string{"command-name"}, nil, false)
|
||||
assert.True(t, callbackExecuted)
|
||||
assert.True(t, closerExecuted)
|
||||
}
|
||||
|
||||
@@ -234,11 +234,15 @@ func (l *LocalConfig) IsEmpty() bool {
|
||||
|
||||
// DefaultConfigDir returns the local configuration path for settings such as cached authentication tokens.
|
||||
func DefaultConfigDir() (string, error) {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
homeDir := os.Getenv("HOME")
|
||||
if homeDir == "" {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
homeDir = usr.HomeDir
|
||||
}
|
||||
return path.Join(usr.HomeDir, ".argocd"), nil
|
||||
return path.Join(homeDir, ".argocd"), nil
|
||||
}
|
||||
|
||||
// DefaultLocalConfigPath returns the local configuration path for settings such as cached authentication tokens.
|
||||
|
||||
@@ -45,7 +45,7 @@ func (vm VM) runLua(obj *unstructured.Unstructured, script string) (*lua.LState,
|
||||
SkipOpenLibs: !vm.UseOpenLibs,
|
||||
})
|
||||
defer l.Close()
|
||||
// Opens table library to allow access to functions to manulate tables
|
||||
// Opens table library to allow access to functions to manipulate tables
|
||||
for _, pair := range []struct {
|
||||
n string
|
||||
f lua.LGFunction
|
||||
@@ -53,6 +53,8 @@ func (vm VM) runLua(obj *unstructured.Unstructured, script string) (*lua.LState,
|
||||
{lua.LoadLibName, lua.OpenPackage},
|
||||
{lua.BaseLibName, lua.OpenBase},
|
||||
{lua.TabLibName, lua.OpenTable},
|
||||
// load our 'safe' version of the os library
|
||||
{lua.OsLibName, OpenSafeOs},
|
||||
} {
|
||||
if err := l.CallByParam(lua.P{
|
||||
Fn: l.NewFunction(pair.f),
|
||||
@@ -62,6 +64,8 @@ func (vm VM) runLua(obj *unstructured.Unstructured, script string) (*lua.LState,
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// preload our 'safe' version of the os library. Allows the 'local os = require("os")' to work
|
||||
l.PreloadModule(lua.OsLibName, SafeOsLoader)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
184
util/lua/oslib_safe.go
Normal file
184
util/lua/oslib_safe.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package lua
|
||||
|
||||
// oslib_safe contains a subset of the lua os library. For security reasons, we do not expose
|
||||
// the entirety of lua os library to custom actions, such as ones which can exit, read files, etc.
|
||||
// Only the safe functions like os.time(), os.date() are exposed. Implementation was copied from
|
||||
// github.com/yuin/gopher-lua.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
func OpenSafeOs(L *lua.LState) int {
|
||||
tabmod := L.RegisterModule(lua.TabLibName, osFuncs)
|
||||
L.Push(tabmod)
|
||||
return 1
|
||||
}
|
||||
|
||||
func SafeOsLoader(L *lua.LState) int {
|
||||
mod := L.SetFuncs(L.NewTable(), osFuncs)
|
||||
L.Push(mod)
|
||||
return 1
|
||||
}
|
||||
|
||||
var osFuncs = map[string]lua.LGFunction{
|
||||
"time": osTime,
|
||||
"date": osDate,
|
||||
}
|
||||
|
||||
func osTime(L *lua.LState) int {
|
||||
if L.GetTop() == 0 {
|
||||
L.Push(lua.LNumber(time.Now().Unix()))
|
||||
} else {
|
||||
tbl := L.CheckTable(1)
|
||||
sec := getIntField(tbl, "sec", 0)
|
||||
min := getIntField(tbl, "min", 0)
|
||||
hour := getIntField(tbl, "hour", 12)
|
||||
day := getIntField(tbl, "day", -1)
|
||||
month := getIntField(tbl, "month", -1)
|
||||
year := getIntField(tbl, "year", -1)
|
||||
isdst := getBoolField(tbl, "isdst", false)
|
||||
t := time.Date(year, time.Month(month), day, hour, min, sec, 0, time.Local)
|
||||
// TODO dst
|
||||
if false {
|
||||
print(isdst)
|
||||
}
|
||||
L.Push(lua.LNumber(t.Unix()))
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func getIntField(tb *lua.LTable, key string, v int) int {
|
||||
ret := tb.RawGetString(key)
|
||||
if ln, ok := ret.(lua.LNumber); ok {
|
||||
return int(ln)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func getBoolField(tb *lua.LTable, key string, v bool) bool {
|
||||
ret := tb.RawGetString(key)
|
||||
if lb, ok := ret.(lua.LBool); ok {
|
||||
return bool(lb)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func osDate(L *lua.LState) int {
|
||||
t := time.Now()
|
||||
cfmt := "%c"
|
||||
if L.GetTop() >= 1 {
|
||||
cfmt = L.CheckString(1)
|
||||
if strings.HasPrefix(cfmt, "!") {
|
||||
t = time.Now().UTC()
|
||||
cfmt = strings.TrimLeft(cfmt, "!")
|
||||
}
|
||||
if L.GetTop() >= 2 {
|
||||
t = time.Unix(L.CheckInt64(2), 0)
|
||||
}
|
||||
if strings.HasPrefix(cfmt, "*t") {
|
||||
ret := L.NewTable()
|
||||
ret.RawSetString("year", lua.LNumber(t.Year()))
|
||||
ret.RawSetString("month", lua.LNumber(t.Month()))
|
||||
ret.RawSetString("day", lua.LNumber(t.Day()))
|
||||
ret.RawSetString("hour", lua.LNumber(t.Hour()))
|
||||
ret.RawSetString("min", lua.LNumber(t.Minute()))
|
||||
ret.RawSetString("sec", lua.LNumber(t.Second()))
|
||||
ret.RawSetString("wday", lua.LNumber(t.Weekday()+1))
|
||||
// TODO yday & dst
|
||||
ret.RawSetString("yday", lua.LNumber(0))
|
||||
ret.RawSetString("isdst", lua.LFalse)
|
||||
L.Push(ret)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
L.Push(lua.LString(strftime(t, cfmt)))
|
||||
return 1
|
||||
}
|
||||
|
||||
var cDateFlagToGo = map[byte]string{
|
||||
'a': "mon", 'A': "Monday", 'b': "Jan", 'B': "January", 'c': "02 Jan 06 15:04 MST", 'd': "02",
|
||||
'F': "2006-01-02", 'H': "15", 'I': "03", 'm': "01", 'M': "04", 'p': "PM", 'P': "pm", 'S': "05",
|
||||
'x': "15/04/05", 'X': "15:04:05", 'y': "06", 'Y': "2006", 'z': "-0700", 'Z': "MST"}
|
||||
|
||||
func strftime(t time.Time, cfmt string) string {
|
||||
sc := newFlagScanner('%', "", "", cfmt)
|
||||
for c, eos := sc.Next(); !eos; c, eos = sc.Next() {
|
||||
if !sc.ChangeFlag {
|
||||
if sc.HasFlag {
|
||||
if v, ok := cDateFlagToGo[c]; ok {
|
||||
sc.AppendString(t.Format(v))
|
||||
} else {
|
||||
switch c {
|
||||
case 'w':
|
||||
sc.AppendString(fmt.Sprint(int(t.Weekday())))
|
||||
default:
|
||||
sc.AppendChar('%')
|
||||
sc.AppendChar(c)
|
||||
}
|
||||
}
|
||||
sc.HasFlag = false
|
||||
} else {
|
||||
sc.AppendChar(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sc.String()
|
||||
}
|
||||
|
||||
type flagScanner struct {
|
||||
flag byte
|
||||
start string
|
||||
end string
|
||||
buf []byte
|
||||
str string
|
||||
Length int
|
||||
Pos int
|
||||
HasFlag bool
|
||||
ChangeFlag bool
|
||||
}
|
||||
|
||||
func newFlagScanner(flag byte, start, end, str string) *flagScanner {
|
||||
return &flagScanner{flag, start, end, make([]byte, 0, len(str)), str, len(str), 0, false, false}
|
||||
}
|
||||
|
||||
func (fs *flagScanner) AppendString(str string) { fs.buf = append(fs.buf, str...) }
|
||||
|
||||
func (fs *flagScanner) AppendChar(ch byte) { fs.buf = append(fs.buf, ch) }
|
||||
|
||||
func (fs *flagScanner) String() string { return string(fs.buf) }
|
||||
|
||||
func (fs *flagScanner) Next() (byte, bool) {
|
||||
c := byte('\000')
|
||||
fs.ChangeFlag = false
|
||||
if fs.Pos == fs.Length {
|
||||
if fs.HasFlag {
|
||||
fs.AppendString(fs.end)
|
||||
}
|
||||
return c, true
|
||||
} else {
|
||||
c = fs.str[fs.Pos]
|
||||
if c == fs.flag {
|
||||
if fs.Pos < (fs.Length-1) && fs.str[fs.Pos+1] == fs.flag {
|
||||
fs.HasFlag = false
|
||||
fs.AppendChar(fs.flag)
|
||||
fs.Pos += 2
|
||||
return fs.Next()
|
||||
} else if fs.Pos != fs.Length-1 {
|
||||
if fs.HasFlag {
|
||||
fs.AppendString(fs.end)
|
||||
}
|
||||
fs.AppendString(fs.start)
|
||||
fs.ChangeFlag = true
|
||||
fs.HasFlag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.Pos++
|
||||
return c, false
|
||||
}
|
||||
12
util/util.go
12
util/util.go
@@ -30,6 +30,18 @@ type Closer interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
type inlineCloser struct {
|
||||
close func() error
|
||||
}
|
||||
|
||||
func (c *inlineCloser) Close() error {
|
||||
return c.close()
|
||||
}
|
||||
|
||||
func NewCloser(close func() error) Closer {
|
||||
return &inlineCloser{close: close}
|
||||
}
|
||||
|
||||
// Close is a convenience function to close a object that has a Close() method, ignoring any errors
|
||||
// Used to satisfy errcheck lint
|
||||
func Close(c Closer) {
|
||||
|
||||
Reference in New Issue
Block a user