diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..e8dd351c5 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,28 @@ +name: CI + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: actions/cache@v1 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - uses: actions/setup-go@v1 + with: + go-version: '1.13.6' + - run: make test + - uses: actions-contrib/golangci-lint@v1 + with: + args: run --timeout=5m + env: + GOROOT: "" + - uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} #required + file: ./coverage.out diff --git a/.gitignore b/.gitignore index 53311f549..d10940ffc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.swp *~ .vscode +.idea +coverage.out diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..28dc4f0ea --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +.PHONY: test +test: + go test ./... -coverprofile=coverage.out + +.PHONY: lint +lint: + golangci-lint run diff --git a/common/common.go b/common/common.go deleted file mode 100644 index 6741532c7..000000000 --- a/common/common.go +++ /dev/null @@ -1,49 +0,0 @@ -package common - -const ( - // AnnotationCompareOptions is a comma-separated list of options for comparison - AnnotationCompareOptions = "argocd.argoproj.io/compare-options" - // AnnotationSyncOptions is a comma-separated list of options for syncing - AnnotationSyncOptions = "argocd.argoproj.io/sync-options" - // AnnotationSyncWave indicates which wave of the sync the resource or hook should be in - AnnotationSyncWave = "argocd.argoproj.io/sync-wave" - // AnnotationKeyHook contains the hook type of a resource - AnnotationKeyHook = "argocd.argoproj.io/hook" - // AnnotationKeyHookDeletePolicy is the policy of deleting a hook - AnnotationKeyHookDeletePolicy = "argocd.argoproj.io/hook-delete-policy" - // AnnotationKeyRefresh is the annotation key which indicates that app needs to be refreshed. Removed by application controller after app is refreshed. - // Might take values 'normal'/'hard'. Value 'hard' means manifest cache and target cluster state cache should be invalidated before refresh. - AnnotationKeyRefresh = "argocd.argoproj.io/refresh" - // ResourcesFinalizerName the finalizer value which we inject to finalize deletion of an application - ResourcesFinalizerName = "resources-finalizer.argocd.argoproj.io" - // RevisionHistoryLimit is the max number of successful sync to keep in history - RevisionHistoryLimit = 10 - // KubernetesInternalAPIServerAddr is address of the k8s API server when accessing internal to the cluster - KubernetesInternalAPIServerAddr = "https://kubernetes.default.svc" - // DefaultAppProjectName contains name of 'default' app project, which is available in every Argo CD installation - DefaultAppProjectName = "default" - // EnvVarFakeInClusterConfig is an environment variable to fake an in-cluster RESTConfig using - // the current kubectl context (for development purposes) - EnvVarFakeInClusterConfig = "ARGOCD_FAKE_IN_CLUSTER" - // K8sClientConfigQPS controls the QPS to be used in K8s REST client configs - K8sClientConfigQPS = 25 - // K8sClientConfigBurst controls the burst to be used in K8s REST client configs - K8sClientConfigBurst = 50 - // LabelKeyAppInstance is the label key to use to uniquely identify the instance of an application - // The Argo CD application name is used as the instance name - LabelKeyAppInstance = "app.kubernetes.io/instance" - // LegacyLabelApplicationName is the legacy label (v0.10 and below) and is superceded by 'app.kubernetes.io/instance' - LabelKeyLegacyApplicationName = "applications.argoproj.io/app-name" - // Overrides the location where TLS certificate for repo access data is stored - EnvVarTLSDataPath = "ARGOCD_TLS_DATA_PATH" - // The default path where TLS certificates for repositories are located - DefaultPathTLSConfig = "/app/config/tls" - // The default path where SSH known hosts are stored - DefaultPathSSHConfig = "/app/config/ssh" - // Default name for the SSH known hosts file - DefaultSSHKnownHostsName = "ssh_known_hosts" - // Overrides the location where SSH known hosts for repo access data is stored - EnvVarSSHDataPath = "ARGOCD_SSH_DATA_PATH" - // Specifies number of git remote operations attempts count - EnvGitAttemptsCount = "ARGOCD_GIT_ATTEMPTS_COUNT" -) diff --git a/controller/appcontroller.go b/controller/appcontroller.go deleted file mode 100644 index 4d287ebee..000000000 --- a/controller/appcontroller.go +++ /dev/null @@ -1,1171 +0,0 @@ -package controller - -import ( - "context" - "encoding/json" - "fmt" - "math" - "reflect" - "runtime/debug" - "strings" - "sync" - "time" - - "github.com/argoproj/argo-cd/engine/util/settings" - - argocache "github.com/argoproj/argo-cd/engine/controller/cache" - "github.com/argoproj/argo-cd/engine/controller/metrics" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/argoproj/argo-cd/engine/common" - - "github.com/argoproj/argo-cd/engine/util/misc" - - 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" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/workqueue" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - appinformers "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions" - "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/argo" - "github.com/argoproj/argo-cd/engine/util/diff" - "github.com/argoproj/argo-cd/engine/util/errors" - "github.com/argoproj/argo-cd/engine/util/kube" -) - -const ( - updateOperationStateTimeout = 1 * time.Second - // orphanedIndex contains application which monitor orphaned resources by namespace - orphanedIndex = "orphaned" -) - -type CompareWith int - -const ( - // Compare live application state against state defined in latest git revision. - CompareWithLatest CompareWith = 2 - // Compare live application state against state defined using revision of most recent comparison. - CompareWithRecent CompareWith = 1 - // Skip comparison and only refresh application resources tree - ComparisonWithNothing CompareWith = 0 -) - -func (a CompareWith) Max(b CompareWith) CompareWith { - return CompareWith(math.Max(float64(a), float64(b))) -} - -// ApplicationController is the controller for application resources. -type ApplicationController struct { - cache pkg.AppStateCache - namespace string - kubectl kube.Kubectl - applicationClientset appclientset.Interface - auditLogger pkg.AuditLogger - appRefreshQueue workqueue.RateLimitingInterface - appOperationQueue workqueue.RateLimitingInterface - appInformer cache.SharedIndexInformer - appLister applisters.ApplicationLister - projInformer cache.SharedIndexInformer - appStateManager AppStateManager - stateCache argocache.LiveStateCache - statusRefreshTimeout time.Duration - selfHealTimeout time.Duration - db pkg.CredentialsStore - settingsMgr pkg.ReconciliationSettings - refreshRequestedApps map[string]CompareWith - refreshRequestedAppsMutex *sync.Mutex - metricsServer *metrics.MetricsServer - kubectlSemaphore *semaphore.Weighted - callbacks pkg.Callbacks -} - -type ApplicationControllerConfig struct { - InstanceID string - Namespace string -} - -// NewApplicationController creates new instance of ApplicationController. -func NewApplicationController( - namespace string, - settingsMgr pkg.ReconciliationSettings, - db pkg.CredentialsStore, - auditLogger pkg.AuditLogger, - applicationClientset appclientset.Interface, - repoClientset pkg.ManifestGenerator, - argoCache pkg.AppStateCache, - kubectl kube.Kubectl, - appResyncPeriod time.Duration, - selfHealTimeout time.Duration, - metricsPort int, - kubectlParallelismLimit int64, - healthCheck func() error, - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM, - callbacks pkg.Callbacks, -) (*ApplicationController, error) { - if callbacks == nil { - callbacks = settings.NewNoOpCallbacks() - } - ctrl := ApplicationController{ - cache: argoCache, - namespace: namespace, - kubectl: kubectl, - applicationClientset: applicationClientset, - appRefreshQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), - appOperationQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), - db: db, - statusRefreshTimeout: appResyncPeriod, - refreshRequestedApps: make(map[string]CompareWith), - refreshRequestedAppsMutex: &sync.Mutex{}, - auditLogger: auditLogger, - settingsMgr: settingsMgr, - selfHealTimeout: selfHealTimeout, - callbacks: callbacks, - } - if kubectlParallelismLimit > 0 { - ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit) - } - kubectl.SetOnKubectlRun(ctrl.onKubectlRun) - appInformer, appLister, err := ctrl.newApplicationInformerAndLister() - if err != nil { - return nil, err - } - projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, cache.Indexers{}) - metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort) - ctrl.metricsServer = metrics.NewMetricsServer(metricsAddr, appLister, healthCheck) - stateCache := argocache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, luaVMFactory, callbacks) - appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, luaVMFactory, callbacks) - ctrl.appInformer = appInformer - ctrl.appLister = appLister - ctrl.projInformer = projInformer - ctrl.appStateManager = appStateManager - ctrl.stateCache = stateCache - - return &ctrl, nil -} - -func (ctrl *ApplicationController) onKubectlRun(command string) (misc.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 misc.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 && - ref.Name == app.Name && - ref.Namespace == app.Namespace && - gvk.Group == application.Group && - gvk.Kind == application.ApplicationKind -} - -func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.AppProject, error) { - return argo.GetAppProject(&app.Spec, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace) -} - -func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]bool, ref v1.ObjectReference) { - // if namespaced resource is not managed by any app it might be orphaned resource of some other apps - if len(managedByApp) == 0 && ref.Namespace != "" { - // retrieve applications which monitor orphaned resources in the same namespace and refresh them unless resource is blacklisted in app project - if objs, err := ctrl.appInformer.GetIndexer().ByIndex(orphanedIndex, ref.Namespace); err == nil { - for i := range objs { - app, ok := objs[i].(*appv1.Application) - if !ok { - continue - } - // exclude resource unless it is permitted in the app project. If project is not permitted then it is not controlled by the user and there is no point showing the warning. - if proj, err := ctrl.getAppProj(app); err == nil && proj.IsResourcePermitted(metav1.GroupKind{Group: ref.GroupVersionKind().Group, Kind: ref.Kind}, true) && - !isKnownOrphanedResourceExclusion(kube.NewResourceKey(ref.GroupVersionKind().Group, ref.GroupVersionKind().Kind, ref.Namespace, ref.Name)) { - - managedByApp[app.Name] = false - } - } - } - } - for appName, isManagedResource := range managedByApp { - skipForceRefresh := false - - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(ctrl.namespace + "/" + appName) - if app, ok := obj.(*appv1.Application); exists && err == nil && ok && isSelfReferencedApp(app, ref) { - // Don't force refresh app if related resource is application itself. This prevents infinite reconciliation loop. - skipForceRefresh = true - } - - if !skipForceRefresh { - level := ComparisonWithNothing - if isManagedResource { - level = CompareWithRecent - } - ctrl.requestAppRefresh(appName, level) - } - ctrl.appRefreshQueue.Add(fmt.Sprintf("%s/%s", ctrl.namespace, appName)) - } -} - -func (ctrl *ApplicationController) setAppManagedResources(a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) { - managedResources, err := ctrl.managedResources(comparisonResult) - if err != nil { - return nil, err - } - tree, err := ctrl.getResourceTree(a, managedResources) - if err != nil { - return nil, err - } - err = ctrl.cache.SetAppResourcesTree(a.Name, tree) - if err != nil { - return nil, err - } - return tree, ctrl.cache.SetAppManagedResources(a.Name, managedResources) -} - -// returns true of given resources exist in the namespace by default and not managed by the user -func isKnownOrphanedResourceExclusion(key kube.ResourceKey) bool { - if key.Namespace == "default" && key.Group == "" && key.Kind == kube.ServiceKind && key.Name == "kubernetes" { - return true - } - if key.Group == "" && key.Kind == kube.ServiceAccountKind && key.Name == "default" { - return true - } - return false -} - -func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) { - nodes := make([]appv1.ResourceNode, 0) - - proj, err := argo.GetAppProject(&a.Spec, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace) - if err != nil { - return nil, err - } - orphanedNodesMap := make(map[kube.ResourceKey]appv1.ResourceNode) - warnOrphaned := true - if proj.Spec.OrphanedResources != nil { - orphanedNodesMap, err = ctrl.stateCache.GetNamespaceTopLevelResources(a.Spec.Destination.Server, a.Spec.Destination.Namespace) - if err != nil { - return nil, err - } - warnOrphaned = proj.Spec.OrphanedResources.IsWarn() - } - - for i := range managedResources { - managedResource := managedResources[i] - delete(orphanedNodesMap, kube.NewResourceKey(managedResource.Group, managedResource.Kind, managedResource.Namespace, managedResource.Name)) - var live = &unstructured.Unstructured{} - err := json.Unmarshal([]byte(managedResource.LiveState), &live) - if err != nil { - return nil, err - } - var target = &unstructured.Unstructured{} - err = json.Unmarshal([]byte(managedResource.TargetState), &target) - if err != nil { - return nil, err - } - - if live == nil { - nodes = append(nodes, appv1.ResourceNode{ - ResourceRef: appv1.ResourceRef{ - Version: target.GroupVersionKind().Version, - Name: managedResource.Name, - Kind: managedResource.Kind, - Group: managedResource.Group, - Namespace: managedResource.Namespace, - }, - }) - } else { - err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, kube.GetResourceKey(live), func(child appv1.ResourceNode, appName string) { - nodes = append(nodes, child) - }) - if err != nil { - return nil, err - } - } - } - orphanedNodes := make([]appv1.ResourceNode, 0) - for k := range orphanedNodesMap { - if k.Namespace != "" && proj.IsResourcePermitted(metav1.GroupKind{Group: k.Group, Kind: k.Kind}, true) && !isKnownOrphanedResourceExclusion(k) { - err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, k, func(child appv1.ResourceNode, appName string) { - belongToAnotherApp := false - if appName != "" { - if _, exists, err := ctrl.appInformer.GetIndexer().GetByKey(ctrl.namespace + "/" + appName); exists && err == nil { - belongToAnotherApp = true - } - } - if !belongToAnotherApp { - orphanedNodes = append(orphanedNodes, child) - } - }) - if err != nil { - return nil, err - } - } - } - var conditions []appv1.ApplicationCondition - if len(orphanedNodes) > 0 && warnOrphaned { - conditions = []appv1.ApplicationCondition{{ - Type: appv1.ApplicationConditionOrphanedResourceWarning, - Message: fmt.Sprintf("Application has %d orphaned resources", len(orphanedNodes)), - }} - } - a.Status.SetConditions(conditions, map[appv1.ApplicationConditionType]bool{appv1.ApplicationConditionOrphanedResourceWarning: true}) - return &appv1.ApplicationTree{Nodes: nodes, OrphanedNodes: orphanedNodes}, nil -} - -func (ctrl *ApplicationController) managedResources(comparisonResult *comparisonResult) ([]*appv1.ResourceDiff, error) { - items := make([]*appv1.ResourceDiff, len(comparisonResult.managedResources)) - for i := range comparisonResult.managedResources { - res := comparisonResult.managedResources[i] - item := appv1.ResourceDiff{ - Namespace: res.Namespace, - Name: res.Name, - Group: res.Group, - Kind: res.Kind, - Hook: res.Hook, - } - - target := res.Target - live := res.Live - resDiff := res.Diff - if res.Kind == kube.SecretKind && res.Group == "" { - var err error - target, live, err = diff.HideSecretData(res.Target, res.Live) - if err != nil { - return nil, err - } - resDiff = *diff.Diff(target, live, comparisonResult.diffNormalizer) - } - - if live != nil { - data, err := json.Marshal(live) - if err != nil { - return nil, err - } - item.LiveState = string(data) - } else { - item.LiveState = "null" - } - - if target != nil { - data, err := json.Marshal(target) - if err != nil { - return nil, err - } - item.TargetState = string(data) - } else { - item.TargetState = "null" - } - jsonDiff, err := resDiff.JSONFormat() - if err != nil { - return nil, err - } - item.Diff = jsonDiff - - items[i] = &item - } - return items, nil -} - -// Run starts the Application CRD controller. -func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int, operationProcessors int) { - defer runtime.HandleCrash() - defer ctrl.appRefreshQueue.ShutDown() - - go ctrl.appInformer.Run(ctx.Done()) - go ctrl.projInformer.Run(ctx.Done()) - - if !cache.WaitForCacheSync(ctx.Done(), ctrl.appInformer.HasSynced, ctrl.projInformer.HasSynced) { - log.Error("Timed out waiting for caches to sync") - return - } - - go func() { errors.CheckError(ctrl.stateCache.Run(ctx)) }() - go func() { errors.CheckError(ctrl.metricsServer.ListenAndServe()) }() - - for i := 0; i < statusProcessors; i++ { - go wait.Until(func() { - for ctrl.processAppRefreshQueueItem() { - } - }, time.Second, ctx.Done()) - } - - for i := 0; i < operationProcessors; i++ { - go wait.Until(func() { - for ctrl.processAppOperationQueueItem() { - } - }, time.Second, ctx.Done()) - } - - <-ctx.Done() -} - -func (ctrl *ApplicationController) requestAppRefresh(appName string, compareWith CompareWith) { - ctrl.refreshRequestedAppsMutex.Lock() - defer ctrl.refreshRequestedAppsMutex.Unlock() - ctrl.refreshRequestedApps[appName] = compareWith.Max(ctrl.refreshRequestedApps[appName]) -} - -func (ctrl *ApplicationController) isRefreshRequested(appName string) (bool, CompareWith) { - ctrl.refreshRequestedAppsMutex.Lock() - defer ctrl.refreshRequestedAppsMutex.Unlock() - level, ok := ctrl.refreshRequestedApps[appName] - if ok { - delete(ctrl.refreshRequestedApps, appName) - } - return ok, level -} - -func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext bool) { - appKey, shutdown := ctrl.appOperationQueue.Get() - if shutdown { - processNext = false - return - } - processNext = true - defer func() { - if r := recover(); r != nil { - log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) - } - ctrl.appOperationQueue.Done(appKey) - }() - - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey.(string)) - if err != nil { - log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) - return - } - if !exists { - // This happens after app was deleted, but the work queue still had an entry for it. - return - } - app, ok := obj.(*appv1.Application) - if !ok { - log.Warnf("Key '%s' in index is not an application", appKey) - return - } - if app.Operation != nil { - ctrl.processRequestedAppOperation(app) - } else if app.DeletionTimestamp != nil && app.CascadedDeletion() { - err = ctrl.finalizeApplicationDeletion(app) - if err != nil { - ctrl.setAppCondition(app, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionDeletionError, - Message: err.Error(), - }) - message := fmt.Sprintf("Unable to delete application resources: %v", err.Error()) - ctrl.auditLogger.LogAppEvent(app, pkg.EventInfo{Reason: pkg.EventReasonStatusRefreshed, Type: v1.EventTypeWarning}, message) - } - } - return -} - -func shouldBeDeleted(app *appv1.Application, obj *unstructured.Unstructured) bool { - return !kube.IsCRD(obj) && !isSelfReferencedApp(app, kube.GetObjectRef(obj)) -} - -func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Application) error { - logCtx := log.WithField("application", app.Name) - logCtx.Infof("Deleting resources") - // Get refreshed application info, since informer app copy might be stale - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(app.Name, metav1.GetOptions{}) - if err != nil { - if !apierr.IsNotFound(err) { - logCtx.Errorf("Unable to get refreshed application info prior deleting resources: %v", err) - } - return nil - } - - objsMap, err := ctrl.stateCache.GetManagedLiveObjs(app, []*unstructured.Unstructured{}) - if err != nil { - return err - } - objs := make([]*unstructured.Unstructured, 0) - for k := range objsMap { - if objsMap[k].GetDeletionTimestamp() == nil && shouldBeDeleted(app, objsMap[k]) { - objs = append(objs, objsMap[k]) - } - } - - cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) - if err != nil { - return err - } - config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, cluster.RESTConfig()) - - err = misc.RunAllAsync(len(objs), func(i int) error { - obj := objs[i] - return ctrl.kubectl.DeleteResource(config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), false) - }) - if err != nil { - return err - } - - objsMap, err = ctrl.stateCache.GetManagedLiveObjs(app, []*unstructured.Unstructured{}) - if err != nil { - return err - } - for k, obj := range objsMap { - if !shouldBeDeleted(app, obj) { - delete(objsMap, k) - } - } - if len(objsMap) > 0 { - logCtx.Infof("%d objects remaining for deletion", len(objsMap)) - return nil - } - err = ctrl.cache.SetAppManagedResources(app.Name, nil) - if err != nil { - return err - } - err = ctrl.cache.SetAppResourcesTree(app.Name, nil) - if err != nil { - return err - } - app.SetCascadedDeletion(false) - var patch []byte - patch, _ = json.Marshal(map[string]interface{}{ - "metadata": map[string]interface{}{ - "finalizers": app.Finalizers, - }, - }) - _, err = ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Patch(app.Name, types.MergePatchType, patch) - if err != nil { - return err - } - - logCtx.Info("Successfully deleted resources") - return nil -} - -func (ctrl *ApplicationController) setAppCondition(app *appv1.Application, condition appv1.ApplicationCondition) { - index := -1 - for i, exiting := range app.Status.Conditions { - if exiting.Type == condition.Type { - index = i - break - } - } - if index > -1 { - app.Status.Conditions[index] = condition - } else { - app.Status.Conditions = append(app.Status.Conditions, condition) - } - var patch []byte - patch, err := json.Marshal(map[string]interface{}{ - "status": map[string]interface{}{ - "conditions": app.Status.Conditions, - }, - }) - if err == nil { - _, err = ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Patch(app.Name, types.MergePatchType, patch) - } - if err != nil { - log.Errorf("Unable to set application condition: %v", err) - } -} - -func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Application) { - logCtx := log.WithField("application", app.Name) - var state *appv1.OperationState - // Recover from any unexpected panics and automatically set the status to be failed - defer func() { - if r := recover(); r != nil { - logCtx.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) - state.Phase = appv1.OperationError - if rerr, ok := r.(error); ok { - state.Message = rerr.Error() - } else { - state.Message = fmt.Sprintf("%v", r) - } - ctrl.setOperationState(app, state) - } - }() - if isOperationInProgress(app) { - // If we get here, we are about process an operation but we notice it is already in progress. - // We need to detect if the app object we pulled off the informer is stale and doesn't - // reflect the fact that the operation is completed. We don't want to perform the operation - // again. To detect this, always retrieve the latest version to ensure it is not stale. - freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{}) - if err != nil { - logCtx.Errorf("Failed to retrieve latest application state: %v", err) - return - } - if !isOperationInProgress(freshApp) { - logCtx.Infof("Skipping operation on stale application state") - return - } - app = freshApp - state = app.Status.OperationState.DeepCopy() - logCtx.Infof("Resuming in-progress operation. phase: %s, message: %s", state.Phase, state.Message) - } else { - state = &appv1.OperationState{Phase: appv1.OperationRunning, Operation: *app.Operation, StartedAt: metav1.Now()} - ctrl.setOperationState(app, state) - logCtx.Infof("Initialized new operation: %v", *app.Operation) - } - - ctrl.appStateManager.SyncAppState(app, state) - - if state.Phase == appv1.OperationRunning { - // It's possible for an app to be terminated while we were operating on it. We do not want - // to clobber the Terminated state with Running. Get the latest app state to check for this. - freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{}) - if err == nil { - if freshApp.Status.OperationState != nil && freshApp.Status.OperationState.Phase == appv1.OperationTerminating { - state.Phase = appv1.OperationTerminating - state.Message = "operation is terminating" - // after this, we will get requeued to the workqueue, but next time the - // SyncAppState will operate in a Terminating phase, allowing the worker to perform - // cleanup (e.g. delete jobs, workflows, etc...) - } - } - } - - ctrl.setOperationState(app, state) - if state.Phase.Completed() { - if state != nil { - err := ctrl.callbacks.OnSyncCompleted(app.Name, *state) - if err != nil { - logCtx.Warnf("Fails to run sync completed callback: %v", err) - } - } - - // if we just completed an operation, force a refresh so that UI will report up-to-date - // sync/health information - if key, err := cache.MetaNamespaceKeyFunc(app); err == nil { - // force app refresh with using CompareWithLatest comparison type and trigger app reconciliation loop - ctrl.requestAppRefresh(app.Name, CompareWithLatest) - ctrl.appRefreshQueue.Add(key) - } else { - logCtx.Warnf("Fails to requeue application: %v", err) - } - } -} - -func (ctrl *ApplicationController) setOperationState(app *appv1.Application, state *appv1.OperationState) { - misc.RetryUntilSucceed(func() error { - if state.Phase == "" { - // expose any bugs where we neglect to set phase - panic("no phase was set") - } - if state.Phase.Completed() { - now := metav1.Now() - state.FinishedAt = &now - } - patch := map[string]interface{}{ - "status": map[string]interface{}{ - "operationState": state, - }, - } - if state.Phase.Completed() { - // If operation is completed, clear the operation field to indicate no operation is - // in progress. - patch["operation"] = nil - } - if reflect.DeepEqual(app.Status.OperationState, state) { - log.Infof("No operation updates necessary to '%s'. Skipping patch", app.Name) - return nil - } - patchJSON, err := json.Marshal(patch) - if err != nil { - return err - } - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace) - _, err = appClient.Patch(app.Name, types.MergePatchType, patchJSON) - if err != nil { - // Stop retrying updating deleted application - if apierr.IsNotFound(err) { - return nil - } - return err - } - log.Infof("updated '%s' operation (phase: %s)", app.Name, state.Phase) - if state.Phase.Completed() { - eventInfo := pkg.EventInfo{Reason: pkg.EventReasonOperationCompleted} - var messages []string - if state.Operation.Sync != nil && len(state.Operation.Sync.Resources) > 0 { - messages = []string{"Partial sync operation"} - } else { - messages = []string{"Sync operation"} - } - if state.SyncResult != nil { - messages = append(messages, "to", state.SyncResult.Revision) - } - if state.Phase.Successful() { - eventInfo.Type = v1.EventTypeNormal - messages = append(messages, "succeeded") - } else { - eventInfo.Type = v1.EventTypeWarning - messages = append(messages, "failed:", state.Message) - } - ctrl.auditLogger.LogAppEvent(app, eventInfo, strings.Join(messages, " ")) - ctrl.metricsServer.IncSync(app, state) - } - return nil - }, "Update application operation state", context.Background(), updateOperationStateTimeout) -} - -func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext bool) { - appKey, shutdown := ctrl.appRefreshQueue.Get() - if shutdown { - processNext = false - return - } - processNext = true - defer func() { - if r := recover(); r != nil { - log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) - } - ctrl.appRefreshQueue.Done(appKey) - }() - - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey.(string)) - if err != nil { - log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) - return - } - if !exists { - // This happens after app was deleted, but the work queue still had an entry for it. - return - } - origApp, ok := obj.(*appv1.Application) - if !ok { - log.Warnf("Key '%s' in index is not an application", appKey) - return - } - needRefresh, refreshType, comparisonLevel := ctrl.needRefreshAppStatus(origApp, ctrl.statusRefreshTimeout) - - if !needRefresh { - return - } - - startTime := time.Now() - 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, - "dest-server": origApp.Spec.Destination.Server, - "dest-namespace": origApp.Spec.Destination.Namespace, - }) - logCtx.Info("Reconciliation completed") - }() - - app := origApp.DeepCopy() - logCtx := log.WithFields(log.Fields{"application": app.Name}) - if comparisonLevel == ComparisonWithNothing { - managedResources := make([]*appv1.ResourceDiff, 0) - if err := ctrl.cache.GetAppManagedResources(app.Name, &managedResources); err != nil { - logCtx.Warnf("Failed to get cached managed resources for tree reconciliation, fallback to full reconciliation") - } else { - if tree, err := ctrl.getResourceTree(app, managedResources); err != nil { - app.Status.Conditions = []appv1.ApplicationCondition{{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}} - } else { - app.Status.Summary = tree.GetSummary() - if err = ctrl.cache.SetAppResourcesTree(app.Name, tree); err != nil { - logCtx.Errorf("Failed to cache resources tree: %v", err) - return - } - } - now := metav1.Now() - app.Status.ObservedAt = &now - ctrl.persistAppStatus(origApp, &app.Status) - return - } - } - - hasErrors := ctrl.refreshAppConditions(app) - if hasErrors { - app.Status.Sync.Status = appv1.SyncStatusCodeUnknown - app.Status.Health.Status = appv1.HealthStatusUnknown - ctrl.persistAppStatus(origApp, &app.Status) - return - } - - var localManifests []string - if opState := app.Status.OperationState; opState != nil && opState.Operation.Sync != nil { - localManifests = opState.Operation.Sync.Manifests - } - - revision := app.Spec.Source.TargetRevision - if comparisonLevel == CompareWithRecent { - revision = app.Status.Sync.Revision - } - - compareResult := ctrl.appStateManager.CompareAppState(app, revision, app.Spec.Source, refreshType == appv1.RefreshTypeHard, localManifests) - - ctrl.normalizeApplication(origApp, app) - - tree, err := ctrl.setAppManagedResources(app, compareResult) - if err != nil { - logCtx.Errorf("Failed to cache app resources: %v", err) - } else { - app.Status.Summary = tree.GetSummary() - } - - project, err := ctrl.getAppProj(app) - if err != nil { - logCtx.Infof("Could not lookup project for %s in order to check schedules state", app.Name) - } else { - if project.Spec.SyncWindows.Matches(app).CanSync(false) { - syncErrCond := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources) - if syncErrCond != nil { - app.Status.SetConditions([]appv1.ApplicationCondition{*syncErrCond}, map[appv1.ApplicationConditionType]bool{appv1.ApplicationConditionSyncError: true}) - } else { - app.Status.SetConditions([]appv1.ApplicationCondition{}, map[appv1.ApplicationConditionType]bool{appv1.ApplicationConditionSyncError: true}) - } - } else { - logCtx.Infof("Sync prevented by sync window") - } - } - - app.Status.ObservedAt = &compareResult.reconciledAt - app.Status.ReconciledAt = &compareResult.reconciledAt - app.Status.Sync = *compareResult.syncStatus - app.Status.Health = *compareResult.healthStatus - app.Status.Resources = compareResult.resources - app.Status.SourceType = compareResult.appSourceType - ctrl.persistAppStatus(origApp, &app.Status) - return -} - -// needRefreshAppStatus answers if application status needs to be refreshed. -// Returns true if application never been compared, has changed or comparison result has expired. -// Additionally returns whether full refresh was requested or not. -// If full refresh is requested then target and live state should be reconciled, else only live state tree should be updated. -func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, statusRefreshTimeout time.Duration) (bool, appv1.RefreshType, CompareWith) { - logCtx := log.WithFields(log.Fields{"application": app.Name}) - var reason string - compareWith := CompareWithLatest - refreshType := appv1.RefreshTypeNormal - expired := app.Status.ReconciledAt == nil || app.Status.ReconciledAt.Add(statusRefreshTimeout).Before(time.Now().UTC()) - if requestedType, ok := app.IsRefreshRequested(); ok || expired { - if ok { - refreshType = requestedType - reason = fmt.Sprintf("%s refresh requested", refreshType) - } else if expired { - reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout) - } - } else if requested, level := ctrl.isRefreshRequested(app.Name); requested { - compareWith = level - reason = fmt.Sprintf("controller refresh requested") - } else if app.Status.Sync.Status == appv1.SyncStatusCodeUnknown && expired { - reason = "comparison status unknown" - } 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" - } - if reason != "" { - logCtx.Infof("Refreshing app status (%s), level (%d)", reason, compareWith) - return true, refreshType, compareWith - } - return false, refreshType, compareWith -} - -func (ctrl *ApplicationController) refreshAppConditions(app *appv1.Application) bool { - errorConditions := make([]appv1.ApplicationCondition, 0) - proj, err := ctrl.getAppProj(app) - if err != nil { - if apierr.IsNotFound(err) { - errorConditions = append(errorConditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("Application referencing project %s which does not exist", app.Spec.Project), - }) - } else { - errorConditions = append(errorConditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionUnknownError, - Message: err.Error(), - }) - } - } else { - specConditions, err := argo.ValidatePermissions(context.Background(), &app.Spec, proj, ctrl.db) - if err != nil { - errorConditions = append(errorConditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionUnknownError, - Message: err.Error(), - }) - } else { - errorConditions = append(errorConditions, specConditions...) - } - } - app.Status.SetConditions(errorConditions, map[appv1.ApplicationConditionType]bool{ - appv1.ApplicationConditionInvalidSpecError: true, - appv1.ApplicationConditionUnknownError: true, - }) - return len(errorConditions) > 0 -} - -// normalizeApplication normalizes an application.spec and additionally persists updates if it changed -func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Application) { - logCtx := log.WithFields(log.Fields{"application": app.Name}) - app.Spec = *argo.NormalizeApplicationSpec(&app.Spec) - patch, modified, err := diff.CreateTwoWayMergePatch(orig, app, appv1.Application{}) - if err != nil { - logCtx.Errorf("error constructing app spec patch: %v", err) - } else if modified { - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = appClient.Patch(app.Name, types.MergePatchType, patch) - if err != nil { - logCtx.Errorf("Error persisting normalized application spec: %v", err) - } else { - logCtx.Infof("Normalized app spec: %s", string(patch)) - } - } -} - -// persistAppStatus persists updates to application status. If no changes were made, it is a no-op -func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, newStatus *appv1.ApplicationStatus) { - logCtx := log.WithFields(log.Fields{"application": orig.Name}) - if orig.Status.Sync.Status != newStatus.Sync.Status { - message := fmt.Sprintf("Updated sync status: %s -> %s", orig.Status.Sync.Status, newStatus.Sync.Status) - ctrl.auditLogger.LogAppEvent(orig, pkg.EventInfo{Reason: pkg.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message) - } - if orig.Status.Health.Status != newStatus.Health.Status { - message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status) - ctrl.auditLogger.LogAppEvent(orig, pkg.EventInfo{Reason: pkg.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message) - } - var newAnnotations map[string]string - if orig.GetAnnotations() != nil { - newAnnotations = make(map[string]string) - for k, v := range orig.GetAnnotations() { - newAnnotations[k] = v - } - delete(newAnnotations, common.AnnotationKeyRefresh) - } - patch, modified, err := diff.CreateTwoWayMergePatch( - &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: orig.GetAnnotations()}, Status: orig.Status}, - &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus}, appv1.Application{}) - if err != nil { - logCtx.Errorf("Error constructing app status patch: %v", err) - return - } - if !modified { - logCtx.Infof("No status changes. Skipping patch") - return - } - logCtx.Debugf("patch: %s", string(patch)) - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(orig.Namespace) - _, err = appClient.Patch(orig.Name, types.MergePatchType, patch) - if err != nil { - logCtx.Warnf("Error updating application: %v", err) - } else { - logCtx.Infof("Update successful") - } -} - -// autoSync will initiate a sync operation for an application configured with automated sync -func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *appv1.SyncStatus, resources []appv1.ResourceStatus) *appv1.ApplicationCondition { - if app.Spec.SyncPolicy == nil || app.Spec.SyncPolicy.Automated == nil { - return nil - } - logCtx := log.WithFields(log.Fields{"application": app.Name}) - if app.Operation != nil { - logCtx.Infof("Skipping auto-sync: another operation is in progress") - return nil - } - if app.DeletionTimestamp != nil && !app.DeletionTimestamp.IsZero() { - logCtx.Infof("Skipping auto-sync: deletion in progress") - return nil - } - - // Only perform auto-sync if we detect OutOfSync status. This is to prevent us from attempting - // a sync when application is already in a Synced or Unknown state - if syncStatus.Status != appv1.SyncStatusCodeOutOfSync { - logCtx.Infof("Skipping auto-sync: application status is %s", syncStatus.Status) - return nil - } - - desiredCommitSHA := syncStatus.Revision - alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA) - selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal - op := appv1.Operation{ - Sync: &appv1.SyncOperation{ - Revision: desiredCommitSHA, - Prune: app.Spec.SyncPolicy.Automated.Prune, - }, - } - // It is possible for manifests to remain OutOfSync even after a sync/kubectl apply (e.g. - // auto-sync with pruning disabled). We need to ensure that we do not keep Syncing an - // application in an infinite loop. To detect this, we only attempt the Sync if the revision - // and parameter overrides are different from our most recent sync operation. - if alreadyAttempted && (!selfHeal || !attemptPhase.Successful()) { - if !attemptPhase.Successful() { - logCtx.Warnf("Skipping auto-sync: failed previous sync attempt to %s", desiredCommitSHA) - message := fmt.Sprintf("Failed sync attempt to %s: %s", desiredCommitSHA, app.Status.OperationState.Message) - return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: message} - } - logCtx.Infof("Skipping auto-sync: most recent sync already to %s", desiredCommitSHA) - return nil - } else if alreadyAttempted && selfHeal { - if shouldSelfHeal, retryAfter := ctrl.shouldSelfHeal(app); shouldSelfHeal { - for _, resource := range resources { - if resource.Status != appv1.SyncStatusCodeSynced { - op.Sync.Resources = append(op.Sync.Resources, appv1.SyncOperationResource{ - Kind: resource.Kind, - Group: resource.Group, - Name: resource.Name, - }) - } - } - } else { - logCtx.Infof("Skipping auto-sync: already attempted sync to %s with timeout %v (retrying in %v)", desiredCommitSHA, ctrl.selfHealTimeout, retryAfter) - if key, err := cache.MetaNamespaceKeyFunc(app); err == nil { - ctrl.requestAppRefresh(app.Name, CompareWithLatest) - ctrl.appRefreshQueue.AddAfter(key, retryAfter) - } else { - logCtx.Warnf("Fails to requeue application: %v", err) - } - return nil - } - - } - - appIf := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err := argo.SetAppOperation(appIf, app.Name, &op) - if err != nil { - logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) - return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()} - } - message := fmt.Sprintf("Initiated automated sync to '%s'", desiredCommitSHA) - ctrl.auditLogger.LogAppEvent(app, pkg.EventInfo{Reason: pkg.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message) - logCtx.Info(message) - return nil -} - -// alreadyAttemptedSync returns whether or not the most recent sync was performed against the -// commitSHA and with the same app source config which are currently set in the app -func alreadyAttemptedSync(app *appv1.Application, commitSHA string) (bool, appv1.OperationPhase) { - if app.Status.OperationState == nil || app.Status.OperationState.Operation.Sync == nil || app.Status.OperationState.SyncResult == nil { - return false, "" - } - if app.Status.OperationState.SyncResult.Revision != commitSHA { - return false, "" - } - // Ignore differences in target revision, since we already just verified commitSHAs are equal, - // and we do not want to trigger auto-sync due to things like HEAD != master - specSource := app.Spec.Source.DeepCopy() - specSource.TargetRevision = "" - syncResSource := app.Status.OperationState.SyncResult.Source.DeepCopy() - syncResSource.TargetRevision = "" - return reflect.DeepEqual(app.Spec.Source, app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase -} - -func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, time.Duration) { - if app.Status.OperationState == nil { - return true, time.Duration(0) - } - - var retryAfter time.Duration - if app.Status.OperationState.FinishedAt == nil { - retryAfter = ctrl.selfHealTimeout - } else { - retryAfter = ctrl.selfHealTimeout - time.Since(app.Status.OperationState.FinishedAt.Time) - } - return retryAfter <= 0, retryAfter -} - -func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.SharedIndexInformer, applisters.ApplicationLister, error) { - appInformerFactory := appinformers.NewFilteredSharedInformerFactory( - ctrl.applicationClientset, - ctrl.statusRefreshTimeout, - ctrl.namespace, - func(options *metav1.ListOptions) {}, - ) - informer := appInformerFactory.Argoproj().V1alpha1().Applications().Informer() - lister := appInformerFactory.Argoproj().V1alpha1().Applications().Lister() - informer.AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - key, err := cache.MetaNamespaceKeyFunc(obj) - if err == nil { - ctrl.appRefreshQueue.Add(key) - ctrl.appOperationQueue.Add(key) - } - }, - UpdateFunc: func(old, new interface{}) { - key, err := cache.MetaNamespaceKeyFunc(new) - if err != nil { - return - } - oldApp, oldOK := old.(*appv1.Application) - newApp, newOK := new.(*appv1.Application) - if oldOK && newOK { - if toggledAutomatedSync(oldApp, newApp) { - log.WithField("application", newApp.Name).Info("Enabled automated sync") - ctrl.requestAppRefresh(newApp.Name, CompareWithLatest) - } - } - ctrl.appRefreshQueue.Add(key) - ctrl.appOperationQueue.Add(key) - }, - DeleteFunc: func(obj interface{}) { - // IndexerInformer uses a delta queue, therefore for deletes we have to use this - // key function. - key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - if err == nil { - ctrl.appRefreshQueue.Add(key) - } - }, - }, - ) - err := informer.AddIndexers(cache.Indexers{ - orphanedIndex: func(obj interface{}) (i []string, e error) { - app, ok := obj.(*appv1.Application) - if !ok { - return nil, nil - } - - proj, err := ctrl.getAppProj(app) - if err != nil { - return nil, nil - } - if proj.Spec.OrphanedResources != nil { - return []string{app.Spec.Destination.Namespace}, nil - } - return nil, nil - }, - }) - return informer, lister, err -} - -func isOperationInProgress(app *appv1.Application) bool { - return app.Status.OperationState != nil && !app.Status.OperationState.Phase.Completed() -} - -// toggledAutomatedSync tests if an app went from auto-sync disabled to enabled. -// if it was toggled to be enabled, the informer handler will force a refresh -func toggledAutomatedSync(old *appv1.Application, new *appv1.Application) bool { - if new.Spec.SyncPolicy == nil || new.Spec.SyncPolicy.Automated == nil { - return false - } - // auto-sync is enabled. check if it was previously disabled - if old.Spec.SyncPolicy == nil || old.Spec.SyncPolicy.Automated == nil { - return true - } - // nothing changed - return false -} diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go deleted file mode 100644 index 922097429..000000000 --- a/controller/appcontroller_test.go +++ /dev/null @@ -1,637 +0,0 @@ -package controller - -import ( - "context" - "testing" - "time" - - cachemocks "github.com/argoproj/argo-cd/engine/controller/cache/mocks" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/resource" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - corev1 "k8s.io/api/core/v1" - apierr "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - kubetesting "k8s.io/client-go/testing" - "k8s.io/client-go/tools/cache" - - "github.com/argoproj/argo-cd/engine/mocks" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/kube/kubetest" - - argoappv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/test" -) - -type namespacedResource struct { - argoappv1.ResourceNode - AppName string -} - -type fakeData struct { - apps []runtime.Object - manifestResponse *pkg.ManifestResponse - managedLiveObjs map[kube.ResourceKey]*unstructured.Unstructured - namespacedResources map[kube.ResourceKey]namespacedResource - settingsMockConfig func(settingsMock *mocks.ReconciliationSettings) -} - -func (fd *fakeData) Generate(ctx context.Context, repo *argoappv1.Repository, revision string, source *argoappv1.ApplicationSource, setting *pkg.ManifestGenerationSettings) (*pkg.ManifestResponse, error) { - return fd.manifestResponse, nil -} - -func newFakeController(data *fakeData) *ApplicationController { - credsStoreMock := &mocks.CredentialsStore{} - credsStoreMock.On("GetCluster", mock.Anything, mock.Anything).Return(&argoappv1.Cluster{}, nil) - credsStoreMock.On("ListHelmRepositories", mock.Anything).Return(nil, nil) - credsStoreMock.On("GetRepository", mock.Anything, mock.Anything).Return(&argoappv1.Repository{}, nil) - - settingsMock := &mocks.ReconciliationSettings{} - if data.settingsMockConfig != nil { - data.settingsMockConfig(settingsMock) - } else { - settingsMock.On("GetResourceOverrides").Return(map[string]argoappv1.ResourceOverride{}, nil) - settingsMock.On("GetAppInstanceLabelKey").Return("", nil) - settingsMock.On("GetConfigManagementPlugins").Return(nil, nil) - settingsMock.On("GetKustomizeBuildOptions").Return("", nil) - settingsMock.On("GetResourcesFilter").Return(&resource.ResourcesFilter{}, nil) - } - - auditLoggerMock := &mocks.AuditLogger{} - auditLoggerMock.On("LogAppEvent", mock.Anything, mock.Anything, mock.Anything) - - appStateCacheMock := &mocks.AppStateCache{} - appStateCacheMock.On("SetAppManagedResources", mock.Anything, mock.Anything).Return(nil) - appStateCacheMock.On("SetAppResourcesTree", mock.Anything, mock.Anything).Return(nil) - - kubectl := &kubetest.MockKubectlCmd{} - ctrl, err := NewApplicationController( - test.FakeArgoCDNamespace, - settingsMock, - credsStoreMock, - auditLoggerMock, - appclientset.NewSimpleClientset(data.apps...), - data, - appStateCacheMock, - kubectl, - time.Minute, - time.Minute, - 8082, - 0, - func() error { - return nil - }, - func(overrides map[string]argoappv1.ResourceOverride) *lua.VM { - return &lua.VM{ - ResourceOverrides: overrides, - } - }, - nil, - ) - if err != nil { - panic(err) - } - cancelProj := test.StartInformer(ctrl.projInformer) - defer cancelProj() - cancelApp := test.StartInformer(ctrl.appInformer) - defer cancelApp() - mockStateCache := cachemocks.LiveStateCache{} - ctrl.appStateManager.(*appStateManager).liveStateCache = &mockStateCache - ctrl.stateCache = &mockStateCache - mockStateCache.On("IsNamespaced", mock.Anything, mock.Anything).Return(true, nil) - mockStateCache.On("GetManagedLiveObjs", mock.Anything, mock.Anything).Return(data.managedLiveObjs, nil) - response := make(map[kube.ResourceKey]argoappv1.ResourceNode) - for k, v := range data.namespacedResources { - response[k] = v.ResourceNode - } - mockStateCache.On("GetNamespaceTopLevelResources", mock.Anything, mock.Anything).Return(response, nil) - mockStateCache.On("IterateHierarchy", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - key := args[1].(kube.ResourceKey) - action := args[2].(func(child argoappv1.ResourceNode, appName string)) - appName := "" - if res, ok := data.namespacedResources[key]; ok { - appName = res.AppName - } - action(argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Group: key.Group, Namespace: key.Namespace, Name: key.Name}}, appName) - }).Return(nil) - return ctrl -} - -var fakeApp = ` -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - uid: "123" - name: my-app - namespace: ` + test.FakeArgoCDNamespace + ` -spec: - destination: - namespace: ` + test.FakeDestNamespace + ` - server: https://localhost:6443 - project: default - source: - path: some/path - repoURL: https://github.com/argoproj/argocd-example-apps.git - syncPolicy: - automated: {} -status: - operationState: - finishedAt: 2018-09-21T23:50:29Z - message: successfully synced - operation: - sync: - revision: HEAD - phase: Succeeded - startedAt: 2018-09-21T23:50:25Z - syncResult: - resources: - - kind: RoleBinding - message: |- - rolebinding.rbac.authorization.k8s.io/always-outofsync reconciled - rolebinding.rbac.authorization.k8s.io/always-outofsync configured - name: always-outofsync - namespace: default - status: Synced - revision: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - source: - path: some/path - repoURL: https://github.com/argoproj/argocd-example-apps.git -` - -func newFakeApp() *argoappv1.Application { - var app argoappv1.Application - err := yaml.Unmarshal([]byte(fakeApp), &app) - if err != nil { - panic(err) - } - return &app -} - -func TestAutoSync(t *testing.T) { - app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.NotNil(t, app.Operation) - assert.NotNil(t, app.Operation.Sync) - assert.False(t, app.Operation.Sync.Prune) -} - -func TestSkipAutoSync(t *testing.T) { - // Verify we skip when we previously synced to it in our most recent history - // Set current to 'aaaaa', desired to 'aaaa' and mark system OutOfSync - { - app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) - } - - // Verify we skip when we are already Synced (even if revision is different) - { - app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeSynced, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) - } - - // Verify we skip when auto-sync is disabled - { - app := newFakeApp() - app.Spec.SyncPolicy = nil - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) - } - - // Verify we skip when application is marked for deletion - { - app := newFakeApp() - now := metav1.Now() - app.DeletionTimestamp = &now - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) - } - - // Verify we skip when previous sync attempt failed and return error condition - // Set current to 'aaaaa', desired to 'bbbbb' and add 'bbbbb' to failure history - { - app := newFakeApp() - app.Status.OperationState = &argoappv1.OperationState{ - Operation: argoappv1.Operation{ - Sync: &argoappv1.SyncOperation{}, - }, - Phase: argoappv1.OperationFailed, - SyncResult: &argoappv1.SyncOperationResult{ - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - Source: *app.Spec.Source.DeepCopy(), - }, - } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.NotNil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) - } -} - -// TestAutoSyncIndicateError verifies we skip auto-sync and return error condition if previous sync failed -func TestAutoSyncIndicateError(t *testing.T) { - app := newFakeApp() - app.Spec.Source.Helm = &argoappv1.ApplicationSourceHelm{ - Parameters: []argoappv1.HelmParameter{ - { - Name: "a", - Value: "1", - }, - }, - } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - } - app.Status.OperationState = &argoappv1.OperationState{ - Operation: argoappv1.Operation{ - Sync: &argoappv1.SyncOperation{ - Source: app.Spec.Source.DeepCopy(), - }, - }, - Phase: argoappv1.OperationFailed, - SyncResult: &argoappv1.SyncOperationResult{ - Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - Source: *app.Spec.Source.DeepCopy(), - }, - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.NotNil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.Nil(t, app.Operation) -} - -// TestAutoSyncParameterOverrides verifies we auto-sync if revision is same but parameter overrides are different -func TestAutoSyncParameterOverrides(t *testing.T) { - app := newFakeApp() - app.Spec.Source.Helm = &argoappv1.ApplicationSourceHelm{ - Parameters: []argoappv1.HelmParameter{ - { - Name: "a", - Value: "1", - }, - }, - } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - syncStatus := argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeOutOfSync, - Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - } - app.Status.OperationState = &argoappv1.OperationState{ - Operation: argoappv1.Operation{ - Sync: &argoappv1.SyncOperation{ - Source: &argoappv1.ApplicationSource{ - Helm: &argoappv1.ApplicationSourceHelm{ - Parameters: []argoappv1.HelmParameter{ - { - Name: "a", - Value: "2", // this value changed - }, - }, - }, - }, - }, - }, - Phase: argoappv1.OperationFailed, - SyncResult: &argoappv1.SyncOperationResult{ - Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - }, - } - cond := ctrl.autoSync(app, &syncStatus, []argoappv1.ResourceStatus{}) - assert.Nil(t, cond) - app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get("my-app", metav1.GetOptions{}) - assert.NoError(t, err) - assert.NotNil(t, app.Operation) -} - -// TestFinalizeAppDeletion verifies application deletion -func TestFinalizeAppDeletion(t *testing.T) { - app := newFakeApp() - app.Spec.Destination.Namespace = test.FakeArgoCDNamespace - appObj := kube.MustToUnstructured(&app) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(appObj): appObj, - }}) - - patched := false - fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - defaultReactor := fakeAppCs.ReactionChain[0] - fakeAppCs.ReactionChain = nil - fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { - return defaultReactor.React(action) - }) - fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { - patched = true - return true, nil, nil - }) - err := ctrl.finalizeApplicationDeletion(app) - assert.NoError(t, err) - assert.True(t, patched) -} - -// TestNormalizeApplication verifies we normalize an application during reconciliation -func TestNormalizeApplication(t *testing.T) { - defaultProj := argoappv1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: test.FakeArgoCDNamespace, - }, - Spec: argoappv1.AppProjectSpec{ - SourceRepos: []string{"*"}, - Destinations: []argoappv1.ApplicationDestination{ - { - Server: "*", - Namespace: "*", - }, - }, - }, - } - app := newFakeApp() - app.Spec.Project = "" - app.Spec.Source.Kustomize = &argoappv1.ApplicationSourceKustomize{NamePrefix: "foo-"} - data := fakeData{ - apps: []runtime.Object{app, &defaultProj}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - - { - // Verify we normalize the app because project is missing - ctrl := newFakeController(&data) - key, _ := cache.MetaNamespaceKeyFunc(app) - ctrl.appRefreshQueue.Add(key) - fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - fakeAppCs.ReactionChain = nil - normalized := false - fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { - if patchAction, ok := action.(kubetesting.PatchAction); ok { - if string(patchAction.GetPatch()) == `{"spec":{"project":"default"}}` { - normalized = true - } - } - return true, nil, nil - }) - ctrl.processAppRefreshQueueItem() - assert.True(t, normalized) - } - - { - // Verify we don't unnecessarily normalize app when project is set - app.Spec.Project = "default" - data.apps[0] = app - ctrl := newFakeController(&data) - key, _ := cache.MetaNamespaceKeyFunc(app) - ctrl.appRefreshQueue.Add(key) - fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - fakeAppCs.ReactionChain = nil - normalized := false - fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { - if patchAction, ok := action.(kubetesting.PatchAction); ok { - if string(patchAction.GetPatch()) == `{"spec":{"project":"default"}}` { - normalized = true - } - } - return true, nil, nil - }) - ctrl.processAppRefreshQueueItem() - assert.False(t, normalized) - } -} - -func TestHandleAppUpdated(t *testing.T) { - app := newFakeApp() - app.Spec.Destination.Namespace = test.FakeArgoCDNamespace - app.Spec.Destination.Server = common.KubernetesInternalAPIServerAddr - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) - - ctrl.handleObjectUpdated(map[string]bool{app.Name: true}, kube.GetObjectRef(kube.MustToUnstructured(app))) - isRequested, level := ctrl.isRefreshRequested(app.Name) - assert.False(t, isRequested) - assert.Equal(t, ComparisonWithNothing, level) - - ctrl.handleObjectUpdated(map[string]bool{app.Name: true}, corev1.ObjectReference{UID: "test", Kind: kube.DeploymentKind, Name: "test", Namespace: "default"}) - isRequested, level = ctrl.isRefreshRequested(app.Name) - assert.True(t, isRequested) - assert.Equal(t, CompareWithRecent, level) -} - -func TestHandleOrphanedResourceUpdated(t *testing.T) { - app1 := newFakeApp() - app1.Name = "app1" - app1.Spec.Destination.Namespace = test.FakeArgoCDNamespace - app1.Spec.Destination.Server = common.KubernetesInternalAPIServerAddr - - app2 := newFakeApp() - app2.Name = "app2" - app2.Spec.Destination.Namespace = test.FakeArgoCDNamespace - app2.Spec.Destination.Server = common.KubernetesInternalAPIServerAddr - - proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} - - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app1, app2, proj}}) - - ctrl.handleObjectUpdated(map[string]bool{}, corev1.ObjectReference{UID: "test", Kind: kube.DeploymentKind, Name: "test", Namespace: test.FakeArgoCDNamespace}) - - isRequested, level := ctrl.isRefreshRequested(app1.Name) - assert.True(t, isRequested) - assert.Equal(t, ComparisonWithNothing, level) - - isRequested, level = ctrl.isRefreshRequested(app2.Name) - assert.True(t, isRequested) - assert.Equal(t, ComparisonWithNothing, level) -} - -func TestSetOperationStateOnDeletedApp(t *testing.T) { - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) - fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) - fakeAppCs.ReactionChain = nil - patched := false - fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { - patched = true - return true, nil, apierr.NewNotFound(schema.GroupResource{}, "my-app") - }) - ctrl.setOperationState(newFakeApp(), &argoappv1.OperationState{Phase: argoappv1.OperationSucceeded}) - assert.True(t, patched) -} - -func TestNeedRefreshAppStatus(t *testing.T) { - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) - - app := newFakeApp() - now := metav1.Now() - app.Status.ReconciledAt = &now - app.Status.Sync = argoappv1.SyncStatus{ - Status: argoappv1.SyncStatusCodeSynced, - ComparedTo: argoappv1.ComparedTo{ - Source: app.Spec.Source, - Destination: app.Spec.Destination, - }, - } - - // no need to refresh just reconciled application - needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour) - assert.False(t, needRefresh) - - // refresh app using the 'deepest' requested comparison level - ctrl.requestAppRefresh(app.Name, CompareWithRecent) - ctrl.requestAppRefresh(app.Name, ComparisonWithNothing) - - needRefresh, refreshType, compareWith := ctrl.needRefreshAppStatus(app, 1*time.Hour) - assert.True(t, needRefresh) - assert.Equal(t, argoappv1.RefreshTypeNormal, refreshType) - assert.Equal(t, CompareWithRecent, compareWith) - - // refresh application which status is not reconciled using latest commit - app.Status.Sync = argoappv1.SyncStatus{Status: argoappv1.SyncStatusCodeUnknown} - - needRefresh, refreshType, compareWith = ctrl.needRefreshAppStatus(app, 1*time.Hour) - assert.True(t, needRefresh) - assert.Equal(t, argoappv1.RefreshTypeNormal, refreshType) - assert.Equal(t, CompareWithLatest, compareWith) - - { - // 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) - } - - { - 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) - } -} - -func TestRefreshAppConditions(t *testing.T) { - defaultProj := argoappv1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: test.FakeArgoCDNamespace, - }, - Spec: argoappv1.AppProjectSpec{ - SourceRepos: []string{"*"}, - Destinations: []argoappv1.ApplicationDestination{ - { - Server: "*", - Namespace: "*", - }, - }, - }, - } - - t.Run("NoErrorConditions", func(t *testing.T) { - app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) - - hasErrors := ctrl.refreshAppConditions(app) - assert.False(t, hasErrors) - assert.Len(t, app.Status.Conditions, 0) - }) - - t.Run("PreserveExistingWarningCondition", func(t *testing.T) { - app := newFakeApp() - app.Status.SetConditions([]argoappv1.ApplicationCondition{{Type: argoappv1.ApplicationConditionExcludedResourceWarning}}, nil) - - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) - - hasErrors := ctrl.refreshAppConditions(app) - assert.False(t, hasErrors) - assert.Len(t, app.Status.Conditions, 1) - assert.Equal(t, argoappv1.ApplicationConditionExcludedResourceWarning, app.Status.Conditions[0].Type) - }) - - t.Run("ReplacesSpecErrorCondition", func(t *testing.T) { - app := newFakeApp() - app.Spec.Project = "wrong project" - app.Status.SetConditions([]argoappv1.ApplicationCondition{{Type: argoappv1.ApplicationConditionInvalidSpecError, Message: "old message"}}, nil) - - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) - - hasErrors := ctrl.refreshAppConditions(app) - assert.True(t, hasErrors) - assert.Len(t, app.Status.Conditions, 1) - assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, app.Status.Conditions[0].Type) - assert.Equal(t, "Application referencing project wrong project which does not exist", app.Status.Conditions[0].Message) - }) -} diff --git a/controller/cache/cache.go b/controller/cache/cache.go deleted file mode 100644 index b77e8eed7..000000000 --- a/controller/cache/cache.go +++ /dev/null @@ -1,287 +0,0 @@ -package cache - -import ( - "context" - "reflect" - "sync" - - "github.com/argoproj/argo-cd/engine/controller/metrics" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/util/lua" - "github.com/argoproj/argo-cd/engine/util/misc" - - "github.com/argoproj/argo-cd/engine/resource" - - log "github.com/sirupsen/logrus" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/tools/cache" - - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" -) - -type cacheSettings struct { - ResourceOverrides map[string]appv1.ResourceOverride - AppInstanceLabelKey string - ResourcesFilter *resource.ResourcesFilter -} - -type LiveStateCache interface { - IsNamespaced(server string, gk schema.GroupKind) (bool, error) - // Executes give callback against resource specified by the key and all its children - IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string)) error - // Returns state of live nodes which correspond for target nodes of specified application. - GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) - // Returns all top level resources (resources without owner references) of a specified namespace - GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) - // Starts watching resources of each controlled cluster. - Run(ctx context.Context) error - // Invalidate invalidates the entire cluster state cache - Invalidate() -} - -type ObjectUpdatedHandler = func(managedByApp map[string]bool, ref v1.ObjectReference) - -func GetTargetObjKey(a *appv1.Application, un *unstructured.Unstructured, isNamespaced bool) kube.ResourceKey { - key := kube.GetResourceKey(un) - if !isNamespaced { - key.Namespace = "" - } else if isNamespaced && key.Namespace == "" { - key.Namespace = a.Spec.Destination.Namespace - } - - return key -} -func NewLiveStateCache( - db pkg.CredentialsStore, - appInformer cache.SharedIndexInformer, - settingsMgr pkg.ReconciliationSettings, - kubectl kube.Kubectl, - metricsServer *metrics.MetricsServer, - onObjectUpdated ObjectUpdatedHandler, - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM, - callbacks pkg.Callbacks) LiveStateCache { - - return &liveStateCache{ - appInformer: appInformer, - db: db, - clusters: make(map[string]*clusterInfo), - lock: &sync.Mutex{}, - onObjectUpdated: onObjectUpdated, - kubectl: kubectl, - settingsMgr: settingsMgr, - metricsServer: metricsServer, - cacheSettingsLock: &sync.Mutex{}, - luaVMFactory: luaVMFactory, - callbacks: callbacks, - } -} - -type liveStateCache struct { - db pkg.CredentialsStore - clusters map[string]*clusterInfo - lock *sync.Mutex - appInformer cache.SharedIndexInformer - onObjectUpdated ObjectUpdatedHandler - kubectl kube.Kubectl - settingsMgr pkg.ReconciliationSettings - metricsServer *metrics.MetricsServer - cacheSettingsLock *sync.Mutex - cacheSettings *cacheSettings - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM - callbacks pkg.Callbacks -} - -func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) { - appInstanceLabelKey, err := c.settingsMgr.GetAppInstanceLabelKey() - if err != nil { - return nil, err - } - resourcesFilter, err := c.settingsMgr.GetResourcesFilter() - if err != nil { - return nil, err - } - resourceOverrides, err := c.settingsMgr.GetResourceOverrides() - if err != nil { - return nil, err - } - return &cacheSettings{AppInstanceLabelKey: appInstanceLabelKey, ResourceOverrides: resourceOverrides, ResourcesFilter: resourcesFilter}, nil -} - -func (c *liveStateCache) getCluster(server string) (*clusterInfo, error) { - c.lock.Lock() - defer c.lock.Unlock() - info, ok := c.clusters[server] - if !ok { - cluster, err := c.db.GetCluster(context.Background(), server) - if err != nil { - return nil, err - } - info = &clusterInfo{ - apisMeta: make(map[schema.GroupKind]*apiMeta), - lock: &sync.Mutex{}, - nodes: make(map[kube.ResourceKey]*node), - nsIndex: make(map[string]map[kube.ResourceKey]*node), - onObjectUpdated: c.onObjectUpdated, - kubectl: c.kubectl, - cluster: cluster, - syncTime: nil, - syncLock: &sync.Mutex{}, - log: log.WithField("server", cluster.Server), - cacheSettingsSrc: c.getCacheSettings, - luaVMFactory: c.luaVMFactory, - callbacks: c.callbacks, - } - - c.clusters[cluster.Server] = info - } - return info, nil -} - -func (c *liveStateCache) getSyncedCluster(server string) (*clusterInfo, error) { - info, err := c.getCluster(server) - if err != nil { - return nil, err - } - err = info.ensureSynced() - if err != nil { - return nil, err - } - return info, nil -} - -func (c *liveStateCache) Invalidate() { - log.Info("invalidating live state cache") - c.lock.Lock() - defer c.lock.Unlock() - for _, clust := range c.clusters { - clust.lock.Lock() - clust.invalidate() - clust.lock.Unlock() - } - log.Info("live state cache invalidated") -} - -func (c *liveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool, error) { - clusterInfo, err := c.getSyncedCluster(server) - if err != nil { - return false, err - } - return clusterInfo.isNamespaced(gk), nil -} - -func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string)) error { - clusterInfo, err := c.getSyncedCluster(server) - if err != nil { - return err - } - clusterInfo.iterateHierarchy(key, action) - return nil -} - -func (c *liveStateCache) GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]appv1.ResourceNode, error) { - clusterInfo, err := c.getSyncedCluster(server) - if err != nil { - return nil, err - } - return clusterInfo.getNamespaceTopLevelResources(namespace), nil -} - -func (c *liveStateCache) GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - clusterInfo, err := c.getSyncedCluster(a.Spec.Destination.Server) - if err != nil { - return nil, err - } - return clusterInfo.getManagedLiveObjs(a, targetObjs, c.metricsServer) -} - -func isClusterHasApps(apps []interface{}, cluster *appv1.Cluster) bool { - for _, obj := range apps { - if app, ok := obj.(*appv1.Application); ok && app.Spec.Destination.Server == cluster.Server { - return true - } - } - return false -} - -func (c *liveStateCache) getCacheSettings() *cacheSettings { - c.cacheSettingsLock.Lock() - defer c.cacheSettingsLock.Unlock() - return c.cacheSettings -} - -func (c *liveStateCache) watchSettings(ctx context.Context) { - updateCh := make(chan bool, 1) - c.settingsMgr.Subscribe(updateCh) - - done := false - for !done { - select { - case <-updateCh: - nextCacheSettings, err := c.loadCacheSettings() - if err != nil { - log.Warnf("Failed to read updated settings: %v", err) - continue - } - - c.cacheSettingsLock.Lock() - needInvalidate := false - if !reflect.DeepEqual(c.cacheSettings, nextCacheSettings) { - c.cacheSettings = nextCacheSettings - needInvalidate = true - } - c.cacheSettingsLock.Unlock() - if needInvalidate { - c.Invalidate() - } - case <-ctx.Done(): - done = true - } - } - log.Info("shutting down settings watch") - c.settingsMgr.Unsubscribe(updateCh) - close(updateCh) -} - -// Run watches for resource changes annotated with application label on all registered clusters and schedule corresponding app refresh. -func (c *liveStateCache) Run(ctx context.Context) error { - cacheSettings, err := c.loadCacheSettings() - if err != nil { - return err - } - c.cacheSettings = cacheSettings - - go c.watchSettings(ctx) - - misc.RetryUntilSucceed(func() error { - clusterEventCallback := func(event *pkg.ClusterEvent) { - c.lock.Lock() - defer c.lock.Unlock() - if cluster, ok := c.clusters[event.Cluster.Server]; ok { - if event.Type == watch.Deleted { - cluster.invalidate() - delete(c.clusters, event.Cluster.Server) - } else if event.Type == watch.Modified { - cluster.cluster = event.Cluster - cluster.invalidate() - } - } else if event.Type == watch.Added && isClusterHasApps(c.appInformer.GetStore().List(), event.Cluster) { - go func() { - // warm up cache for cluster with apps - _, _ = c.getSyncedCluster(event.Cluster.Server) - }() - } - } - - return c.db.WatchClusters(ctx, clusterEventCallback) - - }, "watch clusters", ctx, clusterRetryTimeout) - - <-ctx.Done() - return nil -} diff --git a/controller/cache/cluster.go b/controller/cache/cluster.go deleted file mode 100644 index a0cbbc2d2..000000000 --- a/controller/cache/cluster.go +++ /dev/null @@ -1,558 +0,0 @@ -package cache - -import ( - "context" - "fmt" - "runtime/debug" - "sort" - "strings" - "sync" - "time" - - "github.com/argoproj/argo-cd/engine/controller/metrics" - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/argoproj/argo-cd/engine/util/misc" - - "k8s.io/apimachinery/pkg/types" - - log "github.com/sirupsen/logrus" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/health" - "github.com/argoproj/argo-cd/engine/util/kube" -) - -const ( - clusterSyncTimeout = 24 * time.Hour - clusterRetryTimeout = 10 * time.Second - watchResourcesRetryTimeout = 1 * time.Second -) - -type apiMeta struct { - namespaced bool - resourceVersion string - watchCancel context.CancelFunc -} - -type clusterInfo struct { - syncLock *sync.Mutex - syncTime *time.Time - syncError error - apisMeta map[schema.GroupKind]*apiMeta - - lock *sync.Mutex - nodes map[kube.ResourceKey]*node - nsIndex map[string]map[kube.ResourceKey]*node - - onObjectUpdated ObjectUpdatedHandler - kubectl kube.Kubectl - cluster *appv1.Cluster - log *log.Entry - cacheSettingsSrc func() *cacheSettings - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM - callbacks pkg.Callbacks -} - -func (c *clusterInfo) replaceResourceCache(gk schema.GroupKind, resourceVersion string, objs []unstructured.Unstructured) { - c.lock.Lock() - defer c.lock.Unlock() - info, ok := c.apisMeta[gk] - if ok { - objByKind := make(map[kube.ResourceKey]*unstructured.Unstructured) - for i := range objs { - objByKind[kube.GetResourceKey(&objs[i])] = &objs[i] - } - - for i := range objs { - obj := &objs[i] - key := kube.GetResourceKey(&objs[i]) - existingNode, exists := c.nodes[key] - c.onNodeUpdated(exists, existingNode, obj, key) - } - - for key, existingNode := range c.nodes { - if key.Kind != gk.Kind || key.Group != gk.Group { - continue - } - - if _, ok := objByKind[key]; !ok { - c.onNodeRemoved(key, existingNode) - } - } - info.resourceVersion = resourceVersion - } -} - -func isServiceAccountTokenSecret(un *unstructured.Unstructured) (bool, metav1.OwnerReference) { - ref := metav1.OwnerReference{ - APIVersion: "v1", - Kind: kube.ServiceAccountKind, - } - if un.GetKind() != kube.SecretKind || un.GroupVersionKind().Group != "" { - return false, ref - } - - if typeVal, ok, err := unstructured.NestedString(un.Object, "type"); !ok || err != nil || typeVal != "kubernetes.io/service-account-token" { - return false, ref - } - - annotations := un.GetAnnotations() - if annotations == nil { - return false, ref - } - - id, okId := annotations["kubernetes.io/service-account.uid"] - name, okName := annotations["kubernetes.io/service-account.name"] - if okId && okName { - ref.Name = name - ref.UID = types.UID(id) - } - return ref.Name != "" && ref.UID != "", ref -} - -func (c *clusterInfo) createObjInfo(un *unstructured.Unstructured, appInstanceLabel string) *node { - ownerRefs := un.GetOwnerReferences() - // Special case for endpoint. Remove after https://github.com/kubernetes/kubernetes/issues/28483 is fixed - if un.GroupVersionKind().Group == "" && un.GetKind() == kube.EndpointsKind && len(un.GetOwnerReferences()) == 0 { - ownerRefs = append(ownerRefs, metav1.OwnerReference{ - Name: un.GetName(), - Kind: kube.ServiceKind, - APIVersion: "v1", - }) - } - - // edge case. Consider auto-created service account tokens as a child of service account objects - if yes, ref := isServiceAccountTokenSecret(un); yes { - ownerRefs = append(ownerRefs, ref) - } - - nodeInfo := &node{ - resourceVersion: un.GetResourceVersion(), - ref: kube.GetObjectRef(un), - ownerRefs: ownerRefs, - } - - populateNodeInfo(un, nodeInfo) - appName := kube.GetAppInstanceLabel(un, appInstanceLabel) - if len(ownerRefs) == 0 && appName != "" { - nodeInfo.appName = appName - nodeInfo.resource = un - } - vm := c.luaVMFactory(c.cacheSettingsSrc().ResourceOverrides) - nodeInfo.health, _ = health.GetResourceHealth(un, vm) - return nodeInfo -} - -func (c *clusterInfo) setNode(n *node) { - key := n.resourceKey() - c.nodes[key] = n - ns, ok := c.nsIndex[key.Namespace] - if !ok { - ns = make(map[kube.ResourceKey]*node) - c.nsIndex[key.Namespace] = ns - } - ns[key] = n -} - -func (c *clusterInfo) removeNode(key kube.ResourceKey) { - delete(c.nodes, key) - if ns, ok := c.nsIndex[key.Namespace]; ok { - delete(ns, key) - if len(ns) == 0 { - delete(c.nsIndex, key.Namespace) - } - } -} - -func (c *clusterInfo) invalidate() { - c.syncLock.Lock() - defer c.syncLock.Unlock() - c.syncTime = nil - for i := range c.apisMeta { - c.apisMeta[i].watchCancel() - } - c.apisMeta = nil -} - -func (c *clusterInfo) synced() bool { - if c.syncTime == nil { - return false - } - if c.syncError != nil { - return time.Now().Before(c.syncTime.Add(clusterRetryTimeout)) - } - return time.Now().Before(c.syncTime.Add(clusterSyncTimeout)) -} - -func (c *clusterInfo) stopWatching(gk schema.GroupKind) { - c.syncLock.Lock() - defer c.syncLock.Unlock() - if info, ok := c.apisMeta[gk]; ok { - info.watchCancel() - delete(c.apisMeta, gk) - c.replaceResourceCache(gk, "", []unstructured.Unstructured{}) - log.Warnf("Stop watching %s not found on %s.", gk, c.cluster.Server) - } -} - -// startMissingWatches lists supported cluster resources and start watching for changes unless watch is already running -func (c *clusterInfo) startMissingWatches() error { - - apis, err := c.kubectl.GetAPIResources(c.cluster.RESTConfig(), c.cacheSettingsSrc().ResourcesFilter) - if err != nil { - return err - } - - for i := range apis { - api := apis[i] - if _, ok := c.apisMeta[api.GroupKind]; !ok { - ctx, cancel := context.WithCancel(context.Background()) - info := &apiMeta{namespaced: api.Meta.Namespaced, watchCancel: cancel} - c.apisMeta[api.GroupKind] = info - go c.watchEvents(ctx, api, info) - } - } - return nil -} - -func runSynced(lock *sync.Mutex, action func() error) error { - lock.Lock() - defer lock.Unlock() - return action() -} - -func (c *clusterInfo) watchEvents(ctx context.Context, api kube.APIResourceInfo, info *apiMeta) { - misc.RetryUntilSucceed(func() (err error) { - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) - } - }() - - err = runSynced(c.syncLock, func() error { - if info.resourceVersion == "" { - list, err := api.Interface.List(metav1.ListOptions{}) - if err != nil { - return err - } - c.replaceResourceCache(api.GroupKind, list.GetResourceVersion(), list.Items) - } - return nil - }) - - if err != nil { - return err - } - - w, err := api.Interface.Watch(metav1.ListOptions{ResourceVersion: info.resourceVersion}) - if errors.IsNotFound(err) { - c.stopWatching(api.GroupKind) - return nil - } - - err = runSynced(c.syncLock, func() error { - if errors.IsGone(err) { - info.resourceVersion = "" - log.Warnf("Resource version of %s on %s is too old.", api.GroupKind, c.cluster.Server) - } - return err - }) - - if err != nil { - return err - } - defer w.Stop() - for { - select { - case <-ctx.Done(): - return nil - case event, ok := <-w.ResultChan(): - if ok { - obj := event.Object.(*unstructured.Unstructured) - info.resourceVersion = obj.GetResourceVersion() - c.processEvent(event.Type, obj) - if kube.IsCRD(obj) { - if event.Type == watch.Deleted { - group, groupOk, groupErr := unstructured.NestedString(obj.Object, "spec", "group") - kind, kindOk, kindErr := unstructured.NestedString(obj.Object, "spec", "names", "kind") - - if groupOk && groupErr == nil && kindOk && kindErr == nil { - gk := schema.GroupKind{Group: group, Kind: kind} - c.stopWatching(gk) - } - } else { - err = runSynced(c.syncLock, func() error { - return c.startMissingWatches() - }) - - } - } - if err != nil { - log.Warnf("Failed to start missing watch: %v", err) - } - } else { - return fmt.Errorf("Watch %s on %s has closed", api.GroupKind, c.cluster.Server) - } - } - } - - }, fmt.Sprintf("watch %s on %s", api.GroupKind, c.cluster.Server), ctx, watchResourcesRetryTimeout) -} - -func (c *clusterInfo) sync() (err error) { - - c.log.Info("Start syncing cluster") - - for i := range c.apisMeta { - c.apisMeta[i].watchCancel() - } - c.apisMeta = make(map[schema.GroupKind]*apiMeta) - c.nodes = make(map[kube.ResourceKey]*node) - - apis, err := c.kubectl.GetAPIResources(c.cluster.RESTConfig(), c.cacheSettingsSrc().ResourcesFilter) - if err != nil { - return err - } - lock := sync.Mutex{} - err = misc.RunAllAsync(len(apis), func(i int) error { - api := apis[i] - list, err := api.Interface.List(metav1.ListOptions{}) - if err != nil { - return err - } - - lock.Lock() - for i := range list.Items { - c.callbacks.OnResourceUpdated(&list.Items[i]) - c.setNode(c.createObjInfo(&list.Items[i], c.cacheSettingsSrc().AppInstanceLabelKey)) - } - lock.Unlock() - return nil - }) - - if err == nil { - err = c.startMissingWatches() - } - - if err != nil { - log.Errorf("Failed to sync cluster %s: %v", c.cluster.Server, err) - return err - } - - c.log.Info("Cluster successfully synced") - return nil -} - -func (c *clusterInfo) ensureSynced() error { - c.syncLock.Lock() - defer c.syncLock.Unlock() - if c.synced() { - return c.syncError - } - - err := c.sync() - if err == nil { - c.callbacks.OnClusterInitialized(c.cluster.Server) - } - syncTime := time.Now() - c.syncTime = &syncTime - c.syncError = err - return c.syncError -} - -func (c *clusterInfo) getNamespaceTopLevelResources(namespace string) map[kube.ResourceKey]appv1.ResourceNode { - c.lock.Lock() - defer c.lock.Unlock() - nodes := make(map[kube.ResourceKey]appv1.ResourceNode) - for _, node := range c.nsIndex[namespace] { - if len(node.ownerRefs) == 0 { - nodes[node.resourceKey()] = node.asResourceNode() - } - } - return nodes -} - -func (c *clusterInfo) iterateHierarchy(key kube.ResourceKey, action func(child appv1.ResourceNode, appName string)) { - c.lock.Lock() - defer c.lock.Unlock() - if objInfo, ok := c.nodes[key]; ok { - nsNodes := c.nsIndex[key.Namespace] - action(objInfo.asResourceNode(), objInfo.getApp(nsNodes)) - childrenByUID := make(map[types.UID][]*node) - for _, child := range nsNodes { - if objInfo.isParentOf(child) { - childrenByUID[child.ref.UID] = append(childrenByUID[child.ref.UID], child) - } - } - // make sure children has no duplicates - for _, children := range childrenByUID { - if len(children) > 0 { - // The object might have multiple children with the same UID (e.g. replicaset from apps and extensions group). It is ok to pick any object but we need to make sure - // we pick the same child after every refresh. - sort.Slice(children, func(i, j int) bool { - key1 := children[i].resourceKey() - key2 := children[j].resourceKey() - return strings.Compare(key1.String(), key2.String()) < 0 - }) - child := children[0] - action(child.asResourceNode(), child.getApp(nsNodes)) - child.iterateChildren(nsNodes, map[kube.ResourceKey]bool{objInfo.resourceKey(): true}, action) - } - } - } -} - -func (c *clusterInfo) isNamespaced(gk schema.GroupKind) bool { - if api, ok := c.apisMeta[gk]; ok && !api.namespaced { - return false - } - return true -} - -func (c *clusterInfo) getManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured, metricsServer *metrics.MetricsServer) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - c.lock.Lock() - defer c.lock.Unlock() - - managedObjs := make(map[kube.ResourceKey]*unstructured.Unstructured) - // iterate all objects in live state cache to find ones associated with app - for key, o := range c.nodes { - if o.appName == a.Name && o.resource != nil && len(o.ownerRefs) == 0 { - managedObjs[key] = o.resource - } - } - config := metrics.AddMetricsTransportWrapper(metricsServer, a, c.cluster.RESTConfig()) - // iterate target objects and identify ones that already exist in the cluster,\ - // but are simply missing our label - lock := &sync.Mutex{} - err := misc.RunAllAsync(len(targetObjs), func(i int) error { - targetObj := targetObjs[i] - key := GetTargetObjKey(a, targetObj, c.isNamespaced(targetObj.GroupVersionKind().GroupKind())) - lock.Lock() - managedObj := managedObjs[key] - lock.Unlock() - - if managedObj == nil { - if existingObj, exists := c.nodes[key]; exists { - if existingObj.resource != nil { - managedObj = existingObj.resource - } else { - var err error - managedObj, err = c.kubectl.GetResource(config, targetObj.GroupVersionKind(), existingObj.ref.Name, existingObj.ref.Namespace) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - } - } else if _, watched := c.apisMeta[key.GroupKind()]; !watched { - var err error - managedObj, err = c.kubectl.GetResource(config, targetObj.GroupVersionKind(), targetObj.GetName(), targetObj.GetNamespace()) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - } - } - - if managedObj != nil { - converted, err := c.kubectl.ConvertToVersion(managedObj, targetObj.GroupVersionKind().Group, targetObj.GroupVersionKind().Version) - if err != nil { - // fallback to loading resource from kubernetes if conversion fails - log.Warnf("Failed to convert resource: %v", err) - managedObj, err = c.kubectl.GetResource(config, targetObj.GroupVersionKind(), managedObj.GetName(), managedObj.GetNamespace()) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - } else { - managedObj = converted - } - lock.Lock() - managedObjs[key] = managedObj - lock.Unlock() - } - return nil - }) - if err != nil { - return nil, err - } - - return managedObjs, nil -} - -func (c *clusterInfo) processEvent(event watch.EventType, un *unstructured.Unstructured) { - c.lock.Lock() - defer c.lock.Unlock() - key := kube.GetResourceKey(un) - existingNode, exists := c.nodes[key] - if event == watch.Deleted { - if exists { - c.onNodeRemoved(key, existingNode) - } - } else if event != watch.Deleted { - c.onNodeUpdated(exists, existingNode, un, key) - } -} - -func (c *clusterInfo) onNodeUpdated(exists bool, existingNode *node, un *unstructured.Unstructured, key kube.ResourceKey) { - nodes := make([]*node, 0) - if exists { - nodes = append(nodes, existingNode) - } - newObj := c.createObjInfo(un, c.cacheSettingsSrc().AppInstanceLabelKey) - c.setNode(newObj) - c.callbacks.OnResourceUpdated(un) - nodes = append(nodes, newObj) - toNotify := make(map[string]bool) - for i := range nodes { - n := nodes[i] - if ns, ok := c.nsIndex[n.ref.Namespace]; ok { - app := n.getApp(ns) - if app == "" || skipAppRequeing(key) { - continue - } - toNotify[app] = n.isRootAppNode() || toNotify[app] - } - } - c.onObjectUpdated(toNotify, newObj.ref) - c.callbacks.OnResourceUpdated(un) -} - -func (c *clusterInfo) onNodeRemoved(key kube.ResourceKey, n *node) { - appName := n.appName - if ns, ok := c.nsIndex[key.Namespace]; ok { - appName = n.getApp(ns) - } - - c.removeNode(key) - managedByApp := make(map[string]bool) - if appName != "" { - managedByApp[appName] = n.isRootAppNode() - } - c.onObjectUpdated(managedByApp, n.ref) -} - -var ( - ignoredRefreshResources = map[string]bool{ - "/" + kube.EndpointsKind: true, - } -) - -// skipAppRequeing checks if the object is an API type which we want to skip requeuing against. -// We ignore API types which have a high churn rate, and/or whose updates are irrelevant to the app -func skipAppRequeing(key kube.ResourceKey) bool { - return ignoredRefreshResources[key.Group+"/"+key.Kind] -} diff --git a/controller/cache/cluster_test.go b/controller/cache/cluster_test.go deleted file mode 100644 index 76dcb1e6a..000000000 --- a/controller/cache/cluster_test.go +++ /dev/null @@ -1,496 +0,0 @@ -package cache - -import ( - "fmt" - "sort" - "strings" - "sync" - "testing" - - "github.com/argoproj/argo-cd/engine/util/settings" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/ghodss/yaml" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic/fake" - - enginecommon "github.com/argoproj/argo-cd/engine/common" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/errors" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/kube/kubetest" -) - -func strToUnstructured(jsonStr string) *unstructured.Unstructured { - obj := make(map[string]interface{}) - err := yaml.Unmarshal([]byte(jsonStr), &obj) - errors.CheckError(err) - return &unstructured.Unstructured{Object: obj} -} - -func mustToUnstructured(obj interface{}) *unstructured.Unstructured { - un, err := kube.ToUnstructured(obj) - errors.CheckError(err) - return un -} - -var ( - testPod = strToUnstructured(` - apiVersion: v1 - kind: Pod - metadata: - uid: "1" - name: helm-guestbook-pod - namespace: default - ownerReferences: - - apiVersion: apps/v1 - kind: ReplicaSet - name: helm-guestbook-rs - uid: "2" - resourceVersion: "123"`) - - testRS = strToUnstructured(` - apiVersion: apps/v1 - kind: ReplicaSet - metadata: - uid: "2" - name: helm-guestbook-rs - namespace: default - annotations: - deployment.kubernetes.io/revision: "2" - ownerReferences: - - apiVersion: apps/v1beta1 - kind: Deployment - name: helm-guestbook - uid: "3" - resourceVersion: "123"`) - - testDeploy = strToUnstructured(` - apiVersion: apps/v1 - kind: Deployment - metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - uid: "3" - name: helm-guestbook - namespace: default - resourceVersion: "123"`) - - testService = strToUnstructured(` - apiVersion: v1 - kind: Service - metadata: - name: helm-guestbook - namespace: default - resourceVersion: "123" - uid: "4" - spec: - selector: - app: guestbook - type: LoadBalancer - status: - loadBalancer: - ingress: - - hostname: localhost`) - - testIngress = strToUnstructured(` - apiVersion: extensions/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - uid: "4" - spec: - backend: - serviceName: not-found-service - servicePort: 443 - rules: - - host: helm-guestbook.com - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - path: / - - backend: - serviceName: helm-guestbook - servicePort: https - path: / - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) -) - -func newCluster(objs ...*unstructured.Unstructured) *clusterInfo { - runtimeObjs := make([]runtime.Object, len(objs)) - for i := range objs { - runtimeObjs[i] = objs[i] - } - scheme := runtime.NewScheme() - client := fake.NewSimpleDynamicClient(scheme, runtimeObjs...) - - apiResources := []kube.APIResourceInfo{{ - GroupKind: schema.GroupKind{Group: "", Kind: "Pod"}, - Interface: client.Resource(schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}), - Meta: metav1.APIResource{Namespaced: true}, - }, { - GroupKind: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}, - Interface: client.Resource(schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "replicasets"}), - Meta: metav1.APIResource{Namespaced: true}, - }, { - GroupKind: schema.GroupKind{Group: "apps", Kind: "Deployment"}, - Interface: client.Resource(schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}), - Meta: metav1.APIResource{Namespaced: true}, - }} - - return newClusterExt(&kubetest.MockKubectlCmd{APIResources: apiResources}) -} - -func newClusterExt(kubectl kube.Kubectl) *clusterInfo { - return &clusterInfo{ - lock: &sync.Mutex{}, - nodes: make(map[kube.ResourceKey]*node), - onObjectUpdated: func(managedByApp map[string]bool, reference corev1.ObjectReference) {}, - kubectl: kubectl, - nsIndex: make(map[string]map[kube.ResourceKey]*node), - cluster: &appv1.Cluster{}, - syncTime: nil, - syncLock: &sync.Mutex{}, - apisMeta: make(map[schema.GroupKind]*apiMeta), - log: log.WithField("cluster", "test"), - cacheSettingsSrc: func() *cacheSettings { - return &cacheSettings{AppInstanceLabelKey: enginecommon.LabelKeyAppInstance} - }, - luaVMFactory: func(overrides map[string]appv1.ResourceOverride) *lua.VM { - return &lua.VM{ResourceOverrides: overrides} - }, - callbacks: settings.NewNoOpCallbacks(), - } -} - -func getChildren(cluster *clusterInfo, un *unstructured.Unstructured) []appv1.ResourceNode { - hierarchy := make([]appv1.ResourceNode, 0) - cluster.iterateHierarchy(kube.GetResourceKey(un), func(child appv1.ResourceNode, app string) { - hierarchy = append(hierarchy, child) - }) - return hierarchy[1:] -} - -func TestGetNamespaceResources(t *testing.T) { - defaultNamespaceTopLevel1 := strToUnstructured(` - apiVersion: apps/v1 - kind: Deployment - metadata: {"name": "helm-guestbook1", "namespace": "default"} -`) - defaultNamespaceTopLevel2 := strToUnstructured(` - apiVersion: apps/v1 - kind: Deployment - metadata: {"name": "helm-guestbook2", "namespace": "default"} -`) - kubesystemNamespaceTopLevel2 := strToUnstructured(` - apiVersion: apps/v1 - kind: Deployment - metadata: {"name": "helm-guestbook3", "namespace": "kube-system"} -`) - - cluster := newCluster(defaultNamespaceTopLevel1, defaultNamespaceTopLevel2, kubesystemNamespaceTopLevel2) - err := cluster.ensureSynced() - assert.Nil(t, err) - - resources := cluster.getNamespaceTopLevelResources("default") - assert.Len(t, resources, 2) - assert.Equal(t, resources[kube.GetResourceKey(defaultNamespaceTopLevel1)].Name, "helm-guestbook1") - assert.Equal(t, resources[kube.GetResourceKey(defaultNamespaceTopLevel2)].Name, "helm-guestbook2") - - resources = cluster.getNamespaceTopLevelResources("kube-system") - assert.Len(t, resources, 1) - assert.Equal(t, resources[kube.GetResourceKey(kubesystemNamespaceTopLevel2)].Name, "helm-guestbook3") -} - -func TestGetChildren(t *testing.T) { - cluster := newCluster(testPod, testRS, testDeploy) - err := cluster.ensureSynced() - assert.Nil(t, err) - - rsChildren := getChildren(cluster, testRS) - assert.Equal(t, []appv1.ResourceNode{{ - ResourceRef: appv1.ResourceRef{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod", - Group: "", - Version: "v1", - UID: "1", - }, - ParentRefs: []appv1.ResourceRef{{ - Group: "apps", - Version: "", - Kind: "ReplicaSet", - Namespace: "default", - Name: "helm-guestbook-rs", - UID: "2", - }}, - Health: &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, - NetworkingInfo: &appv1.ResourceNetworkingInfo{Labels: testPod.GetLabels()}, - ResourceVersion: "123", - Info: []appv1.InfoItem{{Name: "Containers", Value: "0/0"}}, - }}, rsChildren) - deployChildren := getChildren(cluster, testDeploy) - - assert.Equal(t, append([]appv1.ResourceNode{{ - ResourceRef: appv1.ResourceRef{ - Kind: "ReplicaSet", - Namespace: "default", - Name: "helm-guestbook-rs", - Group: "apps", - Version: "v1", - UID: "2", - }, - ResourceVersion: "123", - Health: &appv1.HealthStatus{Status: appv1.HealthStatusHealthy}, - Info: []appv1.InfoItem{{Name: "Revision", Value: "Rev:2"}}, - ParentRefs: []appv1.ResourceRef{{Group: "apps", Version: "", Kind: "Deployment", Namespace: "default", Name: "helm-guestbook", UID: "3"}}, - }}, rsChildren...), deployChildren) -} - -func TestGetManagedLiveObjs(t *testing.T) { - cluster := newCluster(testPod, testRS, testDeploy) - err := cluster.ensureSynced() - assert.Nil(t, err) - - targetDeploy := strToUnstructured(` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: helm-guestbook - labels: - app: helm-guestbook`) - - managedObjs, err := cluster.getManagedLiveObjs(&appv1.Application{ - ObjectMeta: metav1.ObjectMeta{Name: "helm-guestbook"}, - Spec: appv1.ApplicationSpec{ - Destination: appv1.ApplicationDestination{ - Namespace: "default", - }, - }, - }, []*unstructured.Unstructured{targetDeploy}, nil) - assert.Nil(t, err) - assert.Equal(t, managedObjs, map[kube.ResourceKey]*unstructured.Unstructured{ - kube.NewResourceKey("apps", "Deployment", "default", "helm-guestbook"): testDeploy, - }) -} - -func TestChildDeletedEvent(t *testing.T) { - cluster := newCluster(testPod, testRS, testDeploy) - err := cluster.ensureSynced() - assert.Nil(t, err) - - cluster.processEvent(watch.Deleted, testPod) - - rsChildren := getChildren(cluster, testRS) - assert.Equal(t, []appv1.ResourceNode{}, rsChildren) -} - -func TestProcessNewChildEvent(t *testing.T) { - cluster := newCluster(testPod, testRS, testDeploy) - err := cluster.ensureSynced() - assert.Nil(t, err) - - newPod := strToUnstructured(` - apiVersion: v1 - kind: Pod - metadata: - uid: "4" - name: helm-guestbook-pod2 - namespace: default - ownerReferences: - - apiVersion: apps/v1 - kind: ReplicaSet - name: helm-guestbook-rs - uid: "2" - resourceVersion: "123"`) - - cluster.processEvent(watch.Added, newPod) - - rsChildren := getChildren(cluster, testRS) - sort.Slice(rsChildren, func(i, j int) bool { - return strings.Compare(rsChildren[i].Name, rsChildren[j].Name) < 0 - }) - assert.Equal(t, []appv1.ResourceNode{{ - ResourceRef: appv1.ResourceRef{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod", - Group: "", - Version: "v1", - UID: "1", - }, - Info: []appv1.InfoItem{{Name: "Containers", Value: "0/0"}}, - Health: &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, - NetworkingInfo: &appv1.ResourceNetworkingInfo{Labels: testPod.GetLabels()}, - ParentRefs: []appv1.ResourceRef{{ - Group: "apps", - Version: "", - Kind: "ReplicaSet", - Namespace: "default", - Name: "helm-guestbook-rs", - UID: "2", - }}, - ResourceVersion: "123", - }, { - ResourceRef: appv1.ResourceRef{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod2", - Group: "", - Version: "v1", - UID: "4", - }, - NetworkingInfo: &appv1.ResourceNetworkingInfo{Labels: testPod.GetLabels()}, - Info: []appv1.InfoItem{{Name: "Containers", Value: "0/0"}}, - Health: &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, - ParentRefs: []appv1.ResourceRef{{ - Group: "apps", - Version: "", - Kind: "ReplicaSet", - Namespace: "default", - Name: "helm-guestbook-rs", - UID: "2", - }}, - ResourceVersion: "123", - }}, rsChildren) -} - -func TestUpdateResourceTags(t *testing.T) { - pod := &corev1.Pod{ - TypeMeta: metav1.TypeMeta{Kind: "Pod", APIVersion: "v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "testPod", Namespace: "default"}, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Image: "test", - }}, - }, - } - cluster := newCluster(mustToUnstructured(pod)) - - err := cluster.ensureSynced() - assert.Nil(t, err) - - podNode := cluster.nodes[kube.GetResourceKey(mustToUnstructured(pod))] - - assert.NotNil(t, podNode) - assert.Equal(t, []appv1.InfoItem{{Name: "Containers", Value: "0/1"}}, podNode.info) - - pod.Status = corev1.PodStatus{ - ContainerStatuses: []corev1.ContainerStatus{{ - State: corev1.ContainerState{ - Terminated: &corev1.ContainerStateTerminated{ - ExitCode: -1, - }, - }, - }}, - } - cluster.processEvent(watch.Modified, mustToUnstructured(pod)) - - podNode = cluster.nodes[kube.GetResourceKey(mustToUnstructured(pod))] - - assert.NotNil(t, podNode) - assert.Equal(t, []appv1.InfoItem{{Name: "Status Reason", Value: "ExitCode:-1"}, {Name: "Containers", Value: "0/1"}}, podNode.info) -} - -func TestUpdateAppResource(t *testing.T) { - updatesReceived := make([]string, 0) - cluster := newCluster(testPod, testRS, testDeploy) - cluster.onObjectUpdated = func(managedByApp map[string]bool, _ corev1.ObjectReference) { - for appName, fullRefresh := range managedByApp { - updatesReceived = append(updatesReceived, fmt.Sprintf("%s: %v", appName, fullRefresh)) - } - } - - err := cluster.ensureSynced() - assert.Nil(t, err) - - cluster.processEvent(watch.Modified, mustToUnstructured(testPod)) - - assert.Contains(t, updatesReceived, "helm-guestbook: false") -} - -func TestCircularReference(t *testing.T) { - dep := testDeploy.DeepCopy() - dep.SetOwnerReferences([]metav1.OwnerReference{{ - Name: testPod.GetName(), - Kind: testPod.GetKind(), - APIVersion: testPod.GetAPIVersion(), - }}) - cluster := newCluster(testPod, testRS, dep) - err := cluster.ensureSynced() - - assert.Nil(t, err) - - children := getChildren(cluster, dep) - assert.Len(t, children, 2) - - node := cluster.nodes[kube.GetResourceKey(dep)] - assert.NotNil(t, node) - app := node.getApp(cluster.nodes) - assert.Equal(t, "", app) -} - -func TestWatchCacheUpdated(t *testing.T) { - removed := testPod.DeepCopy() - removed.SetName(testPod.GetName() + "-removed-pod") - - updated := testPod.DeepCopy() - updated.SetName(testPod.GetName() + "-updated-pod") - updated.SetResourceVersion("updated-pod-version") - - cluster := newCluster(removed, updated) - err := cluster.ensureSynced() - - assert.Nil(t, err) - - added := testPod.DeepCopy() - added.SetName(testPod.GetName() + "-new-pod") - - podGroupKind := testPod.GroupVersionKind().GroupKind() - - cluster.replaceResourceCache(podGroupKind, "updated-list-version", []unstructured.Unstructured{*updated, *added}) - - _, ok := cluster.nodes[kube.GetResourceKey(removed)] - assert.False(t, ok) - - updatedNode, ok := cluster.nodes[kube.GetResourceKey(updated)] - assert.True(t, ok) - assert.Equal(t, updatedNode.resourceVersion, "updated-pod-version") - - _, ok = cluster.nodes[kube.GetResourceKey(added)] - assert.True(t, ok) -} - -func TestGetDuplicatedChildren(t *testing.T) { - extensionsRS := testRS.DeepCopy() - extensionsRS.SetGroupVersionKind(schema.GroupVersionKind{Group: "extensions", Kind: kube.ReplicaSetKind, Version: "v1beta1"}) - cluster := newCluster(testDeploy, testRS, extensionsRS) - err := cluster.ensureSynced() - - assert.Nil(t, err) - - // Get children multiple times to make sure the right child is picked up every time. - for i := 0; i < 5; i++ { - children := getChildren(cluster, testDeploy) - assert.Len(t, children, 1) - assert.Equal(t, "apps", children[0].Group) - assert.Equal(t, kube.ReplicaSetKind, children[0].Kind) - assert.Equal(t, testRS.GetName(), children[0].Name) - } -} diff --git a/controller/cache/info.go b/controller/cache/info.go deleted file mode 100644 index 9549b2193..000000000 --- a/controller/cache/info.go +++ /dev/null @@ -1,258 +0,0 @@ -package cache - -import ( - "fmt" - - "github.com/argoproj/argo-cd/engine/util/misc" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - k8snode "k8s.io/kubernetes/pkg/util/node" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" - "github.com/argoproj/argo-cd/engine/util/kube" -) - -func populateNodeInfo(un *unstructured.Unstructured, node *node) { - - gvk := un.GroupVersionKind() - revision := resource.GetRevision(un) - if revision > 0 { - node.info = append(node.info, v1alpha1.InfoItem{Name: "Revision", Value: fmt.Sprintf("Rev:%v", revision)}) - } - switch gvk.Group { - case "": - switch gvk.Kind { - case kube.PodKind: - populatePodInfo(un, node) - return - case kube.ServiceKind: - populateServiceInfo(un, node) - return - } - case "extensions", "networking.k8s.io": - switch gvk.Kind { - case kube.IngressKind: - populateIngressInfo(un, node) - return - } - } -} - -func getIngress(un *unstructured.Unstructured) []v1.LoadBalancerIngress { - ingress, ok, err := unstructured.NestedSlice(un.Object, "status", "loadBalancer", "ingress") - if !ok || err != nil { - return nil - } - res := make([]v1.LoadBalancerIngress, 0) - for _, item := range ingress { - if lbIngress, ok := item.(map[string]interface{}); ok { - if hostname := lbIngress["hostname"]; hostname != nil { - res = append(res, v1.LoadBalancerIngress{Hostname: fmt.Sprintf("%s", hostname)}) - } else if ip := lbIngress["ip"]; ip != nil { - res = append(res, v1.LoadBalancerIngress{IP: fmt.Sprintf("%s", ip)}) - } - } - } - return res -} - -func populateServiceInfo(un *unstructured.Unstructured, node *node) { - targetLabels, _, _ := unstructured.NestedStringMap(un.Object, "spec", "selector") - ingress := make([]v1.LoadBalancerIngress, 0) - if serviceType, ok, err := unstructured.NestedString(un.Object, "spec", "type"); ok && err == nil && serviceType == string(v1.ServiceTypeLoadBalancer) { - ingress = getIngress(un) - } - node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress} -} - -func populateIngressInfo(un *unstructured.Unstructured, node *node) { - ingress := getIngress(un) - targetsMap := make(map[v1alpha1.ResourceRef]bool) - if backend, ok, err := unstructured.NestedMap(un.Object, "spec", "backend"); ok && err == nil { - targetsMap[v1alpha1.ResourceRef{ - Group: "", - Kind: kube.ServiceKind, - Namespace: un.GetNamespace(), - Name: fmt.Sprintf("%s", backend["serviceName"]), - }] = true - } - urlsSet := make(map[string]bool) - if rules, ok, err := unstructured.NestedSlice(un.Object, "spec", "rules"); ok && err == nil { - for i := range rules { - rule, ok := rules[i].(map[string]interface{}) - if !ok { - continue - } - host := rule["host"] - if host == nil || host == "" { - for i := range ingress { - host = misc.FirstNonEmpty(ingress[i].Hostname, ingress[i].IP) - if host != "" { - break - } - } - } - paths, ok, err := unstructured.NestedSlice(rule, "http", "paths") - if !ok || err != nil { - continue - } - for i := range paths { - path, ok := paths[i].(map[string]interface{}) - if !ok { - continue - } - - if serviceName, ok, err := unstructured.NestedString(path, "backend", "serviceName"); ok && err == nil { - targetsMap[v1alpha1.ResourceRef{ - Group: "", - Kind: kube.ServiceKind, - Namespace: un.GetNamespace(), - Name: serviceName, - }] = true - } - - if port, ok, err := unstructured.NestedFieldNoCopy(path, "backend", "servicePort"); ok && err == nil && host != "" && host != nil { - stringPort := "" - switch typedPod := port.(type) { - case int64: - stringPort = fmt.Sprintf("%d", typedPod) - case float64: - stringPort = fmt.Sprintf("%d", int64(typedPod)) - case string: - stringPort = typedPod - default: - stringPort = fmt.Sprintf("%v", port) - } - - var externalURL string - switch stringPort { - case "80", "http": - externalURL = fmt.Sprintf("http://%s", host) - case "443", "https": - externalURL = fmt.Sprintf("https://%s", host) - default: - externalURL = fmt.Sprintf("http://%s:%s", host, stringPort) - } - - subPath := "" - if nestedPath, ok, err := unstructured.NestedString(path, "path"); ok && err == nil { - subPath = nestedPath - } - - externalURL += subPath - urlsSet[externalURL] = true - } - } - } - } - targets := make([]v1alpha1.ResourceRef, 0) - for target := range targetsMap { - targets = append(targets, target) - } - urls := make([]string, 0) - for url := range urlsSet { - urls = append(urls, url) - } - node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, Ingress: ingress, ExternalURLs: urls} -} - -func populatePodInfo(un *unstructured.Unstructured, node *node) { - pod := v1.Pod{} - err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &pod) - if err != nil { - return - } - restarts := 0 - totalContainers := len(pod.Spec.Containers) - readyContainers := 0 - - reason := string(pod.Status.Phase) - if pod.Status.Reason != "" { - reason = pod.Status.Reason - } - - imagesSet := make(map[string]bool) - for _, container := range pod.Spec.InitContainers { - imagesSet[container.Image] = true - } - for _, container := range pod.Spec.Containers { - imagesSet[container.Image] = true - } - - node.images = nil - for image := range imagesSet { - node.images = append(node.images, image) - } - - initializing := false - for i := range pod.Status.InitContainerStatuses { - container := pod.Status.InitContainerStatuses[i] - restarts += int(container.RestartCount) - switch { - case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0: - continue - case container.State.Terminated != nil: - // initialization is failed - if len(container.State.Terminated.Reason) == 0 { - if container.State.Terminated.Signal != 0 { - reason = fmt.Sprintf("Init:Signal:%d", container.State.Terminated.Signal) - } else { - reason = fmt.Sprintf("Init:ExitCode:%d", container.State.Terminated.ExitCode) - } - } else { - reason = "Init:" + container.State.Terminated.Reason - } - initializing = true - case container.State.Waiting != nil && len(container.State.Waiting.Reason) > 0 && container.State.Waiting.Reason != "PodInitializing": - reason = "Init:" + container.State.Waiting.Reason - initializing = true - default: - reason = fmt.Sprintf("Init:%d/%d", i, len(pod.Spec.InitContainers)) - initializing = true - } - break - } - if !initializing { - restarts = 0 - hasRunning := false - for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- { - container := pod.Status.ContainerStatuses[i] - - restarts += int(container.RestartCount) - if container.State.Waiting != nil && container.State.Waiting.Reason != "" { - reason = container.State.Waiting.Reason - } else if container.State.Terminated != nil && container.State.Terminated.Reason != "" { - reason = container.State.Terminated.Reason - } else if container.State.Terminated != nil && container.State.Terminated.Reason == "" { - if container.State.Terminated.Signal != 0 { - reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal) - } else { - reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode) - } - } else if container.Ready && container.State.Running != nil { - hasRunning = true - readyContainers++ - } - } - - // change pod status back to "Running" if there is at least one container still reporting as "Running" status - if reason == "Completed" && hasRunning { - reason = "Running" - } - } - - if pod.DeletionTimestamp != nil && pod.Status.Reason == k8snode.NodeUnreachablePodReason { - reason = "Unknown" - } else if pod.DeletionTimestamp != nil { - reason = "Terminating" - } - - if reason != "" { - node.info = append(node.info, v1alpha1.InfoItem{Name: "Status Reason", Value: reason}) - } - node.info = append(node.info, v1alpha1.InfoItem{Name: "Containers", Value: fmt.Sprintf("%d/%d", readyContainers, totalContainers)}) - node.networkingInfo = &v1alpha1.ResourceNetworkingInfo{Labels: un.GetLabels()} -} diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go deleted file mode 100644 index 57b820b8a..000000000 --- a/controller/cache/info_test.go +++ /dev/null @@ -1,222 +0,0 @@ -package cache - -import ( - "sort" - "strings" - "testing" - - v1 "k8s.io/api/core/v1" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" - - "github.com/stretchr/testify/assert" -) - -func TestGetPodInfo(t *testing.T) { - pod := strToUnstructured(` - apiVersion: v1 - kind: Pod - metadata: - name: helm-guestbook-pod - namespace: default - ownerReferences: - - apiVersion: extensions/v1beta1 - kind: ReplicaSet - name: helm-guestbook-rs - resourceVersion: "123" - labels: - app: guestbook - spec: - containers: - - image: bar`) - - node := &node{} - populateNodeInfo(pod, node) - assert.Equal(t, []v1alpha1.InfoItem{{Name: "Containers", Value: "0/1"}}, node.info) - assert.Equal(t, []string{"bar"}, node.images) - assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, node.networkingInfo) -} - -func TestGetServiceInfo(t *testing.T) { - node := &node{} - populateNodeInfo(testService, node) - assert.Equal(t, 0, len(node.info)) - assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - TargetLabels: map[string]string{"app": "guestbook"}, - Ingress: []v1.LoadBalancerIngress{{Hostname: "localhost"}}, - }, node.networkingInfo) -} - -func TestGetIngressInfo(t *testing.T) { - node := &node{} - populateNodeInfo(testIngress, node) - assert.Equal(t, 0, len(node.info)) - sort.Slice(node.networkingInfo.TargetRefs, func(i, j int) bool { - return strings.Compare(node.networkingInfo.TargetRefs[j].Name, node.networkingInfo.TargetRefs[i].Name) < 0 - }) - assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, - TargetRefs: []v1alpha1.ResourceRef{{ - Namespace: "default", - Group: "", - Kind: kube.ServiceKind, - Name: "not-found-service", - }, { - Namespace: "default", - Group: "", - Kind: kube.ServiceKind, - Name: "helm-guestbook", - }}, - ExternalURLs: []string{"https://helm-guestbook.com/"}, - }, node.networkingInfo) -} - -func TestGetIngressInfoNoHost(t *testing.T) { - ingress := strToUnstructured(` - apiVersion: extensions/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - spec: - rules: - - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - path: / - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) - - node := &node{} - populateNodeInfo(ingress, node) - - assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ - Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}}, - TargetRefs: []v1alpha1.ResourceRef{{ - Namespace: "default", - Group: "", - Kind: kube.ServiceKind, - Name: "helm-guestbook", - }}, - ExternalURLs: []string{"https://107.178.210.11/"}, - }, node.networkingInfo) -} -func TestExternalUrlWithSubPath(t *testing.T) { - ingress := strToUnstructured(` - apiVersion: extensions/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - spec: - rules: - - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - path: /my/sub/path/ - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) - - node := &node{} - populateNodeInfo(ingress, node) - - expectedExternalUrls := []string{"https://107.178.210.11/my/sub/path/"} - assert.Equal(t, expectedExternalUrls, node.networkingInfo.ExternalURLs) -} -func TestExternalUrlWithMultipleSubPaths(t *testing.T) { - ingress := strToUnstructured(` - apiVersion: extensions/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - spec: - rules: - - host: helm-guestbook.com - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - path: /my/sub/path/ - - backend: - serviceName: helm-guestbook-2 - servicePort: 443 - path: /my/sub/path/2 - - backend: - serviceName: helm-guestbook-3 - servicePort: 443 - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) - - node := &node{} - populateNodeInfo(ingress, node) - - expectedExternalUrls := []string{"https://helm-guestbook.com/my/sub/path/", "https://helm-guestbook.com/my/sub/path/2", "https://helm-guestbook.com"} - actualURLs := node.networkingInfo.ExternalURLs - sort.Strings(expectedExternalUrls) - sort.Strings(actualURLs) - assert.Equal(t, expectedExternalUrls, actualURLs) -} -func TestExternalUrlWithNoSubPath(t *testing.T) { - ingress := strToUnstructured(` - apiVersion: extensions/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - spec: - rules: - - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) - - node := &node{} - populateNodeInfo(ingress, node) - - expectedExternalUrls := []string{"https://107.178.210.11"} - assert.Equal(t, expectedExternalUrls, node.networkingInfo.ExternalURLs) -} - -func TestExternalUrlWithNetworkingApi(t *testing.T) { - ingress := strToUnstructured(` - apiVersion: networking.k8s.io/v1beta1 - kind: Ingress - metadata: - name: helm-guestbook - namespace: default - spec: - rules: - - http: - paths: - - backend: - serviceName: helm-guestbook - servicePort: 443 - status: - loadBalancer: - ingress: - - ip: 107.178.210.11`) - - node := &node{} - populateNodeInfo(ingress, node) - - expectedExternalUrls := []string{"https://107.178.210.11"} - assert.Equal(t, expectedExternalUrls, node.networkingInfo.ExternalURLs) -} diff --git a/controller/cache/mocks/LiveStateCache.go b/controller/cache/mocks/LiveStateCache.go deleted file mode 100644 index cffb2fdcc..000000000 --- a/controller/cache/mocks/LiveStateCache.go +++ /dev/null @@ -1,122 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - "context" - - "github.com/stretchr/testify/mock" - - "github.com/argoproj/argo-cd/engine/util/kube" - - "k8s.io/apimachinery/pkg/runtime/schema" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// LiveStateCache is an autogenerated mock type for the LiveStateCache type -type LiveStateCache struct { - mock.Mock -} - -// GetManagedLiveObjs provides a mock function with given fields: a, targetObjs -func (_m *LiveStateCache) GetManagedLiveObjs(a *v1alpha1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) { - ret := _m.Called(a, targetObjs) - - var r0 map[kube.ResourceKey]*unstructured.Unstructured - if rf, ok := ret.Get(0).(func(*v1alpha1.Application, []*unstructured.Unstructured) map[kube.ResourceKey]*unstructured.Unstructured); ok { - r0 = rf(a, targetObjs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[kube.ResourceKey]*unstructured.Unstructured) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*v1alpha1.Application, []*unstructured.Unstructured) error); ok { - r1 = rf(a, targetObjs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetNamespaceTopLevelResources provides a mock function with given fields: server, namespace -func (_m *LiveStateCache) GetNamespaceTopLevelResources(server string, namespace string) (map[kube.ResourceKey]v1alpha1.ResourceNode, error) { - ret := _m.Called(server, namespace) - - var r0 map[kube.ResourceKey]v1alpha1.ResourceNode - if rf, ok := ret.Get(0).(func(string, string) map[kube.ResourceKey]v1alpha1.ResourceNode); ok { - r0 = rf(server, namespace) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[kube.ResourceKey]v1alpha1.ResourceNode) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(server, namespace) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Invalidate provides a mock function with given fields: -func (_m *LiveStateCache) Invalidate() { - _m.Called() -} - -// IsNamespaced provides a mock function with given fields: server, gk -func (_m *LiveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool, error) { - ret := _m.Called(server, gk) - - var r0 bool - if rf, ok := ret.Get(0).(func(string, schema.GroupKind) bool); ok { - r0 = rf(server, gk) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, schema.GroupKind) error); ok { - r1 = rf(server, gk) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// IterateHierarchy provides a mock function with given fields: server, key, action -func (_m *LiveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(v1alpha1.ResourceNode, string)) error { - ret := _m.Called(server, key, action) - - var r0 error - if rf, ok := ret.Get(0).(func(string, kube.ResourceKey, func(v1alpha1.ResourceNode, string)) error); ok { - r0 = rf(server, key, action) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Run provides a mock function with given fields: ctx -func (_m *LiveStateCache) Run(ctx context.Context) error { - ret := _m.Called(ctx) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/controller/cache/node.go b/controller/cache/node.go deleted file mode 100644 index 4a75ab513..000000000 --- a/controller/cache/node.go +++ /dev/null @@ -1,142 +0,0 @@ -package cache - -import ( - log "github.com/sirupsen/logrus" - - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -type node struct { - resourceVersion string - ref v1.ObjectReference - ownerRefs []metav1.OwnerReference - info []appv1.InfoItem - appName string - // available only for root application nodes - resource *unstructured.Unstructured - // networkingInfo are available only for known types involved into networking: Ingress, Service, Pod - networkingInfo *appv1.ResourceNetworkingInfo - images []string - health *appv1.HealthStatus -} - -func (n *node) isRootAppNode() bool { - return n.appName != "" && len(n.ownerRefs) == 0 -} - -func (n *node) resourceKey() kube.ResourceKey { - return kube.NewResourceKey(n.ref.GroupVersionKind().Group, n.ref.Kind, n.ref.Namespace, n.ref.Name) -} - -func (n *node) isParentOf(child *node) bool { - for i, ownerRef := range child.ownerRefs { - - // backfill UID of inferred owner child references - if ownerRef.UID == "" && n.ref.Kind == ownerRef.Kind && n.ref.APIVersion == ownerRef.APIVersion && n.ref.Name == ownerRef.Name { - ownerRef.UID = n.ref.UID - child.ownerRefs[i] = ownerRef - return true - } - - if n.ref.UID == ownerRef.UID { - return true - } - } - - return false -} - -func ownerRefGV(ownerRef metav1.OwnerReference) schema.GroupVersion { - gv, err := schema.ParseGroupVersion(ownerRef.APIVersion) - if err != nil { - gv = schema.GroupVersion{} - } - return gv -} - -func (n *node) getApp(ns map[kube.ResourceKey]*node) string { - return n.getAppRecursive(ns, map[kube.ResourceKey]bool{}) -} - -func (n *node) getAppRecursive(ns map[kube.ResourceKey]*node, visited map[kube.ResourceKey]bool) string { - if !visited[n.resourceKey()] { - visited[n.resourceKey()] = true - } else { - log.Warnf("Circular dependency detected: %v.", visited) - return n.appName - } - - if n.appName != "" { - return n.appName - } - for _, ownerRef := range n.ownerRefs { - gv := ownerRefGV(ownerRef) - if parent, ok := ns[kube.NewResourceKey(gv.Group, ownerRef.Kind, n.ref.Namespace, ownerRef.Name)]; ok { - app := parent.getAppRecursive(ns, visited) - if app != "" { - return app - } - } - } - return "" -} - -func newResourceKeySet(set map[kube.ResourceKey]bool, keys ...kube.ResourceKey) map[kube.ResourceKey]bool { - newSet := make(map[kube.ResourceKey]bool) - for k, v := range set { - newSet[k] = v - } - for i := range keys { - newSet[keys[i]] = true - } - return newSet -} - -func (n *node) asResourceNode() appv1.ResourceNode { - gv, err := schema.ParseGroupVersion(n.ref.APIVersion) - if err != nil { - gv = schema.GroupVersion{} - } - parentRefs := make([]appv1.ResourceRef, len(n.ownerRefs)) - for _, ownerRef := range n.ownerRefs { - ownerGvk := schema.FromAPIVersionAndKind(ownerRef.APIVersion, ownerRef.Kind) - ownerKey := kube.NewResourceKey(ownerGvk.Group, ownerRef.Kind, n.ref.Namespace, ownerRef.Name) - parentRefs[0] = appv1.ResourceRef{Name: ownerRef.Name, Kind: ownerKey.Kind, Namespace: n.ref.Namespace, Group: ownerKey.Group, UID: string(ownerRef.UID)} - } - return appv1.ResourceNode{ - ResourceRef: appv1.ResourceRef{ - UID: string(n.ref.UID), - Name: n.ref.Name, - Group: gv.Group, - Version: gv.Version, - Kind: n.ref.Kind, - Namespace: n.ref.Namespace, - }, - ParentRefs: parentRefs, - Info: n.info, - ResourceVersion: n.resourceVersion, - NetworkingInfo: n.networkingInfo, - Images: n.images, - Health: n.health, - } -} - -func (n *node) iterateChildren(ns map[kube.ResourceKey]*node, parents map[kube.ResourceKey]bool, action func(child appv1.ResourceNode, appName string)) { - for childKey, child := range ns { - if n.isParentOf(ns[childKey]) { - if parents[childKey] { - key := n.resourceKey() - log.Warnf("Circular dependency detected. %s is child and parent of %s", childKey.String(), key.String()) - } else { - action(child.asResourceNode(), child.getApp(ns)) - child.iterateChildren(ns, newResourceKeySet(parents, n.resourceKey()), action) - } - } - } -} diff --git a/controller/metrics/metrics.go b/controller/metrics/metrics.go deleted file mode 100644 index d8189f25c..000000000 --- a/controller/metrics/metrics.go +++ /dev/null @@ -1,226 +0,0 @@ -package metrics - -import ( - "net/http" - "strconv" - "time" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promhttp" - log "github.com/sirupsen/logrus" - "k8s.io/apimachinery/pkg/labels" - - argoappv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - applister "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/git" - "github.com/argoproj/argo-cd/engine/util/healthz" -) - -type MetricsServer struct { - *http.Server - syncCounter *prometheus.CounterVec - k8sRequestCounter *prometheus.CounterVec - kubectlExecCounter *prometheus.CounterVec - kubectlExecPendingGauge *prometheus.GaugeVec - reconcileHistogram *prometheus.HistogramVec -} - -const ( - // MetricsPath is the endpoint to collect application metrics - MetricsPath = "/metrics" -) - -// Follow Prometheus naming practices -// https://prometheus.io/docs/practices/naming/ -var ( - descAppDefaultLabels = []string{"namespace", "name", "project"} - - descAppInfo = prometheus.NewDesc( - "argocd_app_info", - "Information about application.", - append(descAppDefaultLabels, "repo", "dest_server", "dest_namespace"), - nil, - ) - descAppCreated = prometheus.NewDesc( - "argocd_app_created_time", - "Creation time in unix timestamp for an application.", - descAppDefaultLabels, - nil, - ) - descAppSyncStatusCode = prometheus.NewDesc( - "argocd_app_sync_status", - "The application current sync status.", - append(descAppDefaultLabels, "sync_status"), - nil, - ) - descAppHealthStatus = prometheus.NewDesc( - "argocd_app_health_status", - "The application current health status.", - append(descAppDefaultLabels, "health_status"), - nil, - ) -) - -// NewMetricsServer returns a new prometheus server which collects application metrics -func NewMetricsServer(addr string, appLister applister.ApplicationLister, healthCheck func() error) *MetricsServer { - mux := http.NewServeMux() - appRegistry := NewAppRegistry(appLister) - appRegistry.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) - appRegistry.MustRegister(prometheus.NewGoCollector()) - mux.Handle(MetricsPath, promhttp.HandlerFor(appRegistry, promhttp.HandlerOpts{})) - healthz.ServeHealthCheck(mux, healthCheck) - - syncCounter := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "argocd_app_sync_total", - Help: "Number of application syncs.", - }, - 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", - Help: "Number of kubernetes requests executed during application reconciliation.", - }, - append(descAppDefaultLabels, "response_code"), - ) - appRegistry.MustRegister(k8sRequestCounter) - - reconcileHistogram := prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "argocd_app_reconcile", - Help: "Application reconciliation performance.", - // Buckets chosen after observing a ~2100ms mean reconcile time - Buckets: []float64{0.25, .5, 1, 2, 4, 8, 16}, - }, - append(descAppDefaultLabels), - ) - - appRegistry.MustRegister(reconcileHistogram) - - return &MetricsServer{ - Server: &http.Server{ - Addr: addr, - Handler: mux, - }, - syncCounter: syncCounter, - k8sRequestCounter: k8sRequestCounter, - reconcileHistogram: reconcileHistogram, - kubectlExecCounter: kubectlExecCounter, - kubectlExecPendingGauge: kubectlExecPendingGauge, - } -} - -// IncSync increments the sync counter for an application -func (m *MetricsServer) IncSync(app *argoappv1.Application, state *argoappv1.OperationState) { - if !state.Phase.Completed() { - return - } - m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), string(state.Phase)).Inc() -} - -// IncKubernetesRequest increments the kubernetes requests counter for an application -func (m *MetricsServer) IncKubernetesRequest(app *argoappv1.Application, statusCode int) { - m.k8sRequestCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), strconv.Itoa(statusCode)).Inc() -} - -// IncReconcile increments the reconcile counter for an application -func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.Duration) { - m.reconcileHistogram.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject()).Observe(duration.Seconds()) -} - -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 -} - -// NewAppCollector returns a prometheus collector for application metrics -func NewAppCollector(appLister applister.ApplicationLister) prometheus.Collector { - return &appCollector{ - store: appLister, - } -} - -// NewAppRegistry creates a new prometheus registry that collects applications -func NewAppRegistry(appLister applister.ApplicationLister) *prometheus.Registry { - registry := prometheus.NewRegistry() - registry.MustRegister(NewAppCollector(appLister)) - return registry -} - -// Describe implements the prometheus.Collector interface -func (c *appCollector) Describe(ch chan<- *prometheus.Desc) { - ch <- descAppInfo - ch <- descAppCreated - ch <- descAppSyncStatusCode - ch <- descAppHealthStatus -} - -// Collect implements the prometheus.Collector interface -func (c *appCollector) Collect(ch chan<- prometheus.Metric) { - apps, err := c.store.List(labels.NewSelector()) - if err != nil { - log.Warnf("Failed to collect applications: %v", err) - return - } - for _, app := range apps { - collectApps(ch, app) - } -} - -func boolFloat64(b bool) float64 { - if b { - return 1 - } - return 0 -} - -func collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application) { - addConstMetric := func(desc *prometheus.Desc, t prometheus.ValueType, v float64, lv ...string) { - project := app.Spec.GetProject() - lv = append([]string{app.Namespace, app.Name, project}, lv...) - ch <- prometheus.MustNewConstMetric(desc, t, v, lv...) - } - addGauge := func(desc *prometheus.Desc, v float64, lv ...string) { - addConstMetric(desc, prometheus.GaugeValue, v, lv...) - } - - addGauge(descAppInfo, 1, git.NormalizeGitURL(app.Spec.Source.RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace) - - addGauge(descAppCreated, float64(app.CreationTimestamp.Unix())) - - syncStatus := app.Status.Sync.Status - addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeSynced), string(argoappv1.SyncStatusCodeSynced)) - addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeOutOfSync), string(argoappv1.SyncStatusCodeOutOfSync)) - addGauge(descAppSyncStatusCode, boolFloat64(syncStatus == argoappv1.SyncStatusCodeUnknown || syncStatus == ""), string(argoappv1.SyncStatusCodeUnknown)) - - healthStatus := app.Status.Health.Status - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusUnknown || healthStatus == ""), argoappv1.HealthStatusUnknown) - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusProgressing), argoappv1.HealthStatusProgressing) - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusSuspended), argoappv1.HealthStatusSuspended) - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusHealthy), argoappv1.HealthStatusHealthy) - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusDegraded), argoappv1.HealthStatusDegraded) - addGauge(descAppHealthStatus, boolFloat64(healthStatus == argoappv1.HealthStatusMissing), argoappv1.HealthStatusMissing) -} diff --git a/controller/metrics/metrics_test.go b/controller/metrics/metrics_test.go deleted file mode 100644 index fcb3b19ae..000000000 --- a/controller/metrics/metrics_test.go +++ /dev/null @@ -1,237 +0,0 @@ -package metrics - -import ( - "context" - "log" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/tools/cache" - - argoappv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/fake" - appinformer "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions" - applister "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" -) - -const fakeApp = ` -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: my-app - namespace: argocd -spec: - destination: - namespace: dummy-namespace - server: https://localhost:6443 - project: important-project - source: - path: some/path - repoURL: https://github.com/argoproj/argocd-example-apps.git -status: - sync: - status: Synced - health: - status: Healthy -` - -const expectedResponse = `# HELP argocd_app_created_time Creation time in unix timestamp for an application. -# TYPE argocd_app_created_time gauge -argocd_app_created_time{name="my-app",namespace="argocd",project="important-project"} -6.21355968e+10 -# HELP argocd_app_health_status The application current health status. -# TYPE argocd_app_health_status gauge -argocd_app_health_status{health_status="Degraded",name="my-app",namespace="argocd",project="important-project"} 0 -argocd_app_health_status{health_status="Healthy",name="my-app",namespace="argocd",project="important-project"} 1 -argocd_app_health_status{health_status="Missing",name="my-app",namespace="argocd",project="important-project"} 0 -argocd_app_health_status{health_status="Progressing",name="my-app",namespace="argocd",project="important-project"} 0 -argocd_app_health_status{health_status="Suspended",name="my-app",namespace="argocd",project="important-project"} 0 -argocd_app_health_status{health_status="Unknown",name="my-app",namespace="argocd",project="important-project"} 0 -# HELP argocd_app_info Information about application. -# TYPE argocd_app_info gauge -argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:6443",name="my-app",namespace="argocd",project="important-project",repo="https://github.com/argoproj/argocd-example-apps"} 1 -# HELP argocd_app_sync_status The application current sync status. -# TYPE argocd_app_sync_status gauge -argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="OutOfSync"} 0 -argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="Synced"} 1 -argocd_app_sync_status{name="my-app",namespace="argocd",project="important-project",sync_status="Unknown"} 0 -` - -const fakeDefaultApp = ` -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: my-app - namespace: argocd -spec: - destination: - namespace: dummy-namespace - server: https://localhost:6443 - source: - path: some/path - repoURL: https://github.com/argoproj/argocd-example-apps.git -status: - sync: - status: Synced - health: - status: Healthy -` - -const expectedDefaultResponse = `# HELP argocd_app_created_time Creation time in unix timestamp for an application. -# TYPE argocd_app_created_time gauge -argocd_app_created_time{name="my-app",namespace="argocd",project="default"} -6.21355968e+10 -# HELP argocd_app_health_status The application current health status. -# TYPE argocd_app_health_status gauge -argocd_app_health_status{health_status="Degraded",name="my-app",namespace="argocd",project="default"} 0 -argocd_app_health_status{health_status="Healthy",name="my-app",namespace="argocd",project="default"} 1 -argocd_app_health_status{health_status="Missing",name="my-app",namespace="argocd",project="default"} 0 -argocd_app_health_status{health_status="Progressing",name="my-app",namespace="argocd",project="default"} 0 -argocd_app_health_status{health_status="Suspended",name="my-app",namespace="argocd",project="default"} 0 -argocd_app_health_status{health_status="Unknown",name="my-app",namespace="argocd",project="default"} 0 -# HELP argocd_app_info Information about application. -# TYPE argocd_app_info gauge -argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:6443",name="my-app",namespace="argocd",project="default",repo="https://github.com/argoproj/argocd-example-apps"} 1 -# HELP argocd_app_sync_status The application current sync status. -# TYPE argocd_app_sync_status gauge -argocd_app_sync_status{name="my-app",namespace="argocd",project="default",sync_status="OutOfSync"} 0 -argocd_app_sync_status{name="my-app",namespace="argocd",project="default",sync_status="Synced"} 1 -argocd_app_sync_status{name="my-app",namespace="argocd",project="default",sync_status="Unknown"} 0 -` - -var noOpHealthCheck = func() error { - return nil -} - -func newFakeApp(fakeApp string) *argoappv1.Application { - var app argoappv1.Application - err := yaml.Unmarshal([]byte(fakeApp), &app) - if err != nil { - panic(err) - } - return &app -} - -func newFakeLister(fakeApp ...string) (context.CancelFunc, applister.ApplicationLister) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - var fakeApps []runtime.Object - for _, name := range fakeApp { - fakeApps = append(fakeApps, newFakeApp(name)) - } - appClientset := appclientset.NewSimpleClientset(fakeApps...) - factory := appinformer.NewFilteredSharedInformerFactory(appClientset, 0, "argocd", func(options *metav1.ListOptions) {}) - appInformer := factory.Argoproj().V1alpha1().Applications().Informer() - go appInformer.Run(ctx.Done()) - if !cache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) { - log.Fatal("Timed out waiting for caches to sync") - } - return cancel, factory.Argoproj().V1alpha1().Applications().Lister() -} - -func testApp(t *testing.T, fakeApp string, expectedResponse string) { - cancel, appLister := newFakeLister(fakeApp) - defer cancel() - metricsServ := NewMetricsServer("localhost:8082", appLister, noOpHealthCheck) - req, err := http.NewRequest("GET", "/metrics", nil) - assert.NoError(t, err) - rr := httptest.NewRecorder() - metricsServ.Handler.ServeHTTP(rr, req) - assert.Equal(t, rr.Code, http.StatusOK) - body := rr.Body.String() - log.Println(body) - assertMetricsPrinted(t, expectedResponse, body) -} - -type testCombination struct { - application string - expectedResponse string -} - -func TestMetrics(t *testing.T) { - combinations := []testCombination{ - { - application: fakeApp, - expectedResponse: expectedResponse, - }, - { - application: fakeDefaultApp, - expectedResponse: expectedDefaultResponse, - }, - } - - for _, combination := range combinations { - testApp(t, combination.application, combination.expectedResponse) - } -} - -const appSyncTotal = `# HELP argocd_app_sync_total Number of application syncs. -# TYPE argocd_app_sync_total counter -argocd_app_sync_total{name="my-app",namespace="argocd",phase="Error",project="important-project"} 1 -argocd_app_sync_total{name="my-app",namespace="argocd",phase="Failed",project="important-project"} 1 -argocd_app_sync_total{name="my-app",namespace="argocd",phase="Succeeded",project="important-project"} 2 -` - -func TestMetricsSyncCounter(t *testing.T) { - cancel, appLister := newFakeLister() - defer cancel() - metricsServ := NewMetricsServer("localhost:8082", appLister, noOpHealthCheck) - - fakeApp := newFakeApp(fakeApp) - metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: argoappv1.OperationRunning}) - metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: argoappv1.OperationFailed}) - metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: argoappv1.OperationError}) - metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: argoappv1.OperationSucceeded}) - metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: argoappv1.OperationSucceeded}) - - req, err := http.NewRequest("GET", "/metrics", nil) - assert.NoError(t, err) - rr := httptest.NewRecorder() - metricsServ.Handler.ServeHTTP(rr, req) - assert.Equal(t, rr.Code, http.StatusOK) - body := rr.Body.String() - log.Println(body) - assertMetricsPrinted(t, appSyncTotal, body) -} - -// assertMetricsPrinted asserts every line in the expected lines appears in the body -func assertMetricsPrinted(t *testing.T, expectedLines, body string) { - for _, line := range strings.Split(expectedLines, "\n") { - assert.Contains(t, body, line) - } -} - -const appReconcileMetrics = `argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="0.25"} 0 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="0.5"} 0 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="1"} 0 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="2"} 0 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="4"} 0 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="8"} 1 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="16"} 1 -argocd_app_reconcile_bucket{name="my-app",namespace="argocd",project="important-project",le="+Inf"} 1 -argocd_app_reconcile_sum{name="my-app",namespace="argocd",project="important-project"} 5 -argocd_app_reconcile_count{name="my-app",namespace="argocd",project="important-project"} 1 -` - -func TestReconcileMetrics(t *testing.T) { - cancel, appLister := newFakeLister() - defer cancel() - metricsServ := NewMetricsServer("localhost:8082", appLister, noOpHealthCheck) - - fakeApp := newFakeApp(fakeApp) - metricsServ.IncReconcile(fakeApp, 5*time.Second) - - req, err := http.NewRequest("GET", "/metrics", nil) - assert.NoError(t, err) - rr := httptest.NewRecorder() - metricsServ.Handler.ServeHTTP(rr, req) - assert.Equal(t, rr.Code, http.StatusOK) - body := rr.Body.String() - log.Println(body) - assertMetricsPrinted(t, appReconcileMetrics, body) -} diff --git a/controller/metrics/transportwrapper.go b/controller/metrics/transportwrapper.go deleted file mode 100644 index 9dd40ad8c..000000000 --- a/controller/metrics/transportwrapper.go +++ /dev/null @@ -1,37 +0,0 @@ -package metrics - -import ( - "net/http" - - "k8s.io/client-go/rest" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -type metricsRoundTripper struct { - roundTripper http.RoundTripper - app *v1alpha1.Application - metricsServer *MetricsServer -} - -func (mrt *metricsRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { - resp, err := mrt.roundTripper.RoundTrip(r) - statusCode := 0 - if resp != nil { - statusCode = resp.StatusCode - } - mrt.metricsServer.IncKubernetesRequest(mrt.app, statusCode) - return resp, err -} - -// AddMetricsTransportWrapper adds a transport wrapper which increments 'argocd_app_k8s_request_total' counter on each kubernetes request -func AddMetricsTransportWrapper(server *MetricsServer, app *v1alpha1.Application, config *rest.Config) *rest.Config { - wrap := config.WrapTransport - config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { - if wrap != nil { - rt = wrap(rt) - } - return &metricsRoundTripper{roundTripper: rt, metricsServer: server, app: app} - } - return config -} diff --git a/controller/state.go b/controller/state.go deleted file mode 100644 index b250badea..000000000 --- a/controller/state.go +++ /dev/null @@ -1,537 +0,0 @@ -package controller - -import ( - "context" - "encoding/json" - "fmt" - "time" - - controllercache "github.com/argoproj/argo-cd/engine/controller/cache" - "github.com/argoproj/argo-cd/engine/controller/metrics" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/argoproj/argo-cd/engine/util/misc" - - argo2 "github.com/argoproj/argo-cd/engine/util/argo" - - log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/cache" - - "github.com/argoproj/argo-cd/engine/common" - hookutil "github.com/argoproj/argo-cd/engine/hook" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/engine/resource" - "github.com/argoproj/argo-cd/engine/resource/ignore" - "github.com/argoproj/argo-cd/engine/util/diff" - "github.com/argoproj/argo-cd/engine/util/health" - kubeutil "github.com/argoproj/argo-cd/engine/util/kube" -) - -type managedResource struct { - Target *unstructured.Unstructured - Live *unstructured.Unstructured - Diff diff.DiffResult - Group string - Version string - Kind string - Namespace string - Name string - Hook bool -} - -func GetLiveObjs(res []managedResource) []*unstructured.Unstructured { - objs := make([]*unstructured.Unstructured, len(res)) - for i := range res { - objs[i] = res[i].Live - } - return objs -} - -type ResourceInfoProvider interface { - IsNamespaced(server string, gk schema.GroupKind) (bool, error) -} - -// AppStateManager defines methods which allow to compare application spec and actual application state. -type AppStateManager interface { - CompareAppState(app *appv1.Application, revision string, source appv1.ApplicationSource, noCache bool, localObjects []string) *comparisonResult - SyncAppState(app *appv1.Application, state *appv1.OperationState) -} - -type comparisonResult struct { - reconciledAt metav1.Time - syncStatus *appv1.SyncStatus - healthStatus *appv1.HealthStatus - resources []appv1.ResourceStatus - managedResources []managedResource - hooks []*unstructured.Unstructured - diffNormalizer diff.Normalizer - appSourceType appv1.ApplicationSourceType -} - -// appStateManager allows to compare applications to git -type appStateManager struct { - metricsServer *metrics.MetricsServer - db pkg.CredentialsStore - settingsMgr pkg.ReconciliationSettings - appclientset appclientset.Interface - projInformer cache.SharedIndexInformer - kubectl kubeutil.Kubectl - repoClientset pkg.ManifestGenerator - liveStateCache controllercache.LiveStateCache - namespace string - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM - callbacks pkg.Callbacks -} - -func (m *appStateManager) getRepoObjs(app *appv1.Application, source appv1.ApplicationSource, appLabelKey, revision string, noCache bool) ([]*unstructured.Unstructured, []*unstructured.Unstructured, *pkg.ManifestResponse, error) { - helmRepos, err := m.db.ListHelmRepositories(context.Background()) - if err != nil { - return nil, nil, nil, err - } - repo, err := m.db.GetRepository(context.Background(), source.RepoURL) - if err != nil { - return nil, nil, nil, err - } - - if revision == "" { - revision = source.TargetRevision - } - - plugins, err := m.settingsMgr.GetConfigManagementPlugins() - if err != nil { - return nil, nil, nil, err - } - - tools := make([]*appv1.ConfigManagementPlugin, len(plugins)) - for i := range plugins { - tools[i] = &plugins[i] - } - - buildOptions, err := m.settingsMgr.GetKustomizeBuildOptions() - if err != nil { - return nil, nil, nil, err - } - cluster, err := m.db.GetCluster(context.Background(), app.Spec.Destination.Server) - if err != nil { - return nil, nil, nil, err - } - cluster.ServerVersion, err = m.kubectl.GetServerVersion(cluster.RESTConfig()) - if err != nil { - return nil, nil, nil, err - } - manifestInfo, err := m.repoClientset.Generate(context.Background(), repo, revision, &source, &pkg.ManifestGenerationSettings{ - Repos: helmRepos, - NoCache: noCache, - AppLabelKey: appLabelKey, - AppLabelValue: app.Name, - Namespace: app.Spec.Destination.Namespace, - Plugins: tools, - KustomizeOptions: &appv1.KustomizeOptions{ - BuildOptions: buildOptions, - }, - KubeVersion: cluster.ServerVersion, - }) - if err != nil { - return nil, nil, nil, err - } - targetObjs, hooks, err := unmarshalManifests(manifestInfo.Manifests) - if err != nil { - return nil, nil, nil, err - } - return targetObjs, hooks, manifestInfo, nil -} - -func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, []*unstructured.Unstructured, error) { - targetObjs := make([]*unstructured.Unstructured, 0) - hooks := make([]*unstructured.Unstructured, 0) - for _, manifest := range manifests { - obj, err := appv1.UnmarshalToUnstructured(manifest) - if err != nil { - return nil, nil, err - } - if ignore.Ignore(obj) { - continue - } - if hookutil.IsHook(obj) { - hooks = append(hooks, obj) - } else { - targetObjs = append(targetObjs, obj) - } - } - return targetObjs, hooks, nil -} - -func DeduplicateTargetObjects( - server string, - namespace string, - objs []*unstructured.Unstructured, - infoProvider ResourceInfoProvider, -) ([]*unstructured.Unstructured, []appv1.ApplicationCondition, error) { - - targetByKey := make(map[kubeutil.ResourceKey][]*unstructured.Unstructured) - for i := range objs { - obj := objs[i] - isNamespaced, err := infoProvider.IsNamespaced(server, obj.GroupVersionKind().GroupKind()) - if err != nil { - return objs, nil, err - } - if !isNamespaced { - obj.SetNamespace("") - } else if obj.GetNamespace() == "" { - obj.SetNamespace(namespace) - } - key := kubeutil.GetResourceKey(obj) - targetByKey[key] = append(targetByKey[key], obj) - } - conditions := make([]appv1.ApplicationCondition, 0) - result := make([]*unstructured.Unstructured, 0) - for key, targets := range targetByKey { - if len(targets) > 1 { - conditions = append(conditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionRepeatedResourceWarning, - Message: fmt.Sprintf("Resource %s appeared %d times among application resources.", key.String(), len(targets)), - }) - } - result = append(result, targets[len(targets)-1]) - } - - return result, conditions, nil -} - -// dedupLiveResources handles removes live resource duplicates with the same UID. Duplicates are created in a separate resource groups. -// E.g. apps/Deployment produces duplicate in extensions/Deployment, authorization.openshift.io/ClusterRole produces duplicate in rbac.authorization.k8s.io/ClusterRole etc. -// The method removes such duplicates unless it was defined in git ( exists in target resources list ). At least one duplicate stays. -// If non of duplicates are in git at random one stays -func dedupLiveResources(targetObjs []*unstructured.Unstructured, liveObjsByKey map[kubeutil.ResourceKey]*unstructured.Unstructured) { - targetObjByKey := make(map[kubeutil.ResourceKey]*unstructured.Unstructured) - for i := range targetObjs { - targetObjByKey[kubeutil.GetResourceKey(targetObjs[i])] = targetObjs[i] - } - liveObjsById := make(map[types.UID][]*unstructured.Unstructured) - for k := range liveObjsByKey { - obj := liveObjsByKey[k] - if obj != nil { - liveObjsById[obj.GetUID()] = append(liveObjsById[obj.GetUID()], obj) - } - } - for id := range liveObjsById { - objs := liveObjsById[id] - - if len(objs) > 1 { - duplicatesLeft := len(objs) - for i := range objs { - obj := objs[i] - resourceKey := kubeutil.GetResourceKey(obj) - if _, ok := targetObjByKey[resourceKey]; !ok { - delete(liveObjsByKey, resourceKey) - duplicatesLeft-- - if duplicatesLeft == 1 { - break - } - } - } - } - } -} - -func (m *appStateManager) getComparisonSettings(app *appv1.Application) (string, map[string]appv1.ResourceOverride, diff.Normalizer, error) { - resourceOverrides, err := m.settingsMgr.GetResourceOverrides() - if err != nil { - return "", nil, nil, err - } - appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey() - if err != nil { - return "", nil, nil, err - } - diffNormalizer, err := argo2.NewDiffNormalizer(app.Spec.IgnoreDifferences, resourceOverrides) - if err != nil { - return "", nil, nil, err - } - return appLabelKey, resourceOverrides, diffNormalizer, nil -} - -// CompareAppState compares application git state to the live app state, using the specified -// 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 *appv1.Application, revision string, source appv1.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: &appv1.SyncStatus{ - ComparedTo: appv1.ComparedTo{Source: source, Destination: app.Spec.Destination}, - Status: appv1.SyncStatusCodeUnknown, - }, - healthStatus: &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, - } - } - - // do best effort loading live and target state to present as much information about app state as possible - failedToLoadObjs := false - conditions := make([]appv1.ApplicationCondition, 0) - - logCtx := log.WithField("application", app.Name) - logCtx.Infof("Comparing app state (cluster: %s, namespace: %s)", app.Spec.Destination.Server, app.Spec.Destination.Namespace) - - var targetObjs []*unstructured.Unstructured - var hooks []*unstructured.Unstructured - var manifestInfo *pkg.ManifestResponse - - if len(localManifests) == 0 { - targetObjs, hooks, manifestInfo, err = m.getRepoObjs(app, source, appLabelKey, revision, noCache) - if err != nil { - targetObjs = make([]*unstructured.Unstructured, 0) - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - failedToLoadObjs = true - } - } else { - targetObjs, hooks, err = unmarshalManifests(localManifests) - if err != nil { - targetObjs = make([]*unstructured.Unstructured, 0) - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - failedToLoadObjs = true - } - manifestInfo = nil - } - - targetObjs, dedupConditions, err := DeduplicateTargetObjects(app.Spec.Destination.Server, app.Spec.Destination.Namespace, targetObjs, m.liveStateCache) - if err != nil { - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - } - conditions = append(conditions, dedupConditions...) - - resFilter, err := m.settingsMgr.GetResourcesFilter() - if err != nil { - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - } else { - for i := len(targetObjs) - 1; i >= 0; i-- { - targetObj := targetObjs[i] - gvk := targetObj.GroupVersionKind() - if resFilter.IsExcludedResource(gvk.Group, gvk.Kind, app.Spec.Destination.Server) { - targetObjs = append(targetObjs[:i], targetObjs[i+1:]...) - conditions = append(conditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionExcludedResourceWarning, - Message: fmt.Sprintf("Resource %s/%s %s is excluded in the settings", gvk.Group, gvk.Kind, targetObj.GetName()), - }) - } - } - } - - logCtx.Debugf("Generated config manifests") - liveObjByKey, err := m.liveStateCache.GetManagedLiveObjs(app, targetObjs) - dedupLiveResources(targetObjs, liveObjByKey) - if err != nil { - liveObjByKey = make(map[kubeutil.ResourceKey]*unstructured.Unstructured) - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - failedToLoadObjs = true - } - logCtx.Debugf("Retrieved lived manifests") - for _, liveObj := range liveObjByKey { - if liveObj != nil { - appInstanceName := kubeutil.GetAppInstanceLabel(liveObj, appLabelKey) - if appInstanceName != "" && appInstanceName != app.Name { - conditions = append(conditions, appv1.ApplicationCondition{ - Type: appv1.ApplicationConditionSharedResourceWarning, - Message: fmt.Sprintf("%s/%s is part of a different application: %s", liveObj.GetKind(), liveObj.GetName(), appInstanceName), - }) - } - } - } - - managedLiveObj := make([]*unstructured.Unstructured, len(targetObjs)) - for i, obj := range targetObjs { - gvk := obj.GroupVersionKind() - ns := misc.FirstNonEmpty(obj.GetNamespace(), app.Spec.Destination.Namespace) - if namespaced, err := m.liveStateCache.IsNamespaced(app.Spec.Destination.Server, obj.GroupVersionKind().GroupKind()); err == nil && !namespaced { - ns = "" - } - key := kubeutil.NewResourceKey(gvk.Group, gvk.Kind, ns, obj.GetName()) - if liveObj, ok := liveObjByKey[key]; ok { - managedLiveObj[i] = liveObj - delete(liveObjByKey, key) - } else { - managedLiveObj[i] = nil - } - } - logCtx.Debugf("built managed objects list") - // Everything remaining in liveObjByKey are "extra" resources that aren't tracked in git. - // The following adds all the extras to the managedLiveObj list and backfills the targetObj - // list with nils, so that the lists are of equal lengths for comparison purposes. - for _, obj := range liveObjByKey { - targetObjs = append(targetObjs, nil) - managedLiveObj = append(managedLiveObj, obj) - } - - // Do the actual comparison - diffResults, err := diff.DiffArray(targetObjs, managedLiveObj, diffNormalizer) - if err != nil { - diffResults = &diff.DiffResultList{} - failedToLoadObjs = true - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - } - - syncCode := appv1.SyncStatusCodeSynced - managedResources := make([]managedResource, len(targetObjs)) - resourceSummaries := make([]appv1.ResourceStatus, len(targetObjs)) - for i, targetObj := range targetObjs { - liveObj := managedLiveObj[i] - obj := liveObj - if obj == nil { - obj = targetObj - } - if obj == nil { - continue - } - gvk := obj.GroupVersionKind() - - resState := appv1.ResourceStatus{ - Namespace: obj.GetNamespace(), - Name: obj.GetName(), - Kind: gvk.Kind, - Version: gvk.Version, - Group: gvk.Group, - Hook: hookutil.IsHook(obj), - RequiresPruning: targetObj == nil && liveObj != nil, - } - - diffResult := diffResults.Diffs[i] - if resState.Hook || ignore.Ignore(obj) { - // For resource hooks, don't store sync status, and do not affect overall sync status - } else if diffResult.Modified || targetObj == nil || liveObj == nil { - // Set resource state to OutOfSync since one of the following is true: - // * target and live resource are different - // * target resource not defined and live resource is extra - // * target resource present but live resource is missing - resState.Status = appv1.SyncStatusCodeOutOfSync - // we ignore the status if the obj needs pruning AND we have the annotation - needsPruning := targetObj == nil && liveObj != nil - if !(needsPruning && resource.HasAnnotationOption(obj, common.AnnotationCompareOptions, "IgnoreExtraneous")) { - syncCode = appv1.SyncStatusCodeOutOfSync - } - } else { - resState.Status = appv1.SyncStatusCodeSynced - } - managedResources[i] = managedResource{ - Name: resState.Name, - Namespace: resState.Namespace, - Group: resState.Group, - Kind: resState.Kind, - Version: resState.Version, - Live: liveObj, - Target: targetObj, - Diff: diffResult, - Hook: resState.Hook, - } - resourceSummaries[i] = resState - } - - if failedToLoadObjs { - syncCode = appv1.SyncStatusCodeUnknown - } - syncStatus := appv1.SyncStatus{ - ComparedTo: appv1.ComparedTo{ - Source: source, - Destination: app.Spec.Destination, - }, - Status: syncCode, - } - if manifestInfo != nil { - syncStatus.Revision = manifestInfo.Revision - } - - healthStatus, err := health.SetApplicationHealth(resourceSummaries, GetLiveObjs(managedResources), m.luaVMFactory(resourceOverrides), func(obj *unstructured.Unstructured) bool { - return !isSelfReferencedApp(app, kubeutil.GetObjectRef(obj)) - }) - - if err != nil { - conditions = append(conditions, appv1.ApplicationCondition{Type: appv1.ApplicationConditionComparisonError, Message: err.Error()}) - } - - compRes := comparisonResult{ - reconciledAt: reconciledAt, - syncStatus: &syncStatus, - healthStatus: healthStatus, - resources: resourceSummaries, - managedResources: managedResources, - hooks: hooks, - diffNormalizer: diffNormalizer, - } - if manifestInfo != nil { - compRes.appSourceType = appv1.ApplicationSourceType(manifestInfo.SourceType) - } - app.Status.SetConditions(conditions, map[appv1.ApplicationConditionType]bool{ - appv1.ApplicationConditionComparisonError: true, - appv1.ApplicationConditionSharedResourceWarning: true, - appv1.ApplicationConditionRepeatedResourceWarning: true, - appv1.ApplicationConditionExcludedResourceWarning: true, - }) - return &compRes -} - -func (m *appStateManager) persistRevisionHistory(app *appv1.Application, revision string, source appv1.ApplicationSource) error { - var nextID int64 - if len(app.Status.History) > 0 { - nextID = app.Status.History[len(app.Status.History)-1].ID + 1 - } - history := append(app.Status.History, appv1.RevisionHistory{ - Revision: revision, - DeployedAt: metav1.NewTime(time.Now().UTC()), - ID: nextID, - Source: source, - }) - - if len(history) > common.RevisionHistoryLimit { - history = history[1 : common.RevisionHistoryLimit+1] - } - - patch, err := json.Marshal(map[string]map[string][]appv1.RevisionHistory{ - "status": { - "history": history, - }, - }) - if err != nil { - return err - } - _, err = m.appclientset.ArgoprojV1alpha1().Applications(m.namespace).Patch(app.Name, types.MergePatchType, patch) - return err -} - -// NewAppStateManager creates new instance of Ksonnet app comparator -func NewAppStateManager( - db pkg.CredentialsStore, - appclientset appclientset.Interface, - repoClientset pkg.ManifestGenerator, - namespace string, - kubectl kubeutil.Kubectl, - settingsMgr pkg.ReconciliationSettings, - liveStateCache controllercache.LiveStateCache, - projInformer cache.SharedIndexInformer, - metricsServer *metrics.MetricsServer, - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM, - callbacks pkg.Callbacks, -) AppStateManager { - return &appStateManager{ - liveStateCache: liveStateCache, - db: db, - appclientset: appclientset, - kubectl: kubectl, - repoClientset: repoClientset, - namespace: namespace, - settingsMgr: settingsMgr, - projInformer: projInformer, - metricsServer: metricsServer, - luaVMFactory: luaVMFactory, - callbacks: callbacks, - } -} diff --git a/controller/state_test.go b/controller/state_test.go deleted file mode 100644 index f9d73f227..000000000 --- a/controller/state_test.go +++ /dev/null @@ -1,390 +0,0 @@ -package controller - -import ( - "encoding/json" - "errors" - "testing" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/mocks" - argoappv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/test" -) - -// TestCompareAppStateEmpty tests comparison when both git and live have no objects -func TestCompareAppStateEmpty(t *testing.T) { - app := newFakeApp() - data := fakeData{ - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - assert.NotNil(t, compRes) - assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) - assert.Len(t, compRes.resources, 0) - assert.Len(t, compRes.managedResources, 0) - assert.Len(t, app.Status.Conditions, 0) -} - -// TestCompareAppStateMissing tests when there is a manifest defined in the repo which doesn't exist in live -func TestCompareAppStateMissing(t *testing.T) { - app := newFakeApp() - data := fakeData{ - apps: []runtime.Object{app}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{string(test.PodManifest)}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - assert.NotNil(t, compRes) - assert.NotNil(t, compRes.syncStatus) - assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) - assert.Len(t, compRes.resources, 1) - assert.Len(t, compRes.managedResources, 1) - assert.Len(t, app.Status.Conditions, 0) -} - -// TestCompareAppStateExtra tests when there is an extra object in live but not defined in git -func TestCompareAppStateExtra(t *testing.T) { - pod := test.NewPod() - pod.SetNamespace(test.FakeDestNamespace) - app := newFakeApp() - key := kube.ResourceKey{Group: "", Kind: "Pod", Namespace: test.FakeDestNamespace, Name: app.Name} - data := fakeData{ - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - key: pod, - }, - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - assert.NotNil(t, compRes) - assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) - assert.Equal(t, 1, len(compRes.resources)) - assert.Equal(t, 1, len(compRes.managedResources)) - assert.Equal(t, 0, len(app.Status.Conditions)) -} - -// TestCompareAppStateHook checks that hooks are detected during manifest generation, and not -// considered as part of resources when assessing Synced status -func TestCompareAppStateHook(t *testing.T) { - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) - podBytes, _ := json.Marshal(pod) - app := newFakeApp() - data := fakeData{ - apps: []runtime.Object{app}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{string(podBytes)}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - assert.NotNil(t, compRes) - assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) - assert.Equal(t, 0, len(compRes.resources)) - assert.Equal(t, 0, len(compRes.managedResources)) - assert.Equal(t, 1, len(compRes.hooks)) - assert.Equal(t, 0, len(app.Status.Conditions)) -} - -// checks that ignore resources are detected, but excluded from status -func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationCompareOptions: "IgnoreExtraneous"}) - app := newFakeApp() - data := fakeData{ - apps: []runtime.Object{app}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.NotNil(t, compRes) - assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) - assert.Len(t, compRes.resources, 0) - assert.Len(t, compRes.managedResources, 0) - assert.Len(t, app.Status.Conditions, 0) -} - -// TestCompareAppStateExtraHook tests when there is an extra _hook_ object in live but not defined in git -func TestCompareAppStateExtraHook(t *testing.T) { - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) - pod.SetNamespace(test.FakeDestNamespace) - app := newFakeApp() - key := kube.ResourceKey{Group: "", Kind: "Pod", Namespace: test.FakeDestNamespace, Name: app.Name} - data := fakeData{ - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - key: pod, - }, - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.NotNil(t, compRes) - assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) - assert.Equal(t, 1, len(compRes.resources)) - assert.Equal(t, 1, len(compRes.managedResources)) - assert.Equal(t, 0, len(compRes.hooks)) - assert.Equal(t, 0, len(app.Status.Conditions)) -} - -func toJSON(t *testing.T, obj *unstructured.Unstructured) string { - data, err := json.Marshal(obj) - assert.NoError(t, err) - return string(data) -} - -func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { - obj1 := test.NewPod() - obj1.SetNamespace(test.FakeDestNamespace) - obj2 := test.NewPod() - obj3 := test.NewPod() - obj3.SetNamespace("kube-system") - - app := newFakeApp() - data := fakeData{ - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{toJSON(t, obj1), toJSON(t, obj2), toJSON(t, obj3)}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(obj1): obj1, - kube.GetResourceKey(obj3): obj3, - }, - } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.NotNil(t, compRes) - assert.Contains(t, app.Status.Conditions, argoappv1.ApplicationCondition{ - Message: "Resource /Pod/fake-dest-ns/my-pod appeared 2 times among application resources.", - Type: argoappv1.ApplicationConditionRepeatedResourceWarning, - }) - assert.Equal(t, 2, len(compRes.resources)) -} - -var defaultProj = argoappv1.AppProject{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: test.FakeArgoCDNamespace, - }, - Spec: argoappv1.AppProjectSpec{ - SourceRepos: []string{"*"}, - Destinations: []argoappv1.ApplicationDestination{ - { - Server: "*", - Namespace: "*", - }, - }, - }, -} - -func TestSetHealth(t *testing.T) { - app := newFakeApp() - deployment := kube.MustToUnstructured(&v1.Deployment{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "apps/v1beta1", - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "demo", - Namespace: "default", - }, - }) - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app, &defaultProj}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(deployment): deployment, - }, - }) - - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.Equal(t, compRes.healthStatus.Status, argoappv1.HealthStatusHealthy) -} - -func TestSetHealthSelfReferencedApp(t *testing.T) { - app := newFakeApp() - unstructuredApp := kube.MustToUnstructured(app) - deployment := kube.MustToUnstructured(&v1.Deployment{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "apps/v1beta1", - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "demo", - Namespace: "default", - }, - }) - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app, &defaultProj}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(deployment): deployment, - kube.GetResourceKey(unstructuredApp): unstructuredApp, - }, - }) - - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.Equal(t, compRes.healthStatus.Status, argoappv1.HealthStatusHealthy) -} - -func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { - proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} - - app := newFakeApp() - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app, proj}, - namespacedResources: map[kube.ResourceKey]namespacedResource{ - kube.NewResourceKey("apps", kube.DeploymentKind, app.Namespace, "guestbook"): { - ResourceNode: argoappv1.ResourceNode{ - ResourceRef: argoappv1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}, - }, - AppName: "", - }, - }, - }) - - tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) - - assert.NoError(t, err) - assert.Equal(t, len(tree.OrphanedNodes), 1) - assert.Equal(t, "guestbook", tree.OrphanedNodes[0].Name) - assert.Equal(t, app.Namespace, tree.OrphanedNodes[0].Namespace) -} - -func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { - proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} - - app1 := newFakeApp() - app1.Name = "app1" - app2 := newFakeApp() - app2.Name = "app2" - - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app1, app2, proj}, - namespacedResources: map[kube.ResourceKey]namespacedResource{ - kube.NewResourceKey("apps", kube.DeploymentKind, app2.Namespace, "guestbook"): { - ResourceNode: argoappv1.ResourceNode{ - ResourceRef: argoappv1.ResourceRef{Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app2.Namespace}, - }, - AppName: "app2", - }, - }, - }) - - tree, err := ctrl.setAppManagedResources(app1, &comparisonResult{managedResources: make([]managedResource, 0)}) - - assert.NoError(t, err) - assert.Equal(t, len(tree.OrphanedNodes), 0) -} - -func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { - proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} - - app := newFakeApp() - - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app, proj}, - settingsMockConfig: func(settingsMock *mocks.ReconciliationSettings) { - settingsMock.On("GetResourceOverrides").Return(nil, errors.New("fail")) - }, - }) - - compRes := ctrl.appStateManager.CompareAppState(app, "", app.Spec.Source, false, nil) - - assert.Equal(t, argoappv1.HealthStatusUnknown, compRes.healthStatus.Status) - assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) - assert.NotNil(t, compRes.reconciledAt) -} - -func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) { - proj := defaultProj.DeepCopy() - proj.Spec.OrphanedResources = &argoappv1.OrphanedResourcesMonitorSettings{} - - app := newFakeApp() - app.Namespace = "default" - - ctrl := newFakeController(&fakeData{ - apps: []runtime.Object{app, proj}, - namespacedResources: map[kube.ResourceKey]namespacedResource{ - kube.NewResourceKey("apps", kube.DeploymentKind, app.Namespace, "guestbook"): { - ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Group: "apps", Kind: kube.DeploymentKind, Name: "guestbook", Namespace: app.Namespace}}, - }, - kube.NewResourceKey("", kube.ServiceAccountKind, app.Namespace, "default"): { - ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "default", Namespace: app.Namespace}}, - }, - kube.NewResourceKey("", kube.ServiceKind, app.Namespace, "kubernetes"): { - ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "kubernetes", Namespace: app.Namespace}}, - }, - }, - }) - - tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) - - assert.NoError(t, err) - assert.Len(t, tree.OrphanedNodes, 1) - assert.Equal(t, "guestbook", tree.OrphanedNodes[0].Name) -} diff --git a/controller/sync.go b/controller/sync.go deleted file mode 100644 index 917755288..000000000 --- a/controller/sync.go +++ /dev/null @@ -1,819 +0,0 @@ -package controller - -import ( - "context" - "fmt" - "reflect" - "sort" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/argoproj/argo-cd/engine/controller/metrics" - - "github.com/argoproj/argo-cd/engine/util/lua" - - log "github.com/sirupsen/logrus" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apimachinery/pkg/api/errors" - apierr "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/discovery" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/rest" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/hook" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - listersv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" - "github.com/argoproj/argo-cd/engine/util/argo" - "github.com/argoproj/argo-cd/engine/util/health" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/rand" -) - -const ( - crdReadinessTimeout = time.Duration(3) * time.Second -) - -var syncIdPrefix uint64 = 0 - -type syncContext struct { - vm *lua.VM - appName string - proj *v1alpha1.AppProject - compareResult *comparisonResult - config *rest.Config - dynamicIf dynamic.Interface - disco discovery.DiscoveryInterface - extensionsclientset *clientset.Clientset - kubectl kube.Kubectl - namespace string - server string - syncOp *v1alpha1.SyncOperation - syncRes *v1alpha1.SyncOperationResult - syncResources []v1alpha1.SyncOperationResource - opState *v1alpha1.OperationState - log *log.Entry - callbacks pkg.Callbacks - // lock to protect concurrent updates of the result list - lock sync.Mutex -} - -func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) { - // Sync requests might be requested with ambiguous revisions (e.g. master, HEAD, v1.2.3). - // This can change meaning when resuming operations (e.g a hook sync). After calculating a - // concrete git commit SHA, the SHA is remembered in the status.operationState.syncResult field. - // This ensures that when resuming an operation, we sync to the same revision that we initially - // started with. - var revision string - var syncOp v1alpha1.SyncOperation - var syncRes *v1alpha1.SyncOperationResult - var syncResources []v1alpha1.SyncOperationResource - var source v1alpha1.ApplicationSource - - if state.Operation.Sync == nil { - state.Phase = v1alpha1.OperationFailed - state.Message = "Invalid operation request: no operation specified" - return - } - syncOp = *state.Operation.Sync - if syncOp.Source == nil { - // normal sync case (where source is taken from app.spec.source) - source = app.Spec.Source - } else { - // rollback case - source = *state.Operation.Sync.Source - } - syncResources = syncOp.Resources - if state.SyncResult != nil { - syncRes = state.SyncResult - revision = state.SyncResult.Revision - } else { - syncRes = &v1alpha1.SyncOperationResult{} - // status.operationState.syncResult.source. must be set properly since auto-sync relies - // on this information to decide if it should sync (if source is different than the last - // sync attempt) - syncRes.Source = source - state.SyncResult = syncRes - } - - if revision == "" { - // if we get here, it means we did not remember a commit SHA which we should be syncing to. - // This typically indicates we are just about to begin a brand new sync/rollback operation. - // Take the value in the requested operation. We will resolve this to a SHA later. - revision = syncOp.Revision - } - - compareResult := m.CompareAppState(app, revision, source, false, syncOp.Manifests) - - // If there are any comparison or spec errors error conditions do not perform the operation - if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{ - v1alpha1.ApplicationConditionComparisonError: true, - v1alpha1.ApplicationConditionInvalidSpecError: true, - }); len(errConditions) > 0 { - state.Phase = v1alpha1.OperationError - state.Message = argo.FormatAppConditions(errConditions) - return - } - - // We now have a concrete commit SHA. Save this in the sync result revision so that we remember - // what we should be syncing to when resuming operations. - syncRes.Revision = compareResult.syncStatus.Revision - - clst, err := m.db.GetCluster(context.Background(), app.Spec.Destination.Server) - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = err.Error() - return - } - - restConfig := metrics.AddMetricsTransportWrapper(m.metricsServer, app, clst.RESTConfig()) - dynamicIf, err := dynamic.NewForConfig(restConfig) - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = fmt.Sprintf("Failed to initialize dynamic client: %v", err) - return - } - disco, err := discovery.NewDiscoveryClientForConfig(restConfig) - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = fmt.Sprintf("Failed to initialize discovery client: %v", err) - return - } - - extensionsclientset, err := clientset.NewForConfig(restConfig) - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = fmt.Sprintf("Failed to initialize extensions client: %v", err) - return - } - - proj, err := argo.GetAppProject(&app.Spec, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace) - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = fmt.Sprintf("Failed to load application project: %v", err) - return - } - - resourceOverrides, err := m.settingsMgr.GetResourceOverrides() - if err != nil { - state.Phase = v1alpha1.OperationError - state.Message = fmt.Sprintf("Failed to load resource overrides: %v", err) - return - } - vm := m.luaVMFactory(resourceOverrides) - - atomic.AddUint64(&syncIdPrefix, 1) - syncId := fmt.Sprintf("%05d-%s", syncIdPrefix, rand.RandString(5)) - syncCtx := syncContext{ - vm: vm, - appName: app.Name, - proj: proj, - compareResult: compareResult, - config: restConfig, - dynamicIf: dynamicIf, - disco: disco, - extensionsclientset: extensionsclientset, - kubectl: m.kubectl, - namespace: app.Spec.Destination.Namespace, - server: app.Spec.Destination.Server, - syncOp: &syncOp, - syncRes: syncRes, - syncResources: syncResources, - opState: state, - log: log.WithFields(log.Fields{"application": app.Name, "syncId": syncId}), - callbacks: m.callbacks, - } - - start := time.Now() - - if state.Phase == v1alpha1.OperationTerminating { - syncCtx.terminate() - } else { - syncCtx.sync() - } - - syncCtx.log.WithField("duration", time.Since(start)).Info("sync/terminate complete") - - if !syncOp.DryRun && !syncCtx.isSelectiveSync() && syncCtx.opState.Phase.Successful() { - err := m.persistRevisionHistory(app, compareResult.syncStatus.Revision, source) - if err != nil { - syncCtx.setOperationPhase(v1alpha1.OperationError, fmt.Sprintf("failed to record sync to history: %v", err)) - } - } -} - -// sync has performs the actual apply or hook based sync -func (sc *syncContext) sync() { - sc.log.WithFields(log.Fields{"isSelectiveSync": sc.isSelectiveSync(), "skipHooks": sc.skipHooks(), "started": sc.started()}).Info("syncing") - tasks, ok := sc.getSyncTasks() - if !ok { - sc.setOperationPhase(v1alpha1.OperationFailed, "one or more synchronization tasks are not valid") - return - } - - sc.log.WithFields(log.Fields{"tasks": tasks, "isSelectiveSync": sc.isSelectiveSync()}).Info("tasks") - - // Perform a `kubectl apply --dry-run` against all the manifests. This will detect most (but - // not all) validation issues with the user's manifests (e.g. will detect syntax issues, but - // will not not detect if they are mutating immutable fields). If anything fails, we will refuse - // to perform the sync. we only wish to do this once per operation, performing additional dry-runs - // is harmless, but redundant. The indicator we use to detect if we have already performed - // the dry-run for this operation, is if the resource or hook list is empty. - if !sc.started() { - sc.log.Debug("dry-run") - if sc.runTasks(tasks, true) == failed { - sc.setOperationPhase(v1alpha1.OperationFailed, "one or more objects failed to apply (dry run)") - return - } - } - - // update status of any tasks that are running, note that this must exclude pruning tasks - for _, task := range tasks.Filter(func(t *syncTask) bool { - // just occasionally, you can be running yet not have a live resource - return t.running() && t.LiveObj != nil - }) { - if task.isHook() { - // update the hook's result - operationState, message := getOperationPhase(task.LiveObj) - sc.setResourceResult(task, "", operationState, message) - - // maybe delete the hook - if task.needsDeleting() { - err := sc.deleteResource(task) - if err != nil && !errors.IsNotFound(err) { - sc.setResourceResult(task, "", v1alpha1.OperationError, fmt.Sprintf("failed to delete resource: %v", err)) - } - } - } else { - // this must be calculated on the live object - healthStatus, err := health.GetResourceHealth(task.LiveObj, sc.vm) - if err == nil { - log.WithFields(log.Fields{"task": task, "healthStatus": healthStatus}).Debug("attempting to update health of running task") - if healthStatus == nil { - // some objects (e.g. secret) do not have health, and they automatically success - sc.setResourceResult(task, task.syncStatus, v1alpha1.OperationSucceeded, task.message) - } else { - switch healthStatus.Status { - case v1alpha1.HealthStatusHealthy: - sc.setResourceResult(task, task.syncStatus, v1alpha1.OperationSucceeded, healthStatus.Message) - case v1alpha1.HealthStatusDegraded: - sc.setResourceResult(task, task.syncStatus, v1alpha1.OperationFailed, healthStatus.Message) - } - } - } - } - } - - // if (a) we are multi-step and we have any running tasks, - // or (b) there are any running hooks, - // then wait... - multiStep := tasks.multiStep() - if tasks.Any(func(t *syncTask) bool { return (multiStep || t.isHook()) && t.running() }) { - sc.setOperationPhase(v1alpha1.OperationRunning, "one or more tasks are running") - return - } - - // syncFailTasks only run during failure, so separate them from regular tasks - syncFailTasks, tasks := tasks.Split(func(t *syncTask) bool { return t.Phase == v1alpha1.SyncPhaseSyncFail }) - - // if there are any completed but unsuccessful tasks, sync is a failure. - if tasks.Any(func(t *syncTask) bool { return t.completed() && !t.successful() }) { - sc.setOperationFailed(syncFailTasks, "one or more synchronization tasks completed unsuccessfully") - return - } - - sc.log.WithFields(log.Fields{"tasks": tasks}).Debug("filtering out non-pending tasks") - // remove tasks that are completed, we can assume that there are no running tasks - tasks = tasks.Filter(func(t *syncTask) bool { return t.pending() }) - - // If no sync tasks were generated (e.g., in case all application manifests have been removed), - // the sync operation is successful. - if len(tasks) == 0 { - sc.setOperationPhase(v1alpha1.OperationSucceeded, "successfully synced (no more tasks)") - return - } - - // remove any tasks not in this wave - phase := tasks.phase() - wave := tasks.wave() - - // if it is the last phase/wave and the only remaining tasks are non-hooks, the we are successful - // EVEN if those objects subsequently degraded - // This handles the common case where neither hooks or waves are used and a sync equates to simply an (asynchronous) kubectl apply of manifests, which succeeds immediately. - complete := !tasks.Any(func(t *syncTask) bool { return t.Phase != phase || wave != t.wave() || t.isHook() }) - - sc.log.WithFields(log.Fields{"phase": phase, "wave": wave, "tasks": tasks, "syncFailTasks": syncFailTasks}).Debug("filtering tasks in correct phase and wave") - tasks = tasks.Filter(func(t *syncTask) bool { return t.Phase == phase && t.wave() == wave }) - - sc.setOperationPhase(v1alpha1.OperationRunning, "one or more tasks are running") - - sc.log.WithFields(log.Fields{"tasks": tasks}).Debug("wet-run") - runState := sc.runTasks(tasks, false) - switch runState { - case failed: - sc.setOperationFailed(syncFailTasks, "one or more objects failed to apply") - case successful: - if complete { - sc.setOperationPhase(v1alpha1.OperationSucceeded, "successfully synced (all tasks run)") - } - } -} - -func (sc *syncContext) setOperationFailed(syncFailTasks syncTasks, message string) { - if len(syncFailTasks) > 0 { - // if all the failure hooks are completed, don't run them again, and mark the sync as failed - if syncFailTasks.All(func(task *syncTask) bool { return task.completed() }) { - sc.setOperationPhase(v1alpha1.OperationFailed, message) - return - } - // otherwise, we need to start the failure hooks, and then return without setting - // the phase, so we make sure we have at least one more sync - sc.log.WithFields(log.Fields{"syncFailTasks": syncFailTasks}).Debug("running sync fail tasks") - if sc.runTasks(syncFailTasks, false) == failed { - sc.setOperationPhase(v1alpha1.OperationFailed, message) - } - } else { - sc.setOperationPhase(v1alpha1.OperationFailed, message) - } -} - -func (sc *syncContext) started() bool { - return len(sc.syncRes.Resources) > 0 -} - -func (sc *syncContext) isSelectiveSync() bool { - // we've selected no resources - if sc.syncResources == nil { - return false - } - - // map both lists into string - var a []string - for _, r := range sc.compareResult.resources { - if !r.Hook { - a = append(a, fmt.Sprintf("%s:%s:%s", r.Group, r.Kind, r.Name)) - } - } - sort.Strings(a) - - var b []string - for _, r := range sc.syncResources { - b = append(b, fmt.Sprintf("%s:%s:%s", r.Group, r.Kind, r.Name)) - } - sort.Strings(b) - - return !reflect.DeepEqual(a, b) -} - -// this essentially enforces the old "apply" behaviour -func (sc *syncContext) skipHooks() bool { - // All objects passed a `kubectl apply --dry-run`, so we are now ready to actually perform the sync. - // default sync strategy to hook if no strategy - return sc.syncOp.IsApplyStrategy() || sc.isSelectiveSync() -} - -func (sc *syncContext) containsResource(resourceState managedResource) bool { - return !sc.isSelectiveSync() || - (resourceState.Live != nil && argo.ContainsSyncResource(resourceState.Live.GetName(), resourceState.Live.GroupVersionKind(), sc.syncResources)) || - (resourceState.Target != nil && argo.ContainsSyncResource(resourceState.Target.GetName(), resourceState.Target.GroupVersionKind(), sc.syncResources)) -} - -// generates the list of sync tasks we will be performing during this sync. -func (sc *syncContext) getSyncTasks() (_ syncTasks, successful bool) { - resourceTasks := make([]pkg.SyncTaskInfo, 0) - successful = true - - for _, resource := range sc.compareResult.managedResources { - if !sc.containsResource(resource) { - sc.log.WithFields(log.Fields{"group": resource.Group, "kind": resource.Kind, "name": resource.Name}). - Debug("skipping") - continue - } - - obj := obj(resource.Target, resource.Live) - - // this creates garbage tasks - if hook.IsHook(obj) { - sc.log.WithFields(log.Fields{"group": obj.GroupVersionKind().Group, "kind": obj.GetKind(), "namespace": obj.GetNamespace(), "name": obj.GetName()}). - Debug("skipping hook") - continue - } - - for _, phase := range syncPhases(obj) { - resourceTasks = append(resourceTasks, pkg.SyncTaskInfo{Phase: phase, TargetObj: resource.Target, LiveObj: resource.Live}) - } - } - - hookTasks := make([]pkg.SyncTaskInfo, 0) - if !sc.skipHooks() { - for _, obj := range sc.compareResult.hooks { - for _, phase := range syncPhases(obj) { - // Hook resources names are deterministic, whether they are defined by the user (metadata.name), - // or formulated at the time of the operation (metadata.generateName). If user specifies - // metadata.generateName, then we will generate a formulated metadata.name before submission. - targetObj := obj.DeepCopy() - if targetObj.GetName() == "" { - postfix := strings.ToLower(fmt.Sprintf("%s-%s-%d", sc.syncRes.Revision[0:7], phase, sc.opState.StartedAt.UTC().Unix())) - generateName := obj.GetGenerateName() - targetObj.SetName(fmt.Sprintf("%s%s", generateName, postfix)) - } - - hookTasks = append(hookTasks, pkg.SyncTaskInfo{Phase: phase, TargetObj: targetObj, IsHook: true}) - } - } - } - - tasksInfo, err := sc.callbacks.OnBeforeSync(sc.appName, append(resourceTasks, hookTasks...)) - if err != nil { - sc.setOperationFailed(nil, err.Error()) - return nil, false - } - tasks := syncTasks{} - for _, info := range tasksInfo { - tasks = append(tasks, &syncTask{SyncTaskInfo: info}) - } - - // enrich target objects with the namespace - for _, task := range tasks { - if task.TargetObj == nil { - continue - } - - if task.TargetObj.GetNamespace() == "" { - // If target object's namespace is empty, we set namespace in the object. We do - // this even though it might be a cluster-scoped resource. This prevents any - // possibility of the resource from unintentionally becoming created in the - // namespace during the `kubectl apply` - task.TargetObj = task.TargetObj.DeepCopy() - task.TargetObj.SetNamespace(sc.namespace) - } - } - - // enrich task with live obj - for _, task := range tasks { - if task.TargetObj == nil || task.LiveObj != nil { - continue - } - task.LiveObj = sc.liveObj(task.TargetObj) - } - - // enrich tasks with the result - for _, task := range tasks { - _, result := sc.syncRes.Resources.Find(task.group(), task.kind(), task.namespace(), task.name(), task.Phase) - if result != nil { - task.syncStatus = result.Status - task.operationState = result.HookPhase - task.message = result.Message - } - } - - // check permissions - for _, task := range tasks { - serverRes, err := kube.ServerResourceForGroupVersionKind(sc.disco, task.groupVersionKind()) - if err != nil { - // Special case for custom resources: if CRD is not yet known by the K8s API server, - // skip verification during `kubectl apply --dry-run` since we expect the CRD - // to be created during app synchronization. - if apierr.IsNotFound(err) && sc.hasCRDOfGroupKind(task.group(), task.kind()) { - sc.log.WithFields(log.Fields{"task": task}).Debug("skip dry-run for custom resource") - task.skipDryRun = true - } else { - sc.setResourceResult(task, v1alpha1.ResultCodeSyncFailed, "", err.Error()) - successful = false - } - } else { - if !sc.proj.IsResourcePermitted(metav1.GroupKind{Group: task.group(), Kind: task.kind()}, serverRes.Namespaced) { - sc.setResourceResult(task, v1alpha1.ResultCodeSyncFailed, "", fmt.Sprintf("Resource %s:%s is not permitted in project %s.", task.group(), task.kind(), sc.proj.Name)) - successful = false - } - if serverRes.Namespaced && !sc.proj.IsDestinationPermitted(v1alpha1.ApplicationDestination{Namespace: task.namespace(), Server: sc.server}) { - sc.setResourceResult(task, v1alpha1.ResultCodeSyncFailed, "", fmt.Sprintf("namespace %v is not permitted in project '%s'", task.namespace(), sc.proj.Name)) - successful = false - } - } - } - - sort.Sort(tasks) - - return tasks, successful -} - -func obj(a, b *unstructured.Unstructured) *unstructured.Unstructured { - if a != nil { - return a - } else { - return b - } -} - -func (sc *syncContext) liveObj(obj *unstructured.Unstructured) *unstructured.Unstructured { - for _, resource := range sc.compareResult.managedResources { - if resource.Group == obj.GroupVersionKind().Group && - resource.Kind == obj.GetKind() && - // cluster scoped objects will not have a namespace, even if the user has defined it - (resource.Namespace == "" || resource.Namespace == obj.GetNamespace()) && - resource.Name == obj.GetName() { - return resource.Live - } - } - return nil -} - -func (sc *syncContext) setOperationPhase(phase v1alpha1.OperationPhase, message string) { - if sc.opState.Phase != phase || sc.opState.Message != message { - sc.log.Infof("Updating operation state. phase: %s -> %s, message: '%s' -> '%s'", sc.opState.Phase, phase, sc.opState.Message, message) - } - sc.opState.Phase = phase - sc.opState.Message = message -} - -// ensureCRDReady waits until specified CRD is ready (established condition is true). Method is best effort - it does not fail even if CRD is not ready without timeout. -func (sc *syncContext) ensureCRDReady(name string) { - _ = wait.PollImmediate(time.Duration(100)*time.Millisecond, crdReadinessTimeout, func() (bool, error) { - crd, err := sc.extensionsclientset.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) - if err != nil { - return false, err - } - for _, condition := range crd.Status.Conditions { - if condition.Type == v1beta1.Established { - return condition.Status == v1beta1.ConditionTrue, nil - } - } - return false, nil - }) -} - -// applyObject performs a `kubectl apply` of a single resource -func (sc *syncContext) applyObject(targetObj *unstructured.Unstructured, dryRun bool, force bool) (v1alpha1.ResultCode, string) { - validate := !resource.HasAnnotationOption(targetObj, common.AnnotationSyncOptions, "Validate=false") - message, err := sc.kubectl.ApplyResource(sc.config, targetObj, targetObj.GetNamespace(), dryRun, force, validate) - if err != nil { - return v1alpha1.ResultCodeSyncFailed, err.Error() - } - if kube.IsCRD(targetObj) && !dryRun { - sc.ensureCRDReady(targetObj.GetName()) - } - return v1alpha1.ResultCodeSynced, message -} - -// pruneObject deletes the object if both prune is true and dryRun is false. Otherwise appropriate message -func (sc *syncContext) pruneObject(liveObj *unstructured.Unstructured, prune, dryRun bool) (v1alpha1.ResultCode, string) { - if !prune { - return v1alpha1.ResultCodePruneSkipped, "ignored (requires pruning)" - } else if resource.HasAnnotationOption(liveObj, common.AnnotationSyncOptions, "Prune=false") { - return v1alpha1.ResultCodePruneSkipped, "ignored (no prune)" - } else { - if dryRun { - return v1alpha1.ResultCodePruned, "pruned (dry run)" - } else { - // Skip deletion if object is already marked for deletion, so we don't cause a resource update hotloop - deletionTimestamp := liveObj.GetDeletionTimestamp() - if deletionTimestamp == nil || deletionTimestamp.IsZero() { - err := sc.kubectl.DeleteResource(sc.config, liveObj.GroupVersionKind(), liveObj.GetName(), liveObj.GetNamespace(), false) - if err != nil { - return v1alpha1.ResultCodeSyncFailed, err.Error() - } - } - return v1alpha1.ResultCodePruned, "pruned" - } - } -} - -func (sc *syncContext) hasCRDOfGroupKind(group string, kind string) bool { - for _, res := range sc.compareResult.managedResources { - if res.Target != nil && kube.IsCRD(res.Target) { - crdGroup, ok, err := unstructured.NestedString(res.Target.Object, "spec", "group") - if err != nil || !ok { - continue - } - crdKind, ok, err := unstructured.NestedString(res.Target.Object, "spec", "names", "kind") - if err != nil || !ok { - continue - } - if group == crdGroup && crdKind == kind { - return true - } - } - } - return false -} - -// terminate looks for any running jobs/workflow hooks and deletes the resource -func (sc *syncContext) terminate() { - terminateSuccessful := true - sc.log.Debug("terminating") - tasks, _ := sc.getSyncTasks() - for _, task := range tasks { - if !task.isHook() || !task.completed() { - continue - } - if isRunnable(task.groupVersionKind()) { - err := sc.deleteResource(task) - if err != nil { - sc.setResourceResult(task, "", v1alpha1.OperationFailed, fmt.Sprintf("Failed to delete: %v", err)) - terminateSuccessful = false - } else { - sc.setResourceResult(task, "", v1alpha1.OperationSucceeded, fmt.Sprintf("Deleted")) - } - } - } - if terminateSuccessful { - sc.setOperationPhase(v1alpha1.OperationFailed, "Operation terminated") - } else { - sc.setOperationPhase(v1alpha1.OperationError, "Operation termination had errors") - } -} - -func (sc *syncContext) deleteResource(task *syncTask) error { - sc.log.WithFields(log.Fields{"task": task}).Debug("deleting resource") - resIf, err := sc.getResourceIf(task) - if err != nil { - return err - } - propagationPolicy := metav1.DeletePropagationForeground - return resIf.Delete(task.name(), &metav1.DeleteOptions{PropagationPolicy: &propagationPolicy}) -} - -func (sc *syncContext) getResourceIf(task *syncTask) (dynamic.ResourceInterface, error) { - apiResource, err := kube.ServerResourceForGroupVersionKind(sc.disco, task.groupVersionKind()) - if err != nil { - return nil, err - } - res := kube.ToGroupVersionResource(task.groupVersionKind().GroupVersion().String(), apiResource) - resIf := kube.ToResourceInterface(sc.dynamicIf, apiResource, res, task.namespace()) - return resIf, err -} - -var operationPhases = map[v1alpha1.ResultCode]v1alpha1.OperationPhase{ - v1alpha1.ResultCodeSynced: v1alpha1.OperationRunning, - v1alpha1.ResultCodeSyncFailed: v1alpha1.OperationFailed, - v1alpha1.ResultCodePruned: v1alpha1.OperationSucceeded, - v1alpha1.ResultCodePruneSkipped: v1alpha1.OperationSucceeded, -} - -// tri-state -type runState = int - -const ( - successful = iota - pending - failed -) - -func (sc *syncContext) runTasks(tasks syncTasks, dryRun bool) runState { - - dryRun = dryRun || sc.syncOp.DryRun - - sc.log.WithFields(log.Fields{"numTasks": len(tasks), "dryRun": dryRun}).Debug("running tasks") - - runState := successful - var createTasks syncTasks - var pruneTasks syncTasks - - for _, task := range tasks { - if task.isPrune() { - pruneTasks = append(pruneTasks, task) - } else { - createTasks = append(createTasks, task) - } - } - // prune first - { - var wg sync.WaitGroup - for _, task := range pruneTasks { - wg.Add(1) - go func(t *syncTask) { - defer wg.Done() - sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}).Debug("pruning") - result, message := sc.pruneObject(t.LiveObj, sc.syncOp.Prune, dryRun) - if result == v1alpha1.ResultCodeSyncFailed { - runState = failed - } - if !dryRun || result == v1alpha1.ResultCodeSyncFailed { - sc.setResourceResult(t, result, operationPhases[result], message) - } - }(task) - } - wg.Wait() - } - - // delete anything that need deleting - if runState == successful && createTasks.Any(func(t *syncTask) bool { return t.needsDeleting() }) { - var wg sync.WaitGroup - for _, task := range createTasks.Filter(func(t *syncTask) bool { return t.needsDeleting() }) { - wg.Add(1) - go func(t *syncTask) { - defer wg.Done() - sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}).Debug("deleting") - if !dryRun { - err := sc.deleteResource(t) - if err != nil { - // it is possible to get a race condition here, such that the resource does not exist when - // delete is requested, we treat this as a nop - if !apierr.IsNotFound(err) { - runState = failed - sc.setResourceResult(t, "", v1alpha1.OperationError, fmt.Sprintf("failed to delete resource: %v", err)) - } - } else { - // if there is anything that needs deleting, we are at best now in pending and - // want to return and wait for sync to be invoked again - runState = pending - } - } - }(task) - } - wg.Wait() - } - // finally create resources - if runState == successful { - processCreateTasks := func(tasks syncTasks) { - var createWg sync.WaitGroup - for _, task := range tasks { - if dryRun && task.skipDryRun { - continue - } - createWg.Add(1) - go func(t *syncTask) { - defer createWg.Done() - sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}).Debug("applying") - result, message := sc.applyObject(t.TargetObj, dryRun, sc.syncOp.SyncStrategy.Force()) - if result == v1alpha1.ResultCodeSyncFailed { - runState = failed - } - if !dryRun || result == v1alpha1.ResultCodeSyncFailed { - sc.setResourceResult(t, result, operationPhases[result], message) - } - }(task) - } - createWg.Wait() - } - - var tasksGroup syncTasks - for _, task := range createTasks { - //Only wait if the type of the next task is different than the previous type - if len(tasksGroup) > 0 && tasksGroup[0].TargetObj.GetKind() != task.kind() { - processCreateTasks(tasksGroup) - tasksGroup = syncTasks{task} - } else { - tasksGroup = append(tasksGroup, task) - } - } - if len(tasksGroup) > 0 { - processCreateTasks(tasksGroup) - } - } - return runState -} - -// setResourceResult sets a resource details in the SyncResult.Resources list -func (sc *syncContext) setResourceResult(task *syncTask, syncStatus v1alpha1.ResultCode, operationState v1alpha1.OperationPhase, message string) { - - task.syncStatus = syncStatus - task.operationState = operationState - // we always want to keep the latest message - if message != "" { - task.message = message - } - - sc.lock.Lock() - defer sc.lock.Unlock() - i, existing := sc.syncRes.Resources.Find(task.group(), task.kind(), task.namespace(), task.name(), task.Phase) - - res := v1alpha1.ResourceResult{ - Group: task.group(), - Version: task.version(), - Kind: task.kind(), - Namespace: task.namespace(), - Name: task.name(), - Status: task.syncStatus, - Message: task.message, - HookType: task.hookType(), - HookPhase: task.operationState, - SyncPhase: task.Phase, - } - - logCtx := sc.log.WithFields(log.Fields{"namespace": task.namespace(), "kind": task.kind(), "name": task.name(), "phase": task.Phase}) - - if existing != nil { - // update existing value - if res.Status != existing.Status || res.HookPhase != existing.HookPhase || res.Message != existing.Message { - logCtx.Infof("updating resource result, status: '%s' -> '%s', phase '%s' -> '%s', message '%s' -> '%s'", - existing.Status, res.Status, - existing.HookPhase, res.HookPhase, - existing.Message, res.Message) - } - sc.syncRes.Resources[i] = &res - } else { - logCtx.Infof("adding resource result, status: '%s', phase: '%s', message: '%s'", res.Status, res.HookPhase, res.Message) - sc.syncRes.Resources = append(sc.syncRes.Resources, &res) - } -} diff --git a/controller/sync_hooks.go b/controller/sync_hooks.go deleted file mode 100644 index a1856df14..000000000 --- a/controller/sync_hooks.go +++ /dev/null @@ -1,120 +0,0 @@ -package controller - -import ( - "fmt" - - "github.com/argoproj/argo-cd/engine/util/health" - - apiv1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/kubernetes/pkg/apis/batch" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// getOperationPhase returns a hook status from an _live_ unstructured object -func getOperationPhase(hook *unstructured.Unstructured) (operation v1alpha1.OperationPhase, message string) { - gvk := hook.GroupVersionKind() - if isBatchJob(gvk) { - return getStatusFromBatchJob(hook) - } else if isArgoWorkflow(gvk) { - return health.GetStatusFromArgoWorkflow(hook) - } else if isPod(gvk) { - return getStatusFromPod(hook) - } else { - return v1alpha1.OperationSucceeded, fmt.Sprintf("%s created", hook.GetName()) - } -} - -// isRunnable returns if the resource object is a runnable type which needs to be terminated -func isRunnable(gvk schema.GroupVersionKind) bool { - return isBatchJob(gvk) || isArgoWorkflow(gvk) || isPod(gvk) -} - -func isBatchJob(gvk schema.GroupVersionKind) bool { - return gvk.Group == "batch" && gvk.Kind == "Job" -} - -// TODO this is a copy-and-paste of health.getJobHealth(), refactor out? -func getStatusFromBatchJob(hook *unstructured.Unstructured) (operation v1alpha1.OperationPhase, message string) { - var job batch.Job - err := runtime.DefaultUnstructuredConverter.FromUnstructured(hook.Object, &job) - if err != nil { - return v1alpha1.OperationError, err.Error() - } - failed := false - var failMsg string - complete := false - for _, condition := range job.Status.Conditions { - switch condition.Type { - case batch.JobFailed: - failed = true - complete = true - failMsg = condition.Message - case batch.JobComplete: - complete = true - message = condition.Message - } - } - if !complete { - return v1alpha1.OperationRunning, message - } else if failed { - return v1alpha1.OperationFailed, failMsg - } else { - return v1alpha1.OperationSucceeded, message - } -} - -func isArgoWorkflow(gvk schema.GroupVersionKind) bool { - return gvk.Group == "argoproj.io" && gvk.Kind == "Workflow" -} - -func isPod(gvk schema.GroupVersionKind) bool { - return gvk.Group == "" && gvk.Kind == "Pod" -} - -// TODO - this is very similar to health.getPodHealth() should we use that instead? -func getStatusFromPod(hook *unstructured.Unstructured) (v1alpha1.OperationPhase, string) { - var pod apiv1.Pod - err := runtime.DefaultUnstructuredConverter.FromUnstructured(hook.Object, &pod) - if err != nil { - return v1alpha1.OperationError, err.Error() - } - getFailMessage := func(ctr *apiv1.ContainerStatus) string { - if ctr.State.Terminated != nil { - if ctr.State.Terminated.Message != "" { - return ctr.State.Terminated.Message - } - if ctr.State.Terminated.Reason == "OOMKilled" { - return ctr.State.Terminated.Reason - } - if ctr.State.Terminated.ExitCode != 0 { - return fmt.Sprintf("container %q failed with exit code %d", ctr.Name, ctr.State.Terminated.ExitCode) - } - } - return "" - } - - switch pod.Status.Phase { - case apiv1.PodPending, apiv1.PodRunning: - return v1alpha1.OperationRunning, "" - case apiv1.PodSucceeded: - return v1alpha1.OperationSucceeded, "" - case apiv1.PodFailed: - if pod.Status.Message != "" { - // Pod has a nice error message. Use that. - return v1alpha1.OperationFailed, pod.Status.Message - } - for _, ctr := range append(pod.Status.InitContainerStatuses, pod.Status.ContainerStatuses...) { - if msg := getFailMessage(&ctr); msg != "" { - return v1alpha1.OperationFailed, msg - } - } - return v1alpha1.OperationFailed, "" - case apiv1.PodUnknown: - return v1alpha1.OperationError, "" - } - return v1alpha1.OperationRunning, "" -} diff --git a/controller/sync_phase.go b/controller/sync_phase.go deleted file mode 100644 index e9c449af6..000000000 --- a/controller/sync_phase.go +++ /dev/null @@ -1,29 +0,0 @@ -package controller - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/hook" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -func syncPhases(obj *unstructured.Unstructured) []v1alpha1.SyncPhase { - if hook.Skip(obj) { - return nil - } else if hook.IsHook(obj) { - phasesMap := make(map[v1alpha1.SyncPhase]bool) - for _, hookType := range hook.Types(obj) { - switch hookType { - case v1alpha1.HookTypePreSync, v1alpha1.HookTypeSync, v1alpha1.HookTypePostSync, v1alpha1.HookTypeSyncFail: - phasesMap[v1alpha1.SyncPhase(hookType)] = true - } - } - var phases []v1alpha1.SyncPhase - for phase := range phasesMap { - phases = append(phases, phase) - } - return phases - } else { - return []v1alpha1.SyncPhase{v1alpha1.SyncPhaseSync} - } -} diff --git a/controller/sync_phase_test.go b/controller/sync_phase_test.go deleted file mode 100644 index 8b41eb7bd..000000000 --- a/controller/sync_phase_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package controller - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/test" -) - -func TestSyncPhaseNone(t *testing.T) { - assert.Equal(t, []SyncPhase{SyncPhaseSync}, syncPhases(&unstructured.Unstructured{})) -} - -func TestSyncPhasePreSync(t *testing.T) { - assert.Equal(t, []SyncPhase{SyncPhasePreSync}, syncPhases(pod("PreSync"))) -} - -func TestSyncPhaseSync(t *testing.T) { - assert.Equal(t, []SyncPhase{SyncPhaseSync}, syncPhases(pod("Sync"))) -} - -func TestSyncPhaseSkip(t *testing.T) { - assert.Nil(t, syncPhases(pod("Skip"))) -} - -// garbage hooks are still hooks, but have no phases, because some user spelled something wrong -func TestSyncPhaseGarbage(t *testing.T) { - assert.Nil(t, syncPhases(pod("Garbage"))) -} - -func TestSyncPhasePost(t *testing.T) { - assert.Equal(t, []SyncPhase{SyncPhasePostSync}, syncPhases(pod("PostSync"))) -} - -func TestSyncPhaseFail(t *testing.T) { - assert.Equal(t, []SyncPhase{SyncPhaseSyncFail}, syncPhases(pod("SyncFail"))) -} - -func TestSyncPhaseTwoPhases(t *testing.T) { - assert.ElementsMatch(t, []SyncPhase{SyncPhasePreSync, SyncPhasePostSync}, syncPhases(pod("PreSync,PostSync"))) -} - -func TestSyncDuplicatedPhases(t *testing.T) { - assert.ElementsMatch(t, []SyncPhase{SyncPhasePreSync}, syncPhases(pod("PreSync,PreSync"))) - assert.ElementsMatch(t, []SyncPhase{SyncPhasePreSync}, syncPhases(podWithHelmHook("pre-install,pre-upgrade"))) -} - -func pod(hookType string) *unstructured.Unstructured { - return test.Annotate(test.NewPod(), "argocd.argoproj.io/hook", hookType) -} - -func podWithHelmHook(hookType string) *unstructured.Unstructured { - return test.Annotate(test.NewPod(), "helm.sh/hook", hookType) -} diff --git a/controller/sync_task_test.go b/controller/sync_task_test.go deleted file mode 100644 index 81ca4600e..000000000 --- a/controller/sync_task_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package controller - -import ( - "testing" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" -) - -func Test_syncTask_hookType(t *testing.T) { - type fields struct { - phase SyncPhase - liveObj *unstructured.Unstructured - } - tests := []struct { - name string - fields fields - want HookType - }{ - {"Empty", fields{SyncPhaseSync, NewPod()}, ""}, - {"PreSyncHook", fields{SyncPhasePreSync, NewHook(HookTypePreSync)}, HookTypePreSync}, - {"SyncHook", fields{SyncPhaseSync, NewHook(HookTypeSync)}, HookTypeSync}, - {"PostSyncHook", fields{SyncPhasePostSync, NewHook(HookTypePostSync)}, HookTypePostSync}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - task := &syncTask{ - SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: tt.fields.phase, - LiveObj: tt.fields.liveObj, - }, - } - hookType := task.hookType() - assert.EqualValues(t, tt.want, hookType) - }) - } -} - -func Test_syncTask_hasHookDeletePolicy(t *testing.T) { - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: NewPod()}}).hasHookDeletePolicy(HookDeletePolicyBeforeHookCreation)) - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: NewPod()}}).hasHookDeletePolicy(HookDeletePolicyHookSucceeded)) - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: NewPod()}}).hasHookDeletePolicy(HookDeletePolicyHookFailed)) - // must be hook - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).hasHookDeletePolicy(HookDeletePolicyBeforeHookCreation)) - assert.True(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).hasHookDeletePolicy(HookDeletePolicyBeforeHookCreation)) - assert.True(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded")}}).hasHookDeletePolicy(HookDeletePolicyHookSucceeded)) - assert.True(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookFailed")}}).hasHookDeletePolicy(HookDeletePolicyHookFailed)) -} - -func Test_syncTask_needsDeleting(t *testing.T) { - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: NewPod()}}).needsDeleting()) - // must be hook - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).needsDeleting()) - // no need to delete if no live obj - assert.False(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(Annotate(NewPod(), "argoocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).needsDeleting()) - assert.True(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).needsDeleting()) - assert.True(t, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}}).needsDeleting()) - assert.True(t, (&syncTask{operationState: OperationSucceeded, SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded")}}).needsDeleting()) - assert.True(t, (&syncTask{operationState: OperationFailed, SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookFailed")}}).needsDeleting()) -} - -func Test_syncTask_wave(t *testing.T) { - assert.Equal(t, 0, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: NewPod()}}).wave()) - assert.Equal(t, 1, (&syncTask{SyncTaskInfo: pkg.SyncTaskInfo{TargetObj: Annotate(NewPod(), "argocd.argoproj.io/sync-wave", "1")}}).wave()) -} diff --git a/controller/sync_test.go b/controller/sync_test.go deleted file mode 100644 index c45ad9fae..000000000 --- a/controller/sync_test.go +++ /dev/null @@ -1,696 +0,0 @@ -package controller - -import ( - "fmt" - "reflect" - "testing" - - "github.com/argoproj/argo-cd/engine/util/settings" - - "github.com/argoproj/argo-cd/engine/pkg" - - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - fakedisco "k8s.io/client-go/discovery/fake" - "k8s.io/client-go/dynamic/fake" - "k8s.io/client-go/rest" - testcore "k8s.io/client-go/testing" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/kube/kubetest" - - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/test" -) - -func newTestSyncCtx(resources ...*v1.APIResourceList) *syncContext { - fakeDisco := &fakedisco.FakeDiscovery{Fake: &testcore.Fake{}} - fakeDisco.Resources = append(resources, - &v1.APIResourceList{ - GroupVersion: "v1", - APIResources: []v1.APIResource{ - {Kind: "Pod", Group: "", Version: "v1", Namespaced: true}, - {Kind: "Service", Group: "", Version: "v1", Namespaced: true}, - }, - }, - &v1.APIResourceList{ - GroupVersion: "apps/v1", - APIResources: []v1.APIResource{ - {Kind: "Deployment", Group: "apps", Version: "v1", Namespaced: true}, - }, - }) - sc := syncContext{ - config: &rest.Config{}, - namespace: test.FakeArgoCDNamespace, - server: test.FakeClusterURL, - syncRes: &SyncOperationResult{ - Revision: "FooBarBaz", - }, - syncOp: &SyncOperation{ - Prune: true, - SyncStrategy: &SyncStrategy{ - Apply: &SyncStrategyApply{}, - }, - }, - proj: &AppProject{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - Spec: AppProjectSpec{ - Destinations: []ApplicationDestination{{ - Server: test.FakeClusterURL, - Namespace: test.FakeArgoCDNamespace, - }}, - ClusterResourceWhitelist: []v1.GroupKind{ - {Group: "*", Kind: "*"}, - }, - }, - }, - opState: &OperationState{}, - disco: fakeDisco, - log: log.WithFields(log.Fields{"application": "fake-app"}), - callbacks: settings.NewNoOpCallbacks(), - } - sc.kubectl = &kubetest.MockKubectlCmd{} - return &sc -} - -func newManagedResource(live *unstructured.Unstructured) managedResource { - return managedResource{ - Live: live, - Group: live.GroupVersionKind().Group, - Version: live.GroupVersionKind().Version, - Kind: live.GroupVersionKind().Kind, - Namespace: live.GetNamespace(), - Name: live.GetName(), - } -} - -func TestSyncNotPermittedNamespace(t *testing.T) { - syncCtx := newTestSyncCtx() - targetPod := test.NewPod() - targetPod.SetNamespace("kube-system") - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: targetPod, - }, { - Live: nil, - Target: test.NewService(), - }}, - } - syncCtx.sync() - assert.Equal(t, OperationFailed, syncCtx.opState.Phase) - assert.Contains(t, syncCtx.syncRes.Resources[0].Message, "not permitted in project") -} - -func TestSyncCreateInSortedOrder(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: test.NewPod(), - }, { - Live: nil, - Target: test.NewService(), - }}, - } - syncCtx.sync() - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) - assert.Len(t, syncCtx.syncRes.Resources, 2) - for i := range syncCtx.syncRes.Resources { - result := syncCtx.syncRes.Resources[i] - if result.Kind == "Pod" { - assert.Equal(t, ResultCodeSynced, result.Status) - assert.Equal(t, "", result.Message) - } else if result.Kind == "Service" { - assert.Equal(t, "", result.Message) - } else { - t.Error("Resource isn't a pod or a service") - } - } -} - -func TestSyncCreateNotWhitelistedClusterResources(t *testing.T) { - syncCtx := newTestSyncCtx(&v1.APIResourceList{ - GroupVersion: SchemeGroupVersion.String(), - APIResources: []v1.APIResource{ - {Name: "workflows", Namespaced: false, Kind: "Workflow", Group: "argoproj.io"}, - {Name: "application", Namespaced: false, Kind: "Application", Group: "argoproj.io"}, - }, - }, &v1.APIResourceList{ - GroupVersion: "rbac.authorization.k8s.io/v1", - APIResources: []v1.APIResource{ - {Name: "clusterroles", Namespaced: false, Kind: "ClusterRole", Group: "rbac.authorization.k8s.io"}, - }, - }) - - syncCtx.proj.Spec.ClusterResourceWhitelist = []v1.GroupKind{ - {Group: "argoproj.io", Kind: "*"}, - } - - syncCtx.kubectl = &kubetest.MockKubectlCmd{} - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: kube.MustToUnstructured(&rbacv1.ClusterRole{ - TypeMeta: metav1.TypeMeta{Kind: "ClusterRole", APIVersion: "rbac.authorization.k8s.io/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "argo-ui-cluster-role"}}), - }}, - } - syncCtx.sync() - assert.Len(t, syncCtx.syncRes.Resources, 1) - result := syncCtx.syncRes.Resources[0] - assert.Equal(t, ResultCodeSyncFailed, result.Status) - assert.Contains(t, result.Message, "not permitted in project") -} - -func TestSyncBlacklistedNamespacedResources(t *testing.T) { - syncCtx := newTestSyncCtx() - - syncCtx.proj.Spec.NamespaceResourceBlacklist = []v1.GroupKind{ - {Group: "*", Kind: "Deployment"}, - } - - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: test.NewDeployment(), - }}, - } - syncCtx.sync() - assert.Len(t, syncCtx.syncRes.Resources, 1) - result := syncCtx.syncRes.Resources[0] - assert.Equal(t, ResultCodeSyncFailed, result.Status) - assert.Contains(t, result.Message, "not permitted in project") -} - -func TestSyncSuccessfully(t *testing.T) { - syncCtx := newTestSyncCtx() - pod := test.NewPod() - pod.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: test.NewService(), - }, { - Live: pod, - Target: nil, - }}, - } - syncCtx.sync() - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) - assert.Len(t, syncCtx.syncRes.Resources, 2) - for i := range syncCtx.syncRes.Resources { - result := syncCtx.syncRes.Resources[i] - if result.Kind == "Pod" { - assert.Equal(t, ResultCodePruned, result.Status) - assert.Equal(t, "pruned", result.Message) - } else if result.Kind == "Service" { - assert.Equal(t, ResultCodeSynced, result.Status) - assert.Equal(t, "", result.Message) - } else { - t.Error("Resource isn't a pod or a service") - } - } -} - -func TestSyncDeleteSuccessfully(t *testing.T) { - syncCtx := newTestSyncCtx() - svc := test.NewService() - svc.SetNamespace(test.FakeArgoCDNamespace) - pod := test.NewPod() - pod.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: svc, - Target: nil, - }, { - Live: pod, - Target: nil, - }}, - } - syncCtx.sync() - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) - for i := range syncCtx.syncRes.Resources { - result := syncCtx.syncRes.Resources[i] - if result.Kind == "Pod" { - assert.Equal(t, ResultCodePruned, result.Status) - assert.Equal(t, "pruned", result.Message) - } else if result.Kind == "Service" { - assert.Equal(t, ResultCodePruned, result.Status) - assert.Equal(t, "pruned", result.Message) - } else { - t.Error("Resource isn't a pod or a service") - } - } -} - -func TestSyncCreateFailure(t *testing.T) { - syncCtx := newTestSyncCtx() - testSvc := test.NewService() - syncCtx.kubectl = &kubetest.MockKubectlCmd{ - Commands: map[string]kubetest.KubectlOutput{ - testSvc.GetName(): { - Output: "", - Err: fmt.Errorf("foo"), - }, - }, - } - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: nil, - Target: testSvc, - }}, - } - syncCtx.sync() - assert.Len(t, syncCtx.syncRes.Resources, 1) - result := syncCtx.syncRes.Resources[0] - assert.Equal(t, ResultCodeSyncFailed, result.Status) - assert.Equal(t, "foo", result.Message) -} - -func TestSyncPruneFailure(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.kubectl = &kubetest.MockKubectlCmd{ - Commands: map[string]kubetest.KubectlOutput{ - "test-service": { - Output: "", - Err: fmt.Errorf("foo"), - }, - }, - } - testSvc := test.NewService() - testSvc.SetName("test-service") - testSvc.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{ - Live: testSvc, - Target: nil, - }}, - } - syncCtx.sync() - assert.Equal(t, OperationFailed, syncCtx.opState.Phase) - assert.Len(t, syncCtx.syncRes.Resources, 1) - result := syncCtx.syncRes.Resources[0] - assert.Equal(t, ResultCodeSyncFailed, result.Status) - assert.Equal(t, "foo", result.Message) -} - -func TestDontSyncOrPruneHooks(t *testing.T) { - syncCtx := newTestSyncCtx() - targetPod := test.NewPod() - targetPod.SetName("dont-create-me") - targetPod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) - liveSvc := test.NewService() - liveSvc.SetName("dont-prune-me") - liveSvc.SetNamespace(test.FakeArgoCDNamespace) - liveSvc.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) - - syncCtx.compareResult = &comparisonResult{ - hooks: []*unstructured.Unstructured{targetPod, liveSvc}, - } - syncCtx.sync() - assert.Len(t, syncCtx.syncRes.Resources, 0) - syncCtx.sync() - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) -} - -// make sure that we do not prune resources with Prune=false -func TestDontPrunePruneFalse(t *testing.T) { - syncCtx := newTestSyncCtx() - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationSyncOptions: "Prune=false"}) - pod.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{managedResources: []managedResource{{Live: pod}}} - - syncCtx.sync() - - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) - assert.Len(t, syncCtx.syncRes.Resources, 1) - assert.Equal(t, ResultCodePruneSkipped, syncCtx.syncRes.Resources[0].Status) - assert.Equal(t, "ignored (no prune)", syncCtx.syncRes.Resources[0].Message) - - syncCtx.sync() - - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) -} - -// make sure Validate=false means we don't validate -func TestSyncOptionValidate(t *testing.T) { - tests := []struct { - name string - annotationVal string - want bool - }{ - {"Empty", "", true}, - {"True", "Validate=true", true}, - {"False", "Validate=false", false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - syncCtx := newTestSyncCtx() - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationSyncOptions: tt.annotationVal}) - pod.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{managedResources: []managedResource{{Target: pod, Live: pod}}} - - syncCtx.sync() - - kubectl, _ := syncCtx.kubectl.(*kubetest.MockKubectlCmd) - assert.Equal(t, tt.want, kubectl.LastValidate) - }) - } -} - -func TestSelectiveSyncOnly(t *testing.T) { - syncCtx := newTestSyncCtx() - pod1 := test.NewPod() - pod1.SetName("pod-1") - pod2 := test.NewPod() - pod2.SetName("pod-2") - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{Target: pod1}}, - } - syncCtx.syncResources = []SyncOperationResource{{Kind: "Pod", Name: "pod-1"}} - - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, successful) - assert.Len(t, tasks, 1) - assert.Equal(t, "pod-1", tasks[0].name()) -} - -func TestUnnamedHooksGetUniqueNames(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - pod := test.NewPod() - pod.SetName("") - pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync,PostSync"}) - syncCtx.compareResult = &comparisonResult{hooks: []*unstructured.Unstructured{pod}} - - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, successful) - assert.Len(t, tasks, 2) - assert.Contains(t, tasks[0].name(), "foobarb-presync-") - assert.Contains(t, tasks[1].name(), "foobarb-postsync-") - assert.Equal(t, "", pod.GetName()) -} - -func TestManagedResourceAreNotNamed(t *testing.T) { - syncCtx := newTestSyncCtx() - pod := test.NewPod() - pod.SetName("") - syncCtx.compareResult = &comparisonResult{managedResources: []managedResource{{Target: pod}}} - - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, successful) - assert.Len(t, tasks, 1) - assert.Equal(t, "", tasks[0].name()) - assert.Equal(t, "", pod.GetName()) -} - -func TestDeDupingTasks(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - pod := test.NewPod() - pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "Sync"}) - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{Target: pod}}, - hooks: []*unstructured.Unstructured{pod}, - } - - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, successful) - assert.Len(t, tasks, 1) -} - -func TestObjectsGetANamespace(t *testing.T) { - syncCtx := newTestSyncCtx() - pod := test.NewPod() - syncCtx.compareResult = &comparisonResult{managedResources: []managedResource{{Target: pod}}} - - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, successful) - assert.Len(t, tasks, 1) - assert.Equal(t, test.FakeArgoCDNamespace, tasks[0].namespace()) - assert.Equal(t, "", pod.GetNamespace()) -} - -func TestPersistRevisionHistory(t *testing.T) { - app := newFakeApp() - app.Status.OperationState = nil - app.Status.History = nil - - defaultProject := &AppProject{ - ObjectMeta: v1.ObjectMeta{ - Namespace: test.FakeArgoCDNamespace, - Name: "default", - }, - } - data := fakeData{ - apps: []runtime.Object{app, defaultProject}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - - // Sync with source unspecified - opState := &OperationState{Operation: Operation{ - Sync: &SyncOperation{}, - }} - ctrl.appStateManager.SyncAppState(app, opState) - // Ensure we record spec.source into sync result - assert.Equal(t, app.Spec.Source, opState.SyncResult.Source) - - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(app.Name, v1.GetOptions{}) - assert.Nil(t, err) - assert.Equal(t, 1, len(updatedApp.Status.History)) - assert.Equal(t, app.Spec.Source, updatedApp.Status.History[0].Source) - assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) -} - -func TestPersistRevisionHistoryRollback(t *testing.T) { - app := newFakeApp() - app.Status.OperationState = nil - app.Status.History = nil - defaultProject := &AppProject{ - ObjectMeta: v1.ObjectMeta{ - Namespace: test.FakeArgoCDNamespace, - Name: "default", - }, - } - data := fakeData{ - apps: []runtime.Object{app, defaultProject}, - manifestResponse: &pkg.ManifestResponse{ - Manifests: []string{}, - Namespace: test.FakeDestNamespace, - Server: test.FakeClusterURL, - Revision: "abc123", - }, - managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - } - ctrl := newFakeController(&data) - - // Sync with source specified - source := ApplicationSource{ - Helm: &ApplicationSourceHelm{ - Parameters: []HelmParameter{ - { - Name: "test", - Value: "123", - }, - }, - }, - } - opState := &OperationState{Operation: Operation{ - Sync: &SyncOperation{ - Source: &source, - }, - }} - ctrl.appStateManager.SyncAppState(app, opState) - // Ensure we record opState's source into sync result - assert.Equal(t, source, opState.SyncResult.Source) - - updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(app.Name, v1.GetOptions{}) - assert.Nil(t, err) - assert.Equal(t, 1, len(updatedApp.Status.History)) - assert.Equal(t, source, updatedApp.Status.History[0].Source) - assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) -} - -func TestSyncFailureHookWithSuccessfulSync(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{Target: test.NewPod()}}, - hooks: []*unstructured.Unstructured{test.NewHook(HookTypeSyncFail)}, - } - - syncCtx.sync() - - assert.Equal(t, OperationSucceeded, syncCtx.opState.Phase) - // only one result, we did not run the failure failureHook - assert.Len(t, syncCtx.syncRes.Resources, 1) -} - -func TestSyncFailureHookWithFailedSync(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - pod := test.NewPod() - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{Target: pod}}, - hooks: []*unstructured.Unstructured{test.NewHook(HookTypeSyncFail)}, - } - syncCtx.kubectl = &kubetest.MockKubectlCmd{ - Commands: map[string]kubetest.KubectlOutput{pod.GetName(): {Err: fmt.Errorf("")}}, - } - - syncCtx.sync() - syncCtx.sync() - - assert.Equal(t, OperationFailed, syncCtx.opState.Phase) - assert.Len(t, syncCtx.syncRes.Resources, 2) -} - -func TestBeforeHookCreation(t *testing.T) { - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - hook := test.Annotate(test.Annotate(test.NewPod(), common.AnnotationKeyHook, "Sync"), common.AnnotationKeyHookDeletePolicy, "BeforeHookCreation") - hook.SetNamespace(test.FakeArgoCDNamespace) - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{newManagedResource(hook)}, - hooks: []*unstructured.Unstructured{hook}, - } - syncCtx.dynamicIf = fake.NewSimpleDynamicClient(runtime.NewScheme()) - - syncCtx.sync() - assert.Len(t, syncCtx.syncRes.Resources, 1) - assert.Empty(t, syncCtx.syncRes.Resources[0].Message) -} - -func TestRunSyncFailHooksFailed(t *testing.T) { - // Tests that other SyncFail Hooks run even if one of them fail. - - syncCtx := newTestSyncCtx() - syncCtx.syncOp.SyncStrategy.Apply = nil - pod := test.NewPod() - successfulSyncFailHook := test.NewHook(HookTypeSyncFail) - successfulSyncFailHook.SetName("successful-sync-fail-hook") - failedSyncFailHook := test.NewHook(HookTypeSyncFail) - failedSyncFailHook.SetName("failed-sync-fail-hook") - syncCtx.compareResult = &comparisonResult{ - managedResources: []managedResource{{Target: pod}}, - hooks: []*unstructured.Unstructured{successfulSyncFailHook, failedSyncFailHook}, - } - - syncCtx.kubectl = &kubetest.MockKubectlCmd{ - Commands: map[string]kubetest.KubectlOutput{ - // Fail operation - pod.GetName(): {Err: fmt.Errorf("")}, - // Fail a single SyncFail hook - failedSyncFailHook.GetName(): {Err: fmt.Errorf("")}}, - } - - syncCtx.sync() - syncCtx.sync() - - fmt.Println(syncCtx.syncRes.Resources) - fmt.Println(syncCtx.opState.Phase) - // Operation as a whole should fail - assert.Equal(t, OperationFailed, syncCtx.opState.Phase) - // failedSyncFailHook should fail - assert.Equal(t, OperationFailed, syncCtx.syncRes.Resources[1].HookPhase) - assert.Equal(t, ResultCodeSyncFailed, syncCtx.syncRes.Resources[1].Status) - // successfulSyncFailHook should be synced running (it is an nginx pod) - assert.Equal(t, OperationRunning, syncCtx.syncRes.Resources[2].HookPhase) - assert.Equal(t, ResultCodeSynced, syncCtx.syncRes.Resources[2].Status) -} - -func Test_syncContext_isSelectiveSync(t *testing.T) { - type fields struct { - compareResult *comparisonResult - syncResources []SyncOperationResource - } - oneSyncResource := []SyncOperationResource{{}} - oneResource := func(group, kind, name string, hook bool) *comparisonResult { - return &comparisonResult{resources: []ResourceStatus{{Group: group, Kind: kind, Name: name, Hook: hook}}} - } - tests := []struct { - name string - fields fields - want bool - }{ - {"Empty", fields{}, false}, - {"OneCompareResult", fields{oneResource("", "", "", false), []SyncOperationResource{}}, true}, - {"OneSyncResource", fields{&comparisonResult{}, oneSyncResource}, true}, - {"Equal", fields{oneResource("", "", "", false), oneSyncResource}, false}, - {"EqualOutOfOrder", fields{&comparisonResult{resources: []ResourceStatus{{Group: "a"}, {Group: "b"}}}, []SyncOperationResource{{Group: "b"}, {Group: "a"}}}, false}, - {"KindDifferent", fields{oneResource("foo", "", "", false), oneSyncResource}, true}, - {"GroupDifferent", fields{oneResource("", "foo", "", false), oneSyncResource}, true}, - {"NameDifferent", fields{oneResource("", "", "foo", false), oneSyncResource}, true}, - {"HookIgnored", fields{oneResource("", "", "", true), []SyncOperationResource{}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - sc := &syncContext{ - compareResult: tt.fields.compareResult, - syncResources: tt.fields.syncResources, - callbacks: settings.NewNoOpCallbacks(), - } - if got := sc.isSelectiveSync(); got != tt.want { - t.Errorf("syncContext.isSelectiveSync() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_syncContext_liveObj(t *testing.T) { - type fields struct { - compareResult *comparisonResult - } - type args struct { - obj *unstructured.Unstructured - } - obj := test.NewPod() - obj.SetNamespace("my-ns") - - found := test.NewPod() - - tests := []struct { - name string - fields fields - args args - want *unstructured.Unstructured - }{ - {"None", fields{compareResult: &comparisonResult{managedResources: []managedResource{}}}, args{obj: &unstructured.Unstructured{}}, nil}, - {"Found", fields{compareResult: &comparisonResult{managedResources: []managedResource{{Group: obj.GroupVersionKind().Group, Kind: obj.GetKind(), Namespace: obj.GetNamespace(), Name: obj.GetName(), Live: found}}}}, args{obj: obj}, found}, - {"EmptyNamespace", fields{compareResult: &comparisonResult{managedResources: []managedResource{{Group: obj.GroupVersionKind().Group, Kind: obj.GetKind(), Name: obj.GetName(), Live: found}}}}, args{obj: obj}, found}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - sc := &syncContext{ - compareResult: tt.fields.compareResult, - callbacks: settings.NewNoOpCallbacks(), - } - if got := sc.liveObj(tt.args.obj); !reflect.DeepEqual(got, tt.want) { - t.Errorf("syncContext.liveObj() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/engine.go b/engine.go deleted file mode 100644 index fb1d76afd..000000000 --- a/engine.go +++ /dev/null @@ -1,47 +0,0 @@ -package engine - -import ( - "time" - - "github.com/argoproj/argo-cd/engine/controller" - - "github.com/argoproj/argo-cd/engine/pkg" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/lua" -) - -func NewEngine( - namespace string, // TODO: remove - settingsMgr pkg.ReconciliationSettings, - db pkg.CredentialsStore, - auditLogger pkg.AuditLogger, - applicationClientset appclientset.Interface, - repoClientset pkg.ManifestGenerator, - argoCache pkg.AppStateCache, - appResyncPeriod time.Duration, - selfHealTimeout time.Duration, - metricsPort int, - kubectlParallelismLimit int64, - healthCheck func() error, // TODO: remove - luaVMFactory func(map[string]appv1.ResourceOverride) *lua.VM, // TODO: probably remove - callbacks pkg.Callbacks, -) (pkg.Engine, error) { - return controller.NewApplicationController( - namespace, - settingsMgr, - db, - auditLogger, - applicationClientset, - repoClientset, - argoCache, - &kube.KubectlCmd{}, - appResyncPeriod, - selfHealTimeout, - metricsPort, - kubectlParallelismLimit, - healthCheck, - luaVMFactory, - callbacks) -} diff --git a/example.go b/example.go new file mode 100644 index 000000000..3d31f9e72 --- /dev/null +++ b/example.go @@ -0,0 +1,5 @@ +package main + +func main() { + println("TODO:") +} diff --git a/go.mod b/go.mod index 595953a68..7c9be1e1e 100644 --- a/go.mod +++ b/go.mod @@ -1,55 +1,55 @@ module github.com/argoproj/gitops-engine -go 1.12 +go 1.13 require ( - github.com/Knetic/govaluate v3.0.0+incompatible // indirect - github.com/argoproj/argo-cd v1.2.3 - github.com/argoproj/pkg v0.0.0-20190718233452-38dba6e98495 - github.com/casbin/casbin v1.5.0 - github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/Masterminds/semver v1.5.0 // indirect + github.com/argoproj/pkg v0.0.0-20200102163130-2dd1f3f6b4de github.com/evanphx/json-patch v4.2.0+incompatible github.com/ghodss/yaml v1.0.0 - github.com/go-openapi/spec v0.19.2 - github.com/gobuffalo/packr v1.11.0 // indirect - github.com/gobwas/glob v0.2.3 - github.com/gogo/protobuf v1.1.1 - github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc // indirect - github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf - github.com/google/uuid v1.1.1 // indirect - github.com/googleapis/gnostic v0.1.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/grpc-ecosystem/grpc-gateway v1.3.1 - github.com/imdario/mergo v0.3.8 // indirect - github.com/json-iterator/go v1.1.6 // indirect - github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/mattn/go-colorable v0.1.4 // indirect - github.com/onsi/ginkgo v1.8.0 // indirect - github.com/onsi/gomega v1.5.0 // indirect - github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/prometheus/client_golang v0.9.2 - github.com/robfig/cron v1.2.0 + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pkg/errors v0.9.1 + github.com/sergi/go-diff v1.1.0 // indirect github.com/sirupsen/logrus v1.4.2 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 github.com/yudai/gojsondiff v1.0.1-0.20180504020246-0525c875b75c github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect - github.com/yudai/pp v2.0.1+incompatible // indirect - github.com/yuin/gopher-lua v0.0.0-20190115140932-732aa6820ec4 - golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 - golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect - golang.org/x/sync v0.0.0-20190423024810-112230192c58 - golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect - google.golang.org/grpc v1.15.0 - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/src-d/go-git.v4 v4.9.1 - gopkg.in/yaml.v2 v2.2.2 - k8s.io/api v0.0.0-20190816222004-e3a6b8045b0b - k8s.io/apiextensions-apiserver v0.0.0-20190404071145-7f7d2b94eca3 - k8s.io/apimachinery v0.0.0-20190816221834-a9f1d8a9c101 + gopkg.in/src-d/go-git.v4 v4.13.1 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect + k8s.io/api v0.16.6 + k8s.io/apiextensions-apiserver v0.16.6 + k8s.io/apimachinery v0.16.6 + k8s.io/cli-runtime v0.16.6 k8s.io/client-go v11.0.1-0.20190816222228-6d55c1b1f1ca+incompatible - k8s.io/klog v0.3.3 // indirect - k8s.io/kube-aggregator v0.0.0-20190711105720-e80910364765 - k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503 - k8s.io/kubernetes v1.15.0-alpha.0.0.20190914015840-8fca2ec50a61 - layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 + k8s.io/kube-aggregator v0.0.0 + k8s.io/kubectl v0.16.6 + k8s.io/kubernetes v1.16.6 +) + +replace ( + // https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280 + k8s.io/api => k8s.io/api v0.16.6 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.16.6 // indirect + k8s.io/apimachinery => k8s.io/apimachinery v0.16.6 // indirect + k8s.io/apiserver => k8s.io/apiserver v0.16.6 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.16.6 + k8s.io/client-go => k8s.io/client-go v0.16.6 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.16.6 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.16.6 + k8s.io/code-generator => k8s.io/code-generator v0.16.6 + k8s.io/component-base => k8s.io/component-base v0.16.6 + k8s.io/cri-api => k8s.io/cri-api v0.16.6 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.16.6 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.16.6 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.16.6 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.16.6 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.16.6 + k8s.io/kubectl => k8s.io/kubectl v0.16.6 + k8s.io/kubelet => k8s.io/kubelet v0.16.6 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.16.6 + k8s.io/metrics => k8s.io/metrics v0.16.6 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.16.6 ) diff --git a/go.sum b/go.sum index f38ee1174..d02bcf30d 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,33 @@ -cloud.google.com/go v0.0.0-20160913182117-3b1ae45394a2/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v11.1.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= +github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= +github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= @@ -17,446 +35,769 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= +github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/argoproj/argo-cd v1.2.3 h1:5fmdNQ6I6F+5PUVhwIm6N6jDJm3vtjkfCFDzzzUnGcw= -github.com/argoproj/argo-cd v1.2.3/go.mod h1:UPOPiF6Y1y/oTL3X1KcuLbu7ljD7f4+SIaXvlowBmhE= -github.com/argoproj/pkg v0.0.0-20190718233452-38dba6e98495 h1:AP0ylCjCa87LMo2uWleH7TtBLebXj7CJapZOjOEYGnA= github.com/argoproj/pkg v0.0.0-20190718233452-38dba6e98495/go.mod h1:2EZ44RG/CcgtPTwrRR0apOc7oU6UIw8GjCUJWZ8X3bM= +github.com/argoproj/pkg v0.0.0-20200102163130-2dd1f3f6b4de h1:i19Yd0ERYAHtR84jnB8vmTuizk2q4Qw4NuayfRja5/A= +github.com/argoproj/pkg v0.0.0-20200102163130-2dd1f3f6b4de/go.mod h1:2EZ44RG/CcgtPTwrRR0apOc7oU6UIw8GjCUJWZ8X3bM= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM= +github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/bazelbuild/bazel-gazelle v0.18.2/go.mod h1:D0ehMSbS+vesFsLGiD6JXu3mVEzOlfUl8wNnq+x/9p0= +github.com/bazelbuild/bazel-gazelle v0.19.1-0.20191105222053-70208cbdc798/go.mod h1:rPwzNHUqEzngx1iVBfO/2X2npKaT3tqPqqHW6rVsn/A= +github.com/bazelbuild/buildtools v0.0.0-20190731111112-f720930ceb60/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= +github.com/bazelbuild/buildtools v0.0.0-20190917191645-69366ca98f89/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= +github.com/bazelbuild/rules_go v0.0.0-20190719190356-6dae44dc5cab/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= +github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/casbin/casbin v1.5.0 h1:mu575Bh7CW6JrjAjnQz0sTtHJvhpf3Gm5r2+tsWn6AY= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= github.com/casbin/casbin v1.5.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho= +github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/cloudflare/cfssl v0.0.0-20180726162950-56268a613adf/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= +github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= +github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= +github.com/container-storage-interface/spec v1.1.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= +github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/containerd v1.0.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo= +github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/docker/docker v0.0.0-20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libnetwork v0.0.0-20180830151422-a9cd636e3789/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= +github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M= +github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= +github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= +github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2 h1:ophLETFestFZHk3ji7niPEL4d466QjW+0Tdg5VyDq7E= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2 h1:rf5ArTHmIJxyV5Oiks+Su0mUens1+AjpkPoWr5xFRcI= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q= +github.com/go-openapi/runtime v0.19.0 h1:sU6pp4dSV2sGlNKKyHxZzi1m1kG4WnYtWcJ+HYbygjE= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0 h1:0Dn9qy1G9+UJfRU7TR8bmdGxb4uifB7HNrJjOnV0yPk= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/packr v1.11.0 h1:lxysfHcxVCWGNMHzKABP7ZEL3A7iIVYfkev/D7AR0aM= +github.com/go-openapi/validate v0.19.2 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/gobuffalo/packr v1.11.0/go.mod h1:rYwMLC6NXbAbkKb+9j3NTKbxSswkKLlelZYccr4HYVw= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= +github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc h1:55rEp52jU6bkyslZ1+C/7NGfpQsEc6pxGLAGDOctqbw= github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= +github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= +github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= +github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.18.0/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg= +github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= +github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= +github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/cadvisor v0.34.0/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48= +github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= -github.com/google/uuid v0.0.0-20171113160352-8c31c18f31ed/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20170330212424-2500245aa611/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.3.0 h1:HJtP6RRwj2EpPCD/mhAWzSvLL/dFTdPm1UrWwanoFos= github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.3.1 h1:k2neygAEBYavP90THffKBVlkASdxu4XiI8cAWuL3MG0= github.com/grpc-ecosystem/grpc-gateway v1.3.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= +github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.0.0-20141017032234-72f9bd7c4e0c/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= +github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04= +github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk= +github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao= +github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= +github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= +github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= +github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= +github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY= +github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= +github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.1.0 h1:65VZabgUiV9ktjGM5nTq0+YurgTyX+YI2lSSfDjI+qU= +github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= +github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM= +github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= +github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= +github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vmware/govmomi v0.20.1/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/gojsondiff v1.0.1-0.20180504020246-0525c875b75c h1:vGHScYm0uhmaxwGX38tj1TB1u1zVdO0vlgcz1fEVxc8= github.com/yudai/gojsondiff v1.0.1-0.20180504020246-0525c875b75c/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= -github.com/yuin/gopher-lua v0.0.0-20190115140932-732aa6820ec4 h1:1yOVVSFiradDwXpgdkDjlGOcGJqcohH/W49Zn8Ywgco= github.com/yuin/gopher-lua v0.0.0-20190115140932-732aa6820ec4/go.mod h1:fFiAh+CowNFr0NK5VASokuwKwkbacRmHsVA7Yb1Tqac= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569 h1:nSQar3Y0E3VQF/VdZ8PTAilaXpER+d7ypdABCrpwMdg= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df h1:shvkWr0NAZkg4nPuE3XrKP0VuBPijjk3TfX6Y6acFNg= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15 h1:Z2sc4+v0JHV6Mn4kX1f2a5nruNjmV+Th32sugE8zwz8= go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180808211826-de0752318171/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM= +golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= +golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20170412232759-a6bd8cefa181/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190122071731-054c452bb702/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190122202912-9c309ee22fab/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.15.0 h1:Az/KuahOM4NAidTEuJCv/RonAA7rYsTPkqXVjr+8OOw= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.15.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/natefinch/lumberjack.v2 v2.0.0-20150622162204-20b71e5b60d7/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/square/go-jose.v2 v2.0.0-20180411045311-89060dee6a84/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo= gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= -gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs= +gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.9.1 h1:0oKHJZY8tM7B71378cfTg2c5jmWyNlXvestTT6WfY+4= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.9.1/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.0.0-20190404065945-709cf190c7b7/go.mod h1:qa6Gt7knwxwD/MXwV8iaEoTpniVksiix/r9hpLWYgTA= -k8s.io/api v0.0.0-20190711103429-37c3b8b1ca65/go.mod h1:ndtPUvriKipo+umdrlC6qqG9GNRQ8vbS0t70FMFrjuw= -k8s.io/api v0.0.0-20190816222004-e3a6b8045b0b h1:RXEExX+zpnAwh3WmvQMVy5albf6/wuIP1W2ehL2lTqc= -k8s.io/api v0.0.0-20190816222004-e3a6b8045b0b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apiextensions-apiserver v0.0.0-20190404071145-7f7d2b94eca3 h1:miWvO6076scftqkE8Bl9EY7E5M1bTDhRfswjyuKeN34= -k8s.io/apiextensions-apiserver v0.0.0-20190404071145-7f7d2b94eca3/go.mod h1:lk7TmYmmnkaxbiVUUY7N0I/xnBr8PIRTWMmNHvem6Y4= -k8s.io/apimachinery v0.0.0-20190404065847-4a4abcd45006/go.mod h1:65NCMCFo27j/Cv2DAQSfKd70SAtu/hwoqasuXFCDNvY= -k8s.io/apimachinery v0.0.0-20190711103026-7bf792636534/go.mod h1:M2fZgZL9DbLfeJaPBCDqSqNsdsmLN+V29knYJnIXlMA= -k8s.io/apimachinery v0.0.0-20190816221834-a9f1d8a9c101 h1:QtHYUjIdgXTtJVdYQhWIQZZoXa32aF3O9BNX2up2plE= -k8s.io/apimachinery v0.0.0-20190816221834-a9f1d8a9c101/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/apiserver v0.0.0-20190404070726-04665e6b9c70/go.mod h1:ejjN+CSYTyDbN/dVpSrlxhTAOosMnrWlWm1jek/jIek= -k8s.io/apiserver v0.0.0-20190711105201-c925c445ddf6/go.mod h1:6M1Xg8rqnQKjtp2XM0Sm4mNPJkOTT8YHVScdfUiw7rI= -k8s.io/client-go v0.0.0-20190404070121-75debb4b680d/go.mod h1:bIEHXHbykaOlj+pgLllzLJ2RPGdzkjtqdk0Il07KPEM= -k8s.io/client-go v0.0.0-20190711103903-4a0861cac5e0/go.mod h1:MdhWxiGHTqqubuL4pqFLTAhEjVr0Oa6nj8mAy3kFIEI= -k8s.io/client-go v11.0.1-0.20190816222228-6d55c1b1f1ca+incompatible h1:2fjBDmXTKmTEIpBVgq1sMDHm2Y3RYgMJCrHk/Dbmpmw= -k8s.io/client-go v11.0.1-0.20190816222228-6d55c1b1f1ca+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/code-generator v0.0.0-20190404065638-916349668d3d/go.mod h1:IPqxl/YHk05nodzupwjke6ctMjyNRdV2zZ5/j3/F204= -k8s.io/code-generator v0.0.0-20190711102700-42c1e9a4dc7a/go.mod h1:gZ0mjdzfPz3P+cILxibAJ25xFoZ1Kf0xQrFUHy66AEs= -k8s.io/component-base v0.0.0-20190404070505-d7891e8054ca/go.mod h1:+NvN1jZolC6PvCu9KtpLJETeov4QYehdKLMwZ0yo0Zg= -k8s.io/component-base v0.0.0-20190711104712-4ad84870f76c/go.mod h1:yHi8nnYgJn3NxM9NE+ohCGKltBvgqw69dHs0g+QGIPY= -k8s.io/gengo v0.0.0-20181106084056-51747d6e00da/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.16.6 h1:FyTv/Z4RBlddLGJXRjGXE40QtYGHOjdZKRFSW5rU1oE= +k8s.io/api v0.16.6/go.mod h1:naJcEPKsa3oqutLPPMxA2oLSqV4KxGDLU6IgkqHqgFE= +k8s.io/apiextensions-apiserver v0.16.6 h1:GuzZMQ2t4vwvBSkprMsQhhlqyYZL2Lge+0+zQhDXV9I= +k8s.io/apiextensions-apiserver v0.16.6/go.mod h1:WbwakFromAVhfvLITDk5nRf5UJJwazjeZRx+yKeDcY0= +k8s.io/apimachinery v0.16.6 h1:A4RWH7F3jhkD6YyBpsm/2yXiFUEf9fiNqrz7bxZHPMc= +k8s.io/apimachinery v0.16.6/go.mod h1:mhhO3hoLkWO+2eCvqjPtH2Ly92l9nJDwsswzWKpkN2w= +k8s.io/apiserver v0.16.6 h1:7woiO69qcmhmTv2lsgAux2nb3bekuyogl3wzRI2HOBA= +k8s.io/apiserver v0.16.6/go.mod h1:JaDblfPzg2nbxaA0H3PsMgO72QAx2rBoSYwxLEKu5RE= +k8s.io/cli-runtime v0.16.6 h1:Z0X6rJanDHrpPtpJG3ObfRuPtlhvrJOJsfdqL+Y7bnw= +k8s.io/cli-runtime v0.16.6/go.mod h1:8N6G/UJmYvLXzpD1kjpuss6mFUeez+eg6Nu15VtBHvM= +k8s.io/client-go v0.16.6 h1:OR6ZaSlIn9dUdpiN4r5mAvMv5aCupUJUiDJZdrrvmhw= +k8s.io/client-go v0.16.6/go.mod h1:xIQ44uaAH4SD1EHMtCHsB9By7D0qblbv1ADeGyXpZUQ= +k8s.io/cloud-provider v0.16.6 h1:3cYBxmMBWuvPka7QCrizzUaKEaNCJqoGmHh4edfcS7s= +k8s.io/cloud-provider v0.16.6/go.mod h1:rTwoMb7ogSqEAZWev8ds88EApSPC6vVAikKgpvjOxpE= +k8s.io/cluster-bootstrap v0.16.6/go.mod h1:cOnd4cgo8AthVSyH7rIWpUNUdJyuCthsZjA2MEsFipI= +k8s.io/code-generator v0.16.6/go.mod h1:2aiDuxDU7RQK2PVypXAXHo6+YwOlF33iezHQbSmKSA4= +k8s.io/component-base v0.16.6 h1:1qIWVKni+gqRkN8vvaGYJk+R8tRtKDv0XvvDuYEBD1w= +k8s.io/component-base v0.16.6/go.mod h1:8+4lrSEgLQ9wqOzHVYx4GLSCU6sus8wqg8bfaTdXTwg= +k8s.io/cri-api v0.16.6/go.mod h1:W6aMMPN5fmxcRGaHnb6BEfoTeS82OsJcsUJyKf+EWYc= +k8s.io/csi-translation-lib v0.16.6/go.mod h1:T/bEjsu1sQn2qVi9FzsPqjvT31mSqpThoFwtnj327jg= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.0.0-20190306015804-8e90cee79f82/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c= k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/kube-aggregator v0.0.0-20190711105720-e80910364765 h1:3IT2y/2pU0aRnvC/tB77JXo7br2x0jOxv4X2jKEJpkY= -k8s.io/kube-aggregator v0.0.0-20190711105720-e80910364765/go.mod h1:+OF+X/4y0o3wiKOyNW2apeXc0tfRK8rR4Okx73JJJuU= -k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503 h1:IrnrEIp9du1SngrzGC1fdYEdos7Il6I6EVxwFQHJwCg= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-aggregator v0.16.6 h1:bNwY/t432BgxoL73jEMD5EdZQCUkqw5kwhQxFmxdNss= +k8s.io/kube-aggregator v0.16.6/go.mod h1:lRjo9e3xeyF8tjkIKEX+pErNOdE4yTazx9VPO6zzdcw= +k8s.io/kube-controller-manager v0.16.6/go.mod h1:7ovDaVMCHc4TBOQHzfb5w2XCib7rjx+QCMZTRVQteD4= k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= -k8s.io/kubernetes v1.15.0-alpha.0.0.20190914015840-8fca2ec50a61 h1:htit3IpEzT8j64xwd4lpO2hdcsK9TbDmNTYjGEjmOLc= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kube-proxy v0.16.6/go.mod h1:l7jgZcYyjERYxALU/EizkMx/JmIhN2Ff/f/aR/azFKg= +k8s.io/kube-scheduler v0.16.6/go.mod h1:ohT2kmuQnNex0cDUYvXBAdMKHlneruoD4KOacEDpPq4= +k8s.io/kubectl v0.16.6 h1:u7bQl9F78+7wYcvBSX7JfnIotLIQfAVpN1E11m2s+3w= +k8s.io/kubectl v0.16.6/go.mod h1:ybKdxxoYuQLRqsmBFylvgyFPeVmmRYUbxk134JCiNoM= +k8s.io/kubelet v0.16.6/go.mod h1:NAuB1uZwiOgUnJSgAnJIkWlueXFYkzxwv7xWEA/P35Y= k8s.io/kubernetes v1.15.0-alpha.0.0.20190914015840-8fca2ec50a61/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a h1:2jUDc9gJja832Ftp+QbDV0tVhQHMISFn01els+2ZAcw= -k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 h1:RZkKxMR3jbQxdCEcglq3j7wY3PRJIopAwBlx1RE71X0= +k8s.io/kubernetes v1.16.6 h1:ZWSNwxZ1w/IPV7pYH9gohR7AhKmn1VoJ9fEKxmkkeh8= +k8s.io/kubernetes v1.16.6/go.mod h1:rO6tSgbJjbo6lLkrq4jryUaXqZ2PdDJjzWXKZQmLfnQ= +k8s.io/legacy-cloud-providers v0.16.6/go.mod h1:trzyJ8vT+vD+FEP4NHDbJvOXYtksUbpD7PfR6Iwnhxk= +k8s.io/metrics v0.16.6/go.mod h1:de0nJbsn2wX/fapLW0Yi7k+GwXvEv4/g54agaDjzmQY= +k8s.io/repo-infra v0.0.1-alpha.1/go.mod h1:wO1t9WaB99V80ljbeENTnayuEEwNZt7gECYh/CEyOJ8= +k8s.io/sample-apiserver v0.16.6/go.mod h1:fyN8DaZXgtcQKCtb/x2mr4TDTUkaAdgWNU7BaLnlSqg= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427/go.mod h1:ivKkcY8Zxw5ba0jldhZCYYQfGdb2K6u9tbYK1AwMIBc= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= +sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= +sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v1.0.1 h1:LOs1LZWMsz1xs77Phr/pkB4LFaavH7IVq/3+WTN9XTA= +sigs.k8s.io/structured-merge-diff v1.0.1/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/hook/delete_policy.go b/hook/delete_policy.go deleted file mode 100644 index 86ce501fe..000000000 --- a/hook/delete_policy.go +++ /dev/null @@ -1,24 +0,0 @@ -package hook - -import ( - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/hook/helm" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" -) - -func DeletePolicies(obj *unstructured.Unstructured) []v1alpha1.HookDeletePolicy { - var policies []v1alpha1.HookDeletePolicy - for _, text := range resource.GetAnnotationCSVs(obj, common.AnnotationKeyHookDeletePolicy) { - p, ok := v1alpha1.NewHookDeletePolicy(text) - if ok { - policies = append(policies, p) - } - } - for _, p := range helm.DeletePolicies(obj) { - policies = append(policies, p.DeletePolicy()) - } - return policies -} diff --git a/hook/delete_policy_test.go b/hook/delete_policy_test.go deleted file mode 100644 index 271b472c5..000000000 --- a/hook/delete_policy_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package hook - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" -) - -func TestDeletePolicies(t *testing.T) { - assert.Nil(t, DeletePolicies(NewPod())) - assert.Nil(t, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "garbage"))) - assert.Equal(t, []HookDeletePolicy{HookDeletePolicyBeforeHookCreation}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation"))) - assert.Equal(t, []HookDeletePolicy{HookDeletePolicyHookSucceeded}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded"))) - assert.Equal(t, []HookDeletePolicy{HookDeletePolicyHookFailed}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookFailed"))) - // Helm test - assert.Equal(t, []HookDeletePolicy{HookDeletePolicyHookSucceeded}, DeletePolicies(Annotate(NewPod(), "helm.sh/hook-delete-policy", "hook-succeeded"))) -} diff --git a/hook/helm/hook.go b/hook/helm/hook.go deleted file mode 100644 index f0d9ad17d..000000000 --- a/hook/helm/hook.go +++ /dev/null @@ -1,8 +0,0 @@ -package helm - -import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - -func IsHook(obj *unstructured.Unstructured) bool { - _, ok := obj.GetAnnotations()["helm.sh/hook"] - return ok -} diff --git a/hook/hook.go b/hook/hook.go deleted file mode 100644 index ba5e0846c..000000000 --- a/hook/hook.go +++ /dev/null @@ -1,44 +0,0 @@ -package hook - -import ( - "github.com/argoproj/argo-cd/engine/common" - "github.com/argoproj/argo-cd/engine/hook/helm" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" -) - -func IsHook(obj *unstructured.Unstructured) bool { - _, ok := obj.GetAnnotations()[common.AnnotationKeyHook] - if ok { - return !Skip(obj) - } - return helm.IsHook(obj) -} - -func Skip(obj *unstructured.Unstructured) bool { - for _, hookType := range Types(obj) { - if hookType == v1alpha1.HookTypeSkip { - return len(Types(obj)) == 1 - } - } - return false -} - -func Types(obj *unstructured.Unstructured) []v1alpha1.HookType { - var types []v1alpha1.HookType - for _, text := range resource.GetAnnotationCSVs(obj, common.AnnotationKeyHook) { - t, ok := v1alpha1.NewHookType(text) - if ok { - types = append(types, t) - } - } - // we ignore Helm hooks if we have Argo hook - if len(types) == 0 { - for _, t := range helm.Types(obj) { - types = append(types, t.HookType()) - } - } - return types -} diff --git a/mocks/AppStateCache.go b/mocks/AppStateCache.go deleted file mode 100644 index 662f1107d..000000000 --- a/mocks/AppStateCache.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/stretchr/testify/mock" -) - -// AppStateCache is an autogenerated mock type for the AppStateCache type -type AppStateCache struct { - mock.Mock -} - -// GetAppManagedResources provides a mock function with given fields: appName, res -func (_m *AppStateCache) GetAppManagedResources(appName string, res *[]*v1alpha1.ResourceDiff) error { - ret := _m.Called(appName, res) - - var r0 error - if rf, ok := ret.Get(0).(func(string, *[]*v1alpha1.ResourceDiff) error); ok { - r0 = rf(appName, res) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// SetAppManagedResources provides a mock function with given fields: appName, managedResources -func (_m *AppStateCache) SetAppManagedResources(appName string, managedResources []*v1alpha1.ResourceDiff) error { - ret := _m.Called(appName, managedResources) - - var r0 error - if rf, ok := ret.Get(0).(func(string, []*v1alpha1.ResourceDiff) error); ok { - r0 = rf(appName, managedResources) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// SetAppResourcesTree provides a mock function with given fields: appName, resourcesTree -func (_m *AppStateCache) SetAppResourcesTree(appName string, resourcesTree *v1alpha1.ApplicationTree) error { - ret := _m.Called(appName, resourcesTree) - - var r0 error - if rf, ok := ret.Get(0).(func(string, *v1alpha1.ApplicationTree) error); ok { - r0 = rf(appName, resourcesTree) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/mocks/AuditLogger.go b/mocks/AuditLogger.go deleted file mode 100644 index e835c1c56..000000000 --- a/mocks/AuditLogger.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - "github.com/argoproj/argo-cd/engine/pkg" - "github.com/stretchr/testify/mock" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// AuditLogger is an autogenerated mock type for the AuditLogger type -type AuditLogger struct { - mock.Mock -} - -// LogAppEvent provides a mock function with given fields: app, info, message -func (_m *AuditLogger) LogAppEvent(app *v1alpha1.Application, info pkg.EventInfo, message string) { - _m.Called(app, info, message) -} diff --git a/mocks/CredentialsStore.go b/mocks/CredentialsStore.go deleted file mode 100644 index d908855ab..000000000 --- a/mocks/CredentialsStore.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - "context" - - "github.com/argoproj/argo-cd/engine/pkg" - - "github.com/stretchr/testify/mock" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// CredentialsStore is an autogenerated mock type for the CredentialsStore type -type CredentialsStore struct { - mock.Mock -} - -// GetCluster provides a mock function with given fields: ctx, name -func (_m *CredentialsStore) GetCluster(ctx context.Context, name string) (*v1alpha1.Cluster, error) { - ret := _m.Called(ctx, name) - - var r0 *v1alpha1.Cluster - if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Cluster); ok { - r0 = rf(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Cluster) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetRepository provides a mock function with given fields: ctx, url -func (_m *CredentialsStore) GetRepository(ctx context.Context, url string) (*v1alpha1.Repository, error) { - ret := _m.Called(ctx, url) - - var r0 *v1alpha1.Repository - if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Repository); ok { - r0 = rf(ctx, url) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*v1alpha1.Repository) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, url) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListHelmRepositories provides a mock function with given fields: ctx -func (_m *CredentialsStore) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - ret := _m.Called(ctx) - - var r0 []*v1alpha1.Repository - if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*v1alpha1.Repository) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// WatchClusters provides a mock function with given fields: ctx, callback -func (_m *CredentialsStore) WatchClusters(ctx context.Context, callback func(*pkg.ClusterEvent)) error { - ret := _m.Called(ctx, callback) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, func(*pkg.ClusterEvent)) error); ok { - r0 = rf(ctx, callback) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/mocks/ReconciliationSettings.go b/mocks/ReconciliationSettings.go deleted file mode 100644 index 208ce956a..000000000 --- a/mocks/ReconciliationSettings.go +++ /dev/null @@ -1,136 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - "github.com/argoproj/argo-cd/engine/resource" - "github.com/stretchr/testify/mock" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// ReconciliationSettings is an autogenerated mock type for the ReconciliationSettings type -type ReconciliationSettings struct { - mock.Mock -} - -// GetAppInstanceLabelKey provides a mock function with given fields: -func (_m *ReconciliationSettings) GetAppInstanceLabelKey() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetConfigManagementPlugins provides a mock function with given fields: -func (_m *ReconciliationSettings) GetConfigManagementPlugins() ([]v1alpha1.ConfigManagementPlugin, error) { - ret := _m.Called() - - var r0 []v1alpha1.ConfigManagementPlugin - if rf, ok := ret.Get(0).(func() []v1alpha1.ConfigManagementPlugin); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]v1alpha1.ConfigManagementPlugin) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetKustomizeBuildOptions provides a mock function with given fields: -func (_m *ReconciliationSettings) GetKustomizeBuildOptions() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetResourceOverrides provides a mock function with given fields: -func (_m *ReconciliationSettings) GetResourceOverrides() (map[string]v1alpha1.ResourceOverride, error) { - ret := _m.Called() - - var r0 map[string]v1alpha1.ResourceOverride - if rf, ok := ret.Get(0).(func() map[string]v1alpha1.ResourceOverride); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]v1alpha1.ResourceOverride) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetResourcesFilter provides a mock function with given fields: -func (_m *ReconciliationSettings) GetResourcesFilter() (*resource.ResourcesFilter, error) { - ret := _m.Called() - - var r0 *resource.ResourcesFilter - if rf, ok := ret.Get(0).(func() *resource.ResourcesFilter); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*resource.ResourcesFilter) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Subscribe provides a mock function with given fields: subCh -func (_m *ReconciliationSettings) Subscribe(subCh chan<- bool) { - _m.Called(subCh) -} - -// Unsubscribe provides a mock function with given fields: subCh -func (_m *ReconciliationSettings) Unsubscribe(subCh chan<- bool) { - _m.Called(subCh) -} diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list deleted file mode 100644 index 2410eabea..000000000 --- a/pkg/apis/api-rules/violation_exceptions.list +++ /dev/null @@ -1,11 +0,0 @@ -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,TLAs -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ConnectionState,ModifiedAt -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,JWTToken,ExpiresAt -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,JWTToken,IssuedAt -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,KustomizeOptions,BuildOptions -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,Repository,EnableLFS -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ResourceActionDefinition,ActionLua -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ResourceActions,ActionDiscoveryLua -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ResourceOverride,HealthLua -API rule violation: names_match,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,objectMeta,Name -API rule violation: omitempty_match_case,github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1,ResourceActions,Definitions diff --git a/pkg/apis/application/register.go b/pkg/apis/application/register.go deleted file mode 100644 index 0c39b09e0..000000000 --- a/pkg/apis/application/register.go +++ /dev/null @@ -1,20 +0,0 @@ -package application - -const ( - // API Group - Group string = "argoproj.io" - - // Application constants - ApplicationKind string = "Application" - ApplicationSingular string = "application" - ApplicationPlural string = "applications" - ApplicationShortName string = "app" - ApplicationFullName string = ApplicationPlural + "." + Group - - // AppProject constants - AppProjectKind string = "AppProject" - AppProjectSingular string = "appproject" - AppProjectPlural string = "appprojects" - AppProjectShortName string = "appproject" - AppProjectFullName string = AppProjectPlural + "." + Group -) diff --git a/pkg/apis/application/v1alpha1/doc.go b/pkg/apis/application/v1alpha1/doc.go deleted file mode 100644 index c418575ac..000000000 --- a/pkg/apis/application/v1alpha1/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package v1alpha1 is the v1alpha1 version of the API. -// +groupName=argoproj.io -// +k8s:deepcopy-gen=package,register -// +k8s:openapi-gen=true -package v1alpha1 diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go deleted file mode 100644 index 6b879865b..000000000 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ /dev/null @@ -1,18938 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1/generated.proto - -package v1alpha1 - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" - -import v11 "k8s.io/api/core/v1" -import v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -import k8s_io_apimachinery_pkg_watch "k8s.io/apimachinery/pkg/watch" - -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" - -import strings "strings" -import reflect "reflect" - -import io "io" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -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_85119751c9399dcb, []int{0} -} -func (m *AWSAuthConfig) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AWSAuthConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *AWSAuthConfig) XXX_Merge(src proto.Message) { - xxx_messageInfo_AWSAuthConfig.Merge(dst, src) -} -func (m *AWSAuthConfig) XXX_Size() int { - return m.Size() -} -func (m *AWSAuthConfig) XXX_DiscardUnknown() { - xxx_messageInfo_AWSAuthConfig.DiscardUnknown(m) -} - -var xxx_messageInfo_AWSAuthConfig proto.InternalMessageInfo - -func (m *AppProject) Reset() { *m = AppProject{} } -func (*AppProject) ProtoMessage() {} -func (*AppProject) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{1} -} -func (m *AppProject) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AppProject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *AppProject) XXX_Merge(src proto.Message) { - xxx_messageInfo_AppProject.Merge(dst, src) -} -func (m *AppProject) XXX_Size() int { - return m.Size() -} -func (m *AppProject) XXX_DiscardUnknown() { - xxx_messageInfo_AppProject.DiscardUnknown(m) -} - -var xxx_messageInfo_AppProject proto.InternalMessageInfo - -func (m *AppProjectList) Reset() { *m = AppProjectList{} } -func (*AppProjectList) ProtoMessage() {} -func (*AppProjectList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{2} -} -func (m *AppProjectList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AppProjectList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *AppProjectList) XXX_Merge(src proto.Message) { - xxx_messageInfo_AppProjectList.Merge(dst, src) -} -func (m *AppProjectList) XXX_Size() int { - return m.Size() -} -func (m *AppProjectList) XXX_DiscardUnknown() { - xxx_messageInfo_AppProjectList.DiscardUnknown(m) -} - -var xxx_messageInfo_AppProjectList proto.InternalMessageInfo - -func (m *AppProjectSpec) Reset() { *m = AppProjectSpec{} } -func (*AppProjectSpec) ProtoMessage() {} -func (*AppProjectSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{3} -} -func (m *AppProjectSpec) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AppProjectSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *AppProjectSpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_AppProjectSpec.Merge(dst, src) -} -func (m *AppProjectSpec) XXX_Size() int { - return m.Size() -} -func (m *AppProjectSpec) XXX_DiscardUnknown() { - xxx_messageInfo_AppProjectSpec.DiscardUnknown(m) -} - -var xxx_messageInfo_AppProjectSpec proto.InternalMessageInfo - -func (m *Application) Reset() { *m = Application{} } -func (*Application) ProtoMessage() {} -func (*Application) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{4} -} -func (m *Application) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Application) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Application) XXX_Merge(src proto.Message) { - xxx_messageInfo_Application.Merge(dst, src) -} -func (m *Application) XXX_Size() int { - return m.Size() -} -func (m *Application) XXX_DiscardUnknown() { - xxx_messageInfo_Application.DiscardUnknown(m) -} - -var xxx_messageInfo_Application proto.InternalMessageInfo - -func (m *ApplicationCondition) Reset() { *m = ApplicationCondition{} } -func (*ApplicationCondition) ProtoMessage() {} -func (*ApplicationCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{5} -} -func (m *ApplicationCondition) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationCondition) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationCondition.Merge(dst, src) -} -func (m *ApplicationCondition) XXX_Size() int { - return m.Size() -} -func (m *ApplicationCondition) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationCondition.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationCondition proto.InternalMessageInfo - -func (m *ApplicationDestination) Reset() { *m = ApplicationDestination{} } -func (*ApplicationDestination) ProtoMessage() {} -func (*ApplicationDestination) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{6} -} -func (m *ApplicationDestination) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationDestination) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationDestination) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationDestination.Merge(dst, src) -} -func (m *ApplicationDestination) XXX_Size() int { - return m.Size() -} -func (m *ApplicationDestination) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationDestination.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationDestination proto.InternalMessageInfo - -func (m *ApplicationList) Reset() { *m = ApplicationList{} } -func (*ApplicationList) ProtoMessage() {} -func (*ApplicationList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{7} -} -func (m *ApplicationList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationList.Merge(dst, src) -} -func (m *ApplicationList) XXX_Size() int { - return m.Size() -} -func (m *ApplicationList) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationList.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationList proto.InternalMessageInfo - -func (m *ApplicationSource) Reset() { *m = ApplicationSource{} } -func (*ApplicationSource) ProtoMessage() {} -func (*ApplicationSource) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{8} -} -func (m *ApplicationSource) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSource) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSource.Merge(dst, src) -} -func (m *ApplicationSource) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSource) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSource.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSource proto.InternalMessageInfo - -func (m *ApplicationSourceDirectory) Reset() { *m = ApplicationSourceDirectory{} } -func (*ApplicationSourceDirectory) ProtoMessage() {} -func (*ApplicationSourceDirectory) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{9} -} -func (m *ApplicationSourceDirectory) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourceDirectory) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourceDirectory) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourceDirectory.Merge(dst, src) -} -func (m *ApplicationSourceDirectory) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourceDirectory) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourceDirectory.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourceDirectory proto.InternalMessageInfo - -func (m *ApplicationSourceHelm) Reset() { *m = ApplicationSourceHelm{} } -func (*ApplicationSourceHelm) ProtoMessage() {} -func (*ApplicationSourceHelm) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{10} -} -func (m *ApplicationSourceHelm) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourceHelm) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourceHelm) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourceHelm.Merge(dst, src) -} -func (m *ApplicationSourceHelm) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourceHelm) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourceHelm.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourceHelm proto.InternalMessageInfo - -func (m *ApplicationSourceJsonnet) Reset() { *m = ApplicationSourceJsonnet{} } -func (*ApplicationSourceJsonnet) ProtoMessage() {} -func (*ApplicationSourceJsonnet) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{11} -} -func (m *ApplicationSourceJsonnet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourceJsonnet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourceJsonnet) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourceJsonnet.Merge(dst, src) -} -func (m *ApplicationSourceJsonnet) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourceJsonnet) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourceJsonnet.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourceJsonnet proto.InternalMessageInfo - -func (m *ApplicationSourceKsonnet) Reset() { *m = ApplicationSourceKsonnet{} } -func (*ApplicationSourceKsonnet) ProtoMessage() {} -func (*ApplicationSourceKsonnet) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{12} -} -func (m *ApplicationSourceKsonnet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourceKsonnet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourceKsonnet) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourceKsonnet.Merge(dst, src) -} -func (m *ApplicationSourceKsonnet) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourceKsonnet) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourceKsonnet.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourceKsonnet proto.InternalMessageInfo - -func (m *ApplicationSourceKustomize) Reset() { *m = ApplicationSourceKustomize{} } -func (*ApplicationSourceKustomize) ProtoMessage() {} -func (*ApplicationSourceKustomize) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{13} -} -func (m *ApplicationSourceKustomize) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourceKustomize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourceKustomize) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourceKustomize.Merge(dst, src) -} -func (m *ApplicationSourceKustomize) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourceKustomize) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourceKustomize.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourceKustomize proto.InternalMessageInfo - -func (m *ApplicationSourcePlugin) Reset() { *m = ApplicationSourcePlugin{} } -func (*ApplicationSourcePlugin) ProtoMessage() {} -func (*ApplicationSourcePlugin) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{14} -} -func (m *ApplicationSourcePlugin) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSourcePlugin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSourcePlugin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSourcePlugin.Merge(dst, src) -} -func (m *ApplicationSourcePlugin) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSourcePlugin) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSourcePlugin.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSourcePlugin proto.InternalMessageInfo - -func (m *ApplicationSpec) Reset() { *m = ApplicationSpec{} } -func (*ApplicationSpec) ProtoMessage() {} -func (*ApplicationSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{15} -} -func (m *ApplicationSpec) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSpec.Merge(dst, src) -} -func (m *ApplicationSpec) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSpec) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSpec.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSpec proto.InternalMessageInfo - -func (m *ApplicationStatus) Reset() { *m = ApplicationStatus{} } -func (*ApplicationStatus) ProtoMessage() {} -func (*ApplicationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{16} -} -func (m *ApplicationStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationStatus.Merge(dst, src) -} -func (m *ApplicationStatus) XXX_Size() int { - return m.Size() -} -func (m *ApplicationStatus) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationStatus proto.InternalMessageInfo - -func (m *ApplicationSummary) Reset() { *m = ApplicationSummary{} } -func (*ApplicationSummary) ProtoMessage() {} -func (*ApplicationSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{17} -} -func (m *ApplicationSummary) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationSummary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationSummary) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationSummary.Merge(dst, src) -} -func (m *ApplicationSummary) XXX_Size() int { - return m.Size() -} -func (m *ApplicationSummary) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationSummary.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationSummary proto.InternalMessageInfo - -func (m *ApplicationTree) Reset() { *m = ApplicationTree{} } -func (*ApplicationTree) ProtoMessage() {} -func (*ApplicationTree) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{18} -} -func (m *ApplicationTree) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationTree) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationTree) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationTree.Merge(dst, src) -} -func (m *ApplicationTree) XXX_Size() int { - return m.Size() -} -func (m *ApplicationTree) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationTree.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationTree proto.InternalMessageInfo - -func (m *ApplicationWatchEvent) Reset() { *m = ApplicationWatchEvent{} } -func (*ApplicationWatchEvent) ProtoMessage() {} -func (*ApplicationWatchEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{19} -} -func (m *ApplicationWatchEvent) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ApplicationWatchEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ApplicationWatchEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationWatchEvent.Merge(dst, src) -} -func (m *ApplicationWatchEvent) XXX_Size() int { - return m.Size() -} -func (m *ApplicationWatchEvent) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationWatchEvent.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationWatchEvent proto.InternalMessageInfo - -func (m *Cluster) Reset() { *m = Cluster{} } -func (*Cluster) ProtoMessage() {} -func (*Cluster) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{20} -} -func (m *Cluster) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Cluster) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Cluster) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cluster.Merge(dst, src) -} -func (m *Cluster) XXX_Size() int { - return m.Size() -} -func (m *Cluster) XXX_DiscardUnknown() { - xxx_messageInfo_Cluster.DiscardUnknown(m) -} - -var xxx_messageInfo_Cluster proto.InternalMessageInfo - -func (m *ClusterConfig) Reset() { *m = ClusterConfig{} } -func (*ClusterConfig) ProtoMessage() {} -func (*ClusterConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{21} -} -func (m *ClusterConfig) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ClusterConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ClusterConfig) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClusterConfig.Merge(dst, src) -} -func (m *ClusterConfig) XXX_Size() int { - return m.Size() -} -func (m *ClusterConfig) XXX_DiscardUnknown() { - xxx_messageInfo_ClusterConfig.DiscardUnknown(m) -} - -var xxx_messageInfo_ClusterConfig proto.InternalMessageInfo - -func (m *ClusterList) Reset() { *m = ClusterList{} } -func (*ClusterList) ProtoMessage() {} -func (*ClusterList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{22} -} -func (m *ClusterList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ClusterList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ClusterList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClusterList.Merge(dst, src) -} -func (m *ClusterList) XXX_Size() int { - return m.Size() -} -func (m *ClusterList) XXX_DiscardUnknown() { - xxx_messageInfo_ClusterList.DiscardUnknown(m) -} - -var xxx_messageInfo_ClusterList proto.InternalMessageInfo - -func (m *Command) Reset() { *m = Command{} } -func (*Command) ProtoMessage() {} -func (*Command) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{23} -} -func (m *Command) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Command) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Command) XXX_Merge(src proto.Message) { - xxx_messageInfo_Command.Merge(dst, src) -} -func (m *Command) XXX_Size() int { - return m.Size() -} -func (m *Command) XXX_DiscardUnknown() { - xxx_messageInfo_Command.DiscardUnknown(m) -} - -var xxx_messageInfo_Command proto.InternalMessageInfo - -func (m *ComparedTo) Reset() { *m = ComparedTo{} } -func (*ComparedTo) ProtoMessage() {} -func (*ComparedTo) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{24} -} -func (m *ComparedTo) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ComparedTo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ComparedTo) XXX_Merge(src proto.Message) { - xxx_messageInfo_ComparedTo.Merge(dst, src) -} -func (m *ComparedTo) XXX_Size() int { - return m.Size() -} -func (m *ComparedTo) XXX_DiscardUnknown() { - xxx_messageInfo_ComparedTo.DiscardUnknown(m) -} - -var xxx_messageInfo_ComparedTo proto.InternalMessageInfo - -func (m *ComponentParameter) Reset() { *m = ComponentParameter{} } -func (*ComponentParameter) ProtoMessage() {} -func (*ComponentParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{25} -} -func (m *ComponentParameter) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ComponentParameter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ComponentParameter) XXX_Merge(src proto.Message) { - xxx_messageInfo_ComponentParameter.Merge(dst, src) -} -func (m *ComponentParameter) XXX_Size() int { - return m.Size() -} -func (m *ComponentParameter) XXX_DiscardUnknown() { - xxx_messageInfo_ComponentParameter.DiscardUnknown(m) -} - -var xxx_messageInfo_ComponentParameter proto.InternalMessageInfo - -func (m *ConfigManagementPlugin) Reset() { *m = ConfigManagementPlugin{} } -func (*ConfigManagementPlugin) ProtoMessage() {} -func (*ConfigManagementPlugin) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{26} -} -func (m *ConfigManagementPlugin) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConfigManagementPlugin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ConfigManagementPlugin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConfigManagementPlugin.Merge(dst, src) -} -func (m *ConfigManagementPlugin) XXX_Size() int { - return m.Size() -} -func (m *ConfigManagementPlugin) XXX_DiscardUnknown() { - xxx_messageInfo_ConfigManagementPlugin.DiscardUnknown(m) -} - -var xxx_messageInfo_ConfigManagementPlugin proto.InternalMessageInfo - -func (m *ConnectionState) Reset() { *m = ConnectionState{} } -func (*ConnectionState) ProtoMessage() {} -func (*ConnectionState) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{27} -} -func (m *ConnectionState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConnectionState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ConnectionState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConnectionState.Merge(dst, src) -} -func (m *ConnectionState) XXX_Size() int { - return m.Size() -} -func (m *ConnectionState) XXX_DiscardUnknown() { - xxx_messageInfo_ConnectionState.DiscardUnknown(m) -} - -var xxx_messageInfo_ConnectionState proto.InternalMessageInfo - -func (m *EnvEntry) Reset() { *m = EnvEntry{} } -func (*EnvEntry) ProtoMessage() {} -func (*EnvEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{28} -} -func (m *EnvEntry) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *EnvEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *EnvEntry) XXX_Merge(src proto.Message) { - xxx_messageInfo_EnvEntry.Merge(dst, src) -} -func (m *EnvEntry) XXX_Size() int { - return m.Size() -} -func (m *EnvEntry) XXX_DiscardUnknown() { - xxx_messageInfo_EnvEntry.DiscardUnknown(m) -} - -var xxx_messageInfo_EnvEntry proto.InternalMessageInfo - -func (m *HealthStatus) Reset() { *m = HealthStatus{} } -func (*HealthStatus) ProtoMessage() {} -func (*HealthStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{29} -} -func (m *HealthStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HealthStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *HealthStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_HealthStatus.Merge(dst, src) -} -func (m *HealthStatus) XXX_Size() int { - return m.Size() -} -func (m *HealthStatus) XXX_DiscardUnknown() { - xxx_messageInfo_HealthStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_HealthStatus proto.InternalMessageInfo - -func (m *HelmParameter) Reset() { *m = HelmParameter{} } -func (*HelmParameter) ProtoMessage() {} -func (*HelmParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{30} -} -func (m *HelmParameter) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HelmParameter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *HelmParameter) XXX_Merge(src proto.Message) { - xxx_messageInfo_HelmParameter.Merge(dst, src) -} -func (m *HelmParameter) XXX_Size() int { - return m.Size() -} -func (m *HelmParameter) XXX_DiscardUnknown() { - xxx_messageInfo_HelmParameter.DiscardUnknown(m) -} - -var xxx_messageInfo_HelmParameter proto.InternalMessageInfo - -func (m *Info) Reset() { *m = Info{} } -func (*Info) ProtoMessage() {} -func (*Info) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{31} -} -func (m *Info) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Info) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Info) XXX_Merge(src proto.Message) { - xxx_messageInfo_Info.Merge(dst, src) -} -func (m *Info) XXX_Size() int { - return m.Size() -} -func (m *Info) XXX_DiscardUnknown() { - xxx_messageInfo_Info.DiscardUnknown(m) -} - -var xxx_messageInfo_Info proto.InternalMessageInfo - -func (m *InfoItem) Reset() { *m = InfoItem{} } -func (*InfoItem) ProtoMessage() {} -func (*InfoItem) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{32} -} -func (m *InfoItem) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *InfoItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *InfoItem) XXX_Merge(src proto.Message) { - xxx_messageInfo_InfoItem.Merge(dst, src) -} -func (m *InfoItem) XXX_Size() int { - return m.Size() -} -func (m *InfoItem) XXX_DiscardUnknown() { - xxx_messageInfo_InfoItem.DiscardUnknown(m) -} - -var xxx_messageInfo_InfoItem proto.InternalMessageInfo - -func (m *JWTToken) Reset() { *m = JWTToken{} } -func (*JWTToken) ProtoMessage() {} -func (*JWTToken) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{33} -} -func (m *JWTToken) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *JWTToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *JWTToken) XXX_Merge(src proto.Message) { - xxx_messageInfo_JWTToken.Merge(dst, src) -} -func (m *JWTToken) XXX_Size() int { - return m.Size() -} -func (m *JWTToken) XXX_DiscardUnknown() { - xxx_messageInfo_JWTToken.DiscardUnknown(m) -} - -var xxx_messageInfo_JWTToken proto.InternalMessageInfo - -func (m *JsonnetVar) Reset() { *m = JsonnetVar{} } -func (*JsonnetVar) ProtoMessage() {} -func (*JsonnetVar) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{34} -} -func (m *JsonnetVar) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *JsonnetVar) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *JsonnetVar) XXX_Merge(src proto.Message) { - xxx_messageInfo_JsonnetVar.Merge(dst, src) -} -func (m *JsonnetVar) XXX_Size() int { - return m.Size() -} -func (m *JsonnetVar) XXX_DiscardUnknown() { - xxx_messageInfo_JsonnetVar.DiscardUnknown(m) -} - -var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo - -func (m *KsonnetParameter) Reset() { *m = KsonnetParameter{} } -func (*KsonnetParameter) ProtoMessage() {} -func (*KsonnetParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{35} -} -func (m *KsonnetParameter) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *KsonnetParameter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *KsonnetParameter) XXX_Merge(src proto.Message) { - xxx_messageInfo_KsonnetParameter.Merge(dst, src) -} -func (m *KsonnetParameter) XXX_Size() int { - return m.Size() -} -func (m *KsonnetParameter) XXX_DiscardUnknown() { - xxx_messageInfo_KsonnetParameter.DiscardUnknown(m) -} - -var xxx_messageInfo_KsonnetParameter proto.InternalMessageInfo - -func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} } -func (*KustomizeOptions) ProtoMessage() {} -func (*KustomizeOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{36} -} -func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *KustomizeOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *KustomizeOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_KustomizeOptions.Merge(dst, src) -} -func (m *KustomizeOptions) XXX_Size() int { - return m.Size() -} -func (m *KustomizeOptions) XXX_DiscardUnknown() { - xxx_messageInfo_KustomizeOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo - -func (m *Operation) Reset() { *m = Operation{} } -func (*Operation) ProtoMessage() {} -func (*Operation) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{37} -} -func (m *Operation) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Operation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Operation) XXX_Merge(src proto.Message) { - xxx_messageInfo_Operation.Merge(dst, src) -} -func (m *Operation) XXX_Size() int { - return m.Size() -} -func (m *Operation) XXX_DiscardUnknown() { - xxx_messageInfo_Operation.DiscardUnknown(m) -} - -var xxx_messageInfo_Operation proto.InternalMessageInfo - -func (m *OperationState) Reset() { *m = OperationState{} } -func (*OperationState) ProtoMessage() {} -func (*OperationState) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{38} -} -func (m *OperationState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *OperationState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *OperationState) XXX_Merge(src proto.Message) { - xxx_messageInfo_OperationState.Merge(dst, src) -} -func (m *OperationState) XXX_Size() int { - return m.Size() -} -func (m *OperationState) XXX_DiscardUnknown() { - xxx_messageInfo_OperationState.DiscardUnknown(m) -} - -var xxx_messageInfo_OperationState proto.InternalMessageInfo - -func (m *OrphanedResourcesMonitorSettings) Reset() { *m = OrphanedResourcesMonitorSettings{} } -func (*OrphanedResourcesMonitorSettings) ProtoMessage() {} -func (*OrphanedResourcesMonitorSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{39} -} -func (m *OrphanedResourcesMonitorSettings) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *OrphanedResourcesMonitorSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *OrphanedResourcesMonitorSettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_OrphanedResourcesMonitorSettings.Merge(dst, src) -} -func (m *OrphanedResourcesMonitorSettings) XXX_Size() int { - return m.Size() -} -func (m *OrphanedResourcesMonitorSettings) XXX_DiscardUnknown() { - xxx_messageInfo_OrphanedResourcesMonitorSettings.DiscardUnknown(m) -} - -var xxx_messageInfo_OrphanedResourcesMonitorSettings proto.InternalMessageInfo - -func (m *ProjectRole) Reset() { *m = ProjectRole{} } -func (*ProjectRole) ProtoMessage() {} -func (*ProjectRole) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{40} -} -func (m *ProjectRole) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ProjectRole) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ProjectRole) XXX_Merge(src proto.Message) { - xxx_messageInfo_ProjectRole.Merge(dst, src) -} -func (m *ProjectRole) XXX_Size() int { - return m.Size() -} -func (m *ProjectRole) XXX_DiscardUnknown() { - xxx_messageInfo_ProjectRole.DiscardUnknown(m) -} - -var xxx_messageInfo_ProjectRole proto.InternalMessageInfo - -func (m *Repository) Reset() { *m = Repository{} } -func (*Repository) ProtoMessage() {} -func (*Repository) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{41} -} -func (m *Repository) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Repository) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *Repository) XXX_Merge(src proto.Message) { - xxx_messageInfo_Repository.Merge(dst, src) -} -func (m *Repository) XXX_Size() int { - return m.Size() -} -func (m *Repository) XXX_DiscardUnknown() { - xxx_messageInfo_Repository.DiscardUnknown(m) -} - -var xxx_messageInfo_Repository proto.InternalMessageInfo - -func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} } -func (*RepositoryCertificate) ProtoMessage() {} -func (*RepositoryCertificate) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{42} -} -func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RepositoryCertificate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *RepositoryCertificate) XXX_Merge(src proto.Message) { - xxx_messageInfo_RepositoryCertificate.Merge(dst, src) -} -func (m *RepositoryCertificate) XXX_Size() int { - return m.Size() -} -func (m *RepositoryCertificate) XXX_DiscardUnknown() { - xxx_messageInfo_RepositoryCertificate.DiscardUnknown(m) -} - -var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo - -func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} } -func (*RepositoryCertificateList) ProtoMessage() {} -func (*RepositoryCertificateList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{43} -} -func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RepositoryCertificateList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *RepositoryCertificateList) XXX_Merge(src proto.Message) { - xxx_messageInfo_RepositoryCertificateList.Merge(dst, src) -} -func (m *RepositoryCertificateList) XXX_Size() int { - return m.Size() -} -func (m *RepositoryCertificateList) XXX_DiscardUnknown() { - xxx_messageInfo_RepositoryCertificateList.DiscardUnknown(m) -} - -var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo - -func (m *RepositoryList) Reset() { *m = RepositoryList{} } -func (*RepositoryList) ProtoMessage() {} -func (*RepositoryList) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{44} -} -func (m *RepositoryList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RepositoryList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *RepositoryList) XXX_Merge(src proto.Message) { - xxx_messageInfo_RepositoryList.Merge(dst, src) -} -func (m *RepositoryList) XXX_Size() int { - return m.Size() -} -func (m *RepositoryList) XXX_DiscardUnknown() { - xxx_messageInfo_RepositoryList.DiscardUnknown(m) -} - -var xxx_messageInfo_RepositoryList proto.InternalMessageInfo - -func (m *ResourceAction) Reset() { *m = ResourceAction{} } -func (*ResourceAction) ProtoMessage() {} -func (*ResourceAction) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{45} -} -func (m *ResourceAction) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceAction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceAction) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceAction.Merge(dst, src) -} -func (m *ResourceAction) XXX_Size() int { - return m.Size() -} -func (m *ResourceAction) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceAction.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceAction proto.InternalMessageInfo - -func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} } -func (*ResourceActionDefinition) ProtoMessage() {} -func (*ResourceActionDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{46} -} -func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceActionDefinition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceActionDefinition) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceActionDefinition.Merge(dst, src) -} -func (m *ResourceActionDefinition) XXX_Size() int { - return m.Size() -} -func (m *ResourceActionDefinition) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceActionDefinition.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo - -func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} } -func (*ResourceActionParam) ProtoMessage() {} -func (*ResourceActionParam) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{47} -} -func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceActionParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceActionParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceActionParam.Merge(dst, src) -} -func (m *ResourceActionParam) XXX_Size() int { - return m.Size() -} -func (m *ResourceActionParam) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceActionParam.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo - -func (m *ResourceActions) Reset() { *m = ResourceActions{} } -func (*ResourceActions) ProtoMessage() {} -func (*ResourceActions) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{48} -} -func (m *ResourceActions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceActions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceActions) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceActions.Merge(dst, src) -} -func (m *ResourceActions) XXX_Size() int { - return m.Size() -} -func (m *ResourceActions) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceActions.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceActions proto.InternalMessageInfo - -func (m *ResourceDiff) Reset() { *m = ResourceDiff{} } -func (*ResourceDiff) ProtoMessage() {} -func (*ResourceDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{49} -} -func (m *ResourceDiff) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceDiff) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceDiff) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceDiff.Merge(dst, src) -} -func (m *ResourceDiff) XXX_Size() int { - return m.Size() -} -func (m *ResourceDiff) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceDiff.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo - -func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} } -func (*ResourceIgnoreDifferences) ProtoMessage() {} -func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{50} -} -func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceIgnoreDifferences) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceIgnoreDifferences) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceIgnoreDifferences.Merge(dst, src) -} -func (m *ResourceIgnoreDifferences) XXX_Size() int { - return m.Size() -} -func (m *ResourceIgnoreDifferences) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceIgnoreDifferences.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo - -func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} } -func (*ResourceNetworkingInfo) ProtoMessage() {} -func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{51} -} -func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceNetworkingInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceNetworkingInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceNetworkingInfo.Merge(dst, src) -} -func (m *ResourceNetworkingInfo) XXX_Size() int { - return m.Size() -} -func (m *ResourceNetworkingInfo) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceNetworkingInfo.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo - -func (m *ResourceNode) Reset() { *m = ResourceNode{} } -func (*ResourceNode) ProtoMessage() {} -func (*ResourceNode) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{52} -} -func (m *ResourceNode) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceNode) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceNode.Merge(dst, src) -} -func (m *ResourceNode) XXX_Size() int { - return m.Size() -} -func (m *ResourceNode) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceNode.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceNode proto.InternalMessageInfo - -func (m *ResourceOverride) Reset() { *m = ResourceOverride{} } -func (*ResourceOverride) ProtoMessage() {} -func (*ResourceOverride) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{53} -} -func (m *ResourceOverride) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceOverride) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceOverride) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceOverride.Merge(dst, src) -} -func (m *ResourceOverride) XXX_Size() int { - return m.Size() -} -func (m *ResourceOverride) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceOverride.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo - -func (m *ResourceRef) Reset() { *m = ResourceRef{} } -func (*ResourceRef) ProtoMessage() {} -func (*ResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{54} -} -func (m *ResourceRef) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceRef) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceRef.Merge(dst, src) -} -func (m *ResourceRef) XXX_Size() int { - return m.Size() -} -func (m *ResourceRef) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceRef.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceRef proto.InternalMessageInfo - -func (m *ResourceResult) Reset() { *m = ResourceResult{} } -func (*ResourceResult) ProtoMessage() {} -func (*ResourceResult) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{55} -} -func (m *ResourceResult) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceResult.Merge(dst, src) -} -func (m *ResourceResult) XXX_Size() int { - return m.Size() -} -func (m *ResourceResult) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceResult.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceResult proto.InternalMessageInfo - -func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } -func (*ResourceStatus) ProtoMessage() {} -func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{56} -} -func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResourceStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *ResourceStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResourceStatus.Merge(dst, src) -} -func (m *ResourceStatus) XXX_Size() int { - return m.Size() -} -func (m *ResourceStatus) XXX_DiscardUnknown() { - xxx_messageInfo_ResourceStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo - -func (m *RevisionHistory) Reset() { *m = RevisionHistory{} } -func (*RevisionHistory) ProtoMessage() {} -func (*RevisionHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{57} -} -func (m *RevisionHistory) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RevisionHistory) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *RevisionHistory) XXX_Merge(src proto.Message) { - xxx_messageInfo_RevisionHistory.Merge(dst, src) -} -func (m *RevisionHistory) XXX_Size() int { - return m.Size() -} -func (m *RevisionHistory) XXX_DiscardUnknown() { - xxx_messageInfo_RevisionHistory.DiscardUnknown(m) -} - -var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo - -func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} } -func (*RevisionMetadata) ProtoMessage() {} -func (*RevisionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{58} -} -func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RevisionMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *RevisionMetadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_RevisionMetadata.Merge(dst, src) -} -func (m *RevisionMetadata) XXX_Size() int { - return m.Size() -} -func (m *RevisionMetadata) XXX_DiscardUnknown() { - xxx_messageInfo_RevisionMetadata.DiscardUnknown(m) -} - -var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo - -func (m *SyncOperation) Reset() { *m = SyncOperation{} } -func (*SyncOperation) ProtoMessage() {} -func (*SyncOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{59} -} -func (m *SyncOperation) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncOperation) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncOperation.Merge(dst, src) -} -func (m *SyncOperation) XXX_Size() int { - return m.Size() -} -func (m *SyncOperation) XXX_DiscardUnknown() { - xxx_messageInfo_SyncOperation.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncOperation proto.InternalMessageInfo - -func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} } -func (*SyncOperationResource) ProtoMessage() {} -func (*SyncOperationResource) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{60} -} -func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncOperationResource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncOperationResource) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncOperationResource.Merge(dst, src) -} -func (m *SyncOperationResource) XXX_Size() int { - return m.Size() -} -func (m *SyncOperationResource) XXX_DiscardUnknown() { - xxx_messageInfo_SyncOperationResource.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo - -func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} } -func (*SyncOperationResult) ProtoMessage() {} -func (*SyncOperationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{61} -} -func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncOperationResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncOperationResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncOperationResult.Merge(dst, src) -} -func (m *SyncOperationResult) XXX_Size() int { - return m.Size() -} -func (m *SyncOperationResult) XXX_DiscardUnknown() { - xxx_messageInfo_SyncOperationResult.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo - -func (m *SyncPolicy) Reset() { *m = SyncPolicy{} } -func (*SyncPolicy) ProtoMessage() {} -func (*SyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{62} -} -func (m *SyncPolicy) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncPolicy) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncPolicy.Merge(dst, src) -} -func (m *SyncPolicy) XXX_Size() int { - return m.Size() -} -func (m *SyncPolicy) XXX_DiscardUnknown() { - xxx_messageInfo_SyncPolicy.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo - -func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} } -func (*SyncPolicyAutomated) ProtoMessage() {} -func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{63} -} -func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncPolicyAutomated) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncPolicyAutomated) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncPolicyAutomated.Merge(dst, src) -} -func (m *SyncPolicyAutomated) XXX_Size() int { - return m.Size() -} -func (m *SyncPolicyAutomated) XXX_DiscardUnknown() { - xxx_messageInfo_SyncPolicyAutomated.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo - -func (m *SyncStatus) Reset() { *m = SyncStatus{} } -func (*SyncStatus) ProtoMessage() {} -func (*SyncStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{64} -} -func (m *SyncStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncStatus.Merge(dst, src) -} -func (m *SyncStatus) XXX_Size() int { - return m.Size() -} -func (m *SyncStatus) XXX_DiscardUnknown() { - xxx_messageInfo_SyncStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncStatus proto.InternalMessageInfo - -func (m *SyncStrategy) Reset() { *m = SyncStrategy{} } -func (*SyncStrategy) ProtoMessage() {} -func (*SyncStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{65} -} -func (m *SyncStrategy) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncStrategy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncStrategy) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncStrategy.Merge(dst, src) -} -func (m *SyncStrategy) XXX_Size() int { - return m.Size() -} -func (m *SyncStrategy) XXX_DiscardUnknown() { - xxx_messageInfo_SyncStrategy.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo - -func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} } -func (*SyncStrategyApply) ProtoMessage() {} -func (*SyncStrategyApply) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{66} -} -func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncStrategyApply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncStrategyApply) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncStrategyApply.Merge(dst, src) -} -func (m *SyncStrategyApply) XXX_Size() int { - return m.Size() -} -func (m *SyncStrategyApply) XXX_DiscardUnknown() { - xxx_messageInfo_SyncStrategyApply.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo - -func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} } -func (*SyncStrategyHook) ProtoMessage() {} -func (*SyncStrategyHook) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{67} -} -func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncStrategyHook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncStrategyHook) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncStrategyHook.Merge(dst, src) -} -func (m *SyncStrategyHook) XXX_Size() int { - return m.Size() -} -func (m *SyncStrategyHook) XXX_DiscardUnknown() { - xxx_messageInfo_SyncStrategyHook.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo - -func (m *SyncWindow) Reset() { *m = SyncWindow{} } -func (*SyncWindow) ProtoMessage() {} -func (*SyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{68} -} -func (m *SyncWindow) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncWindow) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *SyncWindow) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncWindow.Merge(dst, src) -} -func (m *SyncWindow) XXX_Size() int { - return m.Size() -} -func (m *SyncWindow) XXX_DiscardUnknown() { - xxx_messageInfo_SyncWindow.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncWindow proto.InternalMessageInfo - -func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} } -func (*TLSClientConfig) ProtoMessage() {} -func (*TLSClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_generated_85119751c9399dcb, []int{69} -} -func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *TLSClientConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (dst *TLSClientConfig) XXX_Merge(src proto.Message) { - xxx_messageInfo_TLSClientConfig.Merge(dst, src) -} -func (m *TLSClientConfig) XXX_Size() int { - return m.Size() -} -func (m *TLSClientConfig) XXX_DiscardUnknown() { - xxx_messageInfo_TLSClientConfig.DiscardUnknown(m) -} - -var xxx_messageInfo_TLSClientConfig proto.InternalMessageInfo - -func init() { - proto.RegisterType((*AWSAuthConfig)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.AWSAuthConfig") - proto.RegisterType((*AppProject)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.AppProject") - proto.RegisterType((*AppProjectList)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.AppProjectList") - proto.RegisterType((*AppProjectSpec)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.AppProjectSpec") - proto.RegisterType((*Application)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Application") - proto.RegisterType((*ApplicationCondition)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationCondition") - proto.RegisterType((*ApplicationDestination)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationDestination") - proto.RegisterType((*ApplicationList)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationList") - proto.RegisterType((*ApplicationSource)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSource") - proto.RegisterType((*ApplicationSourceDirectory)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceDirectory") - proto.RegisterType((*ApplicationSourceHelm)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceHelm") - proto.RegisterType((*ApplicationSourceJsonnet)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceJsonnet") - proto.RegisterType((*ApplicationSourceKsonnet)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceKsonnet") - proto.RegisterType((*ApplicationSourceKustomize)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceKustomize") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourceKustomize.CommonLabelsEntry") - proto.RegisterType((*ApplicationSourcePlugin)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSourcePlugin") - proto.RegisterType((*ApplicationSpec)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSpec") - proto.RegisterType((*ApplicationStatus)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationStatus") - proto.RegisterType((*ApplicationSummary)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationSummary") - proto.RegisterType((*ApplicationTree)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationTree") - proto.RegisterType((*ApplicationWatchEvent)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ApplicationWatchEvent") - proto.RegisterType((*Cluster)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Cluster") - proto.RegisterType((*ClusterConfig)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ClusterConfig") - proto.RegisterType((*ClusterList)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ClusterList") - proto.RegisterType((*Command)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Command") - proto.RegisterType((*ComparedTo)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ComparedTo") - proto.RegisterType((*ComponentParameter)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ComponentParameter") - proto.RegisterType((*ConfigManagementPlugin)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ConfigManagementPlugin") - proto.RegisterType((*ConnectionState)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ConnectionState") - proto.RegisterType((*EnvEntry)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.EnvEntry") - proto.RegisterType((*HealthStatus)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.HealthStatus") - proto.RegisterType((*HelmParameter)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.HelmParameter") - proto.RegisterType((*Info)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Info") - proto.RegisterType((*InfoItem)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.InfoItem") - proto.RegisterType((*JWTToken)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.JWTToken") - proto.RegisterType((*JsonnetVar)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.JsonnetVar") - proto.RegisterType((*KsonnetParameter)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.KsonnetParameter") - proto.RegisterType((*KustomizeOptions)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.KustomizeOptions") - proto.RegisterType((*Operation)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Operation") - proto.RegisterType((*OperationState)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.OperationState") - proto.RegisterType((*OrphanedResourcesMonitorSettings)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.OrphanedResourcesMonitorSettings") - proto.RegisterType((*ProjectRole)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ProjectRole") - proto.RegisterType((*Repository)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.Repository") - proto.RegisterType((*RepositoryCertificate)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.RepositoryCertificate") - proto.RegisterType((*RepositoryCertificateList)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.RepositoryCertificateList") - proto.RegisterType((*RepositoryList)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.RepositoryList") - proto.RegisterType((*ResourceAction)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceAction") - proto.RegisterType((*ResourceActionDefinition)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceActionDefinition") - proto.RegisterType((*ResourceActionParam)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceActionParam") - proto.RegisterType((*ResourceActions)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceActions") - proto.RegisterType((*ResourceDiff)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceDiff") - proto.RegisterType((*ResourceIgnoreDifferences)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceIgnoreDifferences") - proto.RegisterType((*ResourceNetworkingInfo)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceNetworkingInfo") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.LabelsEntry") - proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.TargetLabelsEntry") - proto.RegisterType((*ResourceNode)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceNode") - proto.RegisterType((*ResourceOverride)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceOverride") - proto.RegisterType((*ResourceRef)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceRef") - proto.RegisterType((*ResourceResult)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceResult") - proto.RegisterType((*ResourceStatus)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.ResourceStatus") - proto.RegisterType((*RevisionHistory)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.RevisionHistory") - proto.RegisterType((*RevisionMetadata)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.RevisionMetadata") - proto.RegisterType((*SyncOperation)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncOperation") - proto.RegisterType((*SyncOperationResource)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncOperationResource") - proto.RegisterType((*SyncOperationResult)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncOperationResult") - proto.RegisterType((*SyncPolicy)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncPolicy") - proto.RegisterType((*SyncPolicyAutomated)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncPolicyAutomated") - proto.RegisterType((*SyncStatus)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncStatus") - proto.RegisterType((*SyncStrategy)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncStrategy") - proto.RegisterType((*SyncStrategyApply)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncStrategyApply") - proto.RegisterType((*SyncStrategyHook)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncStrategyHook") - proto.RegisterType((*SyncWindow)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.SyncWindow") - proto.RegisterType((*TLSClientConfig)(nil), "github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1.TLSClientConfig") -} -func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AWSAuthConfig) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ClusterName))) - i += copy(dAtA[i:], m.ClusterName) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.RoleARN))) - i += copy(dAtA[i:], m.RoleARN) - return i, nil -} - -func (m *AppProject) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AppProject) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n1, err := m.ObjectMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n1 - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n2, err := m.Spec.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n2 - return i, nil -} - -func (m *AppProjectList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AppProjectList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n3, err := m.ListMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n3 - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *AppProjectSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AppProjectSpec) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.SourceRepos) > 0 { - for _, s := range m.SourceRepos { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Destinations) > 0 { - for _, msg := range m.Destinations { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Description))) - i += copy(dAtA[i:], m.Description) - if len(m.Roles) > 0 { - for _, msg := range m.Roles { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.ClusterResourceWhitelist) > 0 { - for _, msg := range m.ClusterResourceWhitelist { - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.NamespaceResourceBlacklist) > 0 { - for _, msg := range m.NamespaceResourceBlacklist { - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if m.OrphanedResources != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.OrphanedResources.Size())) - n4, err := m.OrphanedResources.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n4 - } - if len(m.SyncWindows) > 0 { - for _, msg := range m.SyncWindows { - dAtA[i] = 0x42 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *Application) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Application) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size())) - n5, err := m.ObjectMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n5 - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size())) - n6, err := m.Spec.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n6 - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n7, err := m.Status.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n7 - if m.Operation != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Operation.Size())) - n8, err := m.Operation.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n8 - } - return i, nil -} - -func (m *ApplicationCondition) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationCondition) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i += copy(dAtA[i:], m.Type) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - return i, nil -} - -func (m *ApplicationDestination) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationDestination) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Server))) - i += copy(dAtA[i:], m.Server) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - return i, nil -} - -func (m *ApplicationList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n9, err := m.ListMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n9 - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSource) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.RepoURL))) - i += copy(dAtA[i:], m.RepoURL) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Path))) - i += copy(dAtA[i:], m.Path) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetRevision))) - i += copy(dAtA[i:], m.TargetRevision) - if m.Helm != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Helm.Size())) - n10, err := m.Helm.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n10 - } - if m.Kustomize != nil { - dAtA[i] = 0x42 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Kustomize.Size())) - n11, err := m.Kustomize.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n11 - } - if m.Ksonnet != nil { - dAtA[i] = 0x4a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Ksonnet.Size())) - n12, err := m.Ksonnet.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n12 - } - if m.Directory != nil { - dAtA[i] = 0x52 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Directory.Size())) - n13, err := m.Directory.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n13 - } - if m.Plugin != nil { - dAtA[i] = 0x5a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Plugin.Size())) - n14, err := m.Plugin.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n14 - } - dAtA[i] = 0x62 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Chart))) - i += copy(dAtA[i:], m.Chart) - return i, nil -} - -func (m *ApplicationSourceDirectory) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourceDirectory) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - if m.Recurse { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Jsonnet.Size())) - n15, err := m.Jsonnet.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n15 - return i, nil -} - -func (m *ApplicationSourceHelm) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourceHelm) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.ValueFiles) > 0 { - for _, s := range m.ValueFiles { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Parameters) > 0 { - for _, msg := range m.Parameters { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ReleaseName))) - i += copy(dAtA[i:], m.ReleaseName) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Values))) - i += copy(dAtA[i:], m.Values) - return i, nil -} - -func (m *ApplicationSourceJsonnet) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourceJsonnet) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.ExtVars) > 0 { - for _, msg := range m.ExtVars { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.TLAs) > 0 { - for _, msg := range m.TLAs { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationSourceKsonnet) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourceKsonnet) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Environment))) - i += copy(dAtA[i:], m.Environment) - if len(m.Parameters) > 0 { - for _, msg := range m.Parameters { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationSourceKustomize) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourceKustomize) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.NamePrefix))) - i += copy(dAtA[i:], m.NamePrefix) - if len(m.Images) > 0 { - for _, s := range m.Images { - dAtA[i] = 0x1a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.CommonLabels) > 0 { - keysForCommonLabels := make([]string, 0, len(m.CommonLabels)) - for k := range m.CommonLabels { - keysForCommonLabels = append(keysForCommonLabels, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForCommonLabels) - for _, k := range keysForCommonLabels { - dAtA[i] = 0x22 - i++ - v := m.CommonLabels[string(k)] - mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(k))) - i += copy(dAtA[i:], k) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i += copy(dAtA[i:], v) - } - } - return i, nil -} - -func (m *ApplicationSourcePlugin) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSourcePlugin) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - if len(m.Env) > 0 { - for _, msg := range m.Env { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSpec) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n16, err := m.Source.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n16 - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Destination.Size())) - n17, err := m.Destination.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n17 - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Project))) - i += copy(dAtA[i:], m.Project) - if m.SyncPolicy != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.SyncPolicy.Size())) - n18, err := m.SyncPolicy.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n18 - } - if len(m.IgnoreDifferences) > 0 { - for _, msg := range m.IgnoreDifferences { - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.Info) > 0 { - for _, msg := range m.Info { - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Sync.Size())) - n19, err := m.Sync.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n19 - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Health.Size())) - n20, err := m.Health.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n20 - if len(m.History) > 0 { - for _, msg := range m.History { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.Conditions) > 0 { - for _, msg := range m.Conditions { - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if m.ReconciledAt != nil { - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ReconciledAt.Size())) - n21, err := m.ReconciledAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n21 - } - if m.OperationState != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.OperationState.Size())) - n22, err := m.OperationState.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n22 - } - if m.ObservedAt != nil { - dAtA[i] = 0x42 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedAt.Size())) - n23, err := m.ObservedAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n23 - } - dAtA[i] = 0x4a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.SourceType))) - i += copy(dAtA[i:], m.SourceType) - dAtA[i] = 0x52 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Summary.Size())) - n24, err := m.Summary.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n24 - return i, nil -} - -func (m *ApplicationSummary) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationSummary) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.ExternalURLs) > 0 { - for _, s := range m.ExternalURLs { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Images) > 0 { - for _, s := range m.Images { - dAtA[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *ApplicationTree) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationTree) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Nodes) > 0 { - for _, msg := range m.Nodes { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.OrphanedNodes) > 0 { - for _, msg := range m.OrphanedNodes { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ApplicationWatchEvent) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplicationWatchEvent) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i += copy(dAtA[i:], m.Type) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Application.Size())) - n25, err := m.Application.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n25 - return i, nil -} - -func (m *Cluster) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Cluster) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Server))) - i += copy(dAtA[i:], m.Server) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Config.Size())) - n26, err := m.Config.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n26 - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ConnectionState.Size())) - n27, err := m.ConnectionState.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n27 - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ServerVersion))) - i += copy(dAtA[i:], m.ServerVersion) - return i, nil -} - -func (m *ClusterConfig) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ClusterConfig) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Username))) - i += copy(dAtA[i:], m.Username) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Password))) - i += copy(dAtA[i:], m.Password) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.BearerToken))) - i += copy(dAtA[i:], m.BearerToken) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.TLSClientConfig.Size())) - n28, err := m.TLSClientConfig.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n28 - if m.AWSAuthConfig != nil { - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.AWSAuthConfig.Size())) - n29, err := m.AWSAuthConfig.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n29 - } - return i, nil -} - -func (m *ClusterList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ClusterList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n30, err := m.ListMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n30 - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *Command) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Command) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Command) > 0 { - for _, s := range m.Command { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Args) > 0 { - for _, s := range m.Args { - dAtA[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *ComparedTo) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ComparedTo) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n31, err := m.Source.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n31 - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Destination.Size())) - n32, err := m.Destination.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n32 - return i, nil -} - -func (m *ComponentParameter) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ComponentParameter) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Component))) - i += copy(dAtA[i:], m.Component) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - return i, nil -} - -func (m *ConfigManagementPlugin) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ConfigManagementPlugin) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - if m.Init != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Init.Size())) - n33, err := m.Init.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n33 - } - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Generate.Size())) - n34, err := m.Generate.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n34 - return i, nil -} - -func (m *ConnectionState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ConnectionState) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i += copy(dAtA[i:], m.Status) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - if m.ModifiedAt != nil { - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ModifiedAt.Size())) - n35, err := m.ModifiedAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n35 - } - return i, nil -} - -func (m *EnvEntry) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *EnvEntry) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - return i, nil -} - -func (m *HealthStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HealthStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i += copy(dAtA[i:], m.Status) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - return i, nil -} - -func (m *HelmParameter) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HelmParameter) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - dAtA[i] = 0x18 - i++ - if m.ForceString { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *Info) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Info) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - return i, nil -} - -func (m *InfoItem) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *InfoItem) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - return i, nil -} - -func (m *JWTToken) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *JWTToken) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.IssuedAt)) - dAtA[i] = 0x10 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ExpiresAt)) - return i, nil -} - -func (m *JsonnetVar) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *JsonnetVar) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - dAtA[i] = 0x18 - i++ - if m.Code { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *KsonnetParameter) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *KsonnetParameter) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Component))) - i += copy(dAtA[i:], m.Component) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - return i, nil -} - -func (m *KustomizeOptions) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *KustomizeOptions) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.BuildOptions))) - i += copy(dAtA[i:], m.BuildOptions) - return i, nil -} - -func (m *Operation) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Operation) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Sync != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Sync.Size())) - n36, err := m.Sync.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n36 - } - return i, nil -} - -func (m *OperationState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *OperationState) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Operation.Size())) - n37, err := m.Operation.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n37 - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Phase))) - i += copy(dAtA[i:], m.Phase) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - if m.SyncResult != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.SyncResult.Size())) - n38, err := m.SyncResult.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n38 - } - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.StartedAt.Size())) - n39, err := m.StartedAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n39 - if m.FinishedAt != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.FinishedAt.Size())) - n40, err := m.FinishedAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n40 - } - return i, nil -} - -func (m *OrphanedResourcesMonitorSettings) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *OrphanedResourcesMonitorSettings) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Warn != nil { - dAtA[i] = 0x8 - i++ - if *m.Warn { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } - return i, nil -} - -func (m *ProjectRole) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ProjectRole) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Description))) - i += copy(dAtA[i:], m.Description) - if len(m.Policies) > 0 { - for _, s := range m.Policies { - dAtA[i] = 0x1a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.JWTTokens) > 0 { - for _, msg := range m.JWTTokens { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.Groups) > 0 { - for _, s := range m.Groups { - dAtA[i] = 0x2a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *Repository) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Repository) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Repo))) - i += copy(dAtA[i:], m.Repo) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Username))) - i += copy(dAtA[i:], m.Username) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Password))) - i += copy(dAtA[i:], m.Password) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.SSHPrivateKey))) - i += copy(dAtA[i:], m.SSHPrivateKey) - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ConnectionState.Size())) - n41, err := m.ConnectionState.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n41 - dAtA[i] = 0x30 - i++ - if m.InsecureIgnoreHostKey { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x38 - i++ - if m.Insecure { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x40 - i++ - if m.EnableLFS { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x4a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.TLSClientCertData))) - i += copy(dAtA[i:], m.TLSClientCertData) - dAtA[i] = 0x52 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.TLSClientCertKey))) - i += copy(dAtA[i:], m.TLSClientCertKey) - dAtA[i] = 0x5a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i += copy(dAtA[i:], m.Type) - dAtA[i] = 0x62 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - return i, nil -} - -func (m *RepositoryCertificate) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RepositoryCertificate) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ServerName))) - i += copy(dAtA[i:], m.ServerName) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CertType))) - i += copy(dAtA[i:], m.CertType) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CertSubType))) - i += copy(dAtA[i:], m.CertSubType) - if m.CertData != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CertData))) - i += copy(dAtA[i:], m.CertData) - } - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CertInfo))) - i += copy(dAtA[i:], m.CertInfo) - return i, nil -} - -func (m *RepositoryCertificateList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RepositoryCertificateList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n42, err := m.ListMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n42 - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *RepositoryList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RepositoryList) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size())) - n43, err := m.ListMeta.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n43 - if len(m.Items) > 0 { - for _, msg := range m.Items { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ResourceAction) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceAction) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - if len(m.Params) > 0 { - for _, msg := range m.Params { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - dAtA[i] = 0x18 - i++ - if m.Disabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *ResourceActionDefinition) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceActionDefinition) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ActionLua))) - i += copy(dAtA[i:], m.ActionLua) - return i, nil -} - -func (m *ResourceActionParam) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceActionParam) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) - i += copy(dAtA[i:], m.Value) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i += copy(dAtA[i:], m.Type) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Default))) - i += copy(dAtA[i:], m.Default) - return i, nil -} - -func (m *ResourceActions) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceActions) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ActionDiscoveryLua))) - i += copy(dAtA[i:], m.ActionDiscoveryLua) - if len(m.Definitions) > 0 { - for _, msg := range m.Definitions { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - return i, nil -} - -func (m *ResourceDiff) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceDiff) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetState))) - i += copy(dAtA[i:], m.TargetState) - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.LiveState))) - i += copy(dAtA[i:], m.LiveState) - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Diff))) - i += copy(dAtA[i:], m.Diff) - dAtA[i] = 0x40 - i++ - if m.Hook { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *ResourceIgnoreDifferences) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceIgnoreDifferences) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - if len(m.JSONPointers) > 0 { - for _, s := range m.JSONPointers { - dAtA[i] = 0x2a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *ResourceNetworkingInfo) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceNetworkingInfo) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.TargetLabels) > 0 { - keysForTargetLabels := make([]string, 0, len(m.TargetLabels)) - for k := range m.TargetLabels { - keysForTargetLabels = append(keysForTargetLabels, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForTargetLabels) - for _, k := range keysForTargetLabels { - dAtA[i] = 0xa - i++ - v := m.TargetLabels[string(k)] - mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(k))) - i += copy(dAtA[i:], k) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i += copy(dAtA[i:], v) - } - } - if len(m.TargetRefs) > 0 { - for _, msg := range m.TargetRefs { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.Labels) > 0 { - keysForLabels := make([]string, 0, len(m.Labels)) - for k := range m.Labels { - keysForLabels = append(keysForLabels, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) - for _, k := range keysForLabels { - dAtA[i] = 0x1a - i++ - v := m.Labels[string(k)] - mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(k))) - i += copy(dAtA[i:], k) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i += copy(dAtA[i:], v) - } - } - if len(m.Ingress) > 0 { - for _, msg := range m.Ingress { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.ExternalURLs) > 0 { - for _, s := range m.ExternalURLs { - dAtA[i] = 0x2a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *ResourceNode) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceNode) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ResourceRef.Size())) - n44, err := m.ResourceRef.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n44 - if len(m.ParentRefs) > 0 { - for _, msg := range m.ParentRefs { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if len(m.Info) > 0 { - for _, msg := range m.Info { - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if m.NetworkingInfo != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.NetworkingInfo.Size())) - n45, err := m.NetworkingInfo.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n45 - } - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceVersion))) - i += copy(dAtA[i:], m.ResourceVersion) - if len(m.Images) > 0 { - for _, s := range m.Images { - dAtA[i] = 0x32 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if m.Health != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Health.Size())) - n46, err := m.Health.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n46 - } - return i, nil -} - -func (m *ResourceOverride) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceOverride) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.HealthLua))) - i += copy(dAtA[i:], m.HealthLua) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.IgnoreDifferences))) - i += copy(dAtA[i:], m.IgnoreDifferences) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Actions))) - i += copy(dAtA[i:], m.Actions) - return i, nil -} - -func (m *ResourceRef) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceRef) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Version))) - i += copy(dAtA[i:], m.Version) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) - i += copy(dAtA[i:], m.UID) - return i, nil -} - -func (m *ResourceResult) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceResult) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Version))) - i += copy(dAtA[i:], m.Version) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i += copy(dAtA[i:], m.Status) - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - dAtA[i] = 0x42 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.HookType))) - i += copy(dAtA[i:], m.HookType) - dAtA[i] = 0x4a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.HookPhase))) - i += copy(dAtA[i:], m.HookPhase) - dAtA[i] = 0x52 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.SyncPhase))) - i += copy(dAtA[i:], m.SyncPhase) - return i, nil -} - -func (m *ResourceStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Version))) - i += copy(dAtA[i:], m.Version) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i += copy(dAtA[i:], m.Namespace) - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i += copy(dAtA[i:], m.Status) - if m.Health != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Health.Size())) - n47, err := m.Health.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n47 - } - dAtA[i] = 0x40 - i++ - if m.Hook { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x48 - i++ - if m.RequiresPruning { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *RevisionHistory) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RevisionHistory) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Revision))) - i += copy(dAtA[i:], m.Revision) - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.DeployedAt.Size())) - n48, err := m.DeployedAt.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n48 - dAtA[i] = 0x28 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ID)) - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n49, err := m.Source.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n49 - return i, nil -} - -func (m *RevisionMetadata) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RevisionMetadata) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Author))) - i += copy(dAtA[i:], m.Author) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Date.Size())) - n50, err := m.Date.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n50 - if len(m.Tags) > 0 { - for _, s := range m.Tags { - dAtA[i] = 0x1a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i += copy(dAtA[i:], m.Message) - return i, nil -} - -func (m *SyncOperation) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncOperation) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Revision))) - i += copy(dAtA[i:], m.Revision) - dAtA[i] = 0x10 - i++ - if m.Prune { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x18 - i++ - if m.DryRun { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - if m.SyncStrategy != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.SyncStrategy.Size())) - n51, err := m.SyncStrategy.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n51 - } - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - if m.Source != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n52, err := m.Source.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n52 - } - if len(m.Manifests) > 0 { - for _, s := range m.Manifests { - dAtA[i] = 0x42 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func (m *SyncOperationResource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncOperationResource) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) - i += copy(dAtA[i:], m.Group) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i += copy(dAtA[i:], m.Name) - return i, nil -} - -func (m *SyncOperationResult) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncOperationResult) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Revision))) - i += copy(dAtA[i:], m.Revision) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Source.Size())) - n53, err := m.Source.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n53 - return i, nil -} - -func (m *SyncPolicy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncPolicy) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Automated != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Automated.Size())) - n54, err := m.Automated.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n54 - } - return i, nil -} - -func (m *SyncPolicyAutomated) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncPolicyAutomated) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - if m.Prune { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x10 - i++ - if m.SelfHeal { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *SyncStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i += copy(dAtA[i:], m.Status) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.ComparedTo.Size())) - n55, err := m.ComparedTo.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n55 - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Revision))) - i += copy(dAtA[i:], m.Revision) - return i, nil -} - -func (m *SyncStrategy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncStrategy) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Apply != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Apply.Size())) - n56, err := m.Apply.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n56 - } - if m.Hook != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Hook.Size())) - n57, err := m.Hook.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n57 - } - return i, nil -} - -func (m *SyncStrategyApply) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncStrategyApply) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - if m.Force { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *SyncStrategyHook) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncStrategyHook) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.SyncStrategyApply.Size())) - n58, err := m.SyncStrategyApply.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n58 - return i, nil -} - -func (m *SyncWindow) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncWindow) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i += copy(dAtA[i:], m.Kind) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Schedule))) - i += copy(dAtA[i:], m.Schedule) - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Duration))) - i += copy(dAtA[i:], m.Duration) - if len(m.Applications) > 0 { - for _, s := range m.Applications { - dAtA[i] = 0x22 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Namespaces) > 0 { - for _, s := range m.Namespaces { - dAtA[i] = 0x2a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if len(m.Clusters) > 0 { - for _, s := range m.Clusters { - dAtA[i] = 0x32 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - dAtA[i] = 0x38 - i++ - if m.ManualSync { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - return i, nil -} - -func (m *TLSClientConfig) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TLSClientConfig) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - if m.Insecure { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ServerName))) - i += copy(dAtA[i:], m.ServerName) - if m.CertData != nil { - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CertData))) - i += copy(dAtA[i:], m.CertData) - } - if m.KeyData != nil { - dAtA[i] = 0x22 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.KeyData))) - i += copy(dAtA[i:], m.KeyData) - } - if m.CAData != nil { - dAtA[i] = 0x2a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CAData))) - i += copy(dAtA[i:], m.CAData) - } - return i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return offset + 1 -} -func (m *AWSAuthConfig) Size() (n int) { - var l int - _ = l - l = len(m.ClusterName) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.RoleARN) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *AppProject) Size() (n int) { - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *AppProjectList) Size() (n int) { - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *AppProjectSpec) Size() (n int) { - var l int - _ = l - if len(m.SourceRepos) > 0 { - for _, s := range m.SourceRepos { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Destinations) > 0 { - for _, e := range m.Destinations { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = len(m.Description) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Roles) > 0 { - for _, e := range m.Roles { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.ClusterResourceWhitelist) > 0 { - for _, e := range m.ClusterResourceWhitelist { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.NamespaceResourceBlacklist) > 0 { - for _, e := range m.NamespaceResourceBlacklist { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.OrphanedResources != nil { - l = m.OrphanedResources.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.SyncWindows) > 0 { - for _, e := range m.SyncWindows { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *Application) Size() (n int) { - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.Operation != nil { - l = m.Operation.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ApplicationCondition) Size() (n int) { - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationDestination) Size() (n int) { - var l int - _ = l - l = len(m.Server) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationList) Size() (n int) { - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationSource) Size() (n int) { - var l int - _ = l - l = len(m.RepoURL) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Path) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.TargetRevision) - n += 1 + l + sovGenerated(uint64(l)) - if m.Helm != nil { - l = m.Helm.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Kustomize != nil { - l = m.Kustomize.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Ksonnet != nil { - l = m.Ksonnet.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Directory != nil { - l = m.Directory.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Plugin != nil { - l = m.Plugin.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.Chart) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationSourceDirectory) Size() (n int) { - var l int - _ = l - n += 2 - l = m.Jsonnet.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationSourceHelm) Size() (n int) { - var l int - _ = l - if len(m.ValueFiles) > 0 { - for _, s := range m.ValueFiles { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Parameters) > 0 { - for _, e := range m.Parameters { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = len(m.ReleaseName) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Values) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationSourceJsonnet) Size() (n int) { - var l int - _ = l - if len(m.ExtVars) > 0 { - for _, e := range m.ExtVars { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.TLAs) > 0 { - for _, e := range m.TLAs { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationSourceKsonnet) Size() (n int) { - var l int - _ = l - l = len(m.Environment) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Parameters) > 0 { - for _, e := range m.Parameters { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationSourceKustomize) Size() (n int) { - var l int - _ = l - l = len(m.NamePrefix) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Images) > 0 { - for _, s := range m.Images { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.CommonLabels) > 0 { - for k, v := range m.CommonLabels { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - return n -} - -func (m *ApplicationSourcePlugin) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Env) > 0 { - for _, e := range m.Env { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationSpec) Size() (n int) { - var l int - _ = l - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Destination.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Project) - n += 1 + l + sovGenerated(uint64(l)) - if m.SyncPolicy != nil { - l = m.SyncPolicy.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.IgnoreDifferences) > 0 { - for _, e := range m.IgnoreDifferences { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Info) > 0 { - for _, e := range m.Info { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationStatus) Size() (n int) { - var l int - _ = l - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = m.Sync.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Health.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.History) > 0 { - for _, e := range m.History { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Conditions) > 0 { - for _, e := range m.Conditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.ReconciledAt != nil { - l = m.ReconciledAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.OperationState != nil { - l = m.OperationState.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ObservedAt != nil { - l = m.ObservedAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.SourceType) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Summary.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ApplicationSummary) Size() (n int) { - var l int - _ = l - if len(m.ExternalURLs) > 0 { - for _, s := range m.ExternalURLs { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Images) > 0 { - for _, s := range m.Images { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationTree) Size() (n int) { - var l int - _ = l - if len(m.Nodes) > 0 { - for _, e := range m.Nodes { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.OrphanedNodes) > 0 { - for _, e := range m.OrphanedNodes { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ApplicationWatchEvent) Size() (n int) { - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Application.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *Cluster) Size() (n int) { - var l int - _ = l - l = len(m.Server) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Config.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.ConnectionState.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.ServerVersion) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ClusterConfig) Size() (n int) { - var l int - _ = l - l = len(m.Username) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Password) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.BearerToken) - n += 1 + l + sovGenerated(uint64(l)) - l = m.TLSClientConfig.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.AWSAuthConfig != nil { - l = m.AWSAuthConfig.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ClusterList) Size() (n int) { - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *Command) Size() (n int) { - var l int - _ = l - if len(m.Command) > 0 { - for _, s := range m.Command { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Args) > 0 { - for _, s := range m.Args { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ComparedTo) Size() (n int) { - var l int - _ = l - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Destination.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ComponentParameter) Size() (n int) { - var l int - _ = l - l = len(m.Component) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ConfigManagementPlugin) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.Init != nil { - l = m.Init.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = m.Generate.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ConnectionState) Size() (n int) { - var l int - _ = l - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - if m.ModifiedAt != nil { - l = m.ModifiedAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *EnvEntry) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HealthStatus) Size() (n int) { - var l int - _ = l - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HelmParameter) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - return n -} - -func (m *Info) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *InfoItem) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *JWTToken) Size() (n int) { - var l int - _ = l - n += 1 + sovGenerated(uint64(m.IssuedAt)) - n += 1 + sovGenerated(uint64(m.ExpiresAt)) - return n -} - -func (m *JsonnetVar) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - return n -} - -func (m *KsonnetParameter) Size() (n int) { - var l int - _ = l - l = len(m.Component) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *KustomizeOptions) Size() (n int) { - var l int - _ = l - l = len(m.BuildOptions) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *Operation) Size() (n int) { - var l int - _ = l - if m.Sync != nil { - l = m.Sync.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *OperationState) Size() (n int) { - var l int - _ = l - l = m.Operation.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Phase) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - if m.SyncResult != nil { - l = m.SyncResult.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = m.StartedAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.FinishedAt != nil { - l = m.FinishedAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *OrphanedResourcesMonitorSettings) Size() (n int) { - var l int - _ = l - if m.Warn != nil { - n += 2 - } - return n -} - -func (m *ProjectRole) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Description) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Policies) > 0 { - for _, s := range m.Policies { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.JWTTokens) > 0 { - for _, e := range m.JWTTokens { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Groups) > 0 { - for _, s := range m.Groups { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *Repository) Size() (n int) { - var l int - _ = l - l = len(m.Repo) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Username) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Password) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.SSHPrivateKey) - n += 1 + l + sovGenerated(uint64(l)) - l = m.ConnectionState.Size() - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - n += 2 - n += 2 - l = len(m.TLSClientCertData) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.TLSClientCertKey) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *RepositoryCertificate) Size() (n int) { - var l int - _ = l - l = len(m.ServerName) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.CertType) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.CertSubType) - n += 1 + l + sovGenerated(uint64(l)) - if m.CertData != nil { - l = len(m.CertData) - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.CertInfo) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *RepositoryCertificateList) Size() (n int) { - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *RepositoryList) Size() (n int) { - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ResourceAction) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Params) > 0 { - for _, e := range m.Params { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - return n -} - -func (m *ResourceActionDefinition) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.ActionLua) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceActionParam) Size() (n int) { - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Value) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Default) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceActions) Size() (n int) { - var l int - _ = l - l = len(m.ActionDiscoveryLua) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Definitions) > 0 { - for _, e := range m.Definitions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ResourceDiff) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.TargetState) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.LiveState) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Diff) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - return n -} - -func (m *ResourceIgnoreDifferences) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.JSONPointers) > 0 { - for _, s := range m.JSONPointers { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ResourceNetworkingInfo) Size() (n int) { - var l int - _ = l - if len(m.TargetLabels) > 0 { - for k, v := range m.TargetLabels { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - if len(m.TargetRefs) > 0 { - for _, e := range m.TargetRefs { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Labels) > 0 { - for k, v := range m.Labels { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - if len(m.Ingress) > 0 { - for _, e := range m.Ingress { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.ExternalURLs) > 0 { - for _, s := range m.ExternalURLs { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ResourceNode) Size() (n int) { - var l int - _ = l - l = m.ResourceRef.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.ParentRefs) > 0 { - for _, e := range m.ParentRefs { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Info) > 0 { - for _, e := range m.Info { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.NetworkingInfo != nil { - l = m.NetworkingInfo.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.ResourceVersion) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Images) > 0 { - for _, s := range m.Images { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.Health != nil { - l = m.Health.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ResourceOverride) Size() (n int) { - var l int - _ = l - l = len(m.HealthLua) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.IgnoreDifferences) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Actions) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceRef) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Version) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.UID) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceResult) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Version) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.HookType) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.HookPhase) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.SyncPhase) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceStatus) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Version) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - if m.Health != nil { - l = m.Health.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - n += 2 - n += 2 - return n -} - -func (m *RevisionHistory) Size() (n int) { - var l int - _ = l - l = len(m.Revision) - n += 1 + l + sovGenerated(uint64(l)) - l = m.DeployedAt.Size() - n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.ID)) - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *RevisionMetadata) Size() (n int) { - var l int - _ = l - l = len(m.Author) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Date.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Tags) > 0 { - for _, s := range m.Tags { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *SyncOperation) Size() (n int) { - var l int - _ = l - l = len(m.Revision) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - n += 2 - if m.SyncStrategy != nil { - l = m.SyncStrategy.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.Source != nil { - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.Manifests) > 0 { - for _, s := range m.Manifests { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *SyncOperationResource) Size() (n int) { - var l int - _ = l - l = len(m.Group) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *SyncOperationResult) Size() (n int) { - var l int - _ = l - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = len(m.Revision) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *SyncPolicy) Size() (n int) { - var l int - _ = l - if m.Automated != nil { - l = m.Automated.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *SyncPolicyAutomated) Size() (n int) { - var l int - _ = l - n += 2 - n += 2 - return n -} - -func (m *SyncStatus) Size() (n int) { - var l int - _ = l - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = m.ComparedTo.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Revision) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *SyncStrategy) Size() (n int) { - var l int - _ = l - if m.Apply != nil { - l = m.Apply.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Hook != nil { - l = m.Hook.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *SyncStrategyApply) Size() (n int) { - var l int - _ = l - n += 2 - return n -} - -func (m *SyncStrategyHook) Size() (n int) { - var l int - _ = l - l = m.SyncStrategyApply.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *SyncWindow) Size() (n int) { - var l int - _ = l - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Schedule) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Duration) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Applications) > 0 { - for _, s := range m.Applications { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Namespaces) > 0 { - for _, s := range m.Namespaces { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Clusters) > 0 { - for _, s := range m.Clusters { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - return n -} - -func (m *TLSClientConfig) Size() (n int) { - var l int - _ = l - n += 2 - l = len(m.ServerName) - n += 1 + l + sovGenerated(uint64(l)) - if m.CertData != nil { - l = len(m.CertData) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.KeyData != nil { - l = len(m.KeyData) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.CAData != nil { - l = len(m.CAData) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func sovGenerated(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *AWSAuthConfig) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AWSAuthConfig{`, - `ClusterName:` + fmt.Sprintf("%v", this.ClusterName) + `,`, - `RoleARN:` + fmt.Sprintf("%v", this.RoleARN) + `,`, - `}`, - }, "") - return s -} -func (this *AppProject) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AppProject{`, - `ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "AppProjectSpec", "AppProjectSpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *AppProjectList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AppProjectList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "AppProject", "AppProject", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *AppProjectSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AppProjectSpec{`, - `SourceRepos:` + fmt.Sprintf("%v", this.SourceRepos) + `,`, - `Destinations:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Destinations), "ApplicationDestination", "ApplicationDestination", 1), `&`, ``, 1) + `,`, - `Description:` + fmt.Sprintf("%v", this.Description) + `,`, - `Roles:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Roles), "ProjectRole", "ProjectRole", 1), `&`, ``, 1) + `,`, - `ClusterResourceWhitelist:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ClusterResourceWhitelist), "GroupKind", "v1.GroupKind", 1), `&`, ``, 1) + `,`, - `NamespaceResourceBlacklist:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.NamespaceResourceBlacklist), "GroupKind", "v1.GroupKind", 1), `&`, ``, 1) + `,`, - `OrphanedResources:` + strings.Replace(fmt.Sprintf("%v", this.OrphanedResources), "OrphanedResourcesMonitorSettings", "OrphanedResourcesMonitorSettings", 1) + `,`, - `SyncWindows:` + strings.Replace(fmt.Sprintf("%v", this.SyncWindows), "SyncWindow", "SyncWindow", 1) + `,`, - `}`, - }, "") - return s -} -func (this *Application) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Application{`, - `ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ApplicationSpec", "ApplicationSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ApplicationStatus", "ApplicationStatus", 1), `&`, ``, 1) + `,`, - `Operation:` + strings.Replace(fmt.Sprintf("%v", this.Operation), "Operation", "Operation", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationCondition) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationCondition{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationDestination) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationDestination{`, - `Server:` + fmt.Sprintf("%v", this.Server) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "Application", "Application", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSource{`, - `RepoURL:` + fmt.Sprintf("%v", this.RepoURL) + `,`, - `Path:` + fmt.Sprintf("%v", this.Path) + `,`, - `TargetRevision:` + fmt.Sprintf("%v", this.TargetRevision) + `,`, - `Helm:` + strings.Replace(fmt.Sprintf("%v", this.Helm), "ApplicationSourceHelm", "ApplicationSourceHelm", 1) + `,`, - `Kustomize:` + strings.Replace(fmt.Sprintf("%v", this.Kustomize), "ApplicationSourceKustomize", "ApplicationSourceKustomize", 1) + `,`, - `Ksonnet:` + strings.Replace(fmt.Sprintf("%v", this.Ksonnet), "ApplicationSourceKsonnet", "ApplicationSourceKsonnet", 1) + `,`, - `Directory:` + strings.Replace(fmt.Sprintf("%v", this.Directory), "ApplicationSourceDirectory", "ApplicationSourceDirectory", 1) + `,`, - `Plugin:` + strings.Replace(fmt.Sprintf("%v", this.Plugin), "ApplicationSourcePlugin", "ApplicationSourcePlugin", 1) + `,`, - `Chart:` + fmt.Sprintf("%v", this.Chart) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourceDirectory) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSourceDirectory{`, - `Recurse:` + fmt.Sprintf("%v", this.Recurse) + `,`, - `Jsonnet:` + strings.Replace(strings.Replace(this.Jsonnet.String(), "ApplicationSourceJsonnet", "ApplicationSourceJsonnet", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourceHelm) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSourceHelm{`, - `ValueFiles:` + fmt.Sprintf("%v", this.ValueFiles) + `,`, - `Parameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Parameters), "HelmParameter", "HelmParameter", 1), `&`, ``, 1) + `,`, - `ReleaseName:` + fmt.Sprintf("%v", this.ReleaseName) + `,`, - `Values:` + fmt.Sprintf("%v", this.Values) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourceJsonnet) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSourceJsonnet{`, - `ExtVars:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ExtVars), "JsonnetVar", "JsonnetVar", 1), `&`, ``, 1) + `,`, - `TLAs:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.TLAs), "JsonnetVar", "JsonnetVar", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourceKsonnet) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSourceKsonnet{`, - `Environment:` + fmt.Sprintf("%v", this.Environment) + `,`, - `Parameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Parameters), "KsonnetParameter", "KsonnetParameter", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourceKustomize) String() string { - if this == nil { - return "nil" - } - keysForCommonLabels := make([]string, 0, len(this.CommonLabels)) - for k := range this.CommonLabels { - keysForCommonLabels = append(keysForCommonLabels, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForCommonLabels) - mapStringForCommonLabels := "map[string]string{" - for _, k := range keysForCommonLabels { - mapStringForCommonLabels += fmt.Sprintf("%v: %v,", k, this.CommonLabels[k]) - } - mapStringForCommonLabels += "}" - s := strings.Join([]string{`&ApplicationSourceKustomize{`, - `NamePrefix:` + fmt.Sprintf("%v", this.NamePrefix) + `,`, - `Images:` + fmt.Sprintf("%v", this.Images) + `,`, - `CommonLabels:` + mapStringForCommonLabels + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSourcePlugin) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSourcePlugin{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Env:` + strings.Replace(fmt.Sprintf("%v", this.Env), "EnvEntry", "EnvEntry", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSpec{`, - `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, - `Destination:` + strings.Replace(strings.Replace(this.Destination.String(), "ApplicationDestination", "ApplicationDestination", 1), `&`, ``, 1) + `,`, - `Project:` + fmt.Sprintf("%v", this.Project) + `,`, - `SyncPolicy:` + strings.Replace(fmt.Sprintf("%v", this.SyncPolicy), "SyncPolicy", "SyncPolicy", 1) + `,`, - `IgnoreDifferences:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.IgnoreDifferences), "ResourceIgnoreDifferences", "ResourceIgnoreDifferences", 1), `&`, ``, 1) + `,`, - `Info:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Info), "Info", "Info", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationStatus{`, - `Resources:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Resources), "ResourceStatus", "ResourceStatus", 1), `&`, ``, 1) + `,`, - `Sync:` + strings.Replace(strings.Replace(this.Sync.String(), "SyncStatus", "SyncStatus", 1), `&`, ``, 1) + `,`, - `Health:` + strings.Replace(strings.Replace(this.Health.String(), "HealthStatus", "HealthStatus", 1), `&`, ``, 1) + `,`, - `History:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.History), "RevisionHistory", "RevisionHistory", 1), `&`, ``, 1) + `,`, - `Conditions:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Conditions), "ApplicationCondition", "ApplicationCondition", 1), `&`, ``, 1) + `,`, - `ReconciledAt:` + strings.Replace(fmt.Sprintf("%v", this.ReconciledAt), "Time", "v1.Time", 1) + `,`, - `OperationState:` + strings.Replace(fmt.Sprintf("%v", this.OperationState), "OperationState", "OperationState", 1) + `,`, - `ObservedAt:` + strings.Replace(fmt.Sprintf("%v", this.ObservedAt), "Time", "v1.Time", 1) + `,`, - `SourceType:` + fmt.Sprintf("%v", this.SourceType) + `,`, - `Summary:` + strings.Replace(strings.Replace(this.Summary.String(), "ApplicationSummary", "ApplicationSummary", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationSummary) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationSummary{`, - `ExternalURLs:` + fmt.Sprintf("%v", this.ExternalURLs) + `,`, - `Images:` + fmt.Sprintf("%v", this.Images) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationTree) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationTree{`, - `Nodes:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Nodes), "ResourceNode", "ResourceNode", 1), `&`, ``, 1) + `,`, - `OrphanedNodes:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.OrphanedNodes), "ResourceNode", "ResourceNode", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ApplicationWatchEvent) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ApplicationWatchEvent{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Application:` + strings.Replace(strings.Replace(this.Application.String(), "Application", "Application", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *Cluster) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Cluster{`, - `Server:` + fmt.Sprintf("%v", this.Server) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Config:` + strings.Replace(strings.Replace(this.Config.String(), "ClusterConfig", "ClusterConfig", 1), `&`, ``, 1) + `,`, - `ConnectionState:` + strings.Replace(strings.Replace(this.ConnectionState.String(), "ConnectionState", "ConnectionState", 1), `&`, ``, 1) + `,`, - `ServerVersion:` + fmt.Sprintf("%v", this.ServerVersion) + `,`, - `}`, - }, "") - return s -} -func (this *ClusterConfig) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ClusterConfig{`, - `Username:` + fmt.Sprintf("%v", this.Username) + `,`, - `Password:` + fmt.Sprintf("%v", this.Password) + `,`, - `BearerToken:` + fmt.Sprintf("%v", this.BearerToken) + `,`, - `TLSClientConfig:` + strings.Replace(strings.Replace(this.TLSClientConfig.String(), "TLSClientConfig", "TLSClientConfig", 1), `&`, ``, 1) + `,`, - `AWSAuthConfig:` + strings.Replace(fmt.Sprintf("%v", this.AWSAuthConfig), "AWSAuthConfig", "AWSAuthConfig", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ClusterList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ClusterList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "Cluster", "Cluster", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *Command) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Command{`, - `Command:` + fmt.Sprintf("%v", this.Command) + `,`, - `Args:` + fmt.Sprintf("%v", this.Args) + `,`, - `}`, - }, "") - return s -} -func (this *ComparedTo) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ComparedTo{`, - `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, - `Destination:` + strings.Replace(strings.Replace(this.Destination.String(), "ApplicationDestination", "ApplicationDestination", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ComponentParameter) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ComponentParameter{`, - `Component:` + fmt.Sprintf("%v", this.Component) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `}`, - }, "") - return s -} -func (this *ConfigManagementPlugin) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ConfigManagementPlugin{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Init:` + strings.Replace(fmt.Sprintf("%v", this.Init), "Command", "Command", 1) + `,`, - `Generate:` + strings.Replace(strings.Replace(this.Generate.String(), "Command", "Command", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ConnectionState) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ConnectionState{`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `ModifiedAt:` + strings.Replace(fmt.Sprintf("%v", this.ModifiedAt), "Time", "v1.Time", 1) + `,`, - `}`, - }, "") - return s -} -func (this *EnvEntry) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&EnvEntry{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `}`, - }, "") - return s -} -func (this *HealthStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HealthStatus{`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *HelmParameter) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HelmParameter{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `ForceString:` + fmt.Sprintf("%v", this.ForceString) + `,`, - `}`, - }, "") - return s -} -func (this *Info) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Info{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `}`, - }, "") - return s -} -func (this *InfoItem) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&InfoItem{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `}`, - }, "") - return s -} -func (this *JWTToken) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&JWTToken{`, - `IssuedAt:` + fmt.Sprintf("%v", this.IssuedAt) + `,`, - `ExpiresAt:` + fmt.Sprintf("%v", this.ExpiresAt) + `,`, - `}`, - }, "") - return s -} -func (this *JsonnetVar) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&JsonnetVar{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `Code:` + fmt.Sprintf("%v", this.Code) + `,`, - `}`, - }, "") - return s -} -func (this *KsonnetParameter) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&KsonnetParameter{`, - `Component:` + fmt.Sprintf("%v", this.Component) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `}`, - }, "") - return s -} -func (this *KustomizeOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&KustomizeOptions{`, - `BuildOptions:` + fmt.Sprintf("%v", this.BuildOptions) + `,`, - `}`, - }, "") - return s -} -func (this *Operation) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Operation{`, - `Sync:` + strings.Replace(fmt.Sprintf("%v", this.Sync), "SyncOperation", "SyncOperation", 1) + `,`, - `}`, - }, "") - return s -} -func (this *OperationState) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&OperationState{`, - `Operation:` + strings.Replace(strings.Replace(this.Operation.String(), "Operation", "Operation", 1), `&`, ``, 1) + `,`, - `Phase:` + fmt.Sprintf("%v", this.Phase) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `SyncResult:` + strings.Replace(fmt.Sprintf("%v", this.SyncResult), "SyncOperationResult", "SyncOperationResult", 1) + `,`, - `StartedAt:` + strings.Replace(strings.Replace(this.StartedAt.String(), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, - `FinishedAt:` + strings.Replace(fmt.Sprintf("%v", this.FinishedAt), "Time", "v1.Time", 1) + `,`, - `}`, - }, "") - return s -} -func (this *OrphanedResourcesMonitorSettings) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&OrphanedResourcesMonitorSettings{`, - `Warn:` + valueToStringGenerated(this.Warn) + `,`, - `}`, - }, "") - return s -} -func (this *ProjectRole) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ProjectRole{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Description:` + fmt.Sprintf("%v", this.Description) + `,`, - `Policies:` + fmt.Sprintf("%v", this.Policies) + `,`, - `JWTTokens:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.JWTTokens), "JWTToken", "JWTToken", 1), `&`, ``, 1) + `,`, - `Groups:` + fmt.Sprintf("%v", this.Groups) + `,`, - `}`, - }, "") - return s -} -func (this *Repository) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Repository{`, - `Repo:` + fmt.Sprintf("%v", this.Repo) + `,`, - `Username:` + fmt.Sprintf("%v", this.Username) + `,`, - `Password:` + fmt.Sprintf("%v", this.Password) + `,`, - `SSHPrivateKey:` + fmt.Sprintf("%v", this.SSHPrivateKey) + `,`, - `ConnectionState:` + strings.Replace(strings.Replace(this.ConnectionState.String(), "ConnectionState", "ConnectionState", 1), `&`, ``, 1) + `,`, - `InsecureIgnoreHostKey:` + fmt.Sprintf("%v", this.InsecureIgnoreHostKey) + `,`, - `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, - `EnableLFS:` + fmt.Sprintf("%v", this.EnableLFS) + `,`, - `TLSClientCertData:` + fmt.Sprintf("%v", this.TLSClientCertData) + `,`, - `TLSClientCertKey:` + fmt.Sprintf("%v", this.TLSClientCertKey) + `,`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} -func (this *RepositoryCertificate) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RepositoryCertificate{`, - `ServerName:` + fmt.Sprintf("%v", this.ServerName) + `,`, - `CertType:` + fmt.Sprintf("%v", this.CertType) + `,`, - `CertSubType:` + fmt.Sprintf("%v", this.CertSubType) + `,`, - `CertData:` + valueToStringGenerated(this.CertData) + `,`, - `CertInfo:` + fmt.Sprintf("%v", this.CertInfo) + `,`, - `}`, - }, "") - return s -} -func (this *RepositoryCertificateList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RepositoryCertificateList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "RepositoryCertificate", "RepositoryCertificate", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *RepositoryList) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RepositoryList{`, - `ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + strings.Replace(fmt.Sprintf("%v", this.Items), "Repository", "Repository", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceAction) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceAction{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Params:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Params), "ResourceActionParam", "ResourceActionParam", 1), `&`, ``, 1) + `,`, - `Disabled:` + fmt.Sprintf("%v", this.Disabled) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceActionDefinition) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceActionDefinition{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `ActionLua:` + fmt.Sprintf("%v", this.ActionLua) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceActionParam) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceActionParam{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Default:` + fmt.Sprintf("%v", this.Default) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceActions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceActions{`, - `ActionDiscoveryLua:` + fmt.Sprintf("%v", this.ActionDiscoveryLua) + `,`, - `Definitions:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Definitions), "ResourceActionDefinition", "ResourceActionDefinition", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceDiff) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceDiff{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `TargetState:` + fmt.Sprintf("%v", this.TargetState) + `,`, - `LiveState:` + fmt.Sprintf("%v", this.LiveState) + `,`, - `Diff:` + fmt.Sprintf("%v", this.Diff) + `,`, - `Hook:` + fmt.Sprintf("%v", this.Hook) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceIgnoreDifferences) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceIgnoreDifferences{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `JSONPointers:` + fmt.Sprintf("%v", this.JSONPointers) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceNetworkingInfo) String() string { - if this == nil { - return "nil" - } - keysForTargetLabels := make([]string, 0, len(this.TargetLabels)) - for k := range this.TargetLabels { - keysForTargetLabels = append(keysForTargetLabels, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForTargetLabels) - mapStringForTargetLabels := "map[string]string{" - for _, k := range keysForTargetLabels { - mapStringForTargetLabels += fmt.Sprintf("%v: %v,", k, this.TargetLabels[k]) - } - mapStringForTargetLabels += "}" - keysForLabels := make([]string, 0, len(this.Labels)) - for k := range this.Labels { - keysForLabels = append(keysForLabels, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) - mapStringForLabels := "map[string]string{" - for _, k := range keysForLabels { - mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k]) - } - mapStringForLabels += "}" - s := strings.Join([]string{`&ResourceNetworkingInfo{`, - `TargetLabels:` + mapStringForTargetLabels + `,`, - `TargetRefs:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.TargetRefs), "ResourceRef", "ResourceRef", 1), `&`, ``, 1) + `,`, - `Labels:` + mapStringForLabels + `,`, - `Ingress:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Ingress), "LoadBalancerIngress", "v11.LoadBalancerIngress", 1), `&`, ``, 1) + `,`, - `ExternalURLs:` + fmt.Sprintf("%v", this.ExternalURLs) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceNode) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceNode{`, - `ResourceRef:` + strings.Replace(strings.Replace(this.ResourceRef.String(), "ResourceRef", "ResourceRef", 1), `&`, ``, 1) + `,`, - `ParentRefs:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ParentRefs), "ResourceRef", "ResourceRef", 1), `&`, ``, 1) + `,`, - `Info:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Info), "InfoItem", "InfoItem", 1), `&`, ``, 1) + `,`, - `NetworkingInfo:` + strings.Replace(fmt.Sprintf("%v", this.NetworkingInfo), "ResourceNetworkingInfo", "ResourceNetworkingInfo", 1) + `,`, - `ResourceVersion:` + fmt.Sprintf("%v", this.ResourceVersion) + `,`, - `Images:` + fmt.Sprintf("%v", this.Images) + `,`, - `Health:` + strings.Replace(fmt.Sprintf("%v", this.Health), "HealthStatus", "HealthStatus", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceOverride) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceOverride{`, - `HealthLua:` + fmt.Sprintf("%v", this.HealthLua) + `,`, - `IgnoreDifferences:` + fmt.Sprintf("%v", this.IgnoreDifferences) + `,`, - `Actions:` + fmt.Sprintf("%v", this.Actions) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceRef) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceRef{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Version:` + fmt.Sprintf("%v", this.Version) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `UID:` + fmt.Sprintf("%v", this.UID) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceResult) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceResult{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Version:` + fmt.Sprintf("%v", this.Version) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `HookType:` + fmt.Sprintf("%v", this.HookType) + `,`, - `HookPhase:` + fmt.Sprintf("%v", this.HookPhase) + `,`, - `SyncPhase:` + fmt.Sprintf("%v", this.SyncPhase) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceStatus{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Version:` + fmt.Sprintf("%v", this.Version) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `Health:` + strings.Replace(fmt.Sprintf("%v", this.Health), "HealthStatus", "HealthStatus", 1) + `,`, - `Hook:` + fmt.Sprintf("%v", this.Hook) + `,`, - `RequiresPruning:` + fmt.Sprintf("%v", this.RequiresPruning) + `,`, - `}`, - }, "") - return s -} -func (this *RevisionHistory) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RevisionHistory{`, - `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, - `DeployedAt:` + strings.Replace(strings.Replace(this.DeployedAt.String(), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, - `ID:` + fmt.Sprintf("%v", this.ID) + `,`, - `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *RevisionMetadata) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RevisionMetadata{`, - `Author:` + fmt.Sprintf("%v", this.Author) + `,`, - `Date:` + strings.Replace(strings.Replace(this.Date.String(), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, - `Tags:` + fmt.Sprintf("%v", this.Tags) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *SyncOperation) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncOperation{`, - `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, - `Prune:` + fmt.Sprintf("%v", this.Prune) + `,`, - `DryRun:` + fmt.Sprintf("%v", this.DryRun) + `,`, - `SyncStrategy:` + strings.Replace(fmt.Sprintf("%v", this.SyncStrategy), "SyncStrategy", "SyncStrategy", 1) + `,`, - `Resources:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Resources), "SyncOperationResource", "SyncOperationResource", 1), `&`, ``, 1) + `,`, - `Source:` + strings.Replace(fmt.Sprintf("%v", this.Source), "ApplicationSource", "ApplicationSource", 1) + `,`, - `Manifests:` + fmt.Sprintf("%v", this.Manifests) + `,`, - `}`, - }, "") - return s -} -func (this *SyncOperationResource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncOperationResource{`, - `Group:` + fmt.Sprintf("%v", this.Group) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} -func (this *SyncOperationResult) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncOperationResult{`, - `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "ResourceResult", "ResourceResult", 1) + `,`, - `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, - `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *SyncPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncPolicy{`, - `Automated:` + strings.Replace(fmt.Sprintf("%v", this.Automated), "SyncPolicyAutomated", "SyncPolicyAutomated", 1) + `,`, - `}`, - }, "") - return s -} -func (this *SyncPolicyAutomated) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncPolicyAutomated{`, - `Prune:` + fmt.Sprintf("%v", this.Prune) + `,`, - `SelfHeal:` + fmt.Sprintf("%v", this.SelfHeal) + `,`, - `}`, - }, "") - return s -} -func (this *SyncStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncStatus{`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `ComparedTo:` + strings.Replace(strings.Replace(this.ComparedTo.String(), "ComparedTo", "ComparedTo", 1), `&`, ``, 1) + `,`, - `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, - `}`, - }, "") - return s -} -func (this *SyncStrategy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncStrategy{`, - `Apply:` + strings.Replace(fmt.Sprintf("%v", this.Apply), "SyncStrategyApply", "SyncStrategyApply", 1) + `,`, - `Hook:` + strings.Replace(fmt.Sprintf("%v", this.Hook), "SyncStrategyHook", "SyncStrategyHook", 1) + `,`, - `}`, - }, "") - return s -} -func (this *SyncStrategyApply) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncStrategyApply{`, - `Force:` + fmt.Sprintf("%v", this.Force) + `,`, - `}`, - }, "") - return s -} -func (this *SyncStrategyHook) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncStrategyHook{`, - `SyncStrategyApply:` + strings.Replace(strings.Replace(this.SyncStrategyApply.String(), "SyncStrategyApply", "SyncStrategyApply", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *SyncWindow) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SyncWindow{`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Schedule:` + fmt.Sprintf("%v", this.Schedule) + `,`, - `Duration:` + fmt.Sprintf("%v", this.Duration) + `,`, - `Applications:` + fmt.Sprintf("%v", this.Applications) + `,`, - `Namespaces:` + fmt.Sprintf("%v", this.Namespaces) + `,`, - `Clusters:` + fmt.Sprintf("%v", this.Clusters) + `,`, - `ManualSync:` + fmt.Sprintf("%v", this.ManualSync) + `,`, - `}`, - }, "") - return s -} -func (this *TLSClientConfig) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&TLSClientConfig{`, - `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, - `ServerName:` + fmt.Sprintf("%v", this.ServerName) + `,`, - `CertData:` + valueToStringGenerated(this.CertData) + `,`, - `KeyData:` + valueToStringGenerated(this.KeyData) + `,`, - `CAData:` + valueToStringGenerated(this.CAData) + `,`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *AWSAuthConfig) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AWSAuthConfig: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AWSAuthConfig: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClusterName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RoleARN", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RoleARN = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AppProject) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AppProject: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AppProject: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AppProjectList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AppProjectList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AppProjectList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, AppProject{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AppProjectSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AppProjectSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AppProjectSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SourceRepos", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SourceRepos = append(m.SourceRepos, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Destinations", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Destinations = append(m.Destinations, ApplicationDestination{}) - if err := m.Destinations[len(m.Destinations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Roles = append(m.Roles, ProjectRole{}) - if err := m.Roles[len(m.Roles)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterResourceWhitelist", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClusterResourceWhitelist = append(m.ClusterResourceWhitelist, v1.GroupKind{}) - if err := m.ClusterResourceWhitelist[len(m.ClusterResourceWhitelist)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NamespaceResourceBlacklist", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NamespaceResourceBlacklist = append(m.NamespaceResourceBlacklist, v1.GroupKind{}) - if err := m.NamespaceResourceBlacklist[len(m.NamespaceResourceBlacklist)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OrphanedResources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.OrphanedResources == nil { - m.OrphanedResources = &OrphanedResourcesMonitorSettings{} - } - if err := m.OrphanedResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncWindows", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SyncWindows = append(m.SyncWindows, &SyncWindow{}) - if err := m.SyncWindows[len(m.SyncWindows)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Application) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Application: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Application: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Operation == nil { - m.Operation = &Operation{} - } - if err := m.Operation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationCondition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationCondition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationCondition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationDestination) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationDestination: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationDestination: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Server = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, Application{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RepoURL", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RepoURL = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetRevision", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TargetRevision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Helm", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Helm == nil { - m.Helm = &ApplicationSourceHelm{} - } - if err := m.Helm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kustomize", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Kustomize == nil { - m.Kustomize = &ApplicationSourceKustomize{} - } - if err := m.Kustomize.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ksonnet", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ksonnet == nil { - m.Ksonnet = &ApplicationSourceKsonnet{} - } - if err := m.Ksonnet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Directory", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Directory == nil { - m.Directory = &ApplicationSourceDirectory{} - } - if err := m.Directory.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Plugin", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Plugin == nil { - m.Plugin = &ApplicationSourcePlugin{} - } - if err := m.Plugin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Chart", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Chart = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourceDirectory) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourceDirectory: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourceDirectory: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Recurse", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Recurse = bool(v != 0) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Jsonnet", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Jsonnet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourceHelm: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourceHelm: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValueFiles", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ValueFiles = append(m.ValueFiles, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Parameters = append(m.Parameters, HelmParameter{}) - if err := m.Parameters[len(m.Parameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReleaseName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ReleaseName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Values = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourceJsonnet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourceJsonnet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourceJsonnet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExtVars", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExtVars = append(m.ExtVars, JsonnetVar{}) - if err := m.ExtVars[len(m.ExtVars)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLAs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TLAs = append(m.TLAs, JsonnetVar{}) - if err := m.TLAs[len(m.TLAs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourceKsonnet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourceKsonnet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourceKsonnet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Environment", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Environment = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Parameters = append(m.Parameters, KsonnetParameter{}) - if err := m.Parameters[len(m.Parameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourceKustomize) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourceKustomize: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourceKustomize: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NamePrefix", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NamePrefix = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Images = append(m.Images, KustomizeImage(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CommonLabels", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.CommonLabels == nil { - m.CommonLabels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.CommonLabels[mapkey] = mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSourcePlugin) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSourcePlugin: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSourcePlugin: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = append(m.Env, &EnvEntry{}) - if err := m.Env[len(m.Env)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Destination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Destination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Project = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncPolicy", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SyncPolicy == nil { - m.SyncPolicy = &SyncPolicy{} - } - if err := m.SyncPolicy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreDifferences", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.IgnoreDifferences = append(m.IgnoreDifferences, ResourceIgnoreDifferences{}) - if err := m.IgnoreDifferences[len(m.IgnoreDifferences)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Info = append(m.Info, Info{}) - if err := m.Info[len(m.Info)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, ResourceStatus{}) - if err := m.Resources[len(m.Resources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sync", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Sync.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Health", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Health.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field History", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.History = append(m.History, RevisionHistory{}) - if err := m.History[len(m.History)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Conditions = append(m.Conditions, ApplicationCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReconciledAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ReconciledAt == nil { - m.ReconciledAt = &v1.Time{} - } - if err := m.ReconciledAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OperationState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.OperationState == nil { - m.OperationState = &OperationState{} - } - if err := m.OperationState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ObservedAt == nil { - m.ObservedAt = &v1.Time{} - } - if err := m.ObservedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SourceType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SourceType = ApplicationSourceType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Summary", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Summary.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSummary) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationSummary: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSummary: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExternalURLs", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExternalURLs = append(m.ExternalURLs, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Images = append(m.Images, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationTree) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationTree: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationTree: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Nodes = append(m.Nodes, ResourceNode{}) - if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OrphanedNodes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.OrphanedNodes = append(m.OrphanedNodes, ResourceNode{}) - if err := m.OrphanedNodes[len(m.OrphanedNodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationWatchEvent) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplicationWatchEvent: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationWatchEvent: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = k8s_io_apimachinery_pkg_watch.EventType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Application", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Application.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Cluster) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Cluster: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Cluster: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Server = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ConnectionState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ServerVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClusterConfig) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ClusterConfig: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClusterConfig: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Username = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Password = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BearerToken = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSClientConfig", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TLSClientConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AWSAuthConfig", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AWSAuthConfig == nil { - m.AWSAuthConfig = &AWSAuthConfig{} - } - if err := m.AWSAuthConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClusterList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ClusterList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClusterList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, Cluster{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Command) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Command: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Command: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Command = append(m.Command, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Args = append(m.Args, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ComparedTo) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ComparedTo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ComparedTo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Destination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Destination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ComponentParameter) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ComponentParameter: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ComponentParameter: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Component", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Component = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConfigManagementPlugin) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ConfigManagementPlugin: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConfigManagementPlugin: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Init", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Init == nil { - m.Init = &Command{} - } - if err := m.Init.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Generate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Generate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConnectionState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ConnectionState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConnectionState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ModifiedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ModifiedAt == nil { - m.ModifiedAt = &v1.Time{} - } - if err := m.ModifiedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *EnvEntry) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: EnvEntry: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: EnvEntry: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HealthStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HealthStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HealthStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HelmParameter) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HelmParameter: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HelmParameter: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ForceString", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ForceString = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Info) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Info: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Info: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *InfoItem) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: InfoItem: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: InfoItem: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JWTToken) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JWTToken: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JWTToken: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IssuedAt", wireType) - } - m.IssuedAt = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.IssuedAt |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExpiresAt", wireType) - } - m.ExpiresAt = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ExpiresAt |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JsonnetVar) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JsonnetVar: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JsonnetVar: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Code = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *KsonnetParameter) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: KsonnetParameter: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: KsonnetParameter: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Component", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Component = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *KustomizeOptions) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: KustomizeOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: KustomizeOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BuildOptions", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BuildOptions = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Operation) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Operation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Operation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sync", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Sync == nil { - m.Sync = &SyncOperation{} - } - if err := m.Sync.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *OperationState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: OperationState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: OperationState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Operation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Phase", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Phase = OperationPhase(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncResult", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SyncResult == nil { - m.SyncResult = &SyncOperationResult{} - } - if err := m.SyncResult.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StartedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.StartedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FinishedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.FinishedAt == nil { - m.FinishedAt = &v1.Time{} - } - if err := m.FinishedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *OrphanedResourcesMonitorSettings) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: OrphanedResourcesMonitorSettings: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: OrphanedResourcesMonitorSettings: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Warn", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Warn = &b - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ProjectRole) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ProjectRole: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ProjectRole: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Policies", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Policies = append(m.Policies, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JWTTokens", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.JWTTokens = append(m.JWTTokens, JWTToken{}) - if err := m.JWTTokens[len(m.JWTTokens)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Groups = append(m.Groups, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Repository) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Repository: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Repository: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Repo = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Username = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Password = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SSHPrivateKey", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SSHPrivateKey = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ConnectionState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field InsecureIgnoreHostKey", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.InsecureIgnoreHostKey = bool(v != 0) - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Insecure", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Insecure = bool(v != 0) - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EnableLFS", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.EnableLFS = bool(v != 0) - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertData", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TLSClientCertData = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertKey", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TLSClientCertKey = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RepositoryCertificate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RepositoryCertificate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RepositoryCertificate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ServerName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CertType = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertSubType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CertSubType = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CertData = append(m.CertData[:0], dAtA[iNdEx:postIndex]...) - if m.CertData == nil { - m.CertData = []byte{} - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertInfo", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CertInfo = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RepositoryCertificateList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RepositoryCertificateList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RepositoryCertificateList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, RepositoryCertificate{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RepositoryList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RepositoryList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RepositoryList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, &Repository{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceAction) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceAction: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceAction: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Params = append(m.Params, ResourceActionParam{}) - if err := m.Params[len(m.Params)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Disabled", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Disabled = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceActionDefinition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceActionDefinition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceActionDefinition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ActionLua", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ActionLua = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceActionParam) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceActionParam: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceActionParam: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Default", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Default = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceActions) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceActions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceActions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ActionDiscoveryLua", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ActionDiscoveryLua = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Definitions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Definitions = append(m.Definitions, ResourceActionDefinition{}) - if err := m.Definitions[len(m.Definitions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceDiff) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceDiff: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceDiff: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetState", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TargetState = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LiveState", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.LiveState = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Diff", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Diff = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Hook", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Hook = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceIgnoreDifferences) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceIgnoreDifferences: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceIgnoreDifferences: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JSONPointers", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.JSONPointers = append(m.JSONPointers, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceNetworkingInfo) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceNetworkingInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceNetworkingInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetLabels", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TargetLabels == nil { - m.TargetLabels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.TargetLabels[mapkey] = mapvalue - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetRefs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TargetRefs = append(m.TargetRefs, ResourceRef{}) - if err := m.TargetRefs[len(m.TargetRefs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Labels == nil { - m.Labels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Labels[mapkey] = mapvalue - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ingress = append(m.Ingress, v11.LoadBalancerIngress{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExternalURLs", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExternalURLs = append(m.ExternalURLs, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceNode) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceNode: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceNode: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceRef", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ResourceRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ParentRefs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ParentRefs = append(m.ParentRefs, ResourceRef{}) - if err := m.ParentRefs[len(m.ParentRefs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Info = append(m.Info, InfoItem{}) - if err := m.Info[len(m.Info)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NetworkingInfo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.NetworkingInfo == nil { - m.NetworkingInfo = &ResourceNetworkingInfo{} - } - if err := m.NetworkingInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ResourceVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Images = append(m.Images, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Health", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Health == nil { - m.Health = &HealthStatus{} - } - if err := m.Health.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceOverride) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceOverride: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceOverride: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HealthLua", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.HealthLua = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreDifferences", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.IgnoreDifferences = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Actions", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Actions = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceRef) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceRef: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceRef: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceResult) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceResult: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceResult: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = ResultCode(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HookType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.HookType = HookType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HookPhase", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.HookPhase = OperationPhase(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncPhase", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SyncPhase = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = SyncStatusCode(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Health", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Health == nil { - m.Health = &HealthStatus{} - } - if err := m.Health.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Hook", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Hook = bool(v != 0) - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RequiresPruning", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.RequiresPruning = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RevisionHistory) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RevisionHistory: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RevisionHistory: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Revision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeployedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.DeployedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) - } - m.ID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ID |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RevisionMetadata) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RevisionMetadata: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RevisionMetadata: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Author", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Author = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Date", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Date.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Tags = append(m.Tags, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncOperation) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncOperation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncOperation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Revision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Prune", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Prune = bool(v != 0) - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DryRun = bool(v != 0) - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncStrategy", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SyncStrategy == nil { - m.SyncStrategy = &SyncStrategy{} - } - if err := m.SyncStrategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, SyncOperationResource{}) - if err := m.Resources[len(m.Resources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Source == nil { - m.Source = &ApplicationSource{} - } - if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Manifests", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Manifests = append(m.Manifests, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncOperationResource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncOperationResource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncOperationResource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Group = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncOperationResult) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncOperationResult: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncOperationResult: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &ResourceResult{}) - if err := m.Resources[len(m.Resources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Revision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncPolicy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncPolicy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Automated", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Automated == nil { - m.Automated = &SyncPolicyAutomated{} - } - if err := m.Automated.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncPolicyAutomated) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncPolicyAutomated: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncPolicyAutomated: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Prune", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Prune = bool(v != 0) - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SelfHeal", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.SelfHeal = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = SyncStatusCode(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ComparedTo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ComparedTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Revision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncStrategy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncStrategy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncStrategy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Apply", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Apply == nil { - m.Apply = &SyncStrategyApply{} - } - if err := m.Apply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hook", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Hook == nil { - m.Hook = &SyncStrategyHook{} - } - if err := m.Hook.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncStrategyApply) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncStrategyApply: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncStrategyApply: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Force", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Force = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncStrategyHook) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncStrategyHook: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncStrategyHook: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncStrategyApply", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.SyncStrategyApply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncWindow) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SyncWindow: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SyncWindow: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Schedule", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Schedule = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Duration = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Applications", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Applications = append(m.Applications, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespaces", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespaces = append(m.Namespaces, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Clusters", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Clusters = append(m.Clusters, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ManualSync", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ManualSync = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *TLSClientConfig) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TLSClientConfig: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TLSClientConfig: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Insecure", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Insecure = bool(v != 0) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ServerName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CertData = append(m.CertData[:0], dAtA[iNdEx:postIndex]...) - if m.CertData == nil { - m.CertData = []byte{} - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KeyData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.KeyData = append(m.KeyData[:0], dAtA[iNdEx:postIndex]...) - if m.KeyData == nil { - m.KeyData = []byte{} - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CAData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CAData = append(m.CAData[:0], dAtA[iNdEx:postIndex]...) - if m.CAData == nil { - m.CAData = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - iNdEx += length - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipGenerated(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") -) - -func init() { - proto.RegisterFile("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1/generated.proto", fileDescriptor_generated_85119751c9399dcb) -} - -var fileDescriptor_generated_85119751c9399dcb = []byte{ - // 4715 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3c, 0x4b, 0x8c, 0x1c, 0xd7, - 0x71, 0xea, 0xf9, 0x4f, 0xed, 0x87, 0xdc, 0x27, 0x51, 0x1e, 0x2f, 0x64, 0x92, 0x68, 0xc2, 0xb6, - 0x14, 0xdb, 0xb3, 0x11, 0x41, 0x27, 0x4c, 0x02, 0xc4, 0xde, 0xd9, 0xa5, 0xc4, 0x25, 0x77, 0x97, - 0xab, 0x37, 0x4b, 0xd1, 0x91, 0x85, 0xc4, 0xbd, 0x3d, 0x6f, 0x66, 0x9a, 0x3b, 0xd3, 0xdd, 0xea, - 0xee, 0xd9, 0xe5, 0xda, 0x12, 0x2c, 0xc5, 0x71, 0xa0, 0x38, 0x32, 0x12, 0x27, 0xbe, 0xc5, 0x87, - 0x20, 0x70, 0x90, 0x04, 0xc8, 0x45, 0xa7, 0xe4, 0x16, 0xc0, 0xc8, 0x41, 0xa7, 0xc4, 0x01, 0x0c, - 0x44, 0xb0, 0x11, 0x26, 0x5a, 0x27, 0x80, 0x01, 0x9f, 0x92, 0x43, 0x8c, 0xf0, 0x14, 0xbc, 0xff, - 0xeb, 0x9e, 0x19, 0xee, 0x92, 0xec, 0xa5, 0x00, 0xc3, 0xb7, 0xe9, 0xaa, 0xea, 0xaa, 0x7a, 0xf5, - 0xea, 0xbd, 0x57, 0x55, 0xaf, 0x7a, 0x60, 0xab, 0xe7, 0x25, 0xfd, 0xd1, 0x4e, 0xd3, 0x0d, 0x86, - 0x4b, 0x4e, 0xd4, 0x0b, 0xc2, 0x28, 0xb8, 0xcd, 0x7e, 0x7c, 0xc6, 0xed, 0x2c, 0x11, 0xbf, 0xe7, - 0xf9, 0x64, 0x29, 0xdc, 0xed, 0x2d, 0x39, 0xa1, 0x17, 0x2f, 0x39, 0x61, 0x38, 0xf0, 0x5c, 0x27, - 0xf1, 0x02, 0x7f, 0x69, 0xef, 0x79, 0x67, 0x10, 0xf6, 0x9d, 0xe7, 0x97, 0x7a, 0xc4, 0x27, 0x91, - 0x93, 0x90, 0x4e, 0x33, 0x8c, 0x82, 0x24, 0x40, 0x9f, 0xd7, 0x1c, 0x9b, 0x92, 0x23, 0xfb, 0xf1, - 0x3b, 0x6e, 0xa7, 0xc9, 0x39, 0x36, 0xc3, 0xdd, 0x5e, 0x93, 0x72, 0x6c, 0x1a, 0x1c, 0x9b, 0x92, - 0xe3, 0xe2, 0x67, 0x0c, 0x9d, 0x7a, 0x41, 0x2f, 0x58, 0x62, 0x8c, 0x77, 0x46, 0x5d, 0xf6, 0xc4, - 0x1e, 0xd8, 0x2f, 0x2e, 0x70, 0xd1, 0xde, 0xbd, 0x1c, 0x37, 0xbd, 0x80, 0xaa, 0xb8, 0xe4, 0x06, - 0x11, 0x59, 0xda, 0x1b, 0x53, 0x6a, 0xf1, 0x92, 0xa6, 0x19, 0x3a, 0x6e, 0xdf, 0xf3, 0x49, 0x74, - 0xa0, 0xc7, 0x35, 0x24, 0x89, 0x33, 0xe9, 0xad, 0xa5, 0x69, 0x6f, 0x45, 0x23, 0x3f, 0xf1, 0x86, - 0x64, 0xec, 0x85, 0x5f, 0x39, 0xea, 0x85, 0xd8, 0xed, 0x93, 0xa1, 0x93, 0x7d, 0xcf, 0x7e, 0x0d, - 0xe6, 0x96, 0x6f, 0xb5, 0x97, 0x47, 0x49, 0x7f, 0x25, 0xf0, 0xbb, 0x5e, 0x0f, 0x7d, 0x16, 0x66, - 0xdc, 0xc1, 0x28, 0x4e, 0x48, 0xb4, 0xe9, 0x0c, 0x49, 0xc3, 0x3a, 0x6f, 0x3d, 0x5b, 0x6f, 0x3d, - 0xf9, 0xde, 0xdd, 0x73, 0x4f, 0x1c, 0xde, 0x3d, 0x37, 0xb3, 0xa2, 0x51, 0xd8, 0xa4, 0x43, 0xcf, - 0x41, 0x35, 0x0a, 0x06, 0x64, 0x19, 0x6f, 0x36, 0x0a, 0xec, 0x95, 0x53, 0xe2, 0x95, 0x2a, 0xe6, - 0x60, 0x2c, 0xf1, 0xf6, 0xa1, 0x05, 0xb0, 0x1c, 0x86, 0x5b, 0x51, 0x70, 0x9b, 0xb8, 0x09, 0xfa, - 0x12, 0xd4, 0xa8, 0x15, 0x3a, 0x4e, 0xe2, 0x30, 0x69, 0x33, 0x17, 0x7f, 0xb9, 0xc9, 0x07, 0xd3, - 0x34, 0x07, 0xa3, 0x67, 0x8e, 0x52, 0x37, 0xf7, 0x9e, 0x6f, 0xde, 0xd8, 0xa1, 0xef, 0x6f, 0x90, - 0xc4, 0x69, 0x21, 0x21, 0x0c, 0x34, 0x0c, 0x2b, 0xae, 0x28, 0x82, 0x52, 0x1c, 0x12, 0x97, 0x29, - 0x36, 0x73, 0x71, 0xab, 0xf9, 0xa8, 0x6e, 0xd2, 0xd4, 0xda, 0xb7, 0x43, 0xe2, 0xb6, 0x66, 0x85, - 0xf4, 0x12, 0x7d, 0xc2, 0x4c, 0x96, 0xfd, 0x81, 0x05, 0xf3, 0x9a, 0x6c, 0xdd, 0x8b, 0x13, 0xf4, - 0xea, 0xd8, 0x40, 0x9b, 0xc7, 0x1b, 0x28, 0x7d, 0x9b, 0x0d, 0xf3, 0xb4, 0x10, 0x54, 0x93, 0x10, - 0x63, 0x90, 0xaf, 0x41, 0xd9, 0x4b, 0xc8, 0x30, 0x6e, 0x14, 0xce, 0x17, 0x9f, 0x9d, 0xb9, 0xb8, - 0x9e, 0xe7, 0x28, 0x5b, 0x73, 0x42, 0x70, 0x79, 0x8d, 0x8a, 0xc0, 0x5c, 0x92, 0xfd, 0x83, 0xaa, - 0x39, 0x46, 0x3a, 0x78, 0xf4, 0x3c, 0xcc, 0xc4, 0xc1, 0x28, 0x72, 0x09, 0x26, 0x61, 0x10, 0x37, - 0xac, 0xf3, 0x45, 0xea, 0x0a, 0xd4, 0x73, 0xda, 0x1a, 0x8c, 0x4d, 0x1a, 0xf4, 0x27, 0x16, 0xcc, - 0x76, 0x48, 0x9c, 0x78, 0x3e, 0x93, 0x2f, 0x07, 0xf0, 0x85, 0x5c, 0x06, 0x20, 0x81, 0xab, 0x5a, - 0x40, 0xeb, 0x29, 0x31, 0x98, 0x59, 0x03, 0x18, 0xe3, 0x94, 0x0e, 0x74, 0x15, 0x74, 0x48, 0xec, - 0x46, 0x5e, 0x48, 0x9f, 0x1b, 0xc5, 0xf4, 0x2a, 0x58, 0xd5, 0x28, 0x6c, 0xd2, 0xa1, 0x08, 0xca, - 0xd4, 0xcb, 0xe3, 0x46, 0x89, 0x8d, 0x61, 0xe3, 0xd1, 0xc7, 0x20, 0x8c, 0x4b, 0x17, 0x91, 0x9e, - 0x05, 0xfa, 0x14, 0x63, 0x2e, 0x0a, 0x7d, 0xd3, 0x82, 0x86, 0x58, 0x89, 0x98, 0x70, 0xc3, 0xde, - 0xea, 0x7b, 0x09, 0x19, 0x78, 0x71, 0xd2, 0x28, 0x33, 0x3d, 0x96, 0x8e, 0xe7, 0x67, 0x2f, 0x46, - 0xc1, 0x28, 0xbc, 0xee, 0xf9, 0x9d, 0xd6, 0x79, 0x21, 0xa9, 0xb1, 0x32, 0x85, 0x31, 0x9e, 0x2a, - 0x12, 0xfd, 0xa9, 0x05, 0x8b, 0xbe, 0x33, 0x24, 0x71, 0xe8, 0xd0, 0x29, 0xe6, 0xe8, 0xd6, 0xc0, - 0x71, 0x77, 0x99, 0x46, 0x95, 0x87, 0xd3, 0xc8, 0x16, 0x1a, 0x2d, 0x6e, 0x4e, 0x65, 0x8d, 0xef, - 0x23, 0x16, 0xfd, 0x95, 0x05, 0x0b, 0x41, 0x14, 0xf6, 0x1d, 0x9f, 0x74, 0x24, 0x36, 0x6e, 0x54, - 0xd9, 0x32, 0xdc, 0x79, 0xf4, 0x69, 0xba, 0x91, 0x65, 0xbd, 0x11, 0xf8, 0x5e, 0x12, 0x44, 0x6d, - 0x92, 0x24, 0x9e, 0xdf, 0x8b, 0x5b, 0x67, 0x0e, 0xef, 0x9e, 0x5b, 0x18, 0xa3, 0xc2, 0xe3, 0x3a, - 0xa1, 0xaf, 0xc2, 0x4c, 0x7c, 0xe0, 0xbb, 0xb7, 0x3c, 0xbf, 0x13, 0xec, 0xc7, 0x8d, 0x5a, 0x5e, - 0xcb, 0xb9, 0xad, 0x98, 0x8a, 0x05, 0xa9, 0x85, 0x60, 0x53, 0xa2, 0xfd, 0xa3, 0x22, 0xcc, 0x18, - 0x4b, 0xe7, 0x31, 0x6c, 0xd0, 0x71, 0x6a, 0x83, 0x7e, 0x29, 0xd7, 0x95, 0x3f, 0x6d, 0x87, 0x46, - 0x5f, 0x81, 0x4a, 0x9c, 0x38, 0xc9, 0x28, 0x66, 0xab, 0x7b, 0xe6, 0x62, 0x3b, 0x5f, 0xb1, 0x8c, - 0x75, 0x6b, 0x5e, 0x08, 0xae, 0xf0, 0x67, 0x2c, 0x44, 0xa2, 0x3b, 0x50, 0x0f, 0x42, 0x7a, 0x10, - 0xd3, 0xdd, 0xa5, 0xc4, 0xe4, 0x5f, 0xcf, 0xc1, 0x0b, 0x25, 0xcb, 0xd6, 0xdc, 0xe1, 0xdd, 0x73, - 0x75, 0xf5, 0x88, 0xb5, 0x30, 0xdb, 0x85, 0xa7, 0x0c, 0x35, 0x57, 0x02, 0xbf, 0xe3, 0xb1, 0x59, - 0x3e, 0x0f, 0xa5, 0xe4, 0x20, 0x94, 0x07, 0xbe, 0x32, 0xd8, 0xf6, 0x41, 0x48, 0x30, 0xc3, 0xd0, - 0x23, 0x7e, 0x48, 0xe2, 0xd8, 0xe9, 0x91, 0xec, 0x11, 0xbf, 0xc1, 0xc1, 0x58, 0xe2, 0xed, 0xd7, - 0xe0, 0xe9, 0xc9, 0x9b, 0x2f, 0xfa, 0x04, 0x54, 0x62, 0x12, 0xed, 0x91, 0x48, 0x08, 0xd2, 0x06, - 0x62, 0x50, 0x2c, 0xb0, 0x68, 0x09, 0xea, 0x6a, 0x35, 0x0b, 0x71, 0x0b, 0x82, 0xb4, 0xae, 0xb7, - 0x00, 0x4d, 0x63, 0xff, 0xd8, 0x82, 0x53, 0x86, 0xcc, 0xc7, 0x70, 0xe2, 0x46, 0xe9, 0x13, 0x77, - 0x23, 0x57, 0xff, 0x99, 0x72, 0xe4, 0xfe, 0x6b, 0x05, 0x16, 0x4c, 0x2f, 0x63, 0x7b, 0x06, 0x0b, - 0xbe, 0x48, 0x18, 0xdc, 0xc4, 0xeb, 0xc2, 0xaa, 0x3a, 0xf8, 0xe2, 0x60, 0x2c, 0xf1, 0x74, 0x9a, - 0x43, 0x27, 0xe9, 0x0b, 0x93, 0xaa, 0x69, 0xde, 0x72, 0x92, 0x3e, 0x66, 0x18, 0xf4, 0x9b, 0x30, - 0x9f, 0x38, 0x51, 0x8f, 0x24, 0x98, 0xec, 0x79, 0xb1, 0xf4, 0xcf, 0x7a, 0xeb, 0x69, 0x41, 0x3b, - 0xbf, 0x9d, 0xc2, 0xe2, 0x0c, 0x35, 0x1a, 0x41, 0xa9, 0x4f, 0x06, 0x43, 0xb1, 0xb7, 0xde, 0xca, - 0x77, 0x55, 0xb1, 0xf1, 0x5e, 0x25, 0x83, 0x61, 0xab, 0x46, 0xd5, 0xa6, 0xbf, 0x30, 0x13, 0x87, - 0xfe, 0xc0, 0x82, 0xfa, 0xee, 0x28, 0x4e, 0x82, 0xa1, 0xf7, 0x65, 0xd2, 0xa8, 0x31, 0xe1, 0xaf, - 0x9e, 0x80, 0xf0, 0xeb, 0x52, 0x06, 0x5f, 0x63, 0xea, 0x11, 0x6b, 0xe9, 0xe8, 0x2d, 0x0b, 0xaa, - 0xbb, 0x71, 0xe0, 0xfb, 0x24, 0x69, 0xd4, 0x99, 0x26, 0xaf, 0x9c, 0x84, 0x26, 0x5c, 0x42, 0x6b, - 0x86, 0x4e, 0xb4, 0x78, 0xc0, 0x52, 0x2e, 0xb3, 0x47, 0xc7, 0x8b, 0x88, 0x9b, 0x04, 0xd1, 0x41, - 0x03, 0x4e, 0xcc, 0x1e, 0xab, 0x52, 0x06, 0xb7, 0x87, 0x7a, 0xc4, 0x5a, 0x3a, 0x7a, 0x03, 0x2a, - 0xe1, 0x60, 0xd4, 0xf3, 0xfc, 0xc6, 0x0c, 0xd3, 0xe3, 0xb7, 0x4e, 0x40, 0x8f, 0x2d, 0x26, 0xa0, - 0x05, 0x74, 0x2f, 0xe1, 0xbf, 0xb1, 0x10, 0x8a, 0x2e, 0x40, 0xd9, 0xed, 0x3b, 0x51, 0xd2, 0x98, - 0x65, 0x8e, 0xac, 0x56, 0xd6, 0x0a, 0x05, 0x62, 0x8e, 0xb3, 0xff, 0xd9, 0x82, 0xc5, 0xe9, 0x83, - 0xe3, 0x4b, 0xcc, 0x1d, 0x45, 0x31, 0xdf, 0x21, 0x6b, 0xe6, 0x12, 0x63, 0x60, 0x2c, 0xf1, 0xe8, - 0xeb, 0x16, 0x54, 0x6f, 0x8b, 0xd9, 0x2f, 0x9c, 0xd8, 0xec, 0x5f, 0x13, 0xb3, 0xaf, 0xf4, 0xb8, - 0x26, 0x3d, 0x40, 0xc8, 0xb6, 0xff, 0xb6, 0x00, 0x67, 0x26, 0xae, 0x1d, 0xd4, 0x04, 0xd8, 0x73, - 0x06, 0x23, 0xf2, 0x82, 0x47, 0x63, 0x55, 0x1e, 0xa4, 0xcf, 0xd3, 0xd3, 0xf9, 0x65, 0x05, 0xc5, - 0x06, 0x05, 0xfa, 0x9a, 0x05, 0x10, 0x3a, 0x91, 0x33, 0x24, 0x09, 0x89, 0xe4, 0x7e, 0x77, 0xe3, - 0xd1, 0x07, 0x45, 0x95, 0xd9, 0x92, 0x7c, 0x75, 0x8c, 0xa0, 0x40, 0x31, 0x36, 0xc4, 0xd2, 0x98, - 0x3c, 0x22, 0x03, 0xe2, 0xc4, 0x84, 0x65, 0xa6, 0x99, 0x98, 0x1c, 0x6b, 0x14, 0x36, 0xe9, 0xe8, - 0x89, 0xc3, 0x86, 0x12, 0x8b, 0x7d, 0x4c, 0x9d, 0x38, 0x6c, 0xb0, 0x31, 0x16, 0x58, 0xfb, 0x6b, - 0x05, 0x68, 0x4c, 0xb3, 0x32, 0xda, 0x87, 0x2a, 0xb9, 0x93, 0xbc, 0xec, 0x44, 0xdc, 0x5c, 0xb9, - 0x04, 0x64, 0x82, 0xf7, 0xcb, 0x4e, 0xa4, 0x27, 0xf1, 0x0a, 0x17, 0x82, 0xa5, 0x34, 0xe4, 0x43, - 0x29, 0x19, 0x38, 0x39, 0x66, 0x75, 0x86, 0x54, 0x7d, 0xc8, 0xaf, 0x2f, 0xc7, 0x98, 0xc9, 0xb1, - 0x7f, 0x68, 0x4d, 0xb0, 0x82, 0xd8, 0x5c, 0xe8, 0x0c, 0x10, 0x7f, 0xcf, 0x8b, 0x02, 0x7f, 0x48, - 0xfc, 0x24, 0x5b, 0x1b, 0xb8, 0xa2, 0x51, 0xd8, 0xa4, 0x43, 0xbf, 0x3f, 0xc9, 0x7d, 0xf0, 0xa3, - 0x0f, 0x45, 0xa8, 0x75, 0x6c, 0x0f, 0xb2, 0xff, 0xa7, 0x30, 0x61, 0x8d, 0xab, 0x1d, 0x1c, 0x5d, - 0x04, 0xa0, 0xf1, 0xc4, 0x56, 0x44, 0xba, 0xde, 0x1d, 0x31, 0x3a, 0xc5, 0x72, 0x53, 0x61, 0xb0, - 0x41, 0x85, 0x2e, 0x41, 0xc5, 0x1b, 0x3a, 0x3d, 0x42, 0xa3, 0x48, 0xba, 0x8c, 0x9e, 0xa1, 0x9e, - 0xb5, 0xc6, 0x20, 0xf7, 0xee, 0x9e, 0x9b, 0x57, 0xcc, 0x19, 0x08, 0x0b, 0x5a, 0xf4, 0xd7, 0x16, - 0xcc, 0xba, 0xc1, 0x70, 0x18, 0xf8, 0xeb, 0xce, 0x0e, 0x19, 0xc8, 0x7c, 0xd1, 0x3f, 0xc9, 0xf3, - 0xaa, 0xb9, 0x62, 0x08, 0xbc, 0xe2, 0x27, 0xd1, 0x81, 0xce, 0x84, 0x4d, 0x14, 0x4e, 0x69, 0xb6, - 0xf8, 0x39, 0x58, 0x18, 0x7b, 0x11, 0x9d, 0x86, 0xe2, 0x2e, 0x39, 0xe0, 0x26, 0xc2, 0xf4, 0x27, - 0x7a, 0x0a, 0xca, 0x6c, 0x1d, 0xf1, 0xc0, 0x02, 0xf3, 0x87, 0x5f, 0x2f, 0x5c, 0xb6, 0xec, 0xbf, - 0xb0, 0xe0, 0x23, 0x53, 0x76, 0x6b, 0x1a, 0x8d, 0xf8, 0xba, 0xca, 0xa4, 0xfc, 0x91, 0x2d, 0x62, - 0x86, 0x41, 0x04, 0x8a, 0xc4, 0xdf, 0x13, 0x3e, 0x73, 0xed, 0xd1, 0xed, 0x73, 0xc5, 0xdf, 0xe3, - 0x63, 0xaf, 0x1e, 0xde, 0x3d, 0x57, 0xbc, 0xe2, 0xef, 0x61, 0xca, 0xdf, 0xfe, 0x61, 0x39, 0x15, - 0x3d, 0xb6, 0x65, 0x82, 0xc0, 0x94, 0x15, 0xb1, 0x63, 0xfb, 0x04, 0x66, 0xc7, 0x88, 0x7f, 0x79, - 0x49, 0x44, 0x88, 0x44, 0x7f, 0x64, 0xb1, 0x0a, 0x84, 0x8c, 0x9b, 0xc5, 0x41, 0x72, 0x72, 0x45, - 0x11, 0xb3, 0xb6, 0x21, 0x81, 0xd8, 0xd4, 0x80, 0x9e, 0x80, 0x21, 0x2f, 0x46, 0x88, 0xad, 0x57, - 0x6d, 0x5a, 0xb2, 0x46, 0x21, 0xf1, 0xe8, 0x75, 0x00, 0x9a, 0x50, 0x6e, 0x05, 0x03, 0xcf, 0x3d, - 0x10, 0xe9, 0x4d, 0x4e, 0x19, 0x2c, 0xe7, 0xc9, 0x4f, 0x2b, 0xfd, 0x8c, 0x0d, 0x79, 0xe8, 0xbb, - 0x16, 0x2c, 0x78, 0x3d, 0x3f, 0x88, 0xc8, 0xaa, 0xd7, 0xed, 0x92, 0x88, 0xf8, 0x34, 0xd5, 0xe7, - 0x95, 0x90, 0x2f, 0x3e, 0xba, 0x16, 0x32, 0x53, 0x5f, 0xcb, 0x8a, 0x68, 0x7d, 0x54, 0x18, 0x64, - 0x61, 0x0c, 0x85, 0xc7, 0x15, 0x42, 0x7d, 0x28, 0x79, 0x7e, 0x37, 0x10, 0x05, 0x91, 0x17, 0x1e, - 0x5d, 0xb1, 0x35, 0xbf, 0x1b, 0xe8, 0x35, 0x44, 0x9f, 0x30, 0x93, 0x60, 0xff, 0x65, 0x3d, 0x9d, - 0x34, 0xf0, 0x14, 0xf4, 0x2d, 0x0b, 0xea, 0x91, 0xaa, 0x84, 0xf0, 0x53, 0x6d, 0x2b, 0x3f, 0xf3, - 0x88, 0x04, 0x58, 0x25, 0x6d, 0xba, 0xe6, 0xa1, 0xa5, 0xd2, 0xd3, 0x8d, 0x4e, 0x9c, 0xf0, 0xee, - 0x9c, 0x5c, 0x44, 0x48, 0xd6, 0x39, 0xff, 0x81, 0x4f, 0x73, 0xfe, 0x03, 0xdf, 0x45, 0x7b, 0x50, - 0xe9, 0x13, 0x67, 0x90, 0xf4, 0x45, 0xce, 0xbf, 0x99, 0x47, 0x0c, 0x43, 0xf9, 0x65, 0xd3, 0x7d, - 0x0e, 0xc5, 0x42, 0x1a, 0x7a, 0x1d, 0xaa, 0x7d, 0x2f, 0x66, 0x91, 0x38, 0xdf, 0xe9, 0x5f, 0xca, - 0xc3, 0xd0, 0x3c, 0xe1, 0xba, 0xca, 0x19, 0xeb, 0xe5, 0x28, 0x00, 0x58, 0x8a, 0x44, 0xdf, 0xb0, - 0x00, 0x5c, 0x99, 0xe8, 0xcb, 0x95, 0xf0, 0x72, 0xae, 0x5b, 0x89, 0xaa, 0x23, 0xe8, 0x03, 0x53, - 0x81, 0x62, 0x6c, 0x48, 0x47, 0x5f, 0x82, 0xd9, 0x88, 0xb8, 0x81, 0xef, 0x7a, 0x03, 0xd2, 0x59, - 0x4e, 0x1a, 0x15, 0x36, 0x11, 0xbf, 0x74, 0xbc, 0xbc, 0x7c, 0xdb, 0x1b, 0x92, 0xd6, 0x69, 0x7a, - 0x62, 0x61, 0x83, 0x07, 0x4e, 0x71, 0x44, 0xef, 0x58, 0x30, 0xaf, 0xea, 0x1d, 0x74, 0x62, 0x88, - 0xc8, 0x45, 0xb7, 0x72, 0xac, 0xb0, 0x30, 0xbe, 0x2d, 0x44, 0xf3, 0xe1, 0x34, 0x0c, 0x67, 0x64, - 0xa3, 0x57, 0x00, 0x82, 0x1d, 0x56, 0xd5, 0xa0, 0xc3, 0xad, 0x3d, 0xf0, 0x70, 0xe7, 0x79, 0xd9, - 0x4c, 0x72, 0xc0, 0x06, 0x37, 0x74, 0x1d, 0x80, 0x2f, 0xa5, 0xed, 0x83, 0x90, 0xb0, 0x54, 0xb3, - 0xde, 0xfa, 0x94, 0x9c, 0x80, 0xb6, 0xc2, 0xdc, 0xbb, 0x7b, 0x6e, 0x3c, 0x13, 0x60, 0x95, 0x1d, - 0xe3, 0x75, 0xf4, 0x55, 0xa8, 0xc6, 0xa3, 0xe1, 0xd0, 0x51, 0xe9, 0xe2, 0x76, 0xbe, 0x07, 0x1e, - 0xe7, 0xad, 0xfd, 0x54, 0x00, 0xb0, 0x94, 0x6a, 0xfb, 0x80, 0xc6, 0xe9, 0xd1, 0x25, 0x98, 0x25, - 0x77, 0x12, 0x12, 0xf9, 0xce, 0xe0, 0x26, 0x5e, 0x97, 0xe9, 0x0a, 0x73, 0x82, 0x2b, 0x06, 0x1c, - 0xa7, 0xa8, 0x90, 0xad, 0xe2, 0xb2, 0x02, 0xa3, 0x07, 0x1d, 0x97, 0xc9, 0x28, 0xcc, 0xfe, 0x76, - 0x21, 0x75, 0xe8, 0x6f, 0x47, 0x84, 0xa0, 0x18, 0xca, 0x7e, 0xd0, 0x51, 0x1b, 0xe2, 0x66, 0x7e, - 0x1b, 0xe2, 0x66, 0xd0, 0x31, 0x4a, 0xf8, 0xf4, 0x29, 0xc6, 0x5c, 0x16, 0xfa, 0x43, 0x0b, 0xe6, - 0x64, 0x21, 0x98, 0x21, 0x44, 0xbc, 0x93, 0xb7, 0xf4, 0x33, 0x42, 0xfa, 0xdc, 0x0d, 0x53, 0x18, - 0x4e, 0xcb, 0xb6, 0x7f, 0x6a, 0xa5, 0xf2, 0xc6, 0x5b, 0x4e, 0xe2, 0xf6, 0xaf, 0xec, 0xd1, 0x40, - 0xfe, 0x7a, 0xaa, 0x46, 0xf8, 0xab, 0x66, 0x8d, 0xf0, 0xde, 0xdd, 0x73, 0x9f, 0x9c, 0x76, 0x05, - 0xb9, 0x4f, 0x39, 0x34, 0x19, 0x0b, 0xa3, 0x9c, 0xf8, 0x7b, 0x16, 0xcc, 0x18, 0x2a, 0x8b, 0x33, - 0x20, 0xe7, 0x2a, 0x9a, 0x0a, 0x6b, 0x0c, 0x20, 0x36, 0xc5, 0xda, 0x7f, 0x5e, 0x84, 0xaa, 0xb8, - 0xe5, 0x38, 0x76, 0x71, 0x52, 0x86, 0xad, 0x85, 0xa9, 0x61, 0xeb, 0x3e, 0x54, 0x5c, 0x76, 0x9f, - 0x2a, 0x0e, 0x9a, 0x1c, 0x92, 0x65, 0xa1, 0x24, 0xbf, 0xa6, 0xd5, 0xaa, 0xf1, 0x67, 0x2c, 0xc4, - 0xa1, 0x6f, 0x5b, 0x70, 0xca, 0xa5, 0x69, 0x91, 0xab, 0x77, 0xbf, 0x52, 0x5e, 0x65, 0xf5, 0x95, - 0x34, 0xe3, 0xd6, 0x47, 0x84, 0x12, 0xa7, 0x32, 0x08, 0x9c, 0x55, 0x01, 0xfd, 0x06, 0xcc, 0x71, - 0xdb, 0xbd, 0x4c, 0x22, 0x56, 0x53, 0x2c, 0x33, 0xd3, 0x29, 0x87, 0x6c, 0x9b, 0x48, 0x9c, 0xa6, - 0xb5, 0xff, 0xb1, 0x08, 0x73, 0xa9, 0xd1, 0xa3, 0x4f, 0x43, 0x6d, 0x14, 0xd3, 0xc5, 0xae, 0x72, - 0x07, 0x55, 0xa8, 0xbd, 0x29, 0xe0, 0x58, 0x51, 0x50, 0xea, 0xd0, 0x89, 0xe3, 0xfd, 0x20, 0xea, - 0x88, 0x29, 0x53, 0xd4, 0x5b, 0x02, 0x8e, 0x15, 0x05, 0x4d, 0x72, 0x77, 0x88, 0x13, 0x91, 0x68, - 0x3b, 0xd8, 0x25, 0x63, 0x57, 0x7f, 0x2d, 0x8d, 0xc2, 0x26, 0x1d, 0x33, 0x7c, 0x32, 0x88, 0x57, - 0x06, 0x1e, 0xf1, 0x13, 0xae, 0x66, 0x7e, 0x86, 0xdf, 0x5e, 0x6f, 0x9b, 0x8c, 0xb5, 0xe1, 0x33, - 0x08, 0x9c, 0x55, 0x01, 0xbd, 0x6d, 0xc1, 0x9c, 0xb3, 0x1f, 0xeb, 0x0b, 0x7e, 0x66, 0xf9, 0x5c, - 0x1c, 0x32, 0xd5, 0x37, 0xd0, 0x5a, 0xa0, 0xd3, 0x98, 0x02, 0xe1, 0xb4, 0x60, 0xfb, 0x47, 0x16, - 0xc8, 0xfe, 0x81, 0xc7, 0x50, 0x9d, 0xf7, 0xd3, 0xd5, 0xf9, 0xb5, 0xdc, 0x16, 0xe0, 0x94, 0xca, - 0xfc, 0x26, 0x54, 0x69, 0x9e, 0xec, 0xf8, 0x1d, 0xf4, 0x71, 0xa8, 0xba, 0xfc, 0xa7, 0x38, 0xac, - 0x58, 0x85, 0x56, 0x60, 0xb1, 0xc4, 0xa1, 0x67, 0xa0, 0xe4, 0x44, 0x3d, 0x79, 0x40, 0xb1, 0x7a, - 0xf6, 0x72, 0xd4, 0x8b, 0x31, 0x83, 0xda, 0x7f, 0x56, 0x00, 0x58, 0x09, 0x86, 0xa1, 0x13, 0x91, - 0xce, 0x76, 0xf0, 0x8b, 0x64, 0x34, 0x95, 0x8c, 0xda, 0xef, 0x58, 0x80, 0xa8, 0x75, 0x02, 0x9f, - 0xf8, 0xba, 0x00, 0x84, 0x96, 0xa0, 0xee, 0x4a, 0xa8, 0xd8, 0x18, 0x54, 0x02, 0xa2, 0xc8, 0xb1, - 0xa6, 0x39, 0xc6, 0x4e, 0x7e, 0x41, 0x16, 0x36, 0x8a, 0xe9, 0xe2, 0x31, 0xab, 0x1e, 0x8a, 0x3a, - 0x87, 0xfd, 0x9d, 0x02, 0x3c, 0xcd, 0xbd, 0x7c, 0xc3, 0xf1, 0x9d, 0x1e, 0x19, 0x52, 0xad, 0x8e, - 0x5b, 0xe2, 0xe8, 0xd1, 0x44, 0xd0, 0x93, 0xb5, 0xe2, 0x3c, 0x1c, 0x95, 0x3b, 0x18, 0x77, 0xa9, - 0x35, 0xdf, 0x4b, 0x30, 0x13, 0x80, 0xf6, 0xa1, 0x26, 0xdb, 0x7f, 0xc4, 0xb1, 0x94, 0xa3, 0x30, - 0xb5, 0x16, 0x5f, 0x14, 0x22, 0xb0, 0x12, 0x66, 0x7f, 0xcf, 0x82, 0xec, 0x11, 0xc1, 0xce, 0x5a, - 0x7e, 0xfd, 0x9a, 0x3d, 0x6b, 0xd3, 0x37, 0xa5, 0xc7, 0xbf, 0x75, 0x44, 0xaf, 0xc2, 0x8c, 0x93, - 0x24, 0x64, 0x18, 0x26, 0x2c, 0xd4, 0x2e, 0x3e, 0x5c, 0xa8, 0xbd, 0x11, 0x74, 0xbc, 0xae, 0xc7, - 0x42, 0x6d, 0x93, 0x9d, 0xfd, 0x12, 0xd4, 0x64, 0xf1, 0xe8, 0x18, 0x93, 0x7a, 0x21, 0x55, 0x0f, - 0x9b, 0xe2, 0x36, 0x0e, 0xcc, 0x9a, 0xe9, 0xe3, 0x09, 0xd8, 0xc4, 0xfe, 0xa6, 0x05, 0x73, 0xa9, - 0x32, 0x7b, 0x4e, 0xba, 0xd3, 0x63, 0xb2, 0x1b, 0xb0, 0x3c, 0x3f, 0xf2, 0x7c, 0x1e, 0xe6, 0xd4, - 0xf4, 0xc2, 0x7d, 0x41, 0xa3, 0xb0, 0x49, 0x67, 0x6f, 0x00, 0xab, 0x4c, 0xe4, 0x65, 0xc1, 0x97, - 0xa0, 0x46, 0xd9, 0xd1, 0x9d, 0x38, 0x2f, 0x96, 0x6d, 0xa8, 0x5d, 0xbb, 0xb5, 0xcd, 0x0f, 0x75, - 0x1b, 0x8a, 0x9e, 0xc3, 0x77, 0x92, 0xa2, 0xf6, 0xf0, 0xb5, 0x38, 0x1e, 0x31, 0xff, 0xa0, 0x48, - 0x74, 0x01, 0x8a, 0xe4, 0x4e, 0xc8, 0x58, 0x16, 0xf5, 0x6e, 0x73, 0xe5, 0x4e, 0xe8, 0x45, 0x24, - 0xa6, 0x44, 0xe4, 0x4e, 0x68, 0x8f, 0x00, 0x74, 0xe1, 0x3d, 0xaf, 0x29, 0x38, 0x0f, 0x25, 0x37, - 0xe8, 0x10, 0x61, 0x7b, 0xc5, 0x66, 0x25, 0xe8, 0x10, 0xcc, 0x30, 0xf6, 0x37, 0x2c, 0x38, 0x9d, - 0xad, 0x92, 0x7f, 0x68, 0x9b, 0xe4, 0x3a, 0x9c, 0x56, 0xc5, 0xe8, 0x1b, 0x21, 0xaf, 0x06, 0x5c, - 0x86, 0xd9, 0x9d, 0x91, 0x37, 0xe8, 0x88, 0x67, 0xa1, 0x8e, 0xaa, 0x4b, 0xb7, 0x0c, 0x1c, 0x4e, - 0x51, 0xda, 0x5f, 0x06, 0xdd, 0xdf, 0x80, 0x86, 0xa2, 0x8e, 0x64, 0xe5, 0x15, 0xdb, 0xb4, 0x0f, - 0x7c, 0x57, 0x77, 0x53, 0xd4, 0xd2, 0x65, 0x24, 0xfb, 0xdd, 0x12, 0x64, 0xb2, 0x7e, 0xf4, 0xba, - 0xd9, 0xd0, 0x61, 0xe5, 0xdf, 0xd0, 0xa1, 0x66, 0x68, 0x52, 0x53, 0x07, 0xfa, 0x2c, 0x94, 0xc3, - 0xbe, 0x13, 0xcb, 0x29, 0x3a, 0x27, 0xed, 0xbf, 0x45, 0x81, 0xf7, 0xcc, 0x1a, 0x05, 0x83, 0x60, - 0x4e, 0x6d, 0xee, 0x23, 0xc5, 0x23, 0xf6, 0xd6, 0xaf, 0x5b, 0xbc, 0xa6, 0x8b, 0x49, 0x3c, 0x1a, - 0x24, 0x22, 0xb2, 0xbd, 0x99, 0xb3, 0xa1, 0x39, 0x73, 0x5d, 0xdc, 0xe5, 0xcf, 0xd8, 0x10, 0x8c, - 0xbe, 0x08, 0xf5, 0x38, 0x71, 0xa2, 0xe4, 0x21, 0x6b, 0x47, 0xca, 0x8c, 0x6d, 0xc9, 0x04, 0x6b, - 0x7e, 0xe8, 0x15, 0x80, 0xae, 0xe7, 0x7b, 0x71, 0x9f, 0x71, 0xaf, 0x3e, 0xdc, 0xf9, 0xf1, 0x82, - 0xe2, 0x80, 0x0d, 0x6e, 0xf6, 0xe7, 0xe1, 0xfc, 0x51, 0x4d, 0x62, 0x34, 0x22, 0xdc, 0x77, 0x22, - 0x5f, 0xdc, 0x30, 0x33, 0xaf, 0xbb, 0xe5, 0x44, 0x3e, 0x66, 0x50, 0xfb, 0xdd, 0x02, 0xcc, 0x18, - 0xed, 0x80, 0xc7, 0xd8, 0x45, 0x32, 0x5d, 0x8c, 0x85, 0x63, 0x76, 0x31, 0x3e, 0x0b, 0xb5, 0x30, - 0x18, 0x78, 0xae, 0xa7, 0x6e, 0xb5, 0x66, 0x59, 0xae, 0x24, 0x60, 0x58, 0x61, 0xd1, 0x57, 0xa0, - 0x7e, 0x7b, 0x3f, 0x61, 0x7b, 0xa5, 0xbc, 0xc3, 0xca, 0xe1, 0x8e, 0x46, 0x6e, 0xbf, 0x7a, 0xb6, - 0x24, 0x24, 0xc6, 0x5a, 0x1e, 0xb2, 0xa1, 0xd2, 0x8b, 0x82, 0x51, 0xc8, 0x2b, 0x9a, 0xa2, 0xc4, - 0xc3, 0x3a, 0x06, 0x63, 0x2c, 0x30, 0xf6, 0x7f, 0x95, 0x01, 0x58, 0x9b, 0xa9, 0xc7, 0x2a, 0xa1, - 0xe7, 0xa1, 0x14, 0x91, 0x30, 0xc8, 0x9a, 0x8c, 0x52, 0x60, 0x86, 0x49, 0x65, 0x96, 0x85, 0x07, - 0xca, 0x2c, 0x8b, 0x47, 0x66, 0x96, 0x34, 0x09, 0x8e, 0xfb, 0x5b, 0x91, 0xb7, 0xe7, 0x24, 0xe4, - 0x3a, 0x39, 0x10, 0x17, 0xd2, 0x3a, 0x09, 0x6e, 0x5f, 0xd5, 0x48, 0x9c, 0xa6, 0x9d, 0x98, 0xd8, - 0x97, 0x3f, 0xfc, 0xc4, 0xbe, 0x0d, 0x67, 0x3c, 0x3f, 0x26, 0xee, 0x28, 0x12, 0x17, 0x22, 0x57, - 0x83, 0x38, 0xa1, 0x63, 0xab, 0x30, 0x1f, 0xfe, 0x98, 0x60, 0x74, 0x66, 0x6d, 0x12, 0x11, 0x9e, - 0xfc, 0x2e, 0x35, 0xab, 0x44, 0xb0, 0x55, 0x58, 0x33, 0xce, 0x5e, 0x01, 0xc7, 0x8a, 0x82, 0x9e, - 0x67, 0xc4, 0x77, 0x76, 0x06, 0x64, 0xbd, 0x1b, 0xb3, 0xfa, 0x6a, 0xcd, 0x38, 0x86, 0x39, 0xe2, - 0x85, 0x36, 0xd6, 0x34, 0xe8, 0x45, 0x58, 0xd0, 0x69, 0x32, 0x89, 0x92, 0x55, 0x9a, 0x81, 0xf2, - 0xe2, 0xa9, 0xba, 0xc2, 0xd1, 0x89, 0xb5, 0x20, 0xc0, 0xe3, 0xef, 0xa0, 0x55, 0x38, 0x9d, 0x02, - 0xd2, 0x71, 0x03, 0xe3, 0xd3, 0x10, 0x7c, 0x4e, 0xa7, 0xf8, 0xd0, 0x21, 0x8f, 0xbd, 0xa1, 0x3a, - 0xef, 0x66, 0xa6, 0x76, 0xde, 0xc9, 0x95, 0x3e, 0x3b, 0x6d, 0xa5, 0xdb, 0x6f, 0x17, 0xe0, 0x8c, - 0xf6, 0x73, 0xca, 0xd9, 0xeb, 0xd2, 0x59, 0x66, 0x97, 0xda, 0xbc, 0x9a, 0x62, 0xb4, 0xf3, 0xab, - 0x1a, 0x7d, 0x5b, 0x61, 0xb0, 0x41, 0x45, 0xed, 0xef, 0x92, 0x88, 0x15, 0xeb, 0xb2, 0x8b, 0x60, - 0x45, 0xc0, 0xb1, 0xa2, 0x60, 0x5f, 0x0c, 0x90, 0x28, 0x69, 0x8f, 0x76, 0xd8, 0x0b, 0x99, 0x82, - 0xc9, 0x8a, 0x46, 0x61, 0x93, 0x8e, 0xee, 0x32, 0xae, 0x34, 0x3e, 0x5d, 0x08, 0xb3, 0x7c, 0x97, - 0x51, 0xf6, 0x56, 0x58, 0xa9, 0x0e, 0x0d, 0xf4, 0x44, 0xdd, 0x28, 0xa5, 0x0e, 0xbb, 0xe9, 0x52, - 0x14, 0xf6, 0xcf, 0x2c, 0xf8, 0xe8, 0x44, 0x53, 0x3c, 0x86, 0xa2, 0xc3, 0xeb, 0xe9, 0xa2, 0xc3, - 0xad, 0x3c, 0xea, 0xb7, 0x13, 0x46, 0x32, 0xa5, 0x04, 0xf1, 0x6f, 0x16, 0xcc, 0x6b, 0xfa, 0xc7, - 0x30, 0xdc, 0x61, 0xee, 0xdf, 0x1c, 0x68, 0xf5, 0x5b, 0xf5, 0xb1, 0xf1, 0xfd, 0x3b, 0x1b, 0x1f, - 0x3f, 0x3b, 0x97, 0x5d, 0xd9, 0xb5, 0x7a, 0xc4, 0x19, 0xf8, 0x06, 0x54, 0x58, 0x07, 0x88, 0x54, - 0xf2, 0x66, 0x7e, 0x35, 0x75, 0xae, 0x03, 0x0b, 0xac, 0x75, 0xaa, 0xc6, 0x1e, 0x63, 0x2c, 0x84, - 0x52, 0xdf, 0xed, 0x78, 0x31, 0xdd, 0x79, 0x3a, 0x22, 0x4e, 0x57, 0x06, 0x5d, 0x15, 0x70, 0xac, - 0x28, 0xec, 0x21, 0x34, 0xd2, 0xcc, 0x57, 0x09, 0x0d, 0x21, 0x8e, 0x39, 0xd4, 0x25, 0xa8, 0x3b, - 0xec, 0xad, 0xf5, 0x91, 0x93, 0xed, 0x99, 0x5d, 0x96, 0x08, 0xac, 0x69, 0xec, 0xbf, 0xb1, 0xe0, - 0xc9, 0x09, 0x83, 0xc9, 0x31, 0x3f, 0x49, 0xf4, 0x8e, 0x30, 0xa5, 0xa5, 0xb8, 0x43, 0xba, 0x8e, - 0x8c, 0x28, 0x8d, 0x00, 0x74, 0x95, 0x83, 0xb1, 0xc4, 0xdb, 0xff, 0x6d, 0xc1, 0xa9, 0xb4, 0xae, - 0x31, 0xba, 0x06, 0x88, 0x0f, 0x66, 0xd5, 0x8b, 0xdd, 0x60, 0x8f, 0x44, 0x07, 0x74, 0xe4, 0x5c, - 0xeb, 0x45, 0xc1, 0x09, 0x2d, 0x8f, 0x51, 0xe0, 0x09, 0x6f, 0xa1, 0x6f, 0xb1, 0x1a, 0x97, 0xb4, - 0xb6, 0xf4, 0x96, 0x57, 0xf2, 0xf6, 0x16, 0x3d, 0xa1, 0x66, 0x20, 0xa6, 0xc4, 0x62, 0x53, 0x07, - 0xfb, 0x07, 0x05, 0x98, 0x95, 0xaf, 0xaf, 0x7a, 0xdd, 0x2e, 0x35, 0x3b, 0x0b, 0x6c, 0xc4, 0x18, - 0x95, 0xd9, 0x59, 0xd4, 0x83, 0x39, 0x8e, 0x9a, 0x7d, 0xd7, 0xf3, 0x3b, 0xd9, 0x74, 0xed, 0xba, - 0xe7, 0x77, 0x30, 0xc3, 0xa4, 0x9b, 0xab, 0x8b, 0x47, 0x37, 0x57, 0x2b, 0x87, 0x28, 0xdd, 0x2f, - 0xd4, 0xe4, 0x7d, 0xc0, 0x3a, 0x32, 0x31, 0x0e, 0x81, 0x6d, 0x8d, 0xc2, 0x26, 0x1d, 0xd5, 0x64, - 0xe0, 0xed, 0x11, 0xfe, 0x52, 0x25, 0xad, 0xc9, 0xba, 0x44, 0x60, 0x4d, 0x43, 0x35, 0xe9, 0x78, - 0xdd, 0x2e, 0x0b, 0x0b, 0x0c, 0x4d, 0xa8, 0x75, 0x30, 0xc3, 0x50, 0x8a, 0x7e, 0x10, 0xec, 0x8a, - 0x48, 0x40, 0x51, 0x5c, 0x0d, 0x82, 0x5d, 0xcc, 0x30, 0xf6, 0x4f, 0xd9, 0x09, 0x31, 0xa5, 0x8b, - 0x23, 0x2f, 0x1b, 0x4b, 0x93, 0x15, 0xef, 0xb7, 0x5c, 0xf5, 0x2c, 0x94, 0x8e, 0x31, 0x0b, 0x97, - 0x60, 0xf6, 0x76, 0x1c, 0xf8, 0x5b, 0x81, 0xe7, 0xb3, 0x46, 0xba, 0xb2, 0xbe, 0x09, 0xbd, 0xd6, - 0xbe, 0xb1, 0x29, 0xe1, 0x38, 0x45, 0x65, 0xbf, 0x5f, 0x86, 0xa7, 0xd5, 0x2d, 0x20, 0x49, 0xf6, - 0x83, 0x68, 0xd7, 0xf3, 0x7b, 0xac, 0x08, 0xf3, 0x5d, 0x0b, 0x66, 0xf9, 0x6c, 0x88, 0x36, 0x34, - 0x7e, 0xe9, 0x79, 0x3b, 0xc7, 0x6b, 0xc7, 0x94, 0xc0, 0xe6, 0xb6, 0x21, 0x2c, 0xd3, 0x82, 0x66, - 0xa2, 0x70, 0x4a, 0x2b, 0xf4, 0x96, 0x05, 0x20, 0x9b, 0xcc, 0xbb, 0x39, 0xb6, 0xdb, 0x4b, 0x25, - 0x31, 0xe9, 0xea, 0x90, 0x68, 0x5b, 0x09, 0xc2, 0x86, 0x50, 0xf4, 0x8e, 0x05, 0x95, 0x01, 0x37, - 0x52, 0x91, 0xc9, 0xef, 0x9c, 0x98, 0x91, 0x4c, 0xf3, 0xa8, 0x63, 0x45, 0x18, 0x46, 0xe8, 0x80, - 0x30, 0x54, 0x3d, 0xbf, 0x17, 0x91, 0x58, 0xa6, 0x5d, 0x9f, 0x34, 0x8e, 0xf5, 0xa6, 0x1b, 0x44, - 0x84, 0x1d, 0xe2, 0x81, 0xd3, 0x69, 0x39, 0x03, 0xc7, 0x77, 0x49, 0xb4, 0xc6, 0xc9, 0xf5, 0x0e, - 0x2b, 0x00, 0x58, 0x32, 0x1a, 0xbb, 0x68, 0x2f, 0x1f, 0xe7, 0xa2, 0x7d, 0xf1, 0x73, 0xb0, 0x30, - 0x36, 0xab, 0x0f, 0xd2, 0x1f, 0xb8, 0xf8, 0x6b, 0x30, 0xf3, 0xb0, 0xad, 0x85, 0xff, 0x57, 0xd6, - 0xfb, 0xe3, 0x66, 0xd0, 0xe1, 0x77, 0xca, 0x91, 0x9e, 0x55, 0x11, 0xf2, 0xe4, 0xec, 0x2a, 0x46, - 0xcb, 0xb1, 0x02, 0x62, 0x53, 0x2c, 0x73, 0xd8, 0xd0, 0x89, 0x88, 0xff, 0x38, 0x1c, 0x76, 0x4b, - 0x09, 0xc2, 0x86, 0x50, 0x34, 0x10, 0xed, 0x65, 0xc5, 0xbc, 0xb2, 0x72, 0x59, 0x67, 0x9d, 0xd4, - 0x62, 0x46, 0xb3, 0xd3, 0x79, 0x3f, 0xe5, 0xc6, 0xa2, 0x44, 0xf4, 0x85, 0x93, 0x5a, 0x26, 0xbc, - 0xf7, 0x26, 0x0d, 0xc3, 0x19, 0x1d, 0xd0, 0x32, 0x9c, 0x92, 0xf3, 0x92, 0xbe, 0x78, 0x56, 0x09, - 0x2e, 0x4e, 0xa3, 0x71, 0x96, 0xde, 0x68, 0x24, 0xa9, 0x4c, 0x6b, 0x24, 0x41, 0x91, 0x6a, 0x2b, - 0xab, 0x9e, 0x48, 0x5b, 0x19, 0x8c, 0xb7, 0x94, 0xd9, 0x7f, 0x67, 0xc1, 0x69, 0xa9, 0xfc, 0x8d, - 0x3d, 0x12, 0x45, 0x5e, 0x87, 0x1d, 0x29, 0x1c, 0xad, 0xe3, 0x20, 0x75, 0xa4, 0x5c, 0x95, 0x08, - 0xac, 0x69, 0x68, 0x2a, 0x3c, 0xde, 0x2a, 0x59, 0x48, 0xa7, 0xc2, 0xc7, 0xea, 0x66, 0x7c, 0x0e, - 0xaa, 0x3c, 0xa8, 0x8a, 0xb3, 0xa5, 0x44, 0x11, 0xac, 0x61, 0x89, 0xa7, 0x91, 0x9c, 0xb9, 0x74, - 0x8e, 0x77, 0xe0, 0x3e, 0x07, 0xd5, 0x3d, 0x31, 0x83, 0x99, 0x2b, 0x0f, 0x39, 0x73, 0x12, 0xaf, - 0xce, 0xe6, 0xe2, 0xf1, 0xe2, 0x9f, 0xd2, 0x03, 0xc4, 0x3f, 0xe5, 0xa9, 0x87, 0xf9, 0xc7, 0xa0, - 0x38, 0xf2, 0x3a, 0x22, 0x84, 0x99, 0x11, 0x04, 0xc5, 0x9b, 0x6b, 0xab, 0x98, 0xc2, 0xed, 0xff, - 0x2c, 0xea, 0xd4, 0x45, 0x54, 0x32, 0x7f, 0x2e, 0x86, 0x7d, 0x49, 0xdd, 0x58, 0xf1, 0x91, 0x3f, - 0x93, 0xbe, 0xb1, 0xba, 0x77, 0xf7, 0x1c, 0xf0, 0xe1, 0xb2, 0x4b, 0x89, 0x09, 0xf7, 0x57, 0xd5, - 0x23, 0xea, 0xce, 0x97, 0xa1, 0x46, 0x63, 0x36, 0x56, 0x59, 0xa8, 0xa5, 0x44, 0xd4, 0xae, 0x0a, - 0xf8, 0x3d, 0xe3, 0x37, 0x56, 0xd4, 0x68, 0x19, 0xea, 0xf4, 0x37, 0x2b, 0x78, 0x8b, 0xea, 0xce, - 0x05, 0xb5, 0x16, 0x24, 0x62, 0x42, 0x6d, 0x5c, 0xbf, 0x45, 0x0d, 0xc6, 0xfa, 0x8a, 0x19, 0x0b, - 0x48, 0x1b, 0xac, 0x2d, 0x11, 0x58, 0xd3, 0xd8, 0x3f, 0x31, 0xa6, 0x59, 0xdc, 0xe9, 0xfd, 0x5c, - 0x4c, 0xf3, 0xe5, 0xcc, 0x34, 0x9f, 0x1f, 0x9b, 0xe6, 0x79, 0xdd, 0x79, 0x9b, 0x9a, 0xea, 0x0f, - 0x61, 0x6b, 0x3c, 0x3a, 0x03, 0xe0, 0xe7, 0xc2, 0x6b, 0x23, 0x2f, 0x22, 0xf1, 0x56, 0x34, 0xf2, - 0x3d, 0xbf, 0xc7, 0x3c, 0xa4, 0x66, 0x9e, 0x0b, 0x29, 0x34, 0xce, 0xd2, 0xdb, 0x7f, 0x5f, 0xa0, - 0xf9, 0x68, 0xaa, 0x05, 0x97, 0x26, 0xfb, 0x91, 0xfc, 0x68, 0x32, 0x53, 0x37, 0x53, 0x9f, 0x4b, - 0x2a, 0x0a, 0xf4, 0xdb, 0x00, 0x1d, 0x12, 0x0e, 0x82, 0x03, 0x76, 0xdb, 0x50, 0x7a, 0xe0, 0xdb, - 0x06, 0x15, 0x01, 0xac, 0x2a, 0x2e, 0xd8, 0xe0, 0x88, 0x16, 0xa1, 0xe0, 0x75, 0xd8, 0xa4, 0x16, - 0x5b, 0x20, 0x68, 0x0b, 0x6b, 0xab, 0xb8, 0xe0, 0x75, 0x8c, 0x76, 0x92, 0xca, 0x63, 0x6f, 0x27, - 0xb1, 0xff, 0x85, 0x1d, 0x5d, 0xdc, 0x0a, 0x1b, 0xb2, 0x96, 0xf4, 0x09, 0xa8, 0x38, 0xa3, 0xa4, - 0x1f, 0x8c, 0xf5, 0xde, 0x2d, 0x33, 0x28, 0x16, 0x58, 0xb4, 0x0e, 0xa5, 0x0e, 0x4d, 0x16, 0x0b, - 0x0f, 0x6c, 0x2f, 0x9d, 0x2c, 0xd2, 0x9c, 0x92, 0x71, 0x41, 0xcf, 0x40, 0x29, 0x71, 0x7a, 0xf2, - 0x9a, 0x83, 0xdd, 0xb8, 0x6c, 0x3b, 0xbd, 0x18, 0x33, 0xa8, 0xb9, 0x4f, 0x95, 0x8e, 0xb8, 0x67, - 0xff, 0x5e, 0x09, 0xe6, 0x52, 0x77, 0x59, 0x29, 0x67, 0xb0, 0x8e, 0x74, 0x86, 0x0b, 0x50, 0x0e, - 0xa3, 0x91, 0xcf, 0xc7, 0x55, 0xd3, 0xdb, 0x04, 0x75, 0x37, 0x82, 0x39, 0x8e, 0xda, 0xa8, 0x13, - 0x1d, 0xe0, 0x91, 0x2f, 0x4a, 0x49, 0xca, 0x46, 0xab, 0x0c, 0x8a, 0x05, 0x96, 0x86, 0xc1, 0xb3, - 0x31, 0x5b, 0x8f, 0x91, 0x93, 0x90, 0x9e, 0xfc, 0x04, 0x63, 0x33, 0xaf, 0xfe, 0x7a, 0xce, 0x95, - 0xa7, 0x06, 0x26, 0x04, 0xa7, 0xa4, 0xa2, 0xb7, 0x53, 0x5f, 0x18, 0x54, 0xf2, 0x2a, 0x89, 0x66, - 0xaf, 0x0c, 0xb9, 0xb3, 0xdd, 0xff, 0x43, 0x83, 0x7d, 0xe5, 0xef, 0xd5, 0x93, 0xf3, 0x77, 0x98, - 0xd0, 0x3a, 0xf5, 0x29, 0xa8, 0x0f, 0x1d, 0xdf, 0xeb, 0x92, 0x38, 0xe1, 0xff, 0xe5, 0x50, 0xe7, - 0xdf, 0xc9, 0x6e, 0x48, 0x20, 0xd6, 0x78, 0xfb, 0x4d, 0x0b, 0xce, 0x4c, 0x1c, 0xdd, 0x63, 0x2b, - 0x4a, 0xd8, 0xff, 0x50, 0x80, 0x27, 0x27, 0xdc, 0xc9, 0xa2, 0x37, 0x4e, 0xf4, 0x63, 0x11, 0x71, - 0xf1, 0x3b, 0x37, 0x75, 0xfe, 0x1e, 0x6c, 0x67, 0xd5, 0xbb, 0x5b, 0xf1, 0xf1, 0xef, 0x6e, 0xdf, - 0xb2, 0xc0, 0xf8, 0x32, 0x09, 0xfd, 0xae, 0x05, 0x75, 0x67, 0x94, 0x04, 0x43, 0x27, 0x21, 0x1d, - 0x91, 0x90, 0xde, 0xcc, 0xf3, 0x5b, 0xa8, 0x65, 0xc9, 0x9c, 0x9b, 0x4f, 0x3d, 0x62, 0x2d, 0xd6, - 0xee, 0xf3, 0x49, 0xcd, 0xbc, 0xa0, 0x37, 0x1d, 0xeb, 0x3e, 0x9b, 0xce, 0xa7, 0xa1, 0x16, 0x93, - 0x41, 0x97, 0x9e, 0xb1, 0x62, 0x73, 0x52, 0xa6, 0x6f, 0x0b, 0x38, 0x56, 0x14, 0xf6, 0xcf, 0xc4, - 0xe8, 0x45, 0xf4, 0x73, 0x39, 0xd3, 0xd1, 0x74, 0xfc, 0xc0, 0xe1, 0x4d, 0xf6, 0xd1, 0x8a, 0xec, - 0x7f, 0xcc, 0xef, 0x0b, 0x21, 0xdd, 0x53, 0x69, 0x7e, 0xaa, 0x22, 0x61, 0xd8, 0x90, 0x99, 0x72, - 0xba, 0xe2, 0x51, 0x4e, 0x67, 0xff, 0xaf, 0x05, 0xa9, 0xcd, 0x10, 0x25, 0x50, 0xa6, 0x1a, 0x1c, - 0xe4, 0xd7, 0xb1, 0x69, 0xb2, 0xa7, 0x0e, 0x29, 0x2e, 0x49, 0xd8, 0x4f, 0xcc, 0x85, 0xa1, 0x50, - 0x04, 0x3f, 0xdc, 0x60, 0x38, 0x5f, 0xa1, 0x34, 0x84, 0x12, 0xff, 0xbc, 0xa0, 0xcb, 0xa9, 0x97, - 0x61, 0x61, 0x4c, 0x31, 0xea, 0x5a, 0xac, 0xed, 0x2b, 0xeb, 0x5a, 0xac, 0x31, 0x0c, 0x73, 0x9c, - 0xfd, 0xae, 0x05, 0xa7, 0xb3, 0xec, 0xd1, 0x77, 0x2c, 0x58, 0x88, 0xb3, 0xfc, 0x4e, 0xd2, 0x86, - 0x2a, 0xd1, 0x1d, 0x43, 0xe1, 0x71, 0x45, 0xec, 0x7f, 0x2a, 0x70, 0x07, 0xe7, 0xff, 0x96, 0xa3, - 0xf6, 0x5c, 0x6b, 0xea, 0x9e, 0x4b, 0xd7, 0x8f, 0xdb, 0x27, 0x9d, 0xd1, 0x60, 0xec, 0x32, 0xb5, - 0x2d, 0xe0, 0x58, 0x51, 0xb0, 0xfb, 0xa2, 0x91, 0x68, 0x23, 0xca, 0xf8, 0xdc, 0xaa, 0x80, 0x63, - 0x45, 0x81, 0x2e, 0xc1, 0xac, 0x31, 0x48, 0x5e, 0x0b, 0x14, 0x25, 0x3b, 0x63, 0xc3, 0x8a, 0x71, - 0x8a, 0x0a, 0x35, 0xf9, 0x77, 0xce, 0x2c, 0xf8, 0x97, 0x65, 0xbe, 0x79, 0xf9, 0x8d, 0x33, 0x87, - 0x62, 0x83, 0x82, 0xdd, 0xd4, 0xf2, 0xde, 0x67, 0x59, 0x04, 0xe1, 0x37, 0xb5, 0x02, 0x86, 0x15, - 0x16, 0x5d, 0x04, 0x18, 0x3a, 0xfe, 0xc8, 0x19, 0x50, 0x0b, 0x89, 0xab, 0x7b, 0xb5, 0xca, 0x36, - 0x14, 0x06, 0x1b, 0x54, 0xf6, 0x4f, 0x2c, 0xc8, 0xb6, 0xb1, 0xa7, 0x1a, 0x00, 0xac, 0x23, 0x1b, - 0x00, 0xd2, 0x57, 0xdc, 0x85, 0x63, 0x5d, 0x71, 0x9b, 0xb7, 0xcf, 0xc5, 0xfb, 0xde, 0x3e, 0x7f, - 0x1c, 0xaa, 0xbb, 0xe4, 0xc0, 0xb8, 0xa6, 0xe6, 0xff, 0xb7, 0xc1, 0x41, 0x58, 0xe2, 0x90, 0x0d, - 0x15, 0xd7, 0x61, 0x54, 0x65, 0x46, 0xc5, 0x82, 0x81, 0x95, 0x65, 0x46, 0x24, 0x30, 0xad, 0xe6, - 0x7b, 0x1f, 0x9c, 0x7d, 0xe2, 0xfb, 0x1f, 0x9c, 0x7d, 0xe2, 0xfd, 0x0f, 0xce, 0x3e, 0xf1, 0xe6, - 0xe1, 0x59, 0xeb, 0xbd, 0xc3, 0xb3, 0xd6, 0xf7, 0x0f, 0xcf, 0x5a, 0xef, 0x1f, 0x9e, 0xb5, 0xfe, - 0xe3, 0xf0, 0xac, 0xf5, 0xc7, 0x3f, 0x3e, 0xfb, 0xc4, 0x2b, 0x35, 0xe9, 0xab, 0xff, 0x1f, 0x00, - 0x00, 0xff, 0xff, 0x3c, 0xb5, 0xd5, 0x0a, 0x23, 0x51, 0x00, 0x00, -} diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto deleted file mode 100644 index 5280bf00d..000000000 --- a/pkg/apis/application/v1alpha1/generated.proto +++ /dev/null @@ -1,901 +0,0 @@ - -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -syntax = 'proto2'; - -package github.com.argoproj.argo_cd.engine.pkg.apis.application.v1alpha1; - -import "k8s.io/api/core/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; - -// Package-wide variables from generator "generated". -option go_package = "v1alpha1"; - -// AWSAuthConfig is an AWS IAM authentication configuration -message AWSAuthConfig { - // ClusterName contains AWS cluster name - optional string clusterName = 1; - - // RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain. - optional string roleARN = 2; -} - -// AppProject provides a logical grouping of applications, providing controls for: -// * where the apps may deploy to (cluster whitelist) -// * what may be deployed (repository whitelist, resource whitelist/blacklist) -// * who can access these applications (roles, OIDC group claims bindings) -// * and what they can do (RBAC policies) -// * automation access to these roles (JWT tokens) -// +genclient -// +genclient:noStatus -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:resource:path=appprojects,shortName=appproj;appprojs -message AppProject { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - optional AppProjectSpec spec = 2; -} - -// AppProjectList is list of AppProject resources -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -message AppProjectList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - repeated AppProject items = 2; -} - -// AppProjectSpec is the specification of an AppProject -message AppProjectSpec { - // SourceRepos contains list of repository URLs which can be used for deployment - repeated string sourceRepos = 1; - - // Destinations contains list of destinations available for deployment - repeated ApplicationDestination destinations = 2; - - // Description contains optional project description - optional string description = 3; - - // Roles are user defined RBAC roles associated with this project - repeated ProjectRole roles = 4; - - // ClusterResourceWhitelist contains list of whitelisted cluster level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind clusterResourceWhitelist = 5; - - // NamespaceResourceBlacklist contains list of blacklisted namespace level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind namespaceResourceBlacklist = 6; - - // OrphanedResources specifies if controller should monitor orphaned resources of apps in this project - optional OrphanedResourcesMonitorSettings orphanedResources = 7; - - // SyncWindows controls when syncs can be run for apps in this project - repeated SyncWindow syncWindows = 8; -} - -// Application is a definition of Application resource. -// +genclient -// +genclient:noStatus -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:resource:path=applications,shortName=app;apps -message Application { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - optional ApplicationSpec spec = 2; - - optional ApplicationStatus status = 3; - - optional Operation operation = 4; -} - -// ApplicationCondition contains details about current application condition -message ApplicationCondition { - // Type is an application condition type - optional string type = 1; - - // Message contains human-readable message indicating details about condition - optional string message = 2; -} - -// ApplicationDestination contains deployment destination information -message ApplicationDestination { - // Server overrides the environment server value in the ksonnet app.yaml - optional string server = 1; - - // Namespace overrides the environment namespace value in the ksonnet app.yaml - optional string namespace = 2; -} - -// ApplicationList is list of Application resources -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -message ApplicationList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - repeated Application items = 2; -} - -// ApplicationSource contains information about github repository, path within repository and target application environment. -message ApplicationSource { - // RepoURL is the repository URL of the application manifests - optional string repoURL = 1; - - // Path is a directory path within the Git repository - optional string path = 2; - - // TargetRevision defines the commit, tag, or branch in which to sync the application to. - // If omitted, will sync to HEAD - optional string targetRevision = 4; - - // Helm holds helm specific options - optional ApplicationSourceHelm helm = 7; - - // Kustomize holds kustomize specific options - optional ApplicationSourceKustomize kustomize = 8; - - // Ksonnet holds ksonnet specific options - optional ApplicationSourceKsonnet ksonnet = 9; - - // Directory holds path/directory specific options - optional ApplicationSourceDirectory directory = 10; - - // ConfigManagementPlugin holds config management plugin specific options - optional ApplicationSourcePlugin plugin = 11; - - // Chart is a Helm chart name - optional string chart = 12; -} - -message ApplicationSourceDirectory { - optional bool recurse = 1; - - optional ApplicationSourceJsonnet jsonnet = 2; -} - -// ApplicationSourceHelm holds helm specific options -message ApplicationSourceHelm { - // ValuesFiles is a list of Helm value files to use when generating a template - repeated string valueFiles = 1; - - // Parameters are parameters to the helm template - repeated HelmParameter parameters = 2; - - // The Helm release name. If omitted it will use the application name - optional string releaseName = 3; - - // Values is Helm values, typically defined as a block - optional string values = 4; -} - -// ApplicationSourceJsonnet holds jsonnet specific options -message ApplicationSourceJsonnet { - // ExtVars is a list of Jsonnet External Variables - repeated JsonnetVar extVars = 1; - - // TLAS is a list of Jsonnet Top-level Arguments - repeated JsonnetVar tlas = 2; -} - -// ApplicationSourceKsonnet holds ksonnet specific options -message ApplicationSourceKsonnet { - // Environment is a ksonnet application environment name - optional string environment = 1; - - // Parameters are a list of ksonnet component parameter override values - repeated KsonnetParameter parameters = 2; -} - -// ApplicationSourceKustomize holds kustomize specific options -message ApplicationSourceKustomize { - // NamePrefix is a prefix appended to resources for kustomize apps - optional string namePrefix = 1; - - // Images are kustomize image overrides - repeated string images = 3; - - // CommonLabels adds additional kustomize commonLabels - map commonLabels = 4; -} - -// ApplicationSourcePlugin holds config management plugin specific options -message ApplicationSourcePlugin { - optional string name = 1; - - repeated EnvEntry env = 2; -} - -// ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision. -message ApplicationSpec { - // Source is a reference to the location ksonnet application definition - optional ApplicationSource source = 1; - - // Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml - optional ApplicationDestination destination = 2; - - // Project is a application project name. Empty name means that application belongs to 'default' project. - optional string project = 3; - - // SyncPolicy controls when a sync will be performed - optional SyncPolicy syncPolicy = 4; - - // IgnoreDifferences controls resources fields which should be ignored during comparison - repeated ResourceIgnoreDifferences ignoreDifferences = 5; - - // Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application - repeated Info info = 6; -} - -// ApplicationStatus contains information about application sync, health status -message ApplicationStatus { - repeated ResourceStatus resources = 1; - - optional SyncStatus sync = 2; - - optional HealthStatus health = 3; - - repeated RevisionHistory history = 4; - - repeated ApplicationCondition conditions = 5; - - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time reconciledAt = 6; - - optional OperationState operationState = 7; - - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time observedAt = 8; - - optional string sourceType = 9; - - optional ApplicationSummary summary = 10; -} - -message ApplicationSummary { - // ExternalURLs holds all external URLs of application child resources. - repeated string externalURLs = 1; - - // Images holds all images of application child resources. - repeated string images = 2; -} - -// ApplicationTree holds nodes which belongs to the application -message ApplicationTree { - // Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes. - repeated ResourceNode nodes = 1; - - // OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project. - repeated ResourceNode orphanedNodes = 2; -} - -// ApplicationWatchEvent contains information about application change. -message ApplicationWatchEvent { - optional string type = 1; - - // Application is: - // * If Type is Added or Modified: the new state of the object. - // * If Type is Deleted: the state of the object immediately before deletion. - // * If Type is Error: *api.Status is recommended; other types may make sense - // depending on context. - optional Application application = 2; -} - -// Cluster is the definition of a cluster resource -message Cluster { - // Server is the API server URL of the Kubernetes cluster - optional string server = 1; - - // Name of the cluster. If omitted, will use the server address - optional string name = 2; - - // Config holds cluster information for connecting to a cluster - optional ClusterConfig config = 3; - - // ConnectionState contains information about cluster connection state - optional ConnectionState connectionState = 4; - - // The server version - optional string serverVersion = 5; -} - -// ClusterConfig is the configuration attributes. This structure is subset of the go-client -// rest.Config with annotations added for marshalling. -message ClusterConfig { - // Server requires Basic authentication - optional string username = 1; - - optional string password = 2; - - // Server requires Bearer authentication. This client will not attempt to use - // refresh tokens for an OAuth2 flow. - // TODO: demonstrate an OAuth2 compatible client. - optional string bearerToken = 3; - - // TLSClientConfig contains settings to enable transport layer security - optional TLSClientConfig tlsClientConfig = 4; - - // AWSAuthConfig contains IAM authentication configuration - optional AWSAuthConfig awsAuthConfig = 5; -} - -// ClusterList is a collection of Clusters. -message ClusterList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - repeated Cluster items = 2; -} - -// Command holds binary path and arguments list -message Command { - repeated string command = 1; - - repeated string args = 2; -} - -// ComparedTo contains application source and target which was used for resources comparison -message ComparedTo { - optional ApplicationSource source = 1; - - optional ApplicationDestination destination = 2; -} - -// ComponentParameter contains information about component parameter value -message ComponentParameter { - optional string component = 1; - - optional string name = 2; - - optional string value = 3; -} - -// ConfigManagementPlugin contains config management plugin configuration -message ConfigManagementPlugin { - optional string name = 1; - - optional Command init = 2; - - optional Command generate = 3; -} - -// ConnectionState contains information about remote resource connection state -message ConnectionState { - optional string status = 1; - - optional string message = 2; - - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time attemptedAt = 3; -} - -message EnvEntry { - // the name, usually uppercase - optional string name = 1; - - // the value - optional string value = 2; -} - -message HealthStatus { - optional string status = 1; - - optional string message = 2; -} - -// HelmParameter is a parameter to a helm template -message HelmParameter { - // Name is the name of the helm parameter - optional string name = 1; - - // Value is the value for the helm parameter - optional string value = 2; - - // ForceString determines whether to tell Helm to interpret booleans and numbers as strings - optional bool forceString = 3; -} - -message Info { - optional string name = 1; - - optional string value = 2; -} - -// InfoItem contains human readable information about object -message InfoItem { - // Name is a human readable title for this piece of information. - optional string name = 1; - - // Value is human readable content. - optional string value = 2; -} - -// JWTToken holds the issuedAt and expiresAt values of a token -message JWTToken { - optional int64 iat = 1; - - optional int64 exp = 2; -} - -// JsonnetVar is a jsonnet variable -message JsonnetVar { - optional string name = 1; - - optional string value = 2; - - optional bool code = 3; -} - -// KsonnetParameter is a ksonnet component parameter -message KsonnetParameter { - optional string component = 1; - - optional string name = 2; - - optional string value = 3; -} - -// KustomizeOptions are options for kustomize to use when building manifests -message KustomizeOptions { - // BuildOptions is a string of build parameters to use when calling `kustomize build` - optional string buildOptions = 1; -} - -// Operation contains requested operation parameters. -message Operation { - optional SyncOperation sync = 1; -} - -// OperationState contains information about state of currently performing operation on application. -message OperationState { - // Operation is the original requested operation - optional Operation operation = 1; - - // Phase is the current phase of the operation - optional string phase = 2; - - // Message hold any pertinent messages when attempting to perform operation (typically errors). - optional string message = 3; - - // SyncResult is the result of a Sync operation - optional SyncOperationResult syncResult = 4; - - // StartedAt contains time of operation start - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 6; - - // FinishedAt contains time of operation completion - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 7; -} - -// OrphanedResourcesMonitorSettings holds settings of orphaned resources monitoring -message OrphanedResourcesMonitorSettings { - // Warn indicates if warning condition should be created for apps which have orphaned resources - optional bool warn = 1; -} - -// ProjectRole represents a role that has access to a project -message ProjectRole { - // Name is a name for this role - optional string name = 1; - - // Description is a description of the role - optional string description = 2; - - // Policies Stores a list of casbin formated strings that define access policies for the role in the project - repeated string policies = 3; - - // JWTTokens are a list of generated JWT tokens bound to this role - repeated JWTToken jwtTokens = 4; - - // Groups are a list of OIDC group claims bound to this role - repeated string groups = 5; -} - -// Repository is a repository holding application configurations -message Repository { - // URL of the repo - optional string repo = 1; - - // Username for authenticating at the repo server - optional string username = 2; - - // Password for authenticating at the repo server - optional string password = 3; - - // SSH private key data for authenticating at the repo server - // only for Git repos - optional string sshPrivateKey = 4; - - // Current state of repository server connecting - optional ConnectionState connectionState = 5; - - // InsecureIgnoreHostKey should not be used anymore, Insecure is favoured - // only for Git repos - optional bool insecureIgnoreHostKey = 6; - - // Whether the repo is insecure - optional bool insecure = 7; - - // Whether git-lfs support should be enabled for this repo - optional bool enableLfs = 8; - - // TLS client cert data for authenticating at the repo server - optional string tlsClientCertData = 9; - - // TLS client cert key for authenticating at the repo server - optional string tlsClientCertKey = 10; - - // type of the repo, maybe "git or "helm, "git" is assumed if empty or absent - optional string type = 11; - - // only for Helm repos - optional string name = 12; -} - -// A RepositoryCertificate is either SSH known hosts entry or TLS certificate -message RepositoryCertificate { - // Name of the server the certificate is intended for - optional string serverName = 1; - - // Type of certificate - currently "https" or "ssh" - optional string certType = 2; - - // The sub type of the cert, i.e. "ssh-rsa" - optional string certSubType = 3; - - // Actual certificate data, protocol dependent - optional bytes certData = 4; - - // Additional certificate info (e.g. SSH fingerprint, X509 CommonName) - optional string certInfo = 5; -} - -// RepositoryCertificateList is a collection of RepositoryCertificates -message RepositoryCertificateList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // List of certificates to be processed - repeated RepositoryCertificate items = 2; -} - -// RepositoryList is a collection of Repositories. -message RepositoryList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - repeated Repository items = 2; -} - -message ResourceAction { - optional string name = 1; - - repeated ResourceActionParam params = 2; - - optional bool disabled = 3; -} - -message ResourceActionDefinition { - optional string name = 1; - - optional string actionLua = 2; -} - -message ResourceActionParam { - optional string name = 1; - - optional string value = 2; - - optional string type = 3; - - optional string default = 4; -} - -message ResourceActions { - optional string actionDiscoveryLua = 1; - - repeated ResourceActionDefinition definitions = 2; -} - -// ResourceDiff holds the diff of a live and target resource object -message ResourceDiff { - optional string group = 1; - - optional string kind = 2; - - optional string namespace = 3; - - optional string name = 4; - - optional string targetState = 5; - - optional string liveState = 6; - - optional string diff = 7; - - optional bool hook = 8; -} - -// ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state. -message ResourceIgnoreDifferences { - optional string group = 1; - - optional string kind = 2; - - optional string name = 3; - - optional string namespace = 4; - - repeated string jsonPointers = 5; -} - -// ResourceNetworkingInfo holds networking resource related information -message ResourceNetworkingInfo { - map targetLabels = 1; - - repeated ResourceRef targetRefs = 2; - - map labels = 3; - - repeated k8s.io.api.core.v1.LoadBalancerIngress ingress = 4; - - // ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames. - repeated string externalURLs = 5; -} - -// ResourceNode contains information about live resource and its children -message ResourceNode { - optional ResourceRef resourceRef = 1; - - repeated ResourceRef parentRefs = 2; - - repeated InfoItem info = 3; - - optional ResourceNetworkingInfo networkingInfo = 4; - - optional string resourceVersion = 5; - - repeated string images = 6; - - optional HealthStatus health = 7; -} - -// ResourceOverride holds configuration to customize resource diffing and health assessment -message ResourceOverride { - optional string healthLua = 1; - - optional string actions = 3; - - optional string ignoreDifferences = 2; -} - -// ResourceRef includes fields which unique identify resource -message ResourceRef { - optional string group = 1; - - optional string version = 2; - - optional string kind = 3; - - optional string namespace = 4; - - optional string name = 5; - - optional string uid = 6; -} - -// ResourceResult holds the operation result details of a specific resource -message ResourceResult { - optional string group = 1; - - optional string version = 2; - - optional string kind = 3; - - optional string namespace = 4; - - optional string name = 5; - - // the final result of the sync, this is be empty if the resources is yet to be applied/pruned and is always zero-value for hooks - optional string status = 6; - - // message for the last sync OR operation - optional string message = 7; - - // the type of the hook, empty for non-hook resources - optional string hookType = 8; - - // the state of any operation associated with this resource OR hook - // note: can contain values for non-hook resources - optional string hookPhase = 9; - - // indicates the particular phase of the sync that this is for - optional string syncPhase = 10; -} - -// ResourceStatus holds the current sync and health status of a resource -message ResourceStatus { - optional string group = 1; - - optional string version = 2; - - optional string kind = 3; - - optional string namespace = 4; - - optional string name = 5; - - optional string status = 6; - - optional HealthStatus health = 7; - - optional bool hook = 8; - - optional bool requiresPruning = 9; -} - -// RevisionHistory contains information relevant to an application deployment -message RevisionHistory { - optional string revision = 2; - - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time deployedAt = 4; - - optional int64 id = 5; - - optional ApplicationSource source = 6; -} - -// data about a specific revision within a repo -message RevisionMetadata { - // who authored this revision, - // typically their name and email, e.g. "John Doe ", - // but might not match this example - optional string author = 1; - - // when the revision was authored - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time date = 2; - - // tags on the revision, - // note - tags can move from one revision to another - repeated string tags = 3; - - // the message associated with the revision, - // probably the commit message, - // this is truncated to the first newline or 64 characters (which ever comes first) - optional string message = 4; -} - -// SyncOperation contains sync operation details. -message SyncOperation { - // Revision is the revision in which to sync the application to. - // If omitted, will use the revision specified in app spec. - optional string revision = 1; - - // Prune deletes resources that are no longer tracked in git - optional bool prune = 2; - - // DryRun will perform a `kubectl apply --dry-run` without actually performing the sync - optional bool dryRun = 3; - - // SyncStrategy describes how to perform the sync - optional SyncStrategy syncStrategy = 4; - - // Resources describes which resources to sync - repeated SyncOperationResource resources = 6; - - // Source overrides the source definition set in the application. - // This is typically set in a Rollback operation and nil during a Sync operation - optional ApplicationSource source = 7; - - // Manifests is an optional field that overrides sync source with a local directory for development - repeated string manifests = 8; -} - -// SyncOperationResource contains resources to sync. -message SyncOperationResource { - optional string group = 1; - - optional string kind = 2; - - optional string name = 3; -} - -// SyncOperationResult represent result of sync operation -message SyncOperationResult { - // Resources holds the sync result of each individual resource - repeated ResourceResult resources = 1; - - // Revision holds the revision of the sync - optional string revision = 2; - - // Source records the application source information of the sync, used for comparing auto-sync - optional ApplicationSource source = 3; -} - -// SyncPolicy controls when a sync will be performed in response to updates in git -message SyncPolicy { - // Automated will keep an application synced to the target revision - optional SyncPolicyAutomated automated = 1; -} - -// SyncPolicyAutomated controls the behavior of an automated sync -message SyncPolicyAutomated { - // Prune will prune resources automatically as part of automated sync (default: false) - optional bool prune = 1; - - // SelfHeal enables auto-syncing if (default: false) - optional bool selfHeal = 2; -} - -// SyncStatus is a comparison result of application spec and deployed application. -message SyncStatus { - optional string status = 1; - - optional ComparedTo comparedTo = 2; - - optional string revision = 3; -} - -// SyncStrategy controls the manner in which a sync is performed -message SyncStrategy { - // Apply wil perform a `kubectl apply` to perform the sync. - optional SyncStrategyApply apply = 1; - - // Hook will submit any referenced resources to perform the sync. This is the default strategy - optional SyncStrategyHook hook = 2; -} - -// SyncStrategyApply uses `kubectl apply` to perform the apply -message SyncStrategyApply { - // Force indicates whether or not to supply the --force flag to `kubectl apply`. - // The --force flag deletes and re-create the resource, when PATCH encounters conflict and has - // retried for 5 times. - optional bool force = 1; -} - -// SyncStrategyHook will perform a sync using hooks annotations. -// If no hook annotation is specified falls back to `kubectl apply`. -message SyncStrategyHook { - // Embed SyncStrategyApply type to inherit any `apply` options - // +optional - optional SyncStrategyApply syncStrategyApply = 1; -} - -// SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps -message SyncWindow { - // Kind defines if the window allows or blocks syncs - optional string kind = 1; - - // Schedule is the time the window will begin, specified in cron format - optional string schedule = 2; - - // Duration is the amount of time the sync window will be open - optional string duration = 3; - - // Applications contains a list of applications that the window will apply to - repeated string applications = 4; - - // Namespaces contains a list of namespaces that the window will apply to - repeated string namespaces = 5; - - // Clusters contains a list of clusters that the window will apply to - repeated string clusters = 6; - - // ManualSync enables manual syncs when they would otherwise be blocked - optional bool manualSync = 7; -} - -// TLSClientConfig contains settings to enable transport layer security -message TLSClientConfig { - // Server should be accessed without verifying the TLS certificate. For testing only. - optional bool insecure = 1; - - // ServerName is passed to the server for SNI and is used in the client to check server - // certificates against. If ServerName is empty, the hostname used to contact the - // server is used. - optional string serverName = 2; - - // CertData holds PEM-encoded bytes (typically read from a client certificate file). - // CertData takes precedence over CertFile - optional bytes certData = 3; - - // KeyData holds PEM-encoded bytes (typically read from a client certificate key file). - // KeyData takes precedence over KeyFile - optional bytes keyData = 4; - - // CAData holds PEM-encoded bytes (typically read from a root certificates bundle). - // CAData takes precedence over CAFile - optional bytes caData = 5; -} - diff --git a/pkg/apis/application/v1alpha1/hack.go b/pkg/apis/application/v1alpha1/hack.go deleted file mode 100644 index d22cb30b1..000000000 --- a/pkg/apis/application/v1alpha1/hack.go +++ /dev/null @@ -1,19 +0,0 @@ -package v1alpha1 - -// objectMeta and corresponding GetMetadata() methods is a hack to allow us to use grpc-gateway -// side-by-side with k8s protobuf codegen. The grpc-gateway generated .gw.pb.go files expect a -// GetMetadata() method to be generated because it assumes the .proto files were generated from -// protoc --go_out=plugins=grpc. Instead, kubernetes uses go-to-protobuf to generate .proto files -// from go types, and this method is not auto-generated (presumably since ObjectMeta is embedded but -// is nested in the 'metadata' field in JSON form). -type objectMeta struct { - Name *string -} - -func (a *Application) GetMetadata() *objectMeta { - var om objectMeta - if a != nil { - om.Name = &a.Name - } - return &om -} diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go deleted file mode 100644 index d5540f5cb..000000000 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ /dev/null @@ -1,3150 +0,0 @@ -// +build !ignore_autogenerated - -// Code generated by openapi-gen. DO NOT EDIT. - -// This file was autogenerated by openapi-gen. Do not edit it manually! - -package v1alpha1 - -import ( - spec "github.com/go-openapi/spec" - common "k8s.io/kube-openapi/pkg/common" -) - -func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - return map[string]common.OpenAPIDefinition{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AWSAuthConfig": schema_pkg_apis_application_v1alpha1_AWSAuthConfig(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProject": schema_pkg_apis_application_v1alpha1_AppProject(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProjectList": schema_pkg_apis_application_v1alpha1_AppProjectList(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProjectSpec": schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Application": schema_pkg_apis_application_v1alpha1_Application(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationCondition": schema_pkg_apis_application_v1alpha1_ApplicationCondition(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination": schema_pkg_apis_application_v1alpha1_ApplicationDestination(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationList": schema_pkg_apis_application_v1alpha1_ApplicationList(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource": schema_pkg_apis_application_v1alpha1_ApplicationSource(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceDirectory": schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceHelm": schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet": schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKsonnet": schema_pkg_apis_application_v1alpha1_ApplicationSourceKsonnet(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKustomize": schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourcePlugin": schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSpec": schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationStatus": schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSummary": schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationTree": schema_pkg_apis_application_v1alpha1_ApplicationTree(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationWatchEvent": schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Cluster": schema_pkg_apis_application_v1alpha1_Cluster(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ClusterConfig": schema_pkg_apis_application_v1alpha1_ClusterConfig(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ClusterList": schema_pkg_apis_application_v1alpha1_ClusterList(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Command": schema_pkg_apis_application_v1alpha1_Command(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ComparedTo": schema_pkg_apis_application_v1alpha1_ComparedTo(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ComponentParameter": schema_pkg_apis_application_v1alpha1_ComponentParameter(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConfigManagementPlugin": schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConnectionState": schema_pkg_apis_application_v1alpha1_ConnectionState(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.EnvEntry": schema_pkg_apis_application_v1alpha1_EnvEntry(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus": schema_pkg_apis_application_v1alpha1_HealthStatus(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HelmParameter": schema_pkg_apis_application_v1alpha1_HelmParameter(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Info": schema_pkg_apis_application_v1alpha1_Info(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.InfoItem": schema_pkg_apis_application_v1alpha1_InfoItem(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JWTToken": schema_pkg_apis_application_v1alpha1_JWTToken(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JsonnetVar": schema_pkg_apis_application_v1alpha1_JsonnetVar(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.KsonnetParameter": schema_pkg_apis_application_v1alpha1_KsonnetParameter(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.KustomizeOptions": schema_pkg_apis_application_v1alpha1_KustomizeOptions(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Operation": schema_pkg_apis_application_v1alpha1_Operation(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OperationState": schema_pkg_apis_application_v1alpha1_OperationState(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings": schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ProjectRole": schema_pkg_apis_application_v1alpha1_ProjectRole(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Repository": schema_pkg_apis_application_v1alpha1_Repository(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RepositoryCertificate": schema_pkg_apis_application_v1alpha1_RepositoryCertificate(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RepositoryCertificateList": schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RepositoryList": schema_pkg_apis_application_v1alpha1_RepositoryList(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceAction": schema_pkg_apis_application_v1alpha1_ResourceAction(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionDefinition": schema_pkg_apis_application_v1alpha1_ResourceActionDefinition(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionParam": schema_pkg_apis_application_v1alpha1_ResourceActionParam(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActions": schema_pkg_apis_application_v1alpha1_ResourceActions(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceDiff": schema_pkg_apis_application_v1alpha1_ResourceDiff(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences": schema_pkg_apis_application_v1alpha1_ResourceIgnoreDifferences(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNetworkingInfo": schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNode": schema_pkg_apis_application_v1alpha1_ResourceNode(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceOverride": schema_pkg_apis_application_v1alpha1_ResourceOverride(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceRef": schema_pkg_apis_application_v1alpha1_ResourceRef(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceResult": schema_pkg_apis_application_v1alpha1_ResourceResult(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceStatus": schema_pkg_apis_application_v1alpha1_ResourceStatus(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RevisionHistory": schema_pkg_apis_application_v1alpha1_RevisionHistory(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RevisionMetadata": schema_pkg_apis_application_v1alpha1_RevisionMetadata(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperation": schema_pkg_apis_application_v1alpha1_SyncOperation(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResource": schema_pkg_apis_application_v1alpha1_SyncOperationResource(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResult": schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicy": schema_pkg_apis_application_v1alpha1_SyncPolicy(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicyAutomated": schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStatus": schema_pkg_apis_application_v1alpha1_SyncStatus(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategy": schema_pkg_apis_application_v1alpha1_SyncStrategy(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyApply": schema_pkg_apis_application_v1alpha1_SyncStrategyApply(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyHook": schema_pkg_apis_application_v1alpha1_SyncStrategyHook(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncWindow": schema_pkg_apis_application_v1alpha1_SyncWindow(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.TLSClientConfig": schema_pkg_apis_application_v1alpha1_TLSClientConfig(ref), - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.objectMeta": schema_pkg_apis_application_v1alpha1_objectMeta(ref), - } -} - -func schema_pkg_apis_application_v1alpha1_AWSAuthConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "AWSAuthConfig is an AWS IAM authentication configuration", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "clusterName": { - SchemaProps: spec.SchemaProps{ - Description: "ClusterName contains AWS cluster name", - Type: []string{"string"}, - Format: "", - }, - }, - "roleARN": { - SchemaProps: spec.SchemaProps{ - Description: "RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain.", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_AppProject(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "AppProject provides a logical grouping of applications, providing controls for: * where the apps may deploy to (cluster whitelist) * what may be deployed (repository whitelist, resource whitelist/blacklist) * who can access these applications (roles, OIDC group claims bindings) * and what they can do (RBAC policies) * automation access to these roles (JWT tokens)", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProjectSpec"), - }, - }, - }, - Required: []string{"metadata", "spec"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProjectSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_AppProjectList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "AppProjectList is list of AppProject resources", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProject"), - }, - }, - }, - }, - }, - }, - Required: []string{"metadata", "items"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AppProject", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "AppProjectSpec is the specification of an AppProject", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "sourceRepos": { - SchemaProps: spec.SchemaProps{ - Description: "SourceRepos contains list of repository URLs which can be used for deployment", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "destinations": { - SchemaProps: spec.SchemaProps{ - Description: "Destinations contains list of destinations available for deployment", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination"), - }, - }, - }, - }, - }, - "description": { - SchemaProps: spec.SchemaProps{ - Description: "Description contains optional project description", - Type: []string{"string"}, - Format: "", - }, - }, - "roles": { - SchemaProps: spec.SchemaProps{ - Description: "Roles are user defined RBAC roles associated with this project", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ProjectRole"), - }, - }, - }, - }, - }, - "clusterResourceWhitelist": { - SchemaProps: spec.SchemaProps{ - Description: "ClusterResourceWhitelist contains list of whitelisted cluster level resources", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), - }, - }, - }, - }, - }, - "namespaceResourceBlacklist": { - SchemaProps: spec.SchemaProps{ - Description: "NamespaceResourceBlacklist contains list of blacklisted namespace level resources", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"), - }, - }, - }, - }, - }, - "orphanedResources": { - SchemaProps: spec.SchemaProps{ - Description: "OrphanedResources specifies if controller should monitor orphaned resources of apps in this project", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings"), - }, - }, - "syncWindows": { - SchemaProps: spec.SchemaProps{ - Description: "SyncWindows controls when syncs can be run for apps in this project", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncWindow"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OrphanedResourcesMonitorSettings", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ProjectRole", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncWindow", "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind"}, - } -} - -func schema_pkg_apis_application_v1alpha1_Application(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Application is a definition of Application resource.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationStatus"), - }, - }, - "operation": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Operation"), - }, - }, - }, - Required: []string{"metadata", "spec"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSpec", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationStatus", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Operation", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationCondition(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationCondition contains details about current application condition", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "type": { - SchemaProps: spec.SchemaProps{ - Description: "Type is an application condition type", - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Description: "Message contains human-readable message indicating details about condition", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"type", "message"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationDestination(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationDestination contains deployment destination information", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "server": { - SchemaProps: spec.SchemaProps{ - Description: "Server overrides the environment server value in the ksonnet app.yaml", - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Description: "Namespace overrides the environment namespace value in the ksonnet app.yaml", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationList is list of Application resources", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Application"), - }, - }, - }, - }, - }, - }, - Required: []string{"metadata", "items"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Application", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSource(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSource contains information about github repository, path within repository and target application environment.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "repoURL": { - SchemaProps: spec.SchemaProps{ - Description: "RepoURL is the repository URL of the application manifests", - Type: []string{"string"}, - Format: "", - }, - }, - "path": { - SchemaProps: spec.SchemaProps{ - Description: "Path is a directory path within the Git repository", - Type: []string{"string"}, - Format: "", - }, - }, - "targetRevision": { - SchemaProps: spec.SchemaProps{ - Description: "TargetRevision defines the commit, tag, or branch in which to sync the application to. If omitted, will sync to HEAD", - Type: []string{"string"}, - Format: "", - }, - }, - "helm": { - SchemaProps: spec.SchemaProps{ - Description: "Helm holds helm specific options", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceHelm"), - }, - }, - "kustomize": { - SchemaProps: spec.SchemaProps{ - Description: "Kustomize holds kustomize specific options", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKustomize"), - }, - }, - "ksonnet": { - SchemaProps: spec.SchemaProps{ - Description: "Ksonnet holds ksonnet specific options", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKsonnet"), - }, - }, - "directory": { - SchemaProps: spec.SchemaProps{ - Description: "Directory holds path/directory specific options", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceDirectory"), - }, - }, - "plugin": { - SchemaProps: spec.SchemaProps{ - Description: "ConfigManagementPlugin holds config management plugin specific options", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"), - }, - }, - "chart": { - SchemaProps: spec.SchemaProps{ - Description: "Chart is a Helm chart name", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"repoURL"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceDirectory", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceHelm", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKsonnet", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceKustomize", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourceDirectory(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "recurse": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "jsonnet": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSourceJsonnet"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSourceHelm holds helm specific options", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "valueFiles": { - SchemaProps: spec.SchemaProps{ - Description: "ValuesFiles is a list of Helm value files to use when generating a template", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "parameters": { - SchemaProps: spec.SchemaProps{ - Description: "Parameters are parameters to the helm template", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HelmParameter"), - }, - }, - }, - }, - }, - "releaseName": { - SchemaProps: spec.SchemaProps{ - Description: "The Helm release name. If omitted it will use the application name", - Type: []string{"string"}, - Format: "", - }, - }, - "values": { - SchemaProps: spec.SchemaProps{ - Description: "Values is Helm values, typically defined as a block", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HelmParameter"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourceJsonnet(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSourceJsonnet holds jsonnet specific options", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "extVars": { - SchemaProps: spec.SchemaProps{ - Description: "ExtVars is a list of Jsonnet External Variables", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JsonnetVar"), - }, - }, - }, - }, - }, - "tlas": { - SchemaProps: spec.SchemaProps{ - Description: "TLAS is a list of Jsonnet Top-level Arguments", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JsonnetVar"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JsonnetVar"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourceKsonnet(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSourceKsonnet holds ksonnet specific options", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "environment": { - SchemaProps: spec.SchemaProps{ - Description: "Environment is a ksonnet application environment name", - Type: []string{"string"}, - Format: "", - }, - }, - "parameters": { - SchemaProps: spec.SchemaProps{ - Description: "Parameters are a list of ksonnet component parameter override values", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.KsonnetParameter"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.KsonnetParameter"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSourceKustomize holds kustomize specific options", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "namePrefix": { - SchemaProps: spec.SchemaProps{ - Description: "NamePrefix is a prefix appended to resources for kustomize apps", - Type: []string{"string"}, - Format: "", - }, - }, - "images": { - SchemaProps: spec.SchemaProps{ - Description: "Images are kustomize image overrides", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "commonLabels": { - SchemaProps: spec.SchemaProps{ - Description: "CommonLabels adds additional kustomize commonLabels", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSourcePlugin(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSourcePlugin holds config management plugin specific options", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "env": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.EnvEntry"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.EnvEntry"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "source": { - SchemaProps: spec.SchemaProps{ - Description: "Source is a reference to the location ksonnet application definition", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"), - }, - }, - "destination": { - SchemaProps: spec.SchemaProps{ - Description: "Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination"), - }, - }, - "project": { - SchemaProps: spec.SchemaProps{ - Description: "Project is a application project name. Empty name means that application belongs to 'default' project.", - Type: []string{"string"}, - Format: "", - }, - }, - "syncPolicy": { - SchemaProps: spec.SchemaProps{ - Description: "SyncPolicy controls when a sync will be performed", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicy"), - }, - }, - "ignoreDifferences": { - SchemaProps: spec.SchemaProps{ - Description: "IgnoreDifferences controls resources fields which should be ignored during comparison", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences"), - }, - }, - }, - }, - }, - "info": { - SchemaProps: spec.SchemaProps{ - Description: "Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Info"), - }, - }, - }, - }, - }, - }, - Required: []string{"source", "destination", "project"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicy"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationStatus contains information about application sync, health status", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "resources": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceStatus"), - }, - }, - }, - }, - }, - "sync": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStatus"), - }, - }, - "health": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus"), - }, - }, - "history": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RevisionHistory"), - }, - }, - }, - }, - }, - "conditions": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationCondition"), - }, - }, - }, - }, - }, - "reconciledAt": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "operationState": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OperationState"), - }, - }, - "observedAt": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "sourceType": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "summary": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSummary"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "externalURLs": { - SchemaProps: spec.SchemaProps{ - Description: "ExternalURLs holds all external URLs of application child resources.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "images": { - SchemaProps: spec.SchemaProps{ - Description: "Images holds all images of application child resources.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationTree(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationTree holds nodes which belongs to the application", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "nodes": { - SchemaProps: spec.SchemaProps{ - Description: "Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNode"), - }, - }, - }, - }, - }, - "orphanedNodes": { - SchemaProps: spec.SchemaProps{ - Description: "OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNode"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNode"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ApplicationWatchEvent(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ApplicationWatchEvent contains information about application change.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "type": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "application": { - SchemaProps: spec.SchemaProps{ - Description: "Application is:\n * If Type is Added or Modified: the new state of the object.\n * If Type is Deleted: the state of the object immediately before deletion.\n * If Type is Error: *api.Status is recommended; other types may make sense\n depending on context.", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Application"), - }, - }, - }, - Required: []string{"type", "application"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Application"}, - } -} - -func schema_pkg_apis_application_v1alpha1_Cluster(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Cluster is the definition of a cluster resource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "server": { - SchemaProps: spec.SchemaProps{ - Description: "Server is the API server URL of the Kubernetes cluster", - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Name of the cluster. If omitted, will use the server address", - Type: []string{"string"}, - Format: "", - }, - }, - "config": { - SchemaProps: spec.SchemaProps{ - Description: "Config holds cluster information for connecting to a cluster", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ClusterConfig"), - }, - }, - "connectionState": { - SchemaProps: spec.SchemaProps{ - Description: "ConnectionState contains information about cluster connection state", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConnectionState"), - }, - }, - "serverVersion": { - SchemaProps: spec.SchemaProps{ - Description: "The server version", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"server", "name", "config"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ClusterConfig", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConnectionState"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ClusterConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ClusterConfig is the configuration attributes. This structure is subset of the go-client rest.Config with annotations added for marshalling.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "username": { - SchemaProps: spec.SchemaProps{ - Description: "Server requires Basic authentication", - Type: []string{"string"}, - Format: "", - }, - }, - "password": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "bearerToken": { - SchemaProps: spec.SchemaProps{ - Description: "Server requires Bearer authentication. This client will not attempt to use refresh tokens for an OAuth2 flow.", - Type: []string{"string"}, - Format: "", - }, - }, - "tlsClientConfig": { - SchemaProps: spec.SchemaProps{ - Description: "TLSClientConfig contains settings to enable transport layer security", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.TLSClientConfig"), - }, - }, - "awsAuthConfig": { - SchemaProps: spec.SchemaProps{ - Description: "AWSAuthConfig contains IAM authentication configuration", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AWSAuthConfig"), - }, - }, - }, - Required: []string{"tlsClientConfig"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.AWSAuthConfig", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.TLSClientConfig"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ClusterList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ClusterList is a collection of Clusters.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Cluster"), - }, - }, - }, - }, - }, - }, - Required: []string{"items"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Cluster", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_Command(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Command holds binary path and arguments list", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "command": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "args": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ComparedTo contains application source and target which was used for resources comparison", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "source": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"), - }, - }, - "destination": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination"), - }, - }, - }, - Required: []string{"source", "destination"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ComponentParameter(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ComponentParameter contains information about component parameter value", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "component": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"name", "value"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ConfigManagementPlugin contains config management plugin configuration", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "init": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Command"), - }, - }, - "generate": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Command"), - }, - }, - }, - Required: []string{"name", "generate"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Command"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ConnectionState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ConnectionState contains information about remote resource connection state", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "status": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "attemptedAt": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - }, - Required: []string{"status", "message", "attemptedAt"}, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_application_v1alpha1_EnvEntry(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Description: "the name, usually uppercase", - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Description: "the value", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"name", "value"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_HealthStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "status": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_HelmParameter(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "HelmParameter is a parameter to a helm template", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Name is the name of the helm parameter", - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Description: "Value is the value for the helm parameter", - Type: []string{"string"}, - Format: "", - }, - }, - "forceString": { - SchemaProps: spec.SchemaProps{ - Description: "ForceString determines whether to tell Helm to interpret booleans and numbers as strings", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_Info(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"name", "value"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_InfoItem(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InfoItem contains human readable information about object", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Name is a human readable title for this piece of information.", - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Description: "Value is human readable content.", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_JWTToken(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "JWTToken holds the issuedAt and expiresAt values of a token", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "iat": { - SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, - Format: "int64", - }, - }, - "exp": { - SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, - Format: "int64", - }, - }, - }, - Required: []string{"iat"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_JsonnetVar(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "JsonnetVar is a jsonnet variable", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "code": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - Required: []string{"name", "value"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_KsonnetParameter(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "KsonnetParameter is a ksonnet component parameter", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "component": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"name", "value"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_KustomizeOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "KustomizeOptions are options for kustomize to use when building manifests", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "BuildOptions": { - SchemaProps: spec.SchemaProps{ - Description: "BuildOptions is a string of build parameters to use when calling `kustomize build`", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"BuildOptions"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_Operation(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Operation contains requested operation parameters.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "sync": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperation"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperation"}, - } -} - -func schema_pkg_apis_application_v1alpha1_OperationState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "OperationState contains information about state of currently performing operation on application.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "operation": { - SchemaProps: spec.SchemaProps{ - Description: "Operation is the original requested operation", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Operation"), - }, - }, - "phase": { - SchemaProps: spec.SchemaProps{ - Description: "Phase is the current phase of the operation", - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Description: "Message hold any pertinent messages when attempting to perform operation (typically errors).", - Type: []string{"string"}, - Format: "", - }, - }, - "syncResult": { - SchemaProps: spec.SchemaProps{ - Description: "SyncResult is the result of a Sync operation", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResult"), - }, - }, - "startedAt": { - SchemaProps: spec.SchemaProps{ - Description: "StartedAt contains time of operation start", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "finishedAt": { - SchemaProps: spec.SchemaProps{ - Description: "FinishedAt contains time of operation completion", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - }, - Required: []string{"operation", "phase", "startedAt"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Operation", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResult", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_application_v1alpha1_OrphanedResourcesMonitorSettings(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "OrphanedResourcesMonitorSettings holds settings of orphaned resources monitoring", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "warn": { - SchemaProps: spec.SchemaProps{ - Description: "Warn indicates if warning condition should be created for apps which have orphaned resources", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ProjectRole(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ProjectRole represents a role that has access to a project", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Name is a name for this role", - Type: []string{"string"}, - Format: "", - }, - }, - "description": { - SchemaProps: spec.SchemaProps{ - Description: "Description is a description of the role", - Type: []string{"string"}, - Format: "", - }, - }, - "policies": { - SchemaProps: spec.SchemaProps{ - Description: "Policies Stores a list of casbin formated strings that define access policies for the role in the project", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "jwtTokens": { - SchemaProps: spec.SchemaProps{ - Description: "JWTTokens are a list of generated JWT tokens bound to this role", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JWTToken"), - }, - }, - }, - }, - }, - "groups": { - SchemaProps: spec.SchemaProps{ - Description: "Groups are a list of OIDC group claims bound to this role", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - Required: []string{"name"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.JWTToken"}, - } -} - -func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Repository is a repository holding application configurations", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "repo": { - SchemaProps: spec.SchemaProps{ - Description: "URL of the repo", - Type: []string{"string"}, - Format: "", - }, - }, - "username": { - SchemaProps: spec.SchemaProps{ - Description: "Username for authenticating at the repo server", - Type: []string{"string"}, - Format: "", - }, - }, - "password": { - SchemaProps: spec.SchemaProps{ - Description: "Password for authenticating at the repo server", - Type: []string{"string"}, - Format: "", - }, - }, - "sshPrivateKey": { - SchemaProps: spec.SchemaProps{ - Description: "SSH private key data for authenticating at the repo server only for Git repos", - Type: []string{"string"}, - Format: "", - }, - }, - "connectionState": { - SchemaProps: spec.SchemaProps{ - Description: "Current state of repository server connecting", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConnectionState"), - }, - }, - "insecureIgnoreHostKey": { - SchemaProps: spec.SchemaProps{ - Description: "InsecureIgnoreHostKey should not be used anymore, Insecure is favoured only for Git repos", - Type: []string{"boolean"}, - Format: "", - }, - }, - "insecure": { - SchemaProps: spec.SchemaProps{ - Description: "Whether the repo is insecure", - Type: []string{"boolean"}, - Format: "", - }, - }, - "enableLfs": { - SchemaProps: spec.SchemaProps{ - Description: "Whether git-lfs support should be enabled for this repo", - Type: []string{"boolean"}, - Format: "", - }, - }, - "tlsClientCertData": { - SchemaProps: spec.SchemaProps{ - Description: "TLS client cert data for authenticating at the repo server", - Type: []string{"string"}, - Format: "", - }, - }, - "tlsClientCertKey": { - SchemaProps: spec.SchemaProps{ - Description: "TLS client cert key for authenticating at the repo server", - Type: []string{"string"}, - Format: "", - }, - }, - "type": { - SchemaProps: spec.SchemaProps{ - Description: "type of the repo, maybe \"git or \"helm, \"git\" is assumed if empty or absent", - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Description: "only for Helm repos", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"repo"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ConnectionState"}, - } -} - -func schema_pkg_apis_application_v1alpha1_RepositoryCertificate(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "A RepositoryCertificate is either SSH known hosts entry or TLS certificate", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "serverName": { - SchemaProps: spec.SchemaProps{ - Description: "Name of the server the certificate is intended for", - Type: []string{"string"}, - Format: "", - }, - }, - "certType": { - SchemaProps: spec.SchemaProps{ - Description: "Type of certificate - currently \"https\" or \"ssh\"", - Type: []string{"string"}, - Format: "", - }, - }, - "certSubType": { - SchemaProps: spec.SchemaProps{ - Description: "The sub type of the cert, i.e. \"ssh-rsa\"", - Type: []string{"string"}, - Format: "", - }, - }, - "certData": { - SchemaProps: spec.SchemaProps{ - Description: "Actual certificate data, protocol dependent", - Type: []string{"string"}, - Format: "byte", - }, - }, - "certInfo": { - SchemaProps: spec.SchemaProps{ - Description: "Additional certificate info (e.g. SSH fingerprint, X509 CommonName)", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"serverName", "certType", "certSubType", "certData", "certInfo"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_RepositoryCertificateList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "RepositoryCertificateList is a collection of RepositoryCertificates", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Description: "List of certificates to be processed", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RepositoryCertificate"), - }, - }, - }, - }, - }, - }, - Required: []string{"items"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.RepositoryCertificate", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_RepositoryList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "RepositoryList is a collection of Repositories.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Repository"), - }, - }, - }, - }, - }, - }, - Required: []string{"items"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.Repository", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceAction(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "params": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionParam"), - }, - }, - }, - }, - }, - "disabled": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionParam"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceActionDefinition(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "action.lua": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"name", "action.lua"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceActionParam(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "type": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "default": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceActions(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "discovery.lua": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "definitions": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionDefinition"), - }, - }, - }, - }, - }, - }, - Required: []string{"definitions"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceActionDefinition"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceDiff(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceDiff holds the diff of a live and target resource object", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "targetState": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "liveState": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "diff": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "hook": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceIgnoreDifferences(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "jsonPointers": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - Required: []string{"kind", "jsonPointers"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceNetworkingInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceNetworkingInfo holds networking resource related information", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "targetLabels": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "targetRefs": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceRef"), - }, - }, - }, - }, - }, - "labels": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "ingress": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/api/core/v1.LoadBalancerIngress"), - }, - }, - }, - }, - }, - "externalURLs": { - SchemaProps: spec.SchemaProps{ - Description: "ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceRef", "k8s.io/api/core/v1.LoadBalancerIngress"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceNode(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceNode contains information about live resource and its children", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "version": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "uid": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "parentRefs": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceRef"), - }, - }, - }, - }, - }, - "info": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.InfoItem"), - }, - }, - }, - }, - }, - "networkingInfo": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNetworkingInfo"), - }, - }, - "resourceVersion": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "images": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "health": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.InfoItem", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceNetworkingInfo", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceRef"}, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceOverride(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceOverride holds configuration to customize resource diffing and health assessment", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "health.lua": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "actions": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "ignoreDifferences": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceRef includes fields which unique identify resource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "version": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "uid": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceResult(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceResult holds the operation result details of a specific resource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "version": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Description: "the final result of the sync, this is be empty if the resources is yet to be applied/pruned and is always zero-value for hooks", - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Description: "message for the last sync OR operation", - Type: []string{"string"}, - Format: "", - }, - }, - "hookType": { - SchemaProps: spec.SchemaProps{ - Description: "the type of the hook, empty for non-hook resources", - Type: []string{"string"}, - Format: "", - }, - }, - "hookPhase": { - SchemaProps: spec.SchemaProps{ - Description: "the state of any operation associated with this resource OR hook note: can contain values for non-hook resources", - Type: []string{"string"}, - Format: "", - }, - }, - "syncPhase": { - SchemaProps: spec.SchemaProps{ - Description: "indicates the particular phase of the sync that this is for", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"group", "version", "kind", "namespace", "name"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_ResourceStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ResourceStatus holds the current sync and health status of a resource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "version": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "namespace": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "health": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus"), - }, - }, - "hook": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "requiresPruning": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.HealthStatus"}, - } -} - -func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "RevisionHistory contains information relevant to an application deployment", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "revision": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "deployedAt": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "id": { - SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, - Format: "int64", - }, - }, - "source": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"), - }, - }, - }, - Required: []string{"revision", "deployedAt", "id"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_application_v1alpha1_RevisionMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "data about a specific revision within a repo", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "author": { - SchemaProps: spec.SchemaProps{ - Description: "who authored this revision, typically their name and email, e.g. \"John Doe \", but might not match this example", - Type: []string{"string"}, - Format: "", - }, - }, - "date": { - SchemaProps: spec.SchemaProps{ - Description: "when the revision was authored", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "tags": { - SchemaProps: spec.SchemaProps{ - Description: "tags on the revision, note - tags can move from one revision to another", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Description: "the message associated with the revision, probably the commit message, this is truncated to the first newline or 64 characters (which ever comes first)", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"date"}, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncOperation contains sync operation details.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "revision": { - SchemaProps: spec.SchemaProps{ - Description: "Revision is the revision in which to sync the application to. If omitted, will use the revision specified in app spec.", - Type: []string{"string"}, - Format: "", - }, - }, - "prune": { - SchemaProps: spec.SchemaProps{ - Description: "Prune deletes resources that are no longer tracked in git", - Type: []string{"boolean"}, - Format: "", - }, - }, - "dryRun": { - SchemaProps: spec.SchemaProps{ - Description: "DryRun will perform a `kubectl apply --dry-run` without actually performing the sync", - Type: []string{"boolean"}, - Format: "", - }, - }, - "syncStrategy": { - SchemaProps: spec.SchemaProps{ - Description: "SyncStrategy describes how to perform the sync", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategy"), - }, - }, - "resources": { - SchemaProps: spec.SchemaProps{ - Description: "Resources describes which resources to sync", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResource"), - }, - }, - }, - }, - }, - "source": { - SchemaProps: spec.SchemaProps{ - Description: "Source overrides the source definition set in the application. This is typically set in a Rollback operation and nil during a Sync operation", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"), - }, - }, - "manifests": { - SchemaProps: spec.SchemaProps{ - Description: "Manifests is an optional field that overrides sync source with a local directory for development", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncOperationResource", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategy"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncOperationResource(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncOperationResource contains resources to sync.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "group": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "kind": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"kind", "name"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncOperationResult represent result of sync operation", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "resources": { - SchemaProps: spec.SchemaProps{ - Description: "Resources holds the sync result of each individual resource", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceResult"), - }, - }, - }, - }, - }, - "revision": { - SchemaProps: spec.SchemaProps{ - Description: "Revision holds the revision of the sync", - Type: []string{"string"}, - Format: "", - }, - }, - "source": { - SchemaProps: spec.SchemaProps{ - Description: "Source records the application source information of the sync, used for comparing auto-sync", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource"), - }, - }, - }, - Required: []string{"revision"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ResourceResult"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncPolicy(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncPolicy controls when a sync will be performed in response to updates in git", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "automated": { - SchemaProps: spec.SchemaProps{ - Description: "Automated will keep an application synced to the target revision", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicyAutomated"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncPolicyAutomated"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncPolicyAutomated controls the behavior of an automated sync", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "prune": { - SchemaProps: spec.SchemaProps{ - Description: "Prune will prune resources automatically as part of automated sync (default: false)", - Type: []string{"boolean"}, - Format: "", - }, - }, - "selfHeal": { - SchemaProps: spec.SchemaProps{ - Description: "SelfHeal enables auto-syncing if (default: false)", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncStatus is a comparison result of application spec and deployed application.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "status": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "comparedTo": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ComparedTo"), - }, - }, - "revision": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"status"}, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.ComparedTo"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncStrategy(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncStrategy controls the manner in which a sync is performed", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "apply": { - SchemaProps: spec.SchemaProps{ - Description: "Apply wil perform a `kubectl apply` to perform the sync.", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyApply"), - }, - }, - "hook": { - SchemaProps: spec.SchemaProps{ - Description: "Hook will submit any referenced resources to perform the sync. This is the default strategy", - Ref: ref("github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyHook"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyApply", "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1.SyncStrategyHook"}, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncStrategyApply(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncStrategyApply uses `kubectl apply` to perform the apply", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "force": { - SchemaProps: spec.SchemaProps{ - Description: "Force indicates whether or not to supply the --force flag to `kubectl apply`. The --force flag deletes and re-create the resource, when PATCH encounters conflict and has retried for 5 times.", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncStrategyHook(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncStrategyHook will perform a sync using hooks annotations. If no hook annotation is specified falls back to `kubectl apply`.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "force": { - SchemaProps: spec.SchemaProps{ - Description: "Force indicates whether or not to supply the --force flag to `kubectl apply`. The --force flag deletes and re-create the resource, when PATCH encounters conflict and has retried for 5 times.", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_SyncWindow(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind defines if the window allows or blocks syncs", - Type: []string{"string"}, - Format: "", - }, - }, - "schedule": { - SchemaProps: spec.SchemaProps{ - Description: "Schedule is the time the window will begin, specified in cron format", - Type: []string{"string"}, - Format: "", - }, - }, - "duration": { - SchemaProps: spec.SchemaProps{ - Description: "Duration is the amount of time the sync window will be open", - Type: []string{"string"}, - Format: "", - }, - }, - "applications": { - SchemaProps: spec.SchemaProps{ - Description: "Applications contains a list of applications that the window will apply to", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "namespaces": { - SchemaProps: spec.SchemaProps{ - Description: "Namespaces contains a list of namespaces that the window will apply to", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "clusters": { - SchemaProps: spec.SchemaProps{ - Description: "Clusters contains a list of clusters that the window will apply to", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "manualSync": { - SchemaProps: spec.SchemaProps{ - Description: "ManualSync enables manual syncs when they would otherwise be blocked", - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_TLSClientConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "TLSClientConfig contains settings to enable transport layer security", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "insecure": { - SchemaProps: spec.SchemaProps{ - Description: "Server should be accessed without verifying the TLS certificate. For testing only.", - Type: []string{"boolean"}, - Format: "", - }, - }, - "serverName": { - SchemaProps: spec.SchemaProps{ - Description: "ServerName is passed to the server for SNI and is used in the client to check server certificates against. If ServerName is empty, the hostname used to contact the server is used.", - Type: []string{"string"}, - Format: "", - }, - }, - "certData": { - SchemaProps: spec.SchemaProps{ - Description: "CertData holds PEM-encoded bytes (typically read from a client certificate file). CertData takes precedence over CertFile", - Type: []string{"string"}, - Format: "byte", - }, - }, - "keyData": { - SchemaProps: spec.SchemaProps{ - Description: "KeyData holds PEM-encoded bytes (typically read from a client certificate key file). KeyData takes precedence over KeyFile", - Type: []string{"string"}, - Format: "byte", - }, - }, - "caData": { - SchemaProps: spec.SchemaProps{ - Description: "CAData holds PEM-encoded bytes (typically read from a root certificates bundle). CAData takes precedence over CAFile", - Type: []string{"string"}, - Format: "byte", - }, - }, - }, - Required: []string{"insecure"}, - }, - }, - } -} - -func schema_pkg_apis_application_v1alpha1_objectMeta(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "objectMeta and corresponding GetMetadata() methods is a hack to allow us to use grpc-gateway side-by-side with k8s protobuf codegen. The grpc-gateway generated .gw.pb.go files expect a GetMetadata() method to be generated because it assumes the .proto files were generated from protoc --go_out=plugins=grpc. Instead, kubernetes uses go-to-protobuf to generate .proto files from go types, and this method is not auto-generated (presumably since ObjectMeta is embedded but is nested in the 'metadata' field in JSON form).", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "Name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"Name"}, - }, - }, - } -} diff --git a/pkg/apis/application/v1alpha1/register.go b/pkg/apis/application/v1alpha1/register.go deleted file mode 100644 index 23ee3636d..000000000 --- a/pkg/apis/application/v1alpha1/register.go +++ /dev/null @@ -1,37 +0,0 @@ -package v1alpha1 - -import ( - application2 "github.com/argoproj/argo-cd/engine/pkg/apis/application" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: application2.Group, Version: "v1alpha1"} - ApplicationSchemaGroupVersionKind = schema.GroupVersionKind{Group: application2.Group, Version: "v1alpha1", Kind: application2.ApplicationKind} - AppProjectSchemaGroupVersionKind = schema.GroupVersionKind{Group: application2.Group, Version: "v1alpha1", Kind: application2.AppProjectKind} -) - -// Resource takes an unqualified resource and returns a Group-qualified GroupResource. -func Resource(resource string) schema.GroupResource { - return SchemeGroupVersion.WithResource(resource).GroupResource() -} - -var ( - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - AddToScheme = SchemeBuilder.AddToScheme -) - -// addKnownTypes adds the set of types defined in this package to the supplied scheme. -func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &Application{}, - &ApplicationList{}, - &AppProject{}, - &AppProjectList{}, - ) - metav1.AddToGroupVersion(scheme, SchemeGroupVersion) - return nil -} diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go deleted file mode 100644 index 38dff261f..000000000 --- a/pkg/apis/application/v1alpha1/types.go +++ /dev/null @@ -1,1984 +0,0 @@ -package v1alpha1 - -import ( - "encoding/json" - "fmt" - "net/url" - "os" - "path/filepath" - "reflect" - "regexp" - "strconv" - "strings" - "time" - - "github.com/argoproj/argo-cd/engine/common" - - "github.com/robfig/cron" - log "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "gopkg.in/yaml.v2" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/tools/clientcmd/api" - - "github.com/argoproj/argo-cd/engine/util/cert" - "github.com/argoproj/argo-cd/engine/util/git" - "github.com/argoproj/argo-cd/engine/util/helm" -) - -// Application is a definition of Application resource. -// +genclient -// +genclient:noStatus -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:resource:path=applications,shortName=app;apps -type Application struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` - Spec ApplicationSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - Status ApplicationStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` - Operation *Operation `json:"operation,omitempty" protobuf:"bytes,4,opt,name=operation"` -} - -// ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision. -type ApplicationSpec struct { - // Source is a reference to the location ksonnet application definition - Source ApplicationSource `json:"source" protobuf:"bytes,1,opt,name=source"` - // Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml - Destination ApplicationDestination `json:"destination" protobuf:"bytes,2,name=destination"` - // Project is a application project name. Empty name means that application belongs to 'default' project. - Project string `json:"project" protobuf:"bytes,3,name=project"` - // SyncPolicy controls when a sync will be performed - SyncPolicy *SyncPolicy `json:"syncPolicy,omitempty" protobuf:"bytes,4,name=syncPolicy"` - // IgnoreDifferences controls resources fields which should be ignored during comparison - IgnoreDifferences []ResourceIgnoreDifferences `json:"ignoreDifferences,omitempty" protobuf:"bytes,5,name=ignoreDifferences"` - // Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application - Info []Info `json:"info,omitempty" protobuf:"bytes,6,name=info"` -} - -// ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state. -type ResourceIgnoreDifferences struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` - Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - JSONPointers []string `json:"jsonPointers" protobuf:"bytes,5,opt,name=jsonPointers"` -} - -type EnvEntry struct { - // the name, usually uppercase - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // the value - Value string `json:"value" protobuf:"bytes,2,opt,name=value"` -} - -func (a *EnvEntry) IsZero() bool { - return a == nil || a.Name == "" && a.Value == "" -} - -type Env []*EnvEntry - -func (e Env) IsZero() bool { - return len(e) == 0 -} - -func (e Env) Environ() []string { - var environ []string - for _, item := range e { - if !item.IsZero() { - environ = append(environ, fmt.Sprintf("%s=%s", item.Name, item.Value)) - } - } - return environ -} - -// ApplicationSource contains information about github repository, path within repository and target application environment. -type ApplicationSource struct { - // RepoURL is the repository URL of the application manifests - RepoURL string `json:"repoURL" protobuf:"bytes,1,opt,name=repoURL"` - // Path is a directory path within the Git repository - Path string `json:"path,omitempty" protobuf:"bytes,2,opt,name=path"` - // TargetRevision defines the commit, tag, or branch in which to sync the application to. - // If omitted, will sync to HEAD - TargetRevision string `json:"targetRevision,omitempty" protobuf:"bytes,4,opt,name=targetRevision"` - // Helm holds helm specific options - Helm *ApplicationSourceHelm `json:"helm,omitempty" protobuf:"bytes,7,opt,name=helm"` - // Kustomize holds kustomize specific options - Kustomize *ApplicationSourceKustomize `json:"kustomize,omitempty" protobuf:"bytes,8,opt,name=kustomize"` - // Ksonnet holds ksonnet specific options - Ksonnet *ApplicationSourceKsonnet `json:"ksonnet,omitempty" protobuf:"bytes,9,opt,name=ksonnet"` - // Directory holds path/directory specific options - Directory *ApplicationSourceDirectory `json:"directory,omitempty" protobuf:"bytes,10,opt,name=directory"` - // ConfigManagementPlugin holds config management plugin specific options - Plugin *ApplicationSourcePlugin `json:"plugin,omitempty" protobuf:"bytes,11,opt,name=plugin"` - // Chart is a Helm chart name - Chart string `json:"chart,omitempty" protobuf:"bytes,12,opt,name=chart"` -} - -func (a *ApplicationSource) IsHelm() bool { - return a.Chart != "" -} - -func (a *ApplicationSource) IsZero() bool { - return a == nil || - a.RepoURL == "" && - a.Path == "" && - a.TargetRevision == "" && - a.Helm.IsZero() && - a.Kustomize.IsZero() && - a.Ksonnet.IsZero() && - a.Directory.IsZero() && - a.Plugin.IsZero() -} - -type ApplicationSourceType string - -const ( - ApplicationSourceTypeHelm ApplicationSourceType = "Helm" - ApplicationSourceTypeKustomize ApplicationSourceType = "Kustomize" - ApplicationSourceTypeKsonnet ApplicationSourceType = "Ksonnet" - ApplicationSourceTypeDirectory ApplicationSourceType = "Directory" - ApplicationSourceTypePlugin ApplicationSourceType = "Plugin" -) - -type RefreshType string - -const ( - RefreshTypeNormal RefreshType = "normal" - RefreshTypeHard RefreshType = "hard" -) - -// ApplicationSourceHelm holds helm specific options -type ApplicationSourceHelm struct { - // ValuesFiles is a list of Helm value files to use when generating a template - ValueFiles []string `json:"valueFiles,omitempty" protobuf:"bytes,1,opt,name=valueFiles"` - // Parameters are parameters to the helm template - Parameters []HelmParameter `json:"parameters,omitempty" protobuf:"bytes,2,opt,name=parameters"` - // The Helm release name. If omitted it will use the application name - ReleaseName string `json:"releaseName,omitempty" protobuf:"bytes,3,opt,name=releaseName"` - // Values is Helm values, typically defined as a block - Values string `json:"values,omitempty" protobuf:"bytes,4,opt,name=values"` -} - -// HelmParameter is a parameter to a helm template -type HelmParameter struct { - // Name is the name of the helm parameter - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Value is the value for the helm parameter - Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` - // ForceString determines whether to tell Helm to interpret booleans and numbers as strings - ForceString bool `json:"forceString,omitempty" protobuf:"bytes,3,opt,name=forceString"` -} - -var helmParameterRx = regexp.MustCompile(`([^\\]),`) - -func NewHelmParameter(text string, forceString bool) (*HelmParameter, error) { - parts := strings.SplitN(text, "=", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("Expected helm parameter of the form: param=value. Received: %s", text) - } - return &HelmParameter{ - Name: parts[0], - Value: helmParameterRx.ReplaceAllString(parts[1], `$1\,`), - ForceString: forceString, - }, nil -} - -func (in *ApplicationSourceHelm) AddParameter(p HelmParameter) { - found := false - for i, cp := range in.Parameters { - if cp.Name == p.Name { - found = true - in.Parameters[i] = p - break - } - } - if !found { - in.Parameters = append(in.Parameters, p) - } -} - -func (h *ApplicationSourceHelm) IsZero() bool { - return h == nil || (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && h.Values == "" -} - -type KustomizeImage string - -func (i KustomizeImage) delim() string { - for _, d := range []string{"=", ":", "@"} { - if strings.Contains(string(i), d) { - return d - } - } - return ":" -} - -// if the image name matches (i.e. up to the first delimiter) -func (i KustomizeImage) Match(j KustomizeImage) bool { - delim := j.delim() - if !strings.Contains(string(j), delim) { - return false - } - return strings.HasPrefix(string(i), strings.Split(string(j), delim)[0]) -} - -type KustomizeImages []KustomizeImage - -// find the image or -1 -func (images KustomizeImages) Find(image KustomizeImage) int { - for i, a := range images { - if a.Match(image) { - return i - } - } - return -1 -} - -// ApplicationSourceKustomize holds kustomize specific options -type ApplicationSourceKustomize struct { - // NamePrefix is a prefix appended to resources for kustomize apps - NamePrefix string `json:"namePrefix,omitempty" protobuf:"bytes,1,opt,name=namePrefix"` - // Images are kustomize image overrides - Images KustomizeImages `json:"images,omitempty" protobuf:"bytes,3,opt,name=images"` - // CommonLabels adds additional kustomize commonLabels - CommonLabels map[string]string `json:"commonLabels,omitempty" protobuf:"bytes,4,opt,name=commonLabels"` -} - -func (k *ApplicationSourceKustomize) IsZero() bool { - return k == nil || k.NamePrefix == "" && len(k.Images) == 0 && len(k.CommonLabels) == 0 -} - -// either updates or adds the images -func (k *ApplicationSourceKustomize) MergeImage(image KustomizeImage) { - i := k.Images.Find(image) - if i >= 0 { - k.Images[i] = image - } else { - k.Images = append(k.Images, image) - } -} - -// JsonnetVar is a jsonnet variable -type JsonnetVar struct { - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - Value string `json:"value" protobuf:"bytes,2,opt,name=value"` - Code bool `json:"code,omitempty" protobuf:"bytes,3,opt,name=code"` -} - -// ApplicationSourceJsonnet holds jsonnet specific options -type ApplicationSourceJsonnet struct { - // ExtVars is a list of Jsonnet External Variables - ExtVars []JsonnetVar `json:"extVars,omitempty" protobuf:"bytes,1,opt,name=extVars"` - // TLAS is a list of Jsonnet Top-level Arguments - TLAs []JsonnetVar `json:"tlas,omitempty" protobuf:"bytes,2,opt,name=tlas"` -} - -func (j *ApplicationSourceJsonnet) IsZero() bool { - return j == nil || len(j.ExtVars) == 0 && len(j.TLAs) == 0 -} - -// ApplicationSourceKsonnet holds ksonnet specific options -type ApplicationSourceKsonnet struct { - // Environment is a ksonnet application environment name - Environment string `json:"environment,omitempty" protobuf:"bytes,1,opt,name=environment"` - // Parameters are a list of ksonnet component parameter override values - Parameters []KsonnetParameter `json:"parameters,omitempty" protobuf:"bytes,2,opt,name=parameters"` -} - -// KsonnetParameter is a ksonnet component parameter -type KsonnetParameter struct { - Component string `json:"component,omitempty" protobuf:"bytes,1,opt,name=component"` - Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - Value string `json:"value" protobuf:"bytes,3,opt,name=value"` -} - -func (k *ApplicationSourceKsonnet) IsZero() bool { - return k == nil || k.Environment == "" && len(k.Parameters) == 0 -} - -type ApplicationSourceDirectory struct { - Recurse bool `json:"recurse,omitempty" protobuf:"bytes,1,opt,name=recurse"` - Jsonnet ApplicationSourceJsonnet `json:"jsonnet,omitempty" protobuf:"bytes,2,opt,name=jsonnet"` -} - -func (d *ApplicationSourceDirectory) IsZero() bool { - return d == nil || !d.Recurse && d.Jsonnet.IsZero() -} - -// ApplicationSourcePlugin holds config management plugin specific options -type ApplicationSourcePlugin struct { - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - Env `json:"env,omitempty" protobuf:"bytes,2,opt,name=env"` -} - -func (c *ApplicationSourcePlugin) IsZero() bool { - return c == nil || c.Name == "" && c.Env.IsZero() -} - -// ApplicationDestination contains deployment destination information -type ApplicationDestination struct { - // Server overrides the environment server value in the ksonnet app.yaml - Server string `json:"server,omitempty" protobuf:"bytes,1,opt,name=server"` - // Namespace overrides the environment namespace value in the ksonnet app.yaml - Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"` -} - -// 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"` -} - -// Operation contains requested operation parameters. -type Operation struct { - Sync *SyncOperation `json:"sync,omitempty" protobuf:"bytes,1,opt,name=sync"` -} - -// SyncOperationResource contains resources to sync. -type SyncOperationResource struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - Name string `json:"name" protobuf:"bytes,3,opt,name=name"` -} - -// HasIdentity determines whether a sync operation is identified by a manifest. -func (r SyncOperationResource) HasIdentity(name string, gvk schema.GroupVersionKind) bool { - if name == r.Name && gvk.Kind == r.Kind && gvk.Group == r.Group { - return true - } - return false -} - -// SyncOperation contains sync operation details. -type SyncOperation struct { - // Revision is the revision in which to sync the application to. - // If omitted, will use the revision specified in app spec. - Revision string `json:"revision,omitempty" protobuf:"bytes,1,opt,name=revision"` - // Prune deletes resources that are no longer tracked in git - Prune bool `json:"prune,omitempty" protobuf:"bytes,2,opt,name=prune"` - // DryRun will perform a `kubectl apply --dry-run` without actually performing the sync - DryRun bool `json:"dryRun,omitempty" protobuf:"bytes,3,opt,name=dryRun"` - // SyncStrategy describes how to perform the sync - SyncStrategy *SyncStrategy `json:"syncStrategy,omitempty" protobuf:"bytes,4,opt,name=syncStrategy"` - // Resources describes which resources to sync - Resources []SyncOperationResource `json:"resources,omitempty" protobuf:"bytes,6,opt,name=resources"` - // Source overrides the source definition set in the application. - // This is typically set in a Rollback operation and nil during a Sync operation - Source *ApplicationSource `json:"source,omitempty" protobuf:"bytes,7,opt,name=source"` - // Manifests is an optional field that overrides sync source with a local directory for development - Manifests []string `json:"manifests,omitempty" protobuf:"bytes,8,opt,name=manifests"` -} - -func (o *SyncOperation) IsApplyStrategy() bool { - return o.SyncStrategy != nil && o.SyncStrategy.Apply != nil -} - -type OperationPhase string - -const ( - OperationRunning OperationPhase = "Running" - OperationTerminating OperationPhase = "Terminating" - OperationFailed OperationPhase = "Failed" - OperationError OperationPhase = "Error" - OperationSucceeded OperationPhase = "Succeeded" -) - -func (os OperationPhase) Completed() bool { - switch os { - case OperationFailed, OperationError, OperationSucceeded: - return true - } - return false -} - -func (os OperationPhase) Running() bool { - return os == OperationRunning -} - -func (os OperationPhase) Successful() bool { - return os == OperationSucceeded -} - -func (os OperationPhase) Failed() bool { - return os == OperationFailed -} - -// OperationState contains information about state of currently performing operation on application. -type OperationState struct { - // Operation is the original requested operation - Operation Operation `json:"operation" protobuf:"bytes,1,opt,name=operation"` - // Phase is the current phase of the operation - Phase OperationPhase `json:"phase" protobuf:"bytes,2,opt,name=phase"` - // Message hold any pertinent messages when attempting to perform operation (typically errors). - Message string `json:"message,omitempty" protobuf:"bytes,3,opt,name=message"` - // SyncResult is the result of a Sync operation - SyncResult *SyncOperationResult `json:"syncResult,omitempty" protobuf:"bytes,4,opt,name=syncResult"` - // StartedAt contains time of operation start - StartedAt metav1.Time `json:"startedAt" protobuf:"bytes,6,opt,name=startedAt"` - // FinishedAt contains time of operation completion - FinishedAt *metav1.Time `json:"finishedAt,omitempty" protobuf:"bytes,7,opt,name=finishedAt"` -} - -type Info struct { - Name string `json:"name" protobuf:"bytes,1,name=name"` - Value string `json:"value" protobuf:"bytes,2,name=value"` -} - -// SyncPolicy controls when a sync will be performed in response to updates in git -type SyncPolicy struct { - // Automated will keep an application synced to the target revision - Automated *SyncPolicyAutomated `json:"automated,omitempty" protobuf:"bytes,1,opt,name=automated"` -} - -// SyncPolicyAutomated controls the behavior of an automated sync -type SyncPolicyAutomated struct { - // Prune will prune resources automatically as part of automated sync (default: false) - Prune bool `json:"prune,omitempty" protobuf:"bytes,1,opt,name=prune"` - // SelfHeal enables auto-syncing if (default: false) - SelfHeal bool `json:"selfHeal,omitempty" protobuf:"bytes,2,opt,name=selfHeal"` -} - -// SyncStrategy controls the manner in which a sync is performed -type SyncStrategy struct { - // Apply wil perform a `kubectl apply` to perform the sync. - Apply *SyncStrategyApply `json:"apply,omitempty" protobuf:"bytes,1,opt,name=apply"` - // Hook will submit any referenced resources to perform the sync. This is the default strategy - Hook *SyncStrategyHook `json:"hook,omitempty" protobuf:"bytes,2,opt,name=hook"` -} - -func (m *SyncStrategy) Force() bool { - if m == nil { - return false - } else if m.Apply != nil { - return m.Apply.Force - } else if m.Hook != nil { - return m.Hook.Force - } else { - return false - } -} - -// SyncStrategyApply uses `kubectl apply` to perform the apply -type SyncStrategyApply struct { - // Force indicates whether or not to supply the --force flag to `kubectl apply`. - // The --force flag deletes and re-create the resource, when PATCH encounters conflict and has - // retried for 5 times. - Force bool `json:"force,omitempty" protobuf:"bytes,1,opt,name=force"` -} - -// SyncStrategyHook will perform a sync using hooks annotations. -// If no hook annotation is specified falls back to `kubectl apply`. -type SyncStrategyHook struct { - // Embed SyncStrategyApply type to inherit any `apply` options - // +optional - SyncStrategyApply `json:",inline" protobuf:"bytes,1,opt,name=syncStrategyApply"` -} - -type HookType string - -const ( - HookTypePreSync HookType = "PreSync" - HookTypeSync HookType = "Sync" - HookTypePostSync HookType = "PostSync" - HookTypeSkip HookType = "Skip" - HookTypeSyncFail HookType = "SyncFail" -) - -func NewHookType(t string) (HookType, bool) { - return HookType(t), - t == string(HookTypePreSync) || - t == string(HookTypeSync) || - t == string(HookTypePostSync) || - t == string(HookTypeSyncFail) || - t == string(HookTypeSkip) - -} - -type HookDeletePolicy string - -const ( - HookDeletePolicyHookSucceeded HookDeletePolicy = "HookSucceeded" - HookDeletePolicyHookFailed HookDeletePolicy = "HookFailed" - HookDeletePolicyBeforeHookCreation HookDeletePolicy = "BeforeHookCreation" -) - -func NewHookDeletePolicy(p string) (HookDeletePolicy, bool) { - return HookDeletePolicy(p), - p == string(HookDeletePolicyHookSucceeded) || - p == string(HookDeletePolicyHookFailed) || - p == string(HookDeletePolicyBeforeHookCreation) -} - -// data about a specific revision within a repo -type RevisionMetadata struct { - // who authored this revision, - // typically their name and email, e.g. "John Doe ", - // but might not match this example - Author string `json:"author,omitempty" protobuf:"bytes,1,opt,name=author"` - // when the revision was authored - Date metav1.Time `json:"date" protobuf:"bytes,2,opt,name=date"` - // tags on the revision, - // note - tags can move from one revision to another - Tags []string `json:"tags,omitempty" protobuf:"bytes,3,opt,name=tags"` - // the message associated with the revision, - // probably the commit message, - // this is truncated to the first newline or 64 characters (which ever comes first) - Message string `json:"message,omitempty" protobuf:"bytes,4,opt,name=message"` -} - -// SyncOperationResult represent result of sync operation -type SyncOperationResult struct { - // Resources holds the sync result of each individual resource - Resources ResourceResults `json:"resources,omitempty" protobuf:"bytes,1,opt,name=resources"` - // Revision holds the revision of the sync - Revision string `json:"revision" protobuf:"bytes,2,opt,name=revision"` - // Source records the application source information of the sync, used for comparing auto-sync - Source ApplicationSource `json:"source,omitempty" protobuf:"bytes,3,opt,name=source"` -} - -type ResultCode string - -const ( - ResultCodeSynced ResultCode = "Synced" - ResultCodeSyncFailed ResultCode = "SyncFailed" - ResultCodePruned ResultCode = "Pruned" - ResultCodePruneSkipped ResultCode = "PruneSkipped" -) - -type SyncPhase = string - -const ( - SyncPhasePreSync = "PreSync" - SyncPhaseSync = "Sync" - SyncPhasePostSync = "PostSync" - SyncPhaseSyncFail = "SyncFail" -) - -// ResourceResult holds the operation result details of a specific resource -type ResourceResult struct { - Group string `json:"group" protobuf:"bytes,1,opt,name=group"` - Version string `json:"version" protobuf:"bytes,2,opt,name=version"` - Kind string `json:"kind" protobuf:"bytes,3,opt,name=kind"` - Namespace string `json:"namespace" protobuf:"bytes,4,opt,name=namespace"` - Name string `json:"name" protobuf:"bytes,5,opt,name=name"` - // the final result of the sync, this is be empty if the resources is yet to be applied/pruned and is always zero-value for hooks - Status ResultCode `json:"status,omitempty" protobuf:"bytes,6,opt,name=status"` - // message for the last sync OR operation - Message string `json:"message,omitempty" protobuf:"bytes,7,opt,name=message"` - // the type of the hook, empty for non-hook resources - HookType HookType `json:"hookType,omitempty" protobuf:"bytes,8,opt,name=hookType"` - // the state of any operation associated with this resource OR hook - // note: can contain values for non-hook resources - HookPhase OperationPhase `json:"hookPhase,omitempty" protobuf:"bytes,9,opt,name=hookPhase"` - // indicates the particular phase of the sync that this is for - SyncPhase SyncPhase `json:"syncPhase,omitempty" protobuf:"bytes,10,opt,name=syncPhase"` -} - -func (r *ResourceResult) GroupVersionKind() schema.GroupVersionKind { - return schema.GroupVersionKind{ - Group: r.Group, - Version: r.Version, - Kind: r.Kind, - } -} - -type ResourceResults []*ResourceResult - -func (r ResourceResults) Filter(predicate func(r *ResourceResult) bool) ResourceResults { - results := ResourceResults{} - for _, res := range r { - if predicate(res) { - results = append(results, res) - } - } - return results -} -func (r ResourceResults) Find(group string, kind string, namespace string, name string, phase SyncPhase) (int, *ResourceResult) { - for i, res := range r { - if res.Group == group && res.Kind == kind && res.Namespace == namespace && res.Name == name && res.SyncPhase == phase { - return i, res - } - } - return 0, nil -} - -func (r ResourceResults) PruningRequired() (num int) { - for _, res := range r { - if res.Status == ResultCodePruneSkipped { - num++ - } - } - return num -} - -// RevisionHistory contains information relevant to an application deployment -type RevisionHistory struct { - Revision string `json:"revision" protobuf:"bytes,2,opt,name=revision"` - DeployedAt metav1.Time `json:"deployedAt" protobuf:"bytes,4,opt,name=deployedAt"` - ID int64 `json:"id" protobuf:"bytes,5,opt,name=id"` - Source ApplicationSource `json:"source,omitempty" protobuf:"bytes,6,opt,name=source"` -} - -// ApplicationWatchEvent contains information about application change. -type ApplicationWatchEvent struct { - Type watch.EventType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=k8s.io/apimachinery/pkg/watch.EventType"` - - // Application is: - // * If Type is Added or Modified: the new state of the object. - // * If Type is Deleted: the state of the object immediately before deletion. - // * If Type is Error: *api.Status is recommended; other types may make sense - // depending on context. - Application Application `json:"application" protobuf:"bytes,2,opt,name=application"` -} - -// ApplicationList is list of Application resources -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type ApplicationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` - Items []Application `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// ComponentParameter contains information about component parameter value -type ComponentParameter struct { - Component string `json:"component,omitempty" protobuf:"bytes,1,opt,name=component"` - Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - Value string `json:"value" protobuf:"bytes,3,opt,name=value"` -} - -// SyncStatusCode is a type which represents possible comparison results -type SyncStatusCode string - -// Possible comparison results -const ( - SyncStatusCodeUnknown SyncStatusCode = "Unknown" - SyncStatusCodeSynced SyncStatusCode = "Synced" - SyncStatusCodeOutOfSync SyncStatusCode = "OutOfSync" -) - -// ApplicationConditionType represents type of application condition. Type name has following convention: -// prefix "Error" means error condition -// prefix "Warning" means warning condition -// prefix "Info" means informational condition -type ApplicationConditionType = string - -const ( - // ApplicationConditionDeletionError indicates that controller failed to delete application - ApplicationConditionDeletionError = "DeletionError" - // ApplicationConditionInvalidSpecError indicates that application source is invalid - ApplicationConditionInvalidSpecError = "InvalidSpecError" - // ApplicationConditionComparisonError indicates controller failed to compare application state - ApplicationConditionComparisonError = "ComparisonError" - // ApplicationConditionSyncError indicates controller failed to automatically sync the application - ApplicationConditionSyncError = "SyncError" - // ApplicationConditionUnknownError indicates an unknown controller error - ApplicationConditionUnknownError = "UnknownError" - // ApplicationConditionSharedResourceWarning indicates that controller detected resources which belongs to more than one application - ApplicationConditionSharedResourceWarning = "SharedResourceWarning" - // ApplicationConditionRepeatedResourceWarning indicates that application source has resource with same Group, Kind, Name, Namespace multiple times - ApplicationConditionRepeatedResourceWarning = "RepeatedResourceWarning" - // ApplicationConditionExcludedResourceWarning indicates that application has resource which is configured to be excluded - ApplicationConditionExcludedResourceWarning = "ExcludedResourceWarning" - // ApplicationConditionOrphanedResourceWarning indicates that application has orphaned resources - ApplicationConditionOrphanedResourceWarning = "OrphanedResourceWarning" -) - -// ApplicationCondition contains details about current application condition -type ApplicationCondition struct { - // Type is an application condition type - Type ApplicationConditionType `json:"type" protobuf:"bytes,1,opt,name=type"` - // Message contains human-readable message indicating details about condition - Message string `json:"message" protobuf:"bytes,2,opt,name=message"` -} - -// ComparedTo contains application source and target which was used for resources comparison -type ComparedTo struct { - Source ApplicationSource `json:"source" protobuf:"bytes,1,opt,name=source"` - Destination ApplicationDestination `json:"destination" protobuf:"bytes,2,opt,name=destination"` -} - -// SyncStatus is a comparison result of application spec and deployed application. -type SyncStatus struct { - Status SyncStatusCode `json:"status" protobuf:"bytes,1,opt,name=status,casttype=SyncStatusCode"` - ComparedTo ComparedTo `json:"comparedTo,omitempty" protobuf:"bytes,2,opt,name=comparedTo"` - Revision string `json:"revision,omitempty" protobuf:"bytes,3,opt,name=revision"` -} - -type HealthStatus struct { - Status HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"` - Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` -} - -type HealthStatusCode = string - -const ( - HealthStatusUnknown HealthStatusCode = "Unknown" - HealthStatusProgressing HealthStatusCode = "Progressing" - HealthStatusHealthy HealthStatusCode = "Healthy" - HealthStatusSuspended HealthStatusCode = "Suspended" - HealthStatusDegraded HealthStatusCode = "Degraded" - HealthStatusMissing HealthStatusCode = "Missing" -) - -// InfoItem contains human readable information about object -type InfoItem struct { - // Name is a human readable title for this piece of information. - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Value is human readable content. - Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` -} - -// ResourceNetworkingInfo holds networking resource related information -type ResourceNetworkingInfo struct { - TargetLabels map[string]string `json:"targetLabels,omitempty" protobuf:"bytes,1,opt,name=targetLabels"` - TargetRefs []ResourceRef `json:"targetRefs,omitempty" protobuf:"bytes,2,opt,name=targetRefs"` - Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,3,opt,name=labels"` - Ingress []v1.LoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,4,opt,name=ingress"` - // ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames. - ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,5,opt,name=externalURLs"` -} - -// ApplicationTree holds nodes which belongs to the application -type ApplicationTree struct { - // Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes. - Nodes []ResourceNode `json:"nodes,omitempty" protobuf:"bytes,1,rep,name=nodes"` - // OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project. - OrphanedNodes []ResourceNode `json:"orphanedNodes,omitempty" protobuf:"bytes,2,rep,name=orphanedNodes"` -} - -type ApplicationSummary struct { - // ExternalURLs holds all external URLs of application child resources. - ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,1,opt,name=externalURLs"` - // Images holds all images of application child resources. - Images []string `json:"images,omitempty" protobuf:"bytes,2,opt,name=images"` -} - -func (t *ApplicationTree) FindNode(group string, kind string, namespace string, name string) *ResourceNode { - for _, n := range append(t.Nodes, t.OrphanedNodes...) { - if n.Group == group && n.Kind == kind && n.Namespace == namespace && n.Name == name { - return &n - } - } - return nil -} - -func (t *ApplicationTree) GetSummary() ApplicationSummary { - urlsSet := make(map[string]bool) - imagesSet := make(map[string]bool) - for _, node := range t.Nodes { - if node.NetworkingInfo != nil { - for _, url := range node.NetworkingInfo.ExternalURLs { - urlsSet[url] = true - } - } - for _, image := range node.Images { - imagesSet[image] = true - } - } - urls := make([]string, 0) - for url := range urlsSet { - urls = append(urls, url) - } - images := make([]string, 0) - for image := range imagesSet { - images = append(images, image) - } - return ApplicationSummary{ExternalURLs: urls, Images: images} -} - -// ResourceRef includes fields which unique identify resource -type ResourceRef struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` - Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` - Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` - UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"` -} - -// ResourceNode contains information about live resource and its children -type ResourceNode struct { - ResourceRef `json:",inline" protobuf:"bytes,1,opt,name=resourceRef"` - ParentRefs []ResourceRef `json:"parentRefs,omitempty" protobuf:"bytes,2,opt,name=parentRefs"` - Info []InfoItem `json:"info,omitempty" protobuf:"bytes,3,opt,name=info"` - NetworkingInfo *ResourceNetworkingInfo `json:"networkingInfo,omitempty" protobuf:"bytes,4,opt,name=networkingInfo"` - ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,5,opt,name=resourceVersion"` - Images []string `json:"images,omitempty" protobuf:"bytes,6,opt,name=images"` - Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` -} - -func (n *ResourceNode) GroupKindVersion() schema.GroupVersionKind { - return schema.GroupVersionKind{ - Group: n.Group, - Version: n.Version, - Kind: n.Kind, - } -} - -// ResourceStatus holds the current sync and health status of a resource -type ResourceStatus struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` - Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` - Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` - Status SyncStatusCode `json:"status,omitempty" protobuf:"bytes,6,opt,name=status"` - Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` - Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` - RequiresPruning bool `json:"requiresPruning,omitempty" protobuf:"bytes,9,opt,name=requiresPruning"` -} - -func (r *ResourceStatus) GroupVersionKind() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: r.Group, Version: r.Version, Kind: r.Kind} -} - -// ResourceDiff holds the diff of a live and target resource object -type ResourceDiff struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Kind string `json:"kind,omitempty" protobuf:"bytes,2,opt,name=kind"` - Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` - Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` - TargetState string `json:"targetState,omitempty" protobuf:"bytes,5,opt,name=targetState"` - LiveState string `json:"liveState,omitempty" protobuf:"bytes,6,opt,name=liveState"` - Diff string `json:"diff,omitempty" protobuf:"bytes,7,opt,name=diff"` - Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` -} - -// ConnectionStatus represents connection status -type ConnectionStatus = string - -const ( - ConnectionStatusSuccessful = "Successful" - ConnectionStatusFailed = "Failed" -) - -// ConnectionState contains information about remote resource connection state -type ConnectionState struct { - Status ConnectionStatus `json:"status" protobuf:"bytes,1,opt,name=status"` - Message string `json:"message" protobuf:"bytes,2,opt,name=message"` - ModifiedAt *metav1.Time `json:"attemptedAt" protobuf:"bytes,3,opt,name=attemptedAt"` -} - -// Cluster is the definition of a cluster resource -type Cluster struct { - // Server is the API server URL of the Kubernetes cluster - Server string `json:"server" protobuf:"bytes,1,opt,name=server"` - // Name of the cluster. If omitted, will use the server address - Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // Config holds cluster information for connecting to a cluster - Config ClusterConfig `json:"config" protobuf:"bytes,3,opt,name=config"` - // ConnectionState contains information about cluster connection state - ConnectionState ConnectionState `json:"connectionState,omitempty" protobuf:"bytes,4,opt,name=connectionState"` - // The server version - ServerVersion string `json:"serverVersion,omitempty" protobuf:"bytes,5,opt,name=serverVersion"` -} - -// ClusterList is a collection of Clusters. -type ClusterList struct { - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - Items []Cluster `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// AWSAuthConfig is an AWS IAM authentication configuration -type AWSAuthConfig struct { - // ClusterName contains AWS cluster name - ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,1,opt,name=clusterName"` - - // RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain. - RoleARN string `json:"roleARN,omitempty" protobuf:"bytes,2,opt,name=roleARN"` -} - -// ClusterConfig is the configuration attributes. This structure is subset of the go-client -// rest.Config with annotations added for marshalling. -type ClusterConfig struct { - // Server requires Basic authentication - Username string `json:"username,omitempty" protobuf:"bytes,1,opt,name=username"` - Password string `json:"password,omitempty" protobuf:"bytes,2,opt,name=password"` - - // Server requires Bearer authentication. This client will not attempt to use - // refresh tokens for an OAuth2 flow. - // TODO: demonstrate an OAuth2 compatible client. - BearerToken string `json:"bearerToken,omitempty" protobuf:"bytes,3,opt,name=bearerToken"` - - // TLSClientConfig contains settings to enable transport layer security - TLSClientConfig `json:"tlsClientConfig" protobuf:"bytes,4,opt,name=tlsClientConfig"` - - // AWSAuthConfig contains IAM authentication configuration - AWSAuthConfig *AWSAuthConfig `json:"awsAuthConfig,omitempty" protobuf:"bytes,5,opt,name=awsAuthConfig"` -} - -// TLSClientConfig contains settings to enable transport layer security -type TLSClientConfig struct { - // Server should be accessed without verifying the TLS certificate. For testing only. - Insecure bool `json:"insecure" protobuf:"bytes,1,opt,name=insecure"` - // ServerName is passed to the server for SNI and is used in the client to check server - // certificates against. If ServerName is empty, the hostname used to contact the - // server is used. - ServerName string `json:"serverName,omitempty" protobuf:"bytes,2,opt,name=serverName"` - // CertData holds PEM-encoded bytes (typically read from a client certificate file). - // CertData takes precedence over CertFile - CertData []byte `json:"certData,omitempty" protobuf:"bytes,3,opt,name=certData"` - // KeyData holds PEM-encoded bytes (typically read from a client certificate key file). - // KeyData takes precedence over KeyFile - KeyData []byte `json:"keyData,omitempty" protobuf:"bytes,4,opt,name=keyData"` - // CAData holds PEM-encoded bytes (typically read from a root certificates bundle). - // CAData takes precedence over CAFile - CAData []byte `json:"caData,omitempty" protobuf:"bytes,5,opt,name=caData"` -} - -// ResourceOverride holds configuration to customize resource diffing and health assessment -type ResourceOverride struct { - HealthLua string `json:"health.lua,omitempty" protobuf:"bytes,1,opt,name=healthLua"` - Actions string `json:"actions,omitempty" protobuf:"bytes,3,opt,name=actions"` - IgnoreDifferences string `json:"ignoreDifferences,omitempty" protobuf:"bytes,2,opt,name=ignoreDifferences"` -} - -func (o *ResourceOverride) GetActions() (ResourceActions, error) { - var actions ResourceActions - err := yaml.Unmarshal([]byte(o.Actions), &actions) - if err != nil { - return actions, err - } - return actions, nil -} - -type ResourceActions struct { - ActionDiscoveryLua string `json:"discovery.lua,omitempty" yaml:"discovery.lua,omitempty" protobuf:"bytes,1,opt,name=actionDiscoveryLua"` - Definitions []ResourceActionDefinition `json:"definitions,omitEmpty" protobuf:"bytes,2,rep,name=definitions"` -} - -type ResourceActionDefinition struct { - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - ActionLua string `json:"action.lua" yaml:"action.lua" protobuf:"bytes,2,opt,name=actionLua"` -} - -type ResourceAction struct { - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - Params []ResourceActionParam `json:"params,omitempty" protobuf:"bytes,2,rep,name=params"` - Disabled bool `json:"disabled,omitempty" protobuf:"varint,3,opt,name=disabled"` -} - -type ResourceActionParam struct { - Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` - Type string `json:"type,omitempty" protobuf:"bytes,3,opt,name=type"` - Default string `json:"default,omitempty" protobuf:"bytes,4,opt,name=default"` -} - -// Repository is a repository holding application configurations -type Repository struct { - // URL of the repo - Repo string `json:"repo" protobuf:"bytes,1,opt,name=repo"` - // Username for authenticating at the repo server - Username string `json:"username,omitempty" protobuf:"bytes,2,opt,name=username"` - // Password for authenticating at the repo server - Password string `json:"password,omitempty" protobuf:"bytes,3,opt,name=password"` - // SSH private key data for authenticating at the repo server - // only for Git repos - SSHPrivateKey string `json:"sshPrivateKey,omitempty" protobuf:"bytes,4,opt,name=sshPrivateKey"` - // Current state of repository server connecting - ConnectionState ConnectionState `json:"connectionState,omitempty" protobuf:"bytes,5,opt,name=connectionState"` - // InsecureIgnoreHostKey should not be used anymore, Insecure is favoured - // only for Git repos - InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty" protobuf:"bytes,6,opt,name=insecureIgnoreHostKey"` - // Whether the repo is insecure - Insecure bool `json:"insecure,omitempty" protobuf:"bytes,7,opt,name=insecure"` - // Whether git-lfs support should be enabled for this repo - EnableLFS bool `json:"enableLfs,omitempty" protobuf:"bytes,8,opt,name=enableLfs"` - // TLS client cert data for authenticating at the repo server - TLSClientCertData string `json:"tlsClientCertData,omitempty" protobuf:"bytes,9,opt,name=tlsClientCertData"` - // TLS client cert key for authenticating at the repo server - TLSClientCertKey string `json:"tlsClientCertKey,omitempty" protobuf:"bytes,10,opt,name=tlsClientCertKey"` - // type of the repo, maybe "git or "helm, "git" is assumed if empty or absent - Type string `json:"type,omitempty" protobuf:"bytes,11,opt,name=type"` - // only for Helm repos - Name string `json:"name,omitempty" protobuf:"bytes,12,opt,name=name"` -} - -func (repo *Repository) IsInsecure() bool { - return repo.InsecureIgnoreHostKey || repo.Insecure -} - -func (repo *Repository) IsLFSEnabled() bool { - return repo.EnableLFS -} - -func (repo *Repository) CopyCredentialsFrom(source *Repository) { - if source != nil { - if repo.Username == "" { - repo.Username = source.Username - } - if repo.Password == "" { - repo.Password = source.Password - } - if repo.SSHPrivateKey == "" { - repo.SSHPrivateKey = source.SSHPrivateKey - } - repo.InsecureIgnoreHostKey = repo.InsecureIgnoreHostKey || source.InsecureIgnoreHostKey - repo.Insecure = repo.Insecure || source.Insecure - repo.EnableLFS = repo.EnableLFS || source.EnableLFS - if repo.TLSClientCertData == "" { - repo.TLSClientCertData = source.TLSClientCertData - } - if repo.TLSClientCertKey == "" { - repo.TLSClientCertKey = source.TLSClientCertKey - } - } -} - -func (repo *Repository) GetGitCreds() git.Creds { - if repo == nil { - return git.NopCreds{} - } - if repo.Username != "" && repo.Password != "" { - return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure()) - } - if repo.SSHPrivateKey != "" { - return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure()) - } - return git.NopCreds{} -} - -func (repo *Repository) GetHelmCreds() helm.Creds { - return helm.Creds{ - Username: repo.Username, - Password: repo.Password, - CAPath: getCAPath(repo.Repo), - CertData: []byte(repo.TLSClientCertData), - KeyData: []byte(repo.TLSClientCertKey), - } -} - -func getCAPath(repoURL string) string { - if git.IsHTTPSURL(repoURL) { - if parsedURL, err := url.Parse(repoURL); err == nil { - if caPath, err := cert.GetCertBundlePathForRepository(parsedURL.Host); err == nil { - return caPath - } else { - log.Warnf("Could not get cert bundle path for host '%s'", parsedURL.Host) - } - } else { - // We don't fail if we cannot parse the URL, but log a warning in that - // case. And we execute the command in a verbatim way. - log.Warnf("Could not parse repo URL '%s'", repoURL) - } - } - return "" -} - -type Repositories []*Repository - -func (r Repositories) Filter(predicate func(r *Repository) bool) Repositories { - var res Repositories - for i := range r { - repo := r[i] - if predicate(repo) { - res = append(res, repo) - } - } - return res -} - -// RepositoryList is a collection of Repositories. -type RepositoryList struct { - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - Items Repositories `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// A RepositoryCertificate is either SSH known hosts entry or TLS certificate -type RepositoryCertificate struct { - // Name of the server the certificate is intended for - ServerName string `json:"serverName" protobuf:"bytes,1,opt,name=serverName"` - // Type of certificate - currently "https" or "ssh" - CertType string `json:"certType" protobuf:"bytes,2,opt,name=certType"` - // The sub type of the cert, i.e. "ssh-rsa" - CertSubType string `json:"certSubType" protobuf:"bytes,3,opt,name=certSubType"` - // Actual certificate data, protocol dependent - CertData []byte `json:"certData" protobuf:"bytes,4,opt,name=certData"` - // Additional certificate info (e.g. SSH fingerprint, X509 CommonName) - CertInfo string `json:"certInfo" protobuf:"bytes,5,opt,name=certInfo"` -} - -// RepositoryCertificateList is a collection of RepositoryCertificates -type RepositoryCertificateList struct { - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // List of certificates to be processed - Items []RepositoryCertificate `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// AppProjectList is list of AppProject resources -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type AppProjectList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` - Items []AppProject `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// AppProject provides a logical grouping of applications, providing controls for: -// * where the apps may deploy to (cluster whitelist) -// * what may be deployed (repository whitelist, resource whitelist/blacklist) -// * who can access these applications (roles, OIDC group claims bindings) -// * and what they can do (RBAC policies) -// * automation access to these roles (JWT tokens) -// +genclient -// +genclient:noStatus -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:resource:path=appprojects,shortName=appproj;appprojs -type AppProject struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` - Spec AppProjectSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` -} - -// GetRoleByName returns the role in a project by the name with its index -func (p *AppProject) GetRoleByName(name string) (*ProjectRole, int, error) { - for i, role := range p.Spec.Roles { - if name == role.Name { - return &role, i, nil - } - } - return nil, -1, fmt.Errorf("role '%s' does not exist in project '%s'", name, p.Name) -} - -// GetJWTToken looks up the index of a JWTToken in a project by the issue at time -func (p *AppProject) GetJWTToken(roleName string, issuedAt int64) (*JWTToken, int, error) { - role, _, err := p.GetRoleByName(roleName) - if err != nil { - return nil, -1, err - } - for i, token := range role.JWTTokens { - if issuedAt == token.IssuedAt { - return &token, i, nil - } - } - return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", role.Name, issuedAt, p.Name) -} - -func (p *AppProject) ValidateProject() error { - destKeys := make(map[string]bool) - for _, dest := range p.Spec.Destinations { - key := fmt.Sprintf("%s/%s", dest.Server, dest.Namespace) - if _, ok := destKeys[key]; ok { - return status.Errorf(codes.InvalidArgument, "destination '%s' already added", key) - } - destKeys[key] = true - } - srcRepos := make(map[string]bool) - for _, src := range p.Spec.SourceRepos { - if _, ok := srcRepos[src]; ok { - return status.Errorf(codes.InvalidArgument, "source repository '%s' already added", src) - } - srcRepos[src] = true - } - - roleNames := make(map[string]bool) - for _, role := range p.Spec.Roles { - if _, ok := roleNames[role.Name]; ok { - return status.Errorf(codes.AlreadyExists, "role '%s' already exists", role.Name) - } - if err := validateRoleName(role.Name); err != nil { - return err - } - existingPolicies := make(map[string]bool) - for _, policy := range role.Policies { - if _, ok := existingPolicies[policy]; ok { - return status.Errorf(codes.AlreadyExists, "policy '%s' already exists for role '%s'", policy, role.Name) - } - if err := validatePolicy(p.Name, role.Name, policy); err != nil { - return err - } - existingPolicies[policy] = true - } - existingGroups := make(map[string]bool) - for _, group := range role.Groups { - if _, ok := existingGroups[group]; ok { - return status.Errorf(codes.AlreadyExists, "group '%s' already exists for role '%s'", group, role.Name) - } - if err := validateGroupName(group); err != nil { - return err - } - existingGroups[group] = true - } - roleNames[role.Name] = true - } - - if p.Spec.SyncWindows.HasWindows() { - existingWindows := make(map[string]bool) - for _, window := range p.Spec.SyncWindows { - if _, ok := existingWindows[window.Kind+window.Schedule+window.Duration]; ok { - return status.Errorf(codes.AlreadyExists, "window '%s':'%s':'%s' already exists, update or edit", window.Kind, window.Schedule, window.Duration) - } - err := window.Validate() - if err != nil { - return err - } - if len(window.Applications) == 0 && len(window.Namespaces) == 0 && len(window.Clusters) == 0 { - return status.Errorf(codes.OutOfRange, "window '%s':'%s':'%s' requires one of application, cluster or namespace", window.Kind, window.Schedule, window.Duration) - } - existingWindows[window.Kind+window.Schedule+window.Duration] = true - } - } - return nil -} - -// TODO: refactor to use rbacpolicy.ActionGet, rbacpolicy.ActionCreate, without import cycle -var validActions = map[string]bool{ - "get": true, - "create": true, - "update": true, - "delete": true, - "sync": true, - "override": true, - "*": true, -} - -func isValidAction(action string) bool { - return validActions[action] -} - -func validatePolicy(proj string, role string, policy string) error { - policyComponents := strings.Split(policy, ",") - if len(policyComponents) != 6 || strings.Trim(policyComponents[0], " ") != "p" { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': must be of the form: 'p, sub, res, act, obj, eft'", policy) - } - // subject - subject := strings.Trim(policyComponents[1], " ") - expectedSubject := fmt.Sprintf("proj:%s:%s", proj, role) - if subject != expectedSubject { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': policy subject must be: '%s', not '%s'", policy, expectedSubject, subject) - } - // resource - resource := strings.Trim(policyComponents[2], " ") - if resource != "applications" { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', not '%s'", policy, resource) - } - // action - action := strings.Trim(policyComponents[3], " ") - if !isValidAction(action) { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': invalid action '%s'", policy, action) - } - // object - object := strings.Trim(policyComponents[4], " ") - objectRegexp, err := regexp.Compile(fmt.Sprintf(`^%s/[*\w-]+$`, proj)) - if err != nil || !objectRegexp.MatchString(object) { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': object must be of form '%s/*' or '%s/', not '%s'", policy, proj, proj, object) - } - // effect - effect := strings.Trim(policyComponents[5], " ") - if effect != "allow" && effect != "deny" { - return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': effect must be: 'allow' or 'deny'", policy) - } - return nil -} - -var roleNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9]([-_a-zA-Z0-9]*[a-zA-Z0-9])?$`) - -func validateRoleName(name string) error { - if !roleNameRegexp.MatchString(name) { - return status.Errorf(codes.InvalidArgument, "invalid role name '%s'. Must consist of alphanumeric characters, '-' or '_', and must start and end with an alphanumeric character", name) - } - return nil -} - -var invalidChars = regexp.MustCompile("[,\n\r\t]") - -func validateGroupName(name string) error { - if strings.TrimSpace(name) == "" { - return status.Errorf(codes.InvalidArgument, "group '%s' is empty", name) - } - if invalidChars.MatchString(name) { - return status.Errorf(codes.InvalidArgument, "group '%s' contains invalid characters", name) - } - return nil -} - -// AddGroupToRole adds an OIDC group to a role -func (p *AppProject) AddGroupToRole(roleName, group string) (bool, error) { - role, roleIndex, err := p.GetRoleByName(roleName) - if err != nil { - return false, err - } - for _, roleGroup := range role.Groups { - if group == roleGroup { - return false, nil - } - } - role.Groups = append(role.Groups, group) - p.Spec.Roles[roleIndex] = *role - return true, nil -} - -// RemoveGroupFromRole removes an OIDC group from a role -func (p *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { - role, roleIndex, err := p.GetRoleByName(roleName) - if err != nil { - return false, err - } - for i, roleGroup := range role.Groups { - if group == roleGroup { - role.Groups = append(role.Groups[:i], role.Groups[i+1:]...) - p.Spec.Roles[roleIndex] = *role - return true, nil - } - } - return false, nil -} - -// NormalizePolicies normalizes the policies in the project -func (p *AppProject) NormalizePolicies() { - for i, role := range p.Spec.Roles { - var normalizedPolicies []string - for _, policy := range role.Policies { - normalizedPolicies = append(normalizedPolicies, p.normalizePolicy(policy)) - } - p.Spec.Roles[i].Policies = normalizedPolicies - } -} - -func (p *AppProject) normalizePolicy(policy string) string { - policyComponents := strings.Split(policy, ",") - normalizedPolicy := "" - for _, component := range policyComponents { - if normalizedPolicy == "" { - normalizedPolicy = component - } else { - normalizedPolicy = fmt.Sprintf("%s, %s", normalizedPolicy, strings.Trim(component, " ")) - } - } - return normalizedPolicy -} - -// OrphanedResourcesMonitorSettings holds settings of orphaned resources monitoring -type OrphanedResourcesMonitorSettings struct { - // Warn indicates if warning condition should be created for apps which have orphaned resources - Warn *bool `json:"warn,omitempty" protobuf:"bytes,1,name=warn"` -} - -func (s *OrphanedResourcesMonitorSettings) IsWarn() bool { - return s.Warn == nil || *s.Warn -} - -// AppProjectSpec is the specification of an AppProject -type AppProjectSpec struct { - // SourceRepos contains list of repository URLs which can be used for deployment - SourceRepos []string `json:"sourceRepos,omitempty" protobuf:"bytes,1,name=sourceRepos"` - // Destinations contains list of destinations available for deployment - Destinations []ApplicationDestination `json:"destinations,omitempty" protobuf:"bytes,2,name=destination"` - // Description contains optional project description - Description string `json:"description,omitempty" protobuf:"bytes,3,opt,name=description"` - // Roles are user defined RBAC roles associated with this project - Roles []ProjectRole `json:"roles,omitempty" protobuf:"bytes,4,rep,name=roles"` - // ClusterResourceWhitelist contains list of whitelisted cluster level resources - ClusterResourceWhitelist []metav1.GroupKind `json:"clusterResourceWhitelist,omitempty" protobuf:"bytes,5,opt,name=clusterResourceWhitelist"` - // NamespaceResourceBlacklist contains list of blacklisted namespace level resources - NamespaceResourceBlacklist []metav1.GroupKind `json:"namespaceResourceBlacklist,omitempty" protobuf:"bytes,6,opt,name=namespaceResourceBlacklist"` - // OrphanedResources specifies if controller should monitor orphaned resources of apps in this project - OrphanedResources *OrphanedResourcesMonitorSettings `json:"orphanedResources,omitempty" protobuf:"bytes,7,opt,name=orphanedResources"` - // SyncWindows controls when syncs can be run for apps in this project - SyncWindows SyncWindows `json:"syncWindows,omitempty" protobuf:"bytes,8,opt,name=syncWindows"` -} - -// SyncWindows is a collection of sync windows in this project -type SyncWindows []*SyncWindow - -// SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps -type SyncWindow struct { - // Kind defines if the window allows or blocks syncs - Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"` - // Schedule is the time the window will begin, specified in cron format - Schedule string `json:"schedule,omitempty" protobuf:"bytes,2,opt,name=schedule"` - // Duration is the amount of time the sync window will be open - Duration string `json:"duration,omitempty" protobuf:"bytes,3,opt,name=duration"` - // Applications contains a list of applications that the window will apply to - Applications []string `json:"applications,omitempty" protobuf:"bytes,4,opt,name=applications"` - // Namespaces contains a list of namespaces that the window will apply to - Namespaces []string `json:"namespaces,omitempty" protobuf:"bytes,5,opt,name=namespaces"` - // Clusters contains a list of clusters that the window will apply to - Clusters []string `json:"clusters,omitempty" protobuf:"bytes,6,opt,name=clusters"` - // ManualSync enables manual syncs when they would otherwise be blocked - ManualSync bool `json:"manualSync,omitempty" protobuf:"bytes,7,opt,name=manualSync"` -} - -func (s *SyncWindows) HasWindows() bool { - return s != nil && len(*s) > 0 -} - -func (s *SyncWindows) Active() *SyncWindows { - if s.HasWindows() { - var active SyncWindows - specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - for _, w := range *s { - schedule, _ := specParser.Parse(w.Schedule) - duration, _ := time.ParseDuration(w.Duration) - now := time.Now() - nextWindow := schedule.Next(now.Add(-duration)) - if nextWindow.Before(now) { - active = append(active, w) - } - } - if len(active) > 0 { - return &active - } - } - return nil -} - -func (s *SyncWindows) InactiveAllows() *SyncWindows { - if s.HasWindows() { - var inactive SyncWindows - specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - for _, w := range *s { - if w.Kind == "allow" { - schedule, sErr := specParser.Parse(w.Schedule) - duration, dErr := time.ParseDuration(w.Duration) - now := time.Now() - nextWindow := schedule.Next(now.Add(-duration)) - if !nextWindow.Before(now) && sErr == nil && dErr == nil { - inactive = append(inactive, w) - } - } - } - if len(inactive) > 0 { - return &inactive - } - } - return nil -} - -func (s *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []string, ns []string, cl []string, ms bool) error { - if len(knd) == 0 || len(sch) == 0 || len(dur) == 0 { - return fmt.Errorf("cannot create window: require kind, schedule, duration and one or more of applications, namespaces and clusters") - - } - window := &SyncWindow{ - Kind: knd, - Schedule: sch, - Duration: dur, - ManualSync: ms, - } - - if len(app) > 0 { - window.Applications = app - } - if len(ns) > 0 { - window.Namespaces = ns - } - if len(cl) > 0 { - window.Clusters = cl - } - - err := window.Validate() - if err != nil { - return err - } - - s.SyncWindows = append(s.SyncWindows, window) - - return nil - -} - -func (s *AppProjectSpec) DeleteWindow(id int) error { - var exists bool - for i := range s.SyncWindows { - if i == id { - exists = true - s.SyncWindows = append(s.SyncWindows[:i], s.SyncWindows[i+1:]...) - break - } - } - if !exists { - return fmt.Errorf("window with id '%s' not found", strconv.Itoa(id)) - } - return nil -} - -func (w *SyncWindows) Matches(app *Application) *SyncWindows { - if w.HasWindows() { - var matchingWindows SyncWindows - for _, w := range *w { - if len(w.Applications) > 0 { - for _, a := range w.Applications { - if globMatch(a, app.Name) { - matchingWindows = append(matchingWindows, w) - break - } - } - } - if len(w.Clusters) > 0 { - for _, c := range w.Clusters { - if globMatch(c, app.Spec.Destination.Server) { - matchingWindows = append(matchingWindows, w) - break - } - } - } - if len(w.Namespaces) > 0 { - for _, n := range w.Namespaces { - if globMatch(n, app.Spec.Destination.Namespace) { - matchingWindows = append(matchingWindows, w) - break - } - } - } - } - if len(matchingWindows) > 0 { - return &matchingWindows - } - } - return nil -} - -func (w *SyncWindows) CanSync(isManual bool) bool { - if !w.HasWindows() { - return true - } - - var allowActive, denyActive, manualEnabled bool - active := w.Active() - denyActive, manualEnabled = active.hasDeny() - allowActive = active.hasAllow() - - if !denyActive { - if !allowActive { - if isManual && w.InactiveAllows().manualEnabled() { - return true - } - } else { - return true - } - } else { - if isManual && manualEnabled { - return true - } - } - - return false -} - -func (w *SyncWindows) hasDeny() (bool, bool) { - if !w.HasWindows() { - return false, false - } - var denyActive, manualEnabled bool - for _, a := range *w { - if a.Kind == "deny" { - if !denyActive { - manualEnabled = a.ManualSync - } else { - if manualEnabled { - if !a.ManualSync { - manualEnabled = a.ManualSync - } - } - } - denyActive = true - } - } - return denyActive, manualEnabled -} - -func (w *SyncWindows) hasAllow() bool { - if !w.HasWindows() { - return false - } - for _, a := range *w { - if a.Kind == "allow" { - return true - } - } - return false -} - -func (w *SyncWindows) manualEnabled() bool { - if !w.HasWindows() { - return false - } - for _, s := range *w { - if s.ManualSync { - return true - } - } - return false -} - -func (w SyncWindow) Active() bool { - specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - schedule, _ := specParser.Parse(w.Schedule) - duration, _ := time.ParseDuration(w.Duration) - now := time.Now() - nextWindow := schedule.Next(now.Add(-duration)) - return nextWindow.Before(now) -} - -func (w *SyncWindow) Update(s string, d string, a []string, n []string, c []string) error { - if len(s) == 0 && len(d) == 0 && len(a) == 0 && len(n) == 0 && len(c) == 0 { - return fmt.Errorf("cannot update: require one or more of schedule, duration, application, namespace, or cluster") - } - - if len(s) > 0 { - w.Schedule = s - } - - if len(d) > 0 { - w.Duration = d - } - - if len(a) > 0 { - w.Applications = a - } - if len(n) > 0 { - w.Namespaces = n - } - if len(c) > 0 { - w.Clusters = c - } - - return nil -} - -func (w *SyncWindow) Validate() error { - if w.Kind != "allow" && w.Kind != "deny" { - return fmt.Errorf("kind '%s' mismatch: can only be allow or deny", w.Kind) - } - specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - _, err := specParser.Parse(w.Schedule) - if err != nil { - return fmt.Errorf("cannot parse schedule '%s': %s", w.Schedule, err) - } - _, err = time.ParseDuration(w.Duration) - if err != nil { - return fmt.Errorf("cannot parse duration '%s': %s", w.Duration, err) - } - return nil -} - -func (d AppProjectSpec) DestinationClusters() []string { - servers := make([]string, 0) - - for _, d := range d.Destinations { - servers = append(servers, d.Server) - } - - return servers -} - -// ProjectRole represents a role that has access to a project -type ProjectRole struct { - // Name is a name for this role - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Description is a description of the role - Description string `json:"description,omitempty" protobuf:"bytes,2,opt,name=description"` - // Policies Stores a list of casbin formated strings that define access policies for the role in the project - Policies []string `json:"policies,omitempty" protobuf:"bytes,3,rep,name=policies"` - // JWTTokens are a list of generated JWT tokens bound to this role - JWTTokens []JWTToken `json:"jwtTokens,omitempty" protobuf:"bytes,4,rep,name=jwtTokens"` - // Groups are a list of OIDC group claims bound to this role - Groups []string `json:"groups,omitempty" protobuf:"bytes,5,rep,name=groups"` -} - -// JWTToken holds the issuedAt and expiresAt values of a token -type JWTToken struct { - IssuedAt int64 `json:"iat" protobuf:"int64,1,opt,name=iat"` - ExpiresAt int64 `json:"exp,omitempty" protobuf:"int64,2,opt,name=exp"` -} - -// Command holds binary path and arguments list -type Command struct { - Command []string `json:"command,omitempty" protobuf:"bytes,1,name=command"` - Args []string `json:"args,omitempty" protobuf:"bytes,2,rep,name=args"` -} - -// ConfigManagementPlugin contains config management plugin configuration -type ConfigManagementPlugin struct { - Name string `json:"name" protobuf:"bytes,1,name=name"` - Init *Command `json:"init,omitempty" protobuf:"bytes,2,name=init"` - Generate Command `json:"generate" protobuf:"bytes,3,name=generate"` -} - -// KustomizeOptions are options for kustomize to use when building manifests -type KustomizeOptions struct { - // BuildOptions is a string of build parameters to use when calling `kustomize build` - BuildOptions string `protobuf:"bytes,1,opt,name=buildOptions"` -} - -// ProjectPoliciesString returns Casbin formated string of a project's policies for each role -func (proj *AppProject) ProjectPoliciesString() string { - var policies []string - for _, role := range proj.Spec.Roles { - projectPolicy := fmt.Sprintf("p, proj:%s:%s, projects, get, %s, allow", proj.ObjectMeta.Name, role.Name, proj.ObjectMeta.Name) - policies = append(policies, projectPolicy) - policies = append(policies, role.Policies...) - for _, groupName := range role.Groups { - policies = append(policies, fmt.Sprintf("g, %s, proj:%s:%s", groupName, proj.ObjectMeta.Name, role.Name)) - } - } - return strings.Join(policies, "\n") -} - -func (app *Application) getFinalizerIndex(name string) int { - for i, finalizer := range app.Finalizers { - if finalizer == name { - return i - } - } - return -1 -} - -// CascadedDeletion indicates if resources finalizer is set and controller should delete app resources before deleting app -func (app *Application) CascadedDeletion() bool { - return app.getFinalizerIndex(common.ResourcesFinalizerName) > -1 -} - -func (app *Application) IsRefreshRequested() (RefreshType, bool) { - refreshType := RefreshTypeNormal - annotations := app.GetAnnotations() - if annotations == nil { - return refreshType, false - } - - typeStr, ok := annotations[common.AnnotationKeyRefresh] - if !ok { - return refreshType, false - } - - if typeStr == string(RefreshTypeHard) { - refreshType = RefreshTypeHard - } - - return refreshType, true -} - -// SetCascadedDeletion sets or remove resources finalizer -func (app *Application) SetCascadedDeletion(prune bool) { - index := app.getFinalizerIndex(common.ResourcesFinalizerName) - if prune != (index > -1) { - if index > -1 { - app.Finalizers[index] = app.Finalizers[len(app.Finalizers)-1] - app.Finalizers = app.Finalizers[:len(app.Finalizers)-1] - } else { - app.Finalizers = append(app.Finalizers, common.ResourcesFinalizerName) - } - } -} - -func (status *ApplicationStatus) SetConditions(conditions []ApplicationCondition, evaluatedTypes map[ApplicationConditionType]bool) { - appConditions := make([]ApplicationCondition, 0) - for i := 0; i < len(status.Conditions); i++ { - condition := status.Conditions[i] - if _, ok := evaluatedTypes[condition.Type]; !ok { - appConditions = append(appConditions, condition) - } - } - for i := range conditions { - condition := conditions[i] - appConditions = append(appConditions, condition) - } - status.Conditions = appConditions -} - -func (status *ApplicationStatus) GetConditions(conditionTypes map[ApplicationConditionType]bool) []ApplicationCondition { - result := make([]ApplicationCondition, 0) - for i := range status.Conditions { - condition := status.Conditions[i] - if ok := conditionTypes[condition.Type]; ok { - result = append(result, condition) - } - } - return result -} - -// IsError returns true if condition is error condition -func (condition *ApplicationCondition) IsError() bool { - return strings.HasSuffix(condition.Type, "Error") -} - -// Equals compares two instances of ApplicationSource and return true if instances are equal. -func (source *ApplicationSource) Equals(other ApplicationSource) bool { - return reflect.DeepEqual(*source, other) -} - -func (source *ApplicationSource) ExplicitType() (*ApplicationSourceType, error) { - var appTypes []ApplicationSourceType - if source.Kustomize != nil { - appTypes = append(appTypes, ApplicationSourceTypeKustomize) - } - if source.Helm != nil { - appTypes = append(appTypes, ApplicationSourceTypeHelm) - } - if source.Ksonnet != nil { - appTypes = append(appTypes, ApplicationSourceTypeKsonnet) - } - if source.Directory != nil { - appTypes = append(appTypes, ApplicationSourceTypeDirectory) - } - if source.Plugin != nil { - appTypes = append(appTypes, ApplicationSourceTypePlugin) - } - if len(appTypes) == 0 { - return nil, nil - } - if len(appTypes) > 1 { - typeNames := make([]string, len(appTypes)) - for i := range appTypes { - typeNames[i] = string(appTypes[i]) - } - return nil, fmt.Errorf("multiple application sources defined: %s", strings.Join(typeNames, ",")) - } - appType := appTypes[0] - return &appType, nil -} - -// Equals compares two instances of ApplicationDestination and return true if instances are equal. -func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { - return reflect.DeepEqual(dest, other) -} - -// GetProject returns the application's project. This is preferred over spec.Project which may be empty -func (spec ApplicationSpec) GetProject() string { - if spec.Project == "" { - return common.DefaultAppProjectName - } - return spec.Project -} - -func isResourceInList(res metav1.GroupKind, list []metav1.GroupKind) bool { - for _, item := range list { - ok, err := filepath.Match(item.Kind, res.Kind) - if ok && err == nil { - ok, err = filepath.Match(item.Group, res.Group) - if ok && err == nil { - return true - } - } - } - return false -} - -// IsResourcePermitted validates if the given resource group/kind is permitted to be deployed in the project -func (proj AppProject) IsResourcePermitted(res metav1.GroupKind, namespaced bool) bool { - if namespaced { - return !isResourceInList(res, proj.Spec.NamespaceResourceBlacklist) - } else { - return isResourceInList(res, proj.Spec.ClusterResourceWhitelist) - } -} - -func globMatch(pattern string, val string) bool { - if pattern == "*" { - return true - } - if ok, err := filepath.Match(pattern, val); ok && err == nil { - return true - } - return false -} - -// IsSourcePermitted validates if the provided application's source is a one of the allowed sources for the project. -func (proj AppProject) IsSourcePermitted(src ApplicationSource) bool { - srcNormalized := git.NormalizeGitURL(src.RepoURL) - for _, repoURL := range proj.Spec.SourceRepos { - normalized := git.NormalizeGitURL(repoURL) - if globMatch(normalized, srcNormalized) { - return true - } - } - return false -} - -// IsDestinationPermitted validates if the provided application's destination is one of the allowed destinations for the project -func (proj AppProject) IsDestinationPermitted(dst ApplicationDestination) bool { - for _, item := range proj.Spec.Destinations { - if globMatch(item.Server, dst.Server) && globMatch(item.Namespace, dst.Namespace) { - return true - } - } - return false -} - -// RESTConfig returns a go-client REST config from cluster -func (c *Cluster) RESTConfig() *rest.Config { - var config *rest.Config - var err error - if c.Server == common.KubernetesInternalAPIServerAddr && os.Getenv(common.EnvVarFakeInClusterConfig) == "true" { - conf, exists := os.LookupEnv("KUBECONFIG") - if exists { - config, err = clientcmd.BuildConfigFromFlags("", conf) - } else { - config, err = clientcmd.BuildConfigFromFlags("", filepath.Join(os.Getenv("HOME"), ".kube", "config")) - } - } else if c.Server == common.KubernetesInternalAPIServerAddr && c.Config.Username == "" && c.Config.Password == "" && c.Config.BearerToken == "" { - config, err = rest.InClusterConfig() - } else { - tlsClientConfig := rest.TLSClientConfig{ - Insecure: c.Config.TLSClientConfig.Insecure, - ServerName: c.Config.TLSClientConfig.ServerName, - CertData: c.Config.TLSClientConfig.CertData, - KeyData: c.Config.TLSClientConfig.KeyData, - CAData: c.Config.TLSClientConfig.CAData, - } - if c.Config.AWSAuthConfig != nil { - args := []string{"token", "-i", c.Config.AWSAuthConfig.ClusterName} - if c.Config.AWSAuthConfig.RoleARN != "" { - args = append(args, "-r", c.Config.AWSAuthConfig.RoleARN) - } - config = &rest.Config{ - Host: c.Server, - TLSClientConfig: tlsClientConfig, - ExecProvider: &api.ExecConfig{ - APIVersion: "client.authentication.k8s.io/v1alpha1", - Command: "aws-iam-authenticator", - Args: args, - }, - } - } else { - config = &rest.Config{ - Host: c.Server, - Username: c.Config.Username, - Password: c.Config.Password, - BearerToken: c.Config.BearerToken, - TLSClientConfig: tlsClientConfig, - } - } - } - if err != nil { - panic(fmt.Sprintf("Unable to create K8s REST config: %v", err)) - } - config.QPS = common.K8sClientConfigQPS - config.Burst = common.K8sClientConfigBurst - return config -} - -func UnmarshalToUnstructured(resource string) (*unstructured.Unstructured, error) { - if resource == "" || resource == "null" { - return nil, nil - } - var obj unstructured.Unstructured - err := json.Unmarshal([]byte(resource), &obj) - if err != nil { - return nil, err - } - return &obj, nil -} - -func (r ResourceDiff) LiveObject() (*unstructured.Unstructured, error) { - return UnmarshalToUnstructured(r.LiveState) -} - -func (r ResourceDiff) TargetObject() (*unstructured.Unstructured, error) { - return UnmarshalToUnstructured(r.TargetState) -} diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go deleted file mode 100644 index 4c81da1fe..000000000 --- a/pkg/apis/application/v1alpha1/types_test.go +++ /dev/null @@ -1,1213 +0,0 @@ -package v1alpha1 - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestAppProject_IsSourcePermitted(t *testing.T) { - testData := []struct { - projSources []string - appSource string - isPermitted bool - }{{ - projSources: []string{"*"}, appSource: "https://github.com/argoproj/test.git", isPermitted: true, - }, { - projSources: []string{"https://github.com/argoproj/test.git"}, appSource: "https://github.com/argoproj/test.git", isPermitted: true, - }, { - projSources: []string{"ssh://git@GITHUB.com:argoproj/test"}, appSource: "ssh://git@github.com:argoproj/test", isPermitted: true, - }, { - projSources: []string{"https://github.com/argoproj/*"}, appSource: "https://github.com/argoproj/argoproj.git", isPermitted: true, - }, { - projSources: []string{"https://github.com/test1/test.git", "https://github.com/test2/test.git"}, appSource: "https://github.com/test2/test.git", isPermitted: true, - }, { - projSources: []string{"https://github.com/argoproj/test1.git"}, appSource: "https://github.com/argoproj/test2.git", isPermitted: false, - }, { - projSources: []string{"https://github.com/argoproj/*.git"}, appSource: "https://github.com/argoproj1/test2.git", isPermitted: false, - }, { - projSources: []string{"https://github.com/argoproj/foo"}, appSource: "https://github.com/argoproj/foo1", isPermitted: false, - }} - - for _, data := range testData { - proj := AppProject{ - Spec: AppProjectSpec{ - SourceRepos: data.projSources, - }, - } - assert.Equal(t, proj.IsSourcePermitted(ApplicationSource{ - RepoURL: data.appSource, - }), data.isPermitted) - } -} - -func TestAppProject_IsDestinationPermitted(t *testing.T) { - testData := []struct { - projDest []ApplicationDestination - appDest ApplicationDestination - isPermitted bool - }{{ - projDest: []ApplicationDestination{{ - Server: "https://kubernetes.default.svc", Namespace: "default", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "default"}, - isPermitted: true, - }, { - projDest: []ApplicationDestination{{ - Server: "https://kubernetes.default.svc", Namespace: "default", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "kube-system"}, - isPermitted: false, - }, { - projDest: []ApplicationDestination{{ - Server: "https://my-cluster", Namespace: "default", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "default"}, - isPermitted: false, - }, { - projDest: []ApplicationDestination{{ - Server: "https://kubernetes.default.svc", Namespace: "*", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "kube-system"}, - isPermitted: true, - }, { - projDest: []ApplicationDestination{{ - Server: "https://*.default.svc", Namespace: "default", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "default"}, - isPermitted: true, - }, { - projDest: []ApplicationDestination{{ - Server: "https://team1-*", Namespace: "default", - }}, - appDest: ApplicationDestination{Server: "https://test2-dev-cluster", Namespace: "default"}, - isPermitted: false, - }, { - projDest: []ApplicationDestination{{ - Server: "https://kubernetes.default.svc", Namespace: "test-*", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "test-foo"}, - isPermitted: true, - }, { - projDest: []ApplicationDestination{{ - Server: "https://kubernetes.default.svc", Namespace: "test-*", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "test"}, - isPermitted: false, - }, { - projDest: []ApplicationDestination{{ - Server: "*", Namespace: "*", - }}, - appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "test"}, - isPermitted: true, - }} - - for _, data := range testData { - proj := AppProject{ - Spec: AppProjectSpec{ - Destinations: data.projDest, - }, - } - assert.Equal(t, proj.IsDestinationPermitted(data.appDest), data.isPermitted) - } -} - -func TestAppProject_GetRoleByName(t *testing.T) { - t.Run("NotExists", func(t *testing.T) { - p := &AppProject{} - role, i, err := p.GetRoleByName("test-role") - assert.Error(t, err) - assert.Equal(t, -1, i) - assert.Nil(t, role) - }) - t.Run("NotExists", func(t *testing.T) { - p := AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role"}}}} - role, i, err := p.GetRoleByName("test-role") - assert.NoError(t, err) - assert.Equal(t, 0, i) - assert.Equal(t, &ProjectRole{Name: "test-role"}, role) - }) -} - -func TestAppProject_AddGroupToRole(t *testing.T) { - t.Run("NoRole", func(t *testing.T) { - p := &AppProject{} - got, err := p.AddGroupToRole("test-role", "test-group") - assert.Error(t, err) - assert.False(t, got) - }) - t.Run("NoGroup", func(t *testing.T) { - p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{}}}}} - got, err := p.AddGroupToRole("test-role", "test-group") - assert.NoError(t, err) - assert.True(t, got) - assert.Len(t, p.Spec.Roles[0].Groups, 1) - }) - t.Run("Exists", func(t *testing.T) { - p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{"test-group"}}}}} - got, err := p.AddGroupToRole("test-role", "test-group") - assert.NoError(t, err) - assert.False(t, got) - }) -} - -func TestAppProject_RemoveGroupFromRole(t *testing.T) { - t.Run("NoRole", func(t *testing.T) { - p := &AppProject{} - got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.Error(t, err) - assert.False(t, got) - }) - t.Run("NoGroup", func(t *testing.T) { - p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{}}}}} - got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.NoError(t, err) - assert.False(t, got) - }) - t.Run("Exists", func(t *testing.T) { - p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{"test-group"}}}}} - got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.NoError(t, err) - assert.True(t, got) - assert.Len(t, p.Spec.Roles[0].Groups, 0) - }) -} - -func newTestProject() *AppProject { - p := AppProject{ - ObjectMeta: v1.ObjectMeta{Name: "my-proj"}, - Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "my-role"}}}, - } - return &p -} - -// TestValidateRoleName tests for an invalid role name -func TestAppProject_ValidateRoleName(t *testing.T) { - p := newTestProject() - err := p.ValidateProject() - assert.NoError(t, err) - badRoleNames := []string{ - "", - " ", - "my role", - "my, role", - "my,role", - "my\nrole", - "my\rrole", - "my:role", - "my-role-", - "-my-role", - } - for _, badName := range badRoleNames { - p.Spec.Roles[0].Name = badName - err = p.ValidateProject() - assert.Error(t, err) - } - goodRoleNames := []string{ - "MY-ROLE", - "1MY-ROLE1", - } - for _, goodName := range goodRoleNames { - p.Spec.Roles[0].Name = goodName - err = p.ValidateProject() - assert.NoError(t, err) - } -} - -// TestValidateGroupName tests for an invalid group name -func TestAppProject_ValidateGroupName(t *testing.T) { - p := newTestProject() - err := p.ValidateProject() - assert.NoError(t, err) - p.Spec.Roles[0].Groups = []string{"mygroup"} - err = p.ValidateProject() - assert.NoError(t, err) - badGroupNames := []string{ - "", - " ", - "my, group", - "my,group", - "my\ngroup", - "my\rgroup", - } - for _, badName := range badGroupNames { - p.Spec.Roles[0].Groups = []string{badName} - err = p.ValidateProject() - assert.Error(t, err) - } - goodGroupNames := []string{ - "my:group", - } - for _, goodName := range goodGroupNames { - p.Spec.Roles[0].Groups = []string{goodName} - err = p.ValidateProject() - assert.NoError(t, err) - } -} - -// TestValidPolicyRules checks valid policy rules -func TestAppProject_ValidPolicyRules(t *testing.T) { - p := newTestProject() - err := p.ValidateProject() - assert.NoError(t, err) - goodPolicies := []string{ - "p, proj:my-proj:my-role, applications, get, my-proj/*, allow", - "p, proj:my-proj:my-role, applications, get, my-proj/*, deny", - "p, proj:my-proj:my-role, applications, get, my-proj/foo, allow", - "p, proj:my-proj:my-role, applications, get, my-proj/*-foo, allow", - "p, proj:my-proj:my-role, applications, get, my-proj/foo-*, allow", - "p, proj:my-proj:my-role, applications, get, my-proj/*-*, allow", - "p, proj:my-proj:my-role, applications, *, my-proj/foo, allow", - "p, proj:my-proj:my-role, applications, create, my-proj/foo, allow", - "p, proj:my-proj:my-role, applications, update, my-proj/foo, allow", - "p, proj:my-proj:my-role, applications, sync, my-proj/foo, allow", - "p, proj:my-proj:my-role, applications, delete, my-proj/foo, allow", - } - for _, good := range goodPolicies { - p.Spec.Roles[0].Policies = []string{good} - err = p.ValidateProject() - assert.NoError(t, err) - } -} - -func TestExplicitType(t *testing.T) { - src := ApplicationSource{ - Ksonnet: &ApplicationSourceKsonnet{ - Environment: "foo", - }, - Kustomize: &ApplicationSourceKustomize{ - NamePrefix: "foo", - }, - Helm: &ApplicationSourceHelm{ - ValueFiles: []string{"foo"}, - }, - } - explicitType, err := src.ExplicitType() - assert.NotNil(t, err) - assert.Nil(t, explicitType) - src = ApplicationSource{ - Helm: &ApplicationSourceHelm{ - ValueFiles: []string{"foo"}, - }, - } - - explicitType, err = src.ExplicitType() - assert.Nil(t, err) - assert.Equal(t, *explicitType, ApplicationSourceTypeHelm) -} - -func TestExplicitTypeWithDirectory(t *testing.T) { - src := ApplicationSource{ - Ksonnet: &ApplicationSourceKsonnet{ - Environment: "foo", - }, - Directory: &ApplicationSourceDirectory{}, - } - _, err := src.ExplicitType() - assert.NotNil(t, err, "cannot add directory with any other types") -} - -func TestAppSourceEquality(t *testing.T) { - left := &ApplicationSource{ - Directory: &ApplicationSourceDirectory{ - Recurse: true, - }, - } - right := left.DeepCopy() - assert.True(t, left.Equals(*right)) - right.Directory.Recurse = false - assert.False(t, left.Equals(*right)) -} - -func TestAppDestinationEquality(t *testing.T) { - left := &ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "default", - } - right := left.DeepCopy() - assert.True(t, left.Equals(*right)) - right.Namespace = "kube-system" - assert.False(t, left.Equals(*right)) -} - -func TestAppProjectSpec_DestinationClusters(t *testing.T) { - tests := []struct { - name string - destinations []ApplicationDestination - want []string - }{ - { - name: "Empty", - destinations: []ApplicationDestination{}, - want: []string{}, - }, - { - name: "SingleValue", - destinations: []ApplicationDestination{{Server: "foo"}}, - want: []string{"foo"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - d := AppProjectSpec{Destinations: tt.destinations} - if got := d.DestinationClusters(); !reflect.DeepEqual(got, tt.want) { - t.Errorf("AppProjectSpec.DestinationClusters() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestRepository_CopyCredentialsFrom(t *testing.T) { - tests := []struct { - name string - repo *Repository - source *Repository - want Repository - }{ - {"Username", &Repository{Username: "foo"}, &Repository{}, Repository{Username: "foo"}}, - {"Password", &Repository{Password: "foo"}, &Repository{}, Repository{Password: "foo"}}, - {"SSHPrivateKey", &Repository{SSHPrivateKey: "foo"}, &Repository{}, Repository{SSHPrivateKey: "foo"}}, - {"InsecureHostKey", &Repository{InsecureIgnoreHostKey: true}, &Repository{}, Repository{InsecureIgnoreHostKey: true}}, - {"Insecure", &Repository{Insecure: true}, &Repository{}, Repository{Insecure: true}}, - {"EnableLFS", &Repository{EnableLFS: true}, &Repository{}, Repository{EnableLFS: true}}, - {"TLSClientCertData", &Repository{TLSClientCertData: "foo"}, &Repository{}, Repository{TLSClientCertData: "foo"}}, - {"TLSClientCertKey", &Repository{TLSClientCertKey: "foo"}, &Repository{}, Repository{TLSClientCertKey: "foo"}}, - {"SourceNil", &Repository{}, nil, Repository{}}, - - {"SourceUsername", &Repository{}, &Repository{Username: "foo"}, Repository{Username: "foo"}}, - {"SourcePassword", &Repository{}, &Repository{Password: "foo"}, Repository{Password: "foo"}}, - {"SourceSSHPrivateKey", &Repository{}, &Repository{SSHPrivateKey: "foo"}, Repository{SSHPrivateKey: "foo"}}, - {"SourceInsecureHostKey", &Repository{}, &Repository{InsecureIgnoreHostKey: true}, Repository{InsecureIgnoreHostKey: true}}, - {"SourceInsecure", &Repository{}, &Repository{Insecure: true}, Repository{Insecure: true}}, - {"SourceEnableLFS", &Repository{}, &Repository{EnableLFS: true}, Repository{EnableLFS: true}}, - {"SourceTLSClientCertData", &Repository{}, &Repository{TLSClientCertData: "foo"}, Repository{TLSClientCertData: "foo"}}, - {"SourceTLSClientCertKey", &Repository{}, &Repository{TLSClientCertKey: "foo"}, Repository{TLSClientCertKey: "foo"}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - r := tt.repo.DeepCopy() - r.CopyCredentialsFrom(tt.source) - assert.Equal(t, tt.want, *r) - }) - } -} - -func TestNewHookType(t *testing.T) { - t.Run("Garbage", func(t *testing.T) { - _, ok := NewHookType("Garbage") - assert.False(t, ok) - }) - t.Run("PreSync", func(t *testing.T) { - hookType, ok := NewHookType("PreSync") - assert.True(t, ok) - assert.Equal(t, HookTypePreSync, hookType) - }) - t.Run("Sync", func(t *testing.T) { - hookType, ok := NewHookType("Sync") - assert.True(t, ok) - assert.Equal(t, HookTypeSync, hookType) - }) - t.Run("PostSync", func(t *testing.T) { - hookType, ok := NewHookType("PostSync") - assert.True(t, ok) - assert.Equal(t, HookTypePostSync, hookType) - }) -} - -func TestNewHookDeletePolicy(t *testing.T) { - t.Run("Garbage", func(t *testing.T) { - _, ok := NewHookDeletePolicy("Garbage") - assert.False(t, ok) - }) - t.Run("HookSucceeded", func(t *testing.T) { - p, ok := NewHookDeletePolicy("HookSucceeded") - assert.True(t, ok) - assert.Equal(t, HookDeletePolicyHookSucceeded, p) - }) - t.Run("HookFailed", func(t *testing.T) { - p, ok := NewHookDeletePolicy("HookFailed") - assert.True(t, ok) - assert.Equal(t, HookDeletePolicyHookFailed, p) - }) - t.Run("BeforeHookCreation", func(t *testing.T) { - p, ok := NewHookDeletePolicy("BeforeHookCreation") - assert.True(t, ok) - assert.Equal(t, HookDeletePolicyBeforeHookCreation, p) - }) -} - -func TestSyncStrategy_Force(t *testing.T) { - type fields struct { - Apply *SyncStrategyApply - Hook *SyncStrategyHook - } - tests := []struct { - name string - fields fields - want bool - }{ - {"TestZero", fields{}, false}, - {"TestApply", fields{Apply: &SyncStrategyApply{}}, false}, - {"TestForceApply", fields{Apply: &SyncStrategyApply{Force: true}}, true}, - {"TestHook", fields{Hook: &SyncStrategyHook{}}, false}, - {"TestForceHook", fields{Hook: &SyncStrategyHook{SyncStrategyApply{Force: true}}}, true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - m := &SyncStrategy{ - Apply: tt.fields.Apply, - Hook: tt.fields.Hook, - } - if got := m.Force(); got != tt.want { - t.Errorf("SyncStrategy.Force() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestSyncOperation_IsApplyStrategy(t *testing.T) { - type fields struct { - SyncStrategy *SyncStrategy - } - tests := []struct { - name string - fields fields - want bool - }{ - {"TestZero", fields{}, false}, - {"TestSyncStrategy", fields{SyncStrategy: &SyncStrategy{}}, false}, - {"TestApplySyncStrategy", fields{SyncStrategy: &SyncStrategy{Apply: &SyncStrategyApply{}}}, true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - o := &SyncOperation{ - SyncStrategy: tt.fields.SyncStrategy, - } - if got := o.IsApplyStrategy(); got != tt.want { - t.Errorf("SyncOperation.IsApplyStrategy() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestResourceResults_Filter(t *testing.T) { - type args struct { - predicate func(r *ResourceResult) bool - } - tests := []struct { - name string - r ResourceResults - args args - want ResourceResults - }{ - {"Nil", nil, args{predicate: func(r *ResourceResult) bool { return true }}, ResourceResults{}}, - {"Empty", ResourceResults{}, args{predicate: func(r *ResourceResult) bool { return true }}, ResourceResults{}}, - {"All", ResourceResults{{}}, args{predicate: func(r *ResourceResult) bool { return true }}, ResourceResults{{}}}, - {"None", ResourceResults{{}}, args{predicate: func(r *ResourceResult) bool { return false }}, ResourceResults{}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := tt.r.Filter(tt.args.predicate); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ResourceResults.Filter() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestResourceResults_Find(t *testing.T) { - type args struct { - group string - kind string - namespace string - name string - phase SyncPhase - } - foo := &ResourceResult{Group: "foo"} - results := ResourceResults{ - &ResourceResult{Group: "bar"}, - foo, - } - tests := []struct { - name string - r ResourceResults - args args - want int - want1 *ResourceResult - }{ - {"TestNil", nil, args{}, 0, nil}, - {"TestNotFound", results, args{}, 0, nil}, - {"TestFound", results, args{group: "foo"}, 1, foo}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, got1 := tt.r.Find(tt.args.group, tt.args.kind, tt.args.namespace, tt.args.name, tt.args.phase) - if got != tt.want { - t.Errorf("ResourceResults.Find() got = %v, want %v", got, tt.want) - } - if !reflect.DeepEqual(got1, tt.want1) { - t.Errorf("ResourceResults.Find() got1 = %v, want %v", got1, tt.want1) - } - }) - } -} - -func TestResourceResults_PruningRequired(t *testing.T) { - needsPruning := &ResourceResult{Status: ResultCodePruneSkipped} - tests := []struct { - name string - r ResourceResults - wantNum int - }{ - {"TestNil", ResourceResults{}, 0}, - {"TestOne", ResourceResults{needsPruning}, 1}, - {"TestTwo", ResourceResults{needsPruning, needsPruning}, 2}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotNum := tt.r.PruningRequired(); gotNum != tt.wantNum { - t.Errorf("ResourceResults.PruningRequired() = %v, want %v", gotNum, tt.wantNum) - } - }) - } -} - -func TestApplicationSource_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSource - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSource{}, true}, - {"RepoURL", &ApplicationSource{RepoURL: "foo"}, false}, - {"Path", &ApplicationSource{Path: "foo"}, false}, - {"TargetRevision", &ApplicationSource{TargetRevision: "foo"}, false}, - {"Helm", &ApplicationSource{Helm: &ApplicationSourceHelm{ReleaseName: "foo"}}, false}, - {"Kustomize", &ApplicationSource{Kustomize: &ApplicationSourceKustomize{Images: KustomizeImages{""}}}, false}, - {"Helm", &ApplicationSource{Ksonnet: &ApplicationSourceKsonnet{Environment: "foo"}}, false}, - {"Directory", &ApplicationSource{Directory: &ApplicationSourceDirectory{Recurse: true}}, false}, - {"Plugin", &ApplicationSource{Plugin: &ApplicationSourcePlugin{Name: "foo"}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourceHelm_AddParameter(t *testing.T) { - src := ApplicationSourceHelm{} - t.Run("Add", func(t *testing.T) { - src.AddParameter(HelmParameter{Value: "bar"}) - assert.ElementsMatch(t, []HelmParameter{{Value: "bar"}}, src.Parameters) - - }) - t.Run("Replace", func(t *testing.T) { - src.AddParameter(HelmParameter{Value: "baz"}) - assert.ElementsMatch(t, []HelmParameter{{Value: "baz"}}, src.Parameters) - }) -} - -func TestNewHelmParameter(t *testing.T) { - t.Run("Invalid", func(t *testing.T) { - _, err := NewHelmParameter("garbage", false) - assert.EqualError(t, err, "Expected helm parameter of the form: param=value. Received: garbage") - }) - t.Run("NonString", func(t *testing.T) { - p, err := NewHelmParameter("foo=bar", false) - assert.NoError(t, err) - assert.Equal(t, &HelmParameter{Name: "foo", Value: "bar"}, p) - }) - t.Run("String", func(t *testing.T) { - p, err := NewHelmParameter("foo=bar", true) - assert.NoError(t, err) - assert.Equal(t, &HelmParameter{Name: "foo", Value: "bar", ForceString: true}, p) - }) -} - -func TestApplicationSourceHelm_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSourceHelm - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourceHelm{}, true}, - {"ValueFiles", &ApplicationSourceHelm{ValueFiles: []string{""}}, false}, - {"Parameters", &ApplicationSourceHelm{Parameters: []HelmParameter{{}}}, false}, - {"ReleaseName", &ApplicationSourceHelm{ReleaseName: "foa"}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourceKustomize_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSourceKustomize - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourceKustomize{}, true}, - {"NamePrefix", &ApplicationSourceKustomize{NamePrefix: "foo"}, false}, - {"Images", &ApplicationSourceKustomize{Images: []KustomizeImage{""}}, false}, - {"CommonLabels", &ApplicationSourceKustomize{CommonLabels: map[string]string{"": ""}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourceJsonnet_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSourceJsonnet - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourceJsonnet{}, true}, - {"ExtVars", &ApplicationSourceJsonnet{ExtVars: []JsonnetVar{{}}}, false}, - {"TLAs", &ApplicationSourceJsonnet{TLAs: []JsonnetVar{{}}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourceKsonnet_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSourceKsonnet - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourceKsonnet{}, true}, - {"Environment", &ApplicationSourceKsonnet{Environment: "foo"}, false}, - {"Parameters", &ApplicationSourceKsonnet{Parameters: []KsonnetParameter{{}}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourceDirectory_IsZero(t *testing.T) { - tests := []struct { - name string - source *ApplicationSourceDirectory - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourceDirectory{}, true}, - {"Recurse", &ApplicationSourceDirectory{Recurse: true}, false}, - {"Jsonnet", &ApplicationSourceDirectory{Jsonnet: ApplicationSourceJsonnet{ExtVars: []JsonnetVar{{}}}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestApplicationSourcePlugin_IsZero(t *testing.T) { - - tests := []struct { - name string - source *ApplicationSourcePlugin - want bool - }{ - {"Nil", nil, true}, - {"Empty", &ApplicationSourcePlugin{}, true}, - {"Name", &ApplicationSourcePlugin{Name: "foo"}, false}, - {"Env", &ApplicationSourcePlugin{Env: Env{{}}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.source.IsZero()) - }) - } -} - -func TestEnvEntry_IsZero(t *testing.T) { - tests := []struct { - name string - env *EnvEntry - want bool - }{ - {"Nil", nil, true}, - {"Empty", &EnvEntry{}, true}, - {"Name", &EnvEntry{Name: "FOO"}, false}, - {"Value", &EnvEntry{Value: "foo"}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.env.IsZero()) - }) - } -} - -func TestEnv_IsZero(t *testing.T) { - tests := []struct { - name string - e Env - want bool - }{ - {"Empty", Env{}, true}, - {"One", Env{{}}, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.e.IsZero()) - }) - } -} - -func TestEnv_Environ(t *testing.T) { - tests := []struct { - name string - e Env - want []string - }{ - {"Nil", nil, nil}, - {"Env", Env{{}}, nil}, - {"One", Env{{"FOO", "bar"}}, []string{"FOO=bar"}}, - {"Two", Env{{"FOO", "bar"}, {"FOO", "bar"}}, []string{"FOO=bar", "FOO=bar"}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.e.Environ()) - }) - } -} - -func TestKustomizeImage_Match(t *testing.T) { - // no pefix - assert.False(t, KustomizeImage("foo=1").Match("bar=1")) - // mismatched delimiter - assert.False(t, KustomizeImage("foo=1").Match("bar:1")) - assert.False(t, KustomizeImage("foo:1").Match("bar=1")) - // matches - assert.True(t, KustomizeImage("foo=1").Match("foo=2")) - assert.True(t, KustomizeImage("foo:1").Match("foo:2")) - assert.True(t, KustomizeImage("foo@1").Match("foo@2")) -} - -func TestApplicationSourceKustomize_MergeImage(t *testing.T) { - t.Run("Add", func(t *testing.T) { - k := ApplicationSourceKustomize{Images: KustomizeImages{}} - k.MergeImage("foo=1") - assert.Equal(t, KustomizeImages{"foo=1"}, k.Images) - }) - t.Run("Replace", func(t *testing.T) { - k := ApplicationSourceKustomize{Images: KustomizeImages{"foo=1"}} - k.MergeImage("foo=2") - assert.Equal(t, KustomizeImages{"foo=2"}, k.Images) - }) -} - -func TestSyncWindows_HasWindows(t *testing.T) { - t.Run("True", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - assert.True(t, proj.Spec.SyncWindows.HasWindows()) - }) - t.Run("False", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - err := proj.Spec.DeleteWindow(0) - assert.NoError(t, err) - assert.False(t, proj.Spec.SyncWindows.HasWindows()) - }) -} - -func TestSyncWindows_Active(t *testing.T) { - proj := newTestProjectWithSyncWindows() - assert.Equal(t, 1, len(*proj.Spec.SyncWindows.Active())) -} - -func TestSyncWindows_InactiveAllows(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 1 1" - assert.Equal(t, 1, len(*proj.Spec.SyncWindows.InactiveAllows())) -} - -func TestAppProjectSpec_AddWindow(t *testing.T) { - proj := newTestProjectWithSyncWindows() - tests := []struct { - name string - p *AppProject - k string - s string - d string - a []string - n []string - c []string - m bool - want string - }{ - {"MissingKind", proj, "", "* * * * *", "11", []string{"app1"}, []string{}, []string{}, false, "error"}, - {"MissingSchedule", proj, "allow", "", "", []string{"app1"}, []string{}, []string{}, false, "error"}, - {"MissingDuration", proj, "allow", "* * * * *", "", []string{"app1"}, []string{}, []string{}, false, "error"}, - {"BadSchedule", proj, "allow", "* * *", "1h", []string{"app1"}, []string{}, []string{}, false, "error"}, - {"BadDuration", proj, "deny", "* * * * *", "33mm", []string{"app1"}, []string{}, []string{}, false, "error"}, - {"WorkingApplication", proj, "allow", "1 * * * *", "1h", []string{"app1"}, []string{}, []string{}, false, "noError"}, - {"WorkingNamespace", proj, "deny", "3 * * * *", "1h", []string{}, []string{}, []string{"cluster"}, false, "noError"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - switch tt.want { - case "error": - assert.Error(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m)) - case "noError": - assert.NoError(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m)) - assert.NoError(t, tt.p.Spec.DeleteWindow(0)) - } - }) - - } -} - -func TestAppProjectSpec_DeleteWindow(t *testing.T) { - proj := newTestProjectWithSyncWindows() - window2 := &SyncWindow{Schedule: "1 * * * *", Duration: "2h"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, window2) - t.Run("CannotFind", func(t *testing.T) { - err := proj.Spec.DeleteWindow(3) - assert.Error(t, err) - assert.Equal(t, 2, len(proj.Spec.SyncWindows)) - }) - t.Run("Delete", func(t *testing.T) { - err := proj.Spec.DeleteWindow(0) - assert.NoError(t, err) - assert.Equal(t, 1, len(proj.Spec.SyncWindows)) - }) -} - -func TestSyncWindows_Matches(t *testing.T) { - proj := newTestProjectWithSyncWindows() - app := newTestApp() - t.Run("MatchNamespace", func(t *testing.T) { - proj.Spec.SyncWindows[0].Namespaces = []string{"default"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Equal(t, 1, len(*windows)) - proj.Spec.SyncWindows[0].Namespaces = nil - }) - t.Run("MatchCluster", func(t *testing.T) { - proj.Spec.SyncWindows[0].Clusters = []string{"cluster1"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Equal(t, 1, len(*windows)) - proj.Spec.SyncWindows[0].Clusters = nil - }) - t.Run("MatchAppName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-app"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Equal(t, 1, len(*windows)) - proj.Spec.SyncWindows[0].Applications = nil - }) - t.Run("MatchWildcardAppName", func(t *testing.T) { - proj.Spec.SyncWindows[0].Applications = []string{"test-*"} - windows := proj.Spec.SyncWindows.Matches(app) - assert.Equal(t, 1, len(*windows)) - proj.Spec.SyncWindows[0].Applications = nil - }) - t.Run("NoMatch", func(t *testing.T) { - windows := proj.Spec.SyncWindows.Matches(app) - assert.Nil(t, windows) - }) -} - -func TestSyncWindows_CanSync(t *testing.T) { - t.Run("ManualSync_ActiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny", Schedule: "0 0 1 * *", Duration: "1m"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.True(t, canSync) - }) - t.Run("AutoSync_ActiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny", Schedule: "0 0 1 * *", Duration: "1m"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.True(t, canSync) - }) - t.Run("_ActiveAllowAndInactiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.True(t, canSync) - }) - t.Run("AutoSync_ActiveAllowAndInactiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.True(t, canSync) - }) - t.Run("ManualSync_InactiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.False(t, canSync) - }) - t.Run("AutoSync_InactiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_InactiveAllowWithManualSyncEnabled", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - proj.Spec.SyncWindows[0].ManualSync = true - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.True(t, canSync) - }) - t.Run("AutoSync_InactiveAllowWithManualSyncEnabled", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - proj.Spec.SyncWindows[0].ManualSync = true - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_InactiveAllowAndInactiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - deny := &SyncWindow{Kind: "deny", Schedule: "0 0 1 * *", Duration: "1m"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.False(t, canSync) - }) - t.Run("AutoSync_InactiveAllowAndInactiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Schedule = "0 0 1 * *" - proj.Spec.SyncWindows[0].Duration = "1m" - deny := &SyncWindow{Kind: "deny", Schedule: "0 0 1 * *", Duration: "1m"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_ActiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.False(t, canSync) - }) - t.Run("AutoSync_ActiveDeny", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_ActiveDenyWithManualSyncEnabled", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - proj.Spec.SyncWindows[0].ManualSync = true - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.True(t, canSync) - }) - t.Run("AutoSync_ActiveDenyWithManualSyncEnabled", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - proj.Spec.SyncWindows[0].ManualSync = true - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_MultipleActiveDenyWithManualSyncEnabledOnOne", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - proj.Spec.SyncWindows[0].ManualSync = true - deny2 := &SyncWindow{Kind: "deny", Schedule: "* * * * *", Duration: "2h"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny2) - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.False(t, canSync) - }) - t.Run("AutoSync_MultipleActiveDenyWithManualSyncEnabledOnOne", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - proj.Spec.SyncWindows[0].Schedule = "* * * * *" - proj.Spec.SyncWindows[0].ManualSync = true - deny2 := &SyncWindow{Kind: "deny", Schedule: "* * * * *", Duration: "2h"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny2) - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) - t.Run("ManualSync_ActiveDenyAndActiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny", Schedule: "1 * * * *", Duration: "1h"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(true) - assert.False(t, canSync) - }) - t.Run("AutoSync_ActiveDenyAndActiveAllow", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny", Schedule: "1 * * * *", Duration: "1h"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - canSync := proj.Spec.SyncWindows.CanSync(false) - assert.False(t, canSync) - }) -} - -func TestSyncWindows_hasDeny(t *testing.T) { - t.Run("True", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny"} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - hasDeny, manualEnabled := proj.Spec.SyncWindows.hasDeny() - assert.True(t, hasDeny) - assert.False(t, manualEnabled) - }) - t.Run("TrueManualEnabled", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - deny := &SyncWindow{Kind: "deny", ManualSync: true} - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, deny) - hasDeny, manualEnabled := proj.Spec.SyncWindows.hasDeny() - assert.True(t, hasDeny) - assert.True(t, manualEnabled) - - }) - t.Run("False", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - hasDeny, manualEnabled := proj.Spec.SyncWindows.hasDeny() - assert.False(t, hasDeny) - assert.False(t, manualEnabled) - - }) -} - -func TestSyncWindows_hasAllow(t *testing.T) { - t.Run("NoWindows", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - _ = proj.Spec.DeleteWindow(0) - assert.False(t, proj.Spec.SyncWindows.hasAllow()) - }) - t.Run("True", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - assert.True(t, proj.Spec.SyncWindows.hasAllow()) - }) - t.Run("NoWindows", func(t *testing.T) { - proj := newTestProjectWithSyncWindows() - proj.Spec.SyncWindows[0].Kind = "deny" - assert.False(t, proj.Spec.SyncWindows.hasAllow()) - }) -} - -func TestSyncWindow_Active(t *testing.T) { - window := &SyncWindow{Schedule: "* * * * *", Duration: "1h"} - t.Run("ActiveWindow", func(t *testing.T) { - window.Active() - assert.True(t, window.Active()) - }) -} - -func TestSyncWindow_Update(t *testing.T) { - e := SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h", Applications: []string{"app1"}} - t.Run("AddApplication", func(t *testing.T) { - err := e.Update("", "", []string{"app1", "app2"}, []string{}, []string{}) - assert.NoError(t, err) - assert.Equal(t, []string{"app1", "app2"}, e.Applications) - }) - t.Run("AddNamespace", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{"namespace1"}, []string{}) - assert.NoError(t, err) - assert.Equal(t, []string{"namespace1"}, e.Namespaces) - }) - t.Run("AddCluster", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{}, []string{"cluster1"}) - assert.NoError(t, err) - assert.Equal(t, []string{"cluster1"}, e.Clusters) - }) - t.Run("MissingConfig", func(t *testing.T) { - err := e.Update("", "", []string{}, []string{}, []string{}) - assert.EqualError(t, err, "cannot update: require one or more of schedule, duration, application, namespace, or cluster") - }) - t.Run("ChangeDuration", func(t *testing.T) { - err := e.Update("", "10h", []string{}, []string{}, []string{}) - assert.NoError(t, err) - assert.Equal(t, "10h", e.Duration) - }) - t.Run("ChangeSchedule", func(t *testing.T) { - err := e.Update("* 1 0 0 *", "", []string{}, []string{}, []string{}) - assert.NoError(t, err) - assert.Equal(t, "* 1 0 0 *", e.Schedule) - }) -} - -func TestSyncWindow_Validate(t *testing.T) { - window := &SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} - t.Run("Validates", func(t *testing.T) { - assert.NoError(t, window.Validate()) - }) - t.Run("IncorrectKind", func(t *testing.T) { - window.Kind = "wrong" - assert.Error(t, window.Validate()) - }) - t.Run("IncorrectSchedule", func(t *testing.T) { - window.Kind = "allow" - window.Schedule = "* * *" - assert.Error(t, window.Validate()) - }) - t.Run("IncorrectDuration", func(t *testing.T) { - window.Kind = "allow" - window.Schedule = "* * * * *" - window.Duration = "1000days" - assert.Error(t, window.Validate()) - }) -} - -func TestApplicationStatus_GetConditions(t *testing.T) { - status := ApplicationStatus{ - Conditions: []ApplicationCondition{ - {Type: ApplicationConditionInvalidSpecError}, - {Type: ApplicationConditionRepeatedResourceWarning}, - }, - } - conditions := status.GetConditions(map[ApplicationConditionType]bool{ - ApplicationConditionInvalidSpecError: true, - }) - assert.EqualValues(t, []ApplicationCondition{{Type: ApplicationConditionInvalidSpecError}}, conditions) -} - -func newTestProjectWithSyncWindows() *AppProject { - p := &AppProject{ - ObjectMeta: v1.ObjectMeta{Name: "my-proj"}, - Spec: AppProjectSpec{SyncWindows: SyncWindows{}}} - - window := &SyncWindow{ - Kind: "allow", - Schedule: "* * * * *", - Duration: "1h", - Applications: []string{"app1"}, - Namespaces: []string{"public"}, - } - p.Spec.SyncWindows = append(p.Spec.SyncWindows, window) - return p -} - -func newTestApp() *Application { - a := &Application{ - ObjectMeta: v1.ObjectMeta{Name: "test-app"}, - Spec: ApplicationSpec{ - Destination: ApplicationDestination{ - Namespace: "default", - Server: "cluster1", - }, - }, - } - return a -} diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index ed78aee44..000000000 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,1775 +0,0 @@ -// +build !ignore_autogenerated - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AWSAuthConfig) DeepCopyInto(out *AWSAuthConfig) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSAuthConfig. -func (in *AWSAuthConfig) DeepCopy() *AWSAuthConfig { - if in == nil { - return nil - } - out := new(AWSAuthConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AppProject) DeepCopyInto(out *AppProject) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppProject. -func (in *AppProject) DeepCopy() *AppProject { - if in == nil { - return nil - } - out := new(AppProject) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AppProject) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AppProjectList) DeepCopyInto(out *AppProjectList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]AppProject, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppProjectList. -func (in *AppProjectList) DeepCopy() *AppProjectList { - if in == nil { - return nil - } - out := new(AppProjectList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AppProjectList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AppProjectSpec) DeepCopyInto(out *AppProjectSpec) { - *out = *in - if in.SourceRepos != nil { - in, out := &in.SourceRepos, &out.SourceRepos - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Destinations != nil { - in, out := &in.Destinations, &out.Destinations - *out = make([]ApplicationDestination, len(*in)) - copy(*out, *in) - } - if in.Roles != nil { - in, out := &in.Roles, &out.Roles - *out = make([]ProjectRole, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.ClusterResourceWhitelist != nil { - in, out := &in.ClusterResourceWhitelist, &out.ClusterResourceWhitelist - *out = make([]v1.GroupKind, len(*in)) - copy(*out, *in) - } - if in.NamespaceResourceBlacklist != nil { - in, out := &in.NamespaceResourceBlacklist, &out.NamespaceResourceBlacklist - *out = make([]v1.GroupKind, len(*in)) - copy(*out, *in) - } - if in.OrphanedResources != nil { - in, out := &in.OrphanedResources, &out.OrphanedResources - *out = new(OrphanedResourcesMonitorSettings) - (*in).DeepCopyInto(*out) - } - if in.SyncWindows != nil { - in, out := &in.SyncWindows, &out.SyncWindows - *out = make(SyncWindows, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(SyncWindow) - (*in).DeepCopyInto(*out) - } - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppProjectSpec. -func (in *AppProjectSpec) DeepCopy() *AppProjectSpec { - if in == nil { - return nil - } - out := new(AppProjectSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Application) DeepCopyInto(out *Application) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - if in.Operation != nil { - in, out := &in.Operation, &out.Operation - *out = new(Operation) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. -func (in *Application) DeepCopy() *Application { - if in == nil { - return nil - } - out := new(Application) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Application) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationCondition) DeepCopyInto(out *ApplicationCondition) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationCondition. -func (in *ApplicationCondition) DeepCopy() *ApplicationCondition { - if in == nil { - return nil - } - out := new(ApplicationCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationDestination) DeepCopyInto(out *ApplicationDestination) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationDestination. -func (in *ApplicationDestination) DeepCopy() *ApplicationDestination { - if in == nil { - return nil - } - out := new(ApplicationDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationList) DeepCopyInto(out *ApplicationList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Application, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationList. -func (in *ApplicationList) DeepCopy() *ApplicationList { - if in == nil { - return nil - } - out := new(ApplicationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ApplicationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSource) DeepCopyInto(out *ApplicationSource) { - *out = *in - if in.Helm != nil { - in, out := &in.Helm, &out.Helm - *out = new(ApplicationSourceHelm) - (*in).DeepCopyInto(*out) - } - if in.Kustomize != nil { - in, out := &in.Kustomize, &out.Kustomize - *out = new(ApplicationSourceKustomize) - (*in).DeepCopyInto(*out) - } - if in.Ksonnet != nil { - in, out := &in.Ksonnet, &out.Ksonnet - *out = new(ApplicationSourceKsonnet) - (*in).DeepCopyInto(*out) - } - if in.Directory != nil { - in, out := &in.Directory, &out.Directory - *out = new(ApplicationSourceDirectory) - (*in).DeepCopyInto(*out) - } - if in.Plugin != nil { - in, out := &in.Plugin, &out.Plugin - *out = new(ApplicationSourcePlugin) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSource. -func (in *ApplicationSource) DeepCopy() *ApplicationSource { - if in == nil { - return nil - } - out := new(ApplicationSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourceDirectory) DeepCopyInto(out *ApplicationSourceDirectory) { - *out = *in - in.Jsonnet.DeepCopyInto(&out.Jsonnet) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourceDirectory. -func (in *ApplicationSourceDirectory) DeepCopy() *ApplicationSourceDirectory { - if in == nil { - return nil - } - out := new(ApplicationSourceDirectory) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourceHelm) DeepCopyInto(out *ApplicationSourceHelm) { - *out = *in - if in.ValueFiles != nil { - in, out := &in.ValueFiles, &out.ValueFiles - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = make([]HelmParameter, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourceHelm. -func (in *ApplicationSourceHelm) DeepCopy() *ApplicationSourceHelm { - if in == nil { - return nil - } - out := new(ApplicationSourceHelm) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourceJsonnet) DeepCopyInto(out *ApplicationSourceJsonnet) { - *out = *in - if in.ExtVars != nil { - in, out := &in.ExtVars, &out.ExtVars - *out = make([]JsonnetVar, len(*in)) - copy(*out, *in) - } - if in.TLAs != nil { - in, out := &in.TLAs, &out.TLAs - *out = make([]JsonnetVar, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourceJsonnet. -func (in *ApplicationSourceJsonnet) DeepCopy() *ApplicationSourceJsonnet { - if in == nil { - return nil - } - out := new(ApplicationSourceJsonnet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourceKsonnet) DeepCopyInto(out *ApplicationSourceKsonnet) { - *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = make([]KsonnetParameter, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourceKsonnet. -func (in *ApplicationSourceKsonnet) DeepCopy() *ApplicationSourceKsonnet { - if in == nil { - return nil - } - out := new(ApplicationSourceKsonnet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourceKustomize) DeepCopyInto(out *ApplicationSourceKustomize) { - *out = *in - if in.Images != nil { - in, out := &in.Images, &out.Images - *out = make(KustomizeImages, len(*in)) - copy(*out, *in) - } - if in.CommonLabels != nil { - in, out := &in.CommonLabels, &out.CommonLabels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourceKustomize. -func (in *ApplicationSourceKustomize) DeepCopy() *ApplicationSourceKustomize { - if in == nil { - return nil - } - out := new(ApplicationSourceKustomize) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSourcePlugin) DeepCopyInto(out *ApplicationSourcePlugin) { - *out = *in - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make(Env, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(EnvEntry) - **out = **in - } - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSourcePlugin. -func (in *ApplicationSourcePlugin) DeepCopy() *ApplicationSourcePlugin { - if in == nil { - return nil - } - out := new(ApplicationSourcePlugin) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) { - *out = *in - in.Source.DeepCopyInto(&out.Source) - out.Destination = in.Destination - if in.SyncPolicy != nil { - in, out := &in.SyncPolicy, &out.SyncPolicy - *out = new(SyncPolicy) - (*in).DeepCopyInto(*out) - } - if in.IgnoreDifferences != nil { - in, out := &in.IgnoreDifferences, &out.IgnoreDifferences - *out = make([]ResourceIgnoreDifferences, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Info != nil { - in, out := &in.Info, &out.Info - *out = make([]Info, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSpec. -func (in *ApplicationSpec) DeepCopy() *ApplicationSpec { - if in == nil { - return nil - } - out := new(ApplicationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) { - *out = *in - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]ResourceStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - in.Sync.DeepCopyInto(&out.Sync) - out.Health = in.Health - if in.History != nil { - in, out := &in.History, &out.History - *out = make([]RevisionHistory, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ApplicationCondition, len(*in)) - copy(*out, *in) - } - if in.ReconciledAt != nil { - in, out := &in.ReconciledAt, &out.ReconciledAt - *out = (*in).DeepCopy() - } - if in.OperationState != nil { - in, out := &in.OperationState, &out.OperationState - *out = new(OperationState) - (*in).DeepCopyInto(*out) - } - if in.ObservedAt != nil { - in, out := &in.ObservedAt, &out.ObservedAt - *out = (*in).DeepCopy() - } - in.Summary.DeepCopyInto(&out.Summary) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationStatus. -func (in *ApplicationStatus) DeepCopy() *ApplicationStatus { - if in == nil { - return nil - } - out := new(ApplicationStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationSummary) DeepCopyInto(out *ApplicationSummary) { - *out = *in - if in.ExternalURLs != nil { - in, out := &in.ExternalURLs, &out.ExternalURLs - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Images != nil { - in, out := &in.Images, &out.Images - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSummary. -func (in *ApplicationSummary) DeepCopy() *ApplicationSummary { - if in == nil { - return nil - } - out := new(ApplicationSummary) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationTree) DeepCopyInto(out *ApplicationTree) { - *out = *in - if in.Nodes != nil { - in, out := &in.Nodes, &out.Nodes - *out = make([]ResourceNode, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.OrphanedNodes != nil { - in, out := &in.OrphanedNodes, &out.OrphanedNodes - *out = make([]ResourceNode, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationTree. -func (in *ApplicationTree) DeepCopy() *ApplicationTree { - if in == nil { - return nil - } - out := new(ApplicationTree) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationWatchEvent) DeepCopyInto(out *ApplicationWatchEvent) { - *out = *in - in.Application.DeepCopyInto(&out.Application) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationWatchEvent. -func (in *ApplicationWatchEvent) DeepCopy() *ApplicationWatchEvent { - if in == nil { - return nil - } - out := new(ApplicationWatchEvent) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Cluster) DeepCopyInto(out *Cluster) { - *out = *in - in.Config.DeepCopyInto(&out.Config) - in.ConnectionState.DeepCopyInto(&out.ConnectionState) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. -func (in *Cluster) DeepCopy() *Cluster { - if in == nil { - return nil - } - out := new(Cluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterConfig) DeepCopyInto(out *ClusterConfig) { - *out = *in - in.TLSClientConfig.DeepCopyInto(&out.TLSClientConfig) - if in.AWSAuthConfig != nil { - in, out := &in.AWSAuthConfig, &out.AWSAuthConfig - *out = new(AWSAuthConfig) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfig. -func (in *ClusterConfig) DeepCopy() *ClusterConfig { - if in == nil { - return nil - } - out := new(ClusterConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterList) DeepCopyInto(out *ClusterList) { - *out = *in - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Cluster, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. -func (in *ClusterList) DeepCopy() *ClusterList { - if in == nil { - return nil - } - out := new(ClusterList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Command) DeepCopyInto(out *Command) { - *out = *in - if in.Command != nil { - in, out := &in.Command, &out.Command - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Args != nil { - in, out := &in.Args, &out.Args - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Command. -func (in *Command) DeepCopy() *Command { - if in == nil { - return nil - } - out := new(Command) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComparedTo) DeepCopyInto(out *ComparedTo) { - *out = *in - in.Source.DeepCopyInto(&out.Source) - out.Destination = in.Destination - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComparedTo. -func (in *ComparedTo) DeepCopy() *ComparedTo { - if in == nil { - return nil - } - out := new(ComparedTo) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentParameter) DeepCopyInto(out *ComponentParameter) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentParameter. -func (in *ComponentParameter) DeepCopy() *ComponentParameter { - if in == nil { - return nil - } - out := new(ComponentParameter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ConfigManagementPlugin) DeepCopyInto(out *ConfigManagementPlugin) { - *out = *in - if in.Init != nil { - in, out := &in.Init, &out.Init - *out = new(Command) - (*in).DeepCopyInto(*out) - } - in.Generate.DeepCopyInto(&out.Generate) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigManagementPlugin. -func (in *ConfigManagementPlugin) DeepCopy() *ConfigManagementPlugin { - if in == nil { - return nil - } - out := new(ConfigManagementPlugin) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ConnectionState) DeepCopyInto(out *ConnectionState) { - *out = *in - if in.ModifiedAt != nil { - in, out := &in.ModifiedAt, &out.ModifiedAt - *out = (*in).DeepCopy() - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionState. -func (in *ConnectionState) DeepCopy() *ConnectionState { - if in == nil { - return nil - } - out := new(ConnectionState) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Env) DeepCopyInto(out *Env) { - { - in := &in - *out = make(Env, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(EnvEntry) - **out = **in - } - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Env. -func (in Env) DeepCopy() Env { - if in == nil { - return nil - } - out := new(Env) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvEntry) DeepCopyInto(out *EnvEntry) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvEntry. -func (in *EnvEntry) DeepCopy() *EnvEntry { - if in == nil { - return nil - } - out := new(EnvEntry) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthStatus. -func (in *HealthStatus) DeepCopy() *HealthStatus { - if in == nil { - return nil - } - out := new(HealthStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HelmParameter) DeepCopyInto(out *HelmParameter) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmParameter. -func (in *HelmParameter) DeepCopy() *HelmParameter { - if in == nil { - return nil - } - out := new(HelmParameter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Info) DeepCopyInto(out *Info) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Info. -func (in *Info) DeepCopy() *Info { - if in == nil { - return nil - } - out := new(Info) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfoItem) DeepCopyInto(out *InfoItem) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfoItem. -func (in *InfoItem) DeepCopy() *InfoItem { - if in == nil { - return nil - } - out := new(InfoItem) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JWTToken) DeepCopyInto(out *JWTToken) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTToken. -func (in *JWTToken) DeepCopy() *JWTToken { - if in == nil { - return nil - } - out := new(JWTToken) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JsonnetVar) DeepCopyInto(out *JsonnetVar) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JsonnetVar. -func (in *JsonnetVar) DeepCopy() *JsonnetVar { - if in == nil { - return nil - } - out := new(JsonnetVar) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KsonnetParameter) DeepCopyInto(out *KsonnetParameter) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsonnetParameter. -func (in *KsonnetParameter) DeepCopy() *KsonnetParameter { - if in == nil { - return nil - } - out := new(KsonnetParameter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in KustomizeImages) DeepCopyInto(out *KustomizeImages) { - { - in := &in - *out = make(KustomizeImages, len(*in)) - copy(*out, *in) - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeImages. -func (in KustomizeImages) DeepCopy() KustomizeImages { - if in == nil { - return nil - } - out := new(KustomizeImages) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KustomizeOptions) DeepCopyInto(out *KustomizeOptions) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeOptions. -func (in *KustomizeOptions) DeepCopy() *KustomizeOptions { - if in == nil { - return nil - } - out := new(KustomizeOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Operation) DeepCopyInto(out *Operation) { - *out = *in - if in.Sync != nil { - in, out := &in.Sync, &out.Sync - *out = new(SyncOperation) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Operation. -func (in *Operation) DeepCopy() *Operation { - if in == nil { - return nil - } - out := new(Operation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OperationState) DeepCopyInto(out *OperationState) { - *out = *in - in.Operation.DeepCopyInto(&out.Operation) - if in.SyncResult != nil { - in, out := &in.SyncResult, &out.SyncResult - *out = new(SyncOperationResult) - (*in).DeepCopyInto(*out) - } - in.StartedAt.DeepCopyInto(&out.StartedAt) - if in.FinishedAt != nil { - in, out := &in.FinishedAt, &out.FinishedAt - *out = (*in).DeepCopy() - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperationState. -func (in *OperationState) DeepCopy() *OperationState { - if in == nil { - return nil - } - out := new(OperationState) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OrphanedResourcesMonitorSettings) DeepCopyInto(out *OrphanedResourcesMonitorSettings) { - *out = *in - if in.Warn != nil { - in, out := &in.Warn, &out.Warn - *out = new(bool) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OrphanedResourcesMonitorSettings. -func (in *OrphanedResourcesMonitorSettings) DeepCopy() *OrphanedResourcesMonitorSettings { - if in == nil { - return nil - } - out := new(OrphanedResourcesMonitorSettings) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProjectRole) DeepCopyInto(out *ProjectRole) { - *out = *in - if in.Policies != nil { - in, out := &in.Policies, &out.Policies - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.JWTTokens != nil { - in, out := &in.JWTTokens, &out.JWTTokens - *out = make([]JWTToken, len(*in)) - copy(*out, *in) - } - if in.Groups != nil { - in, out := &in.Groups, &out.Groups - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectRole. -func (in *ProjectRole) DeepCopy() *ProjectRole { - if in == nil { - return nil - } - out := new(ProjectRole) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Repositories) DeepCopyInto(out *Repositories) { - { - in := &in - *out = make(Repositories, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(Repository) - (*in).DeepCopyInto(*out) - } - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repositories. -func (in Repositories) DeepCopy() Repositories { - if in == nil { - return nil - } - out := new(Repositories) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Repository) DeepCopyInto(out *Repository) { - *out = *in - in.ConnectionState.DeepCopyInto(&out.ConnectionState) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repository. -func (in *Repository) DeepCopy() *Repository { - if in == nil { - return nil - } - out := new(Repository) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RepositoryCertificate) DeepCopyInto(out *RepositoryCertificate) { - *out = *in - if in.CertData != nil { - in, out := &in.CertData, &out.CertData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryCertificate. -func (in *RepositoryCertificate) DeepCopy() *RepositoryCertificate { - if in == nil { - return nil - } - out := new(RepositoryCertificate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RepositoryCertificateList) DeepCopyInto(out *RepositoryCertificateList) { - *out = *in - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]RepositoryCertificate, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryCertificateList. -func (in *RepositoryCertificateList) DeepCopy() *RepositoryCertificateList { - if in == nil { - return nil - } - out := new(RepositoryCertificateList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RepositoryList) DeepCopyInto(out *RepositoryList) { - *out = *in - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make(Repositories, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(Repository) - (*in).DeepCopyInto(*out) - } - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryList. -func (in *RepositoryList) DeepCopy() *RepositoryList { - if in == nil { - return nil - } - out := new(RepositoryList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceAction) DeepCopyInto(out *ResourceAction) { - *out = *in - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make([]ResourceActionParam, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceAction. -func (in *ResourceAction) DeepCopy() *ResourceAction { - if in == nil { - return nil - } - out := new(ResourceAction) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceActionDefinition) DeepCopyInto(out *ResourceActionDefinition) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceActionDefinition. -func (in *ResourceActionDefinition) DeepCopy() *ResourceActionDefinition { - if in == nil { - return nil - } - out := new(ResourceActionDefinition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceActionParam) DeepCopyInto(out *ResourceActionParam) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceActionParam. -func (in *ResourceActionParam) DeepCopy() *ResourceActionParam { - if in == nil { - return nil - } - out := new(ResourceActionParam) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceActions) DeepCopyInto(out *ResourceActions) { - *out = *in - if in.Definitions != nil { - in, out := &in.Definitions, &out.Definitions - *out = make([]ResourceActionDefinition, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceActions. -func (in *ResourceActions) DeepCopy() *ResourceActions { - if in == nil { - return nil - } - out := new(ResourceActions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceDiff) DeepCopyInto(out *ResourceDiff) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceDiff. -func (in *ResourceDiff) DeepCopy() *ResourceDiff { - if in == nil { - return nil - } - out := new(ResourceDiff) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceIgnoreDifferences) DeepCopyInto(out *ResourceIgnoreDifferences) { - *out = *in - if in.JSONPointers != nil { - in, out := &in.JSONPointers, &out.JSONPointers - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceIgnoreDifferences. -func (in *ResourceIgnoreDifferences) DeepCopy() *ResourceIgnoreDifferences { - if in == nil { - return nil - } - out := new(ResourceIgnoreDifferences) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceNetworkingInfo) DeepCopyInto(out *ResourceNetworkingInfo) { - *out = *in - if in.TargetLabels != nil { - in, out := &in.TargetLabels, &out.TargetLabels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.TargetRefs != nil { - in, out := &in.TargetRefs, &out.TargetRefs - *out = make([]ResourceRef, len(*in)) - copy(*out, *in) - } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Ingress != nil { - in, out := &in.Ingress, &out.Ingress - *out = make([]corev1.LoadBalancerIngress, len(*in)) - copy(*out, *in) - } - if in.ExternalURLs != nil { - in, out := &in.ExternalURLs, &out.ExternalURLs - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceNetworkingInfo. -func (in *ResourceNetworkingInfo) DeepCopy() *ResourceNetworkingInfo { - if in == nil { - return nil - } - out := new(ResourceNetworkingInfo) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceNode) DeepCopyInto(out *ResourceNode) { - *out = *in - out.ResourceRef = in.ResourceRef - if in.ParentRefs != nil { - in, out := &in.ParentRefs, &out.ParentRefs - *out = make([]ResourceRef, len(*in)) - copy(*out, *in) - } - if in.Info != nil { - in, out := &in.Info, &out.Info - *out = make([]InfoItem, len(*in)) - copy(*out, *in) - } - if in.NetworkingInfo != nil { - in, out := &in.NetworkingInfo, &out.NetworkingInfo - *out = new(ResourceNetworkingInfo) - (*in).DeepCopyInto(*out) - } - if in.Images != nil { - in, out := &in.Images, &out.Images - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Health != nil { - in, out := &in.Health, &out.Health - *out = new(HealthStatus) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceNode. -func (in *ResourceNode) DeepCopy() *ResourceNode { - if in == nil { - return nil - } - out := new(ResourceNode) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceOverride) DeepCopyInto(out *ResourceOverride) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceOverride. -func (in *ResourceOverride) DeepCopy() *ResourceOverride { - if in == nil { - return nil - } - out := new(ResourceOverride) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceRef) DeepCopyInto(out *ResourceRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRef. -func (in *ResourceRef) DeepCopy() *ResourceRef { - if in == nil { - return nil - } - out := new(ResourceRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceResult) DeepCopyInto(out *ResourceResult) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceResult. -func (in *ResourceResult) DeepCopy() *ResourceResult { - if in == nil { - return nil - } - out := new(ResourceResult) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in ResourceResults) DeepCopyInto(out *ResourceResults) { - { - in := &in - *out = make(ResourceResults, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(ResourceResult) - **out = **in - } - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceResults. -func (in ResourceResults) DeepCopy() ResourceResults { - if in == nil { - return nil - } - out := new(ResourceResults) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) { - *out = *in - if in.Health != nil { - in, out := &in.Health, &out.Health - *out = new(HealthStatus) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceStatus. -func (in *ResourceStatus) DeepCopy() *ResourceStatus { - if in == nil { - return nil - } - out := new(ResourceStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RevisionHistory) DeepCopyInto(out *RevisionHistory) { - *out = *in - in.DeployedAt.DeepCopyInto(&out.DeployedAt) - in.Source.DeepCopyInto(&out.Source) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionHistory. -func (in *RevisionHistory) DeepCopy() *RevisionHistory { - if in == nil { - return nil - } - out := new(RevisionHistory) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RevisionMetadata) DeepCopyInto(out *RevisionMetadata) { - *out = *in - in.Date.DeepCopyInto(&out.Date) - if in.Tags != nil { - in, out := &in.Tags, &out.Tags - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionMetadata. -func (in *RevisionMetadata) DeepCopy() *RevisionMetadata { - if in == nil { - return nil - } - out := new(RevisionMetadata) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncOperation) DeepCopyInto(out *SyncOperation) { - *out = *in - if in.SyncStrategy != nil { - in, out := &in.SyncStrategy, &out.SyncStrategy - *out = new(SyncStrategy) - (*in).DeepCopyInto(*out) - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]SyncOperationResource, len(*in)) - copy(*out, *in) - } - if in.Source != nil { - in, out := &in.Source, &out.Source - *out = new(ApplicationSource) - (*in).DeepCopyInto(*out) - } - if in.Manifests != nil { - in, out := &in.Manifests, &out.Manifests - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncOperation. -func (in *SyncOperation) DeepCopy() *SyncOperation { - if in == nil { - return nil - } - out := new(SyncOperation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncOperationResource) DeepCopyInto(out *SyncOperationResource) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncOperationResource. -func (in *SyncOperationResource) DeepCopy() *SyncOperationResource { - if in == nil { - return nil - } - out := new(SyncOperationResource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncOperationResult) DeepCopyInto(out *SyncOperationResult) { - *out = *in - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make(ResourceResults, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(ResourceResult) - **out = **in - } - } - } - in.Source.DeepCopyInto(&out.Source) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncOperationResult. -func (in *SyncOperationResult) DeepCopy() *SyncOperationResult { - if in == nil { - return nil - } - out := new(SyncOperationResult) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncPolicy) DeepCopyInto(out *SyncPolicy) { - *out = *in - if in.Automated != nil { - in, out := &in.Automated, &out.Automated - *out = new(SyncPolicyAutomated) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncPolicy. -func (in *SyncPolicy) DeepCopy() *SyncPolicy { - if in == nil { - return nil - } - out := new(SyncPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncPolicyAutomated) DeepCopyInto(out *SyncPolicyAutomated) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncPolicyAutomated. -func (in *SyncPolicyAutomated) DeepCopy() *SyncPolicyAutomated { - if in == nil { - return nil - } - out := new(SyncPolicyAutomated) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncStatus) DeepCopyInto(out *SyncStatus) { - *out = *in - in.ComparedTo.DeepCopyInto(&out.ComparedTo) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncStatus. -func (in *SyncStatus) DeepCopy() *SyncStatus { - if in == nil { - return nil - } - out := new(SyncStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncStrategy) DeepCopyInto(out *SyncStrategy) { - *out = *in - if in.Apply != nil { - in, out := &in.Apply, &out.Apply - *out = new(SyncStrategyApply) - **out = **in - } - if in.Hook != nil { - in, out := &in.Hook, &out.Hook - *out = new(SyncStrategyHook) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncStrategy. -func (in *SyncStrategy) DeepCopy() *SyncStrategy { - if in == nil { - return nil - } - out := new(SyncStrategy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncStrategyApply) DeepCopyInto(out *SyncStrategyApply) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncStrategyApply. -func (in *SyncStrategyApply) DeepCopy() *SyncStrategyApply { - if in == nil { - return nil - } - out := new(SyncStrategyApply) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncStrategyHook) DeepCopyInto(out *SyncStrategyHook) { - *out = *in - out.SyncStrategyApply = in.SyncStrategyApply - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncStrategyHook. -func (in *SyncStrategyHook) DeepCopy() *SyncStrategyHook { - if in == nil { - return nil - } - out := new(SyncStrategyHook) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SyncWindow) DeepCopyInto(out *SyncWindow) { - *out = *in - if in.Applications != nil { - in, out := &in.Applications, &out.Applications - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Namespaces != nil { - in, out := &in.Namespaces, &out.Namespaces - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Clusters != nil { - in, out := &in.Clusters, &out.Clusters - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncWindow. -func (in *SyncWindow) DeepCopy() *SyncWindow { - if in == nil { - return nil - } - out := new(SyncWindow) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in SyncWindows) DeepCopyInto(out *SyncWindows) { - { - in := &in - *out = make(SyncWindows, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(SyncWindow) - (*in).DeepCopyInto(*out) - } - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncWindows. -func (in SyncWindows) DeepCopy() SyncWindows { - if in == nil { - return nil - } - out := new(SyncWindows) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TLSClientConfig) DeepCopyInto(out *TLSClientConfig) { - *out = *in - if in.CertData != nil { - in, out := &in.CertData, &out.CertData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - if in.KeyData != nil { - in, out := &in.KeyData, &out.KeyData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - if in.CAData != nil { - in, out := &in.CAData, &out.CAData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSClientConfig. -func (in *TLSClientConfig) DeepCopy() *TLSClientConfig { - if in == nil { - return nil - } - out := new(TLSClientConfig) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go deleted file mode 100644 index 8c8b476f6..000000000 --- a/pkg/client/clientset/versioned/clientset.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package versioned - -import ( - argoprojv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1" - discovery "k8s.io/client-go/discovery" - rest "k8s.io/client-go/rest" - flowcontrol "k8s.io/client-go/util/flowcontrol" -) - -type Interface interface { - Discovery() discovery.DiscoveryInterface - ArgoprojV1alpha1() argoprojv1alpha1.ArgoprojV1alpha1Interface -} - -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. -type Clientset struct { - *discovery.DiscoveryClient - argoprojV1alpha1 *argoprojv1alpha1.ArgoprojV1alpha1Client -} - -// ArgoprojV1alpha1 retrieves the ArgoprojV1alpha1Client -func (c *Clientset) ArgoprojV1alpha1() argoprojv1alpha1.ArgoprojV1alpha1Interface { - return c.argoprojV1alpha1 -} - -// Discovery retrieves the DiscoveryClient -func (c *Clientset) Discovery() discovery.DiscoveryInterface { - if c == nil { - return nil - } - return c.DiscoveryClient -} - -// NewForConfig creates a new Clientset for the given config. -func NewForConfig(c *rest.Config) (*Clientset, error) { - configShallowCopy := *c - if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { - configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) - } - var cs Clientset - var err error - cs.argoprojV1alpha1, err = argoprojv1alpha1.NewForConfig(&configShallowCopy) - if err != nil { - return nil, err - } - - cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) - if err != nil { - return nil, err - } - return &cs, nil -} - -// NewForConfigOrDie creates a new Clientset for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *Clientset { - var cs Clientset - cs.argoprojV1alpha1 = argoprojv1alpha1.NewForConfigOrDie(c) - - cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) - return &cs -} - -// New creates a new Clientset for the given RESTClient. -func New(c rest.Interface) *Clientset { - var cs Clientset - cs.argoprojV1alpha1 = argoprojv1alpha1.New(c) - - cs.DiscoveryClient = discovery.NewDiscoveryClient(c) - return &cs -} diff --git a/pkg/client/clientset/versioned/doc.go b/pkg/client/clientset/versioned/doc.go deleted file mode 100644 index 0e0c2a890..000000000 --- a/pkg/client/clientset/versioned/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. -package versioned diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go deleted file mode 100644 index de3e7cdc5..000000000 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ /dev/null @@ -1,61 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - clientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - argoprojv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1" - fakeargoprojv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1/fake" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/discovery" - fakediscovery "k8s.io/client-go/discovery/fake" - "k8s.io/client-go/testing" -) - -// NewSimpleClientset returns a clientset that will respond with the provided objects. -// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, -// without applying any validations and/or defaults. It shouldn't be considered a replacement -// for a real clientset and is mostly useful in simple unit tests. -func NewSimpleClientset(objects ...runtime.Object) *Clientset { - o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) - for _, obj := range objects { - if err := o.Add(obj); err != nil { - panic(err) - } - } - - cs := &Clientset{} - cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} - cs.AddReactor("*", "*", testing.ObjectReaction(o)) - cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { - gvr := action.GetResource() - ns := action.GetNamespace() - watch, err := o.Watch(gvr, ns) - if err != nil { - return false, nil, err - } - return true, watch, nil - }) - - return cs -} - -// Clientset implements clientset.Interface. Meant to be embedded into a -// struct to get a default implementation. This makes faking out just the method -// you want to test easier. -type Clientset struct { - testing.Fake - discovery *fakediscovery.FakeDiscovery -} - -func (c *Clientset) Discovery() discovery.DiscoveryInterface { - return c.discovery -} - -var _ clientset.Interface = &Clientset{} - -// ArgoprojV1alpha1 retrieves the ArgoprojV1alpha1Client -func (c *Clientset) ArgoprojV1alpha1() argoprojv1alpha1.ArgoprojV1alpha1Interface { - return &fakeargoprojv1alpha1.FakeArgoprojV1alpha1{Fake: &c.Fake} -} diff --git a/pkg/client/clientset/versioned/fake/doc.go b/pkg/client/clientset/versioned/fake/doc.go deleted file mode 100644 index 3630ed1cd..000000000 --- a/pkg/client/clientset/versioned/fake/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated fake clientset. -package fake diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go deleted file mode 100644 index 45a3b9f06..000000000 --- a/pkg/client/clientset/versioned/fake/register.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - argoprojv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" -) - -var scheme = runtime.NewScheme() -var codecs = serializer.NewCodecFactory(scheme) -var parameterCodec = runtime.NewParameterCodec(scheme) -var localSchemeBuilder = runtime.SchemeBuilder{ - argoprojv1alpha1.AddToScheme, -} - -// AddToScheme adds all types of this clientset into the given scheme. This allows composition -// of clientsets, like in: -// -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) -// -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) -// -// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types -// correctly. -var AddToScheme = localSchemeBuilder.AddToScheme - -func init() { - v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) - utilruntime.Must(AddToScheme(scheme)) -} diff --git a/pkg/client/clientset/versioned/scheme/doc.go b/pkg/client/clientset/versioned/scheme/doc.go deleted file mode 100644 index 14db57a58..000000000 --- a/pkg/client/clientset/versioned/scheme/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package contains the scheme of the automatically generated clientset. -package scheme diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go deleted file mode 100644 index 9749e29f9..000000000 --- a/pkg/client/clientset/versioned/scheme/register.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package scheme - -import ( - argoprojv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" -) - -var Scheme = runtime.NewScheme() -var Codecs = serializer.NewCodecFactory(Scheme) -var ParameterCodec = runtime.NewParameterCodec(Scheme) -var localSchemeBuilder = runtime.SchemeBuilder{ - argoprojv1alpha1.AddToScheme, -} - -// AddToScheme adds all types of this clientset into the given scheme. This allows composition -// of clientsets, like in: -// -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) -// -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) -// -// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types -// correctly. -var AddToScheme = localSchemeBuilder.AddToScheme - -func init() { - v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - utilruntime.Must(AddToScheme(Scheme)) -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go deleted file mode 100644 index cb19808dd..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "time" - - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" -) - -// ApplicationsGetter has a method to return a ApplicationInterface. -// A group's client should implement this interface. -type ApplicationsGetter interface { - Applications(namespace string) ApplicationInterface -} - -// ApplicationInterface has methods to work with Application resources. -type ApplicationInterface interface { - Create(*v1alpha1.Application) (*v1alpha1.Application, error) - Update(*v1alpha1.Application) (*v1alpha1.Application, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1alpha1.Application, error) - List(opts v1.ListOptions) (*v1alpha1.ApplicationList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Application, err error) - ApplicationExpansion -} - -// applications implements ApplicationInterface -type applications struct { - client rest.Interface - ns string -} - -// newApplications returns a Applications -func newApplications(c *ArgoprojV1alpha1Client, namespace string) *applications { - return &applications{ - client: c.RESTClient(), - ns: namespace, - } -} - -// Get takes name of the application, and returns the corresponding application object, and an error if there is any. -func (c *applications) Get(name string, options v1.GetOptions) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applications"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of Applications that match those selectors. -func (c *applications) List(opts v1.ListOptions) (result *v1alpha1.ApplicationList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.ApplicationList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested applications. -func (c *applications) Watch(opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch() -} - -// Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any. -func (c *applications) Create(application *v1alpha1.Application) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Post(). - Namespace(c.ns). - Resource("applications"). - Body(application). - Do(). - Into(result) - return -} - -// Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any. -func (c *applications) Update(application *v1alpha1.Application) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Put(). - Namespace(c.ns). - Resource("applications"). - Name(application.Name). - Body(application). - Do(). - Into(result) - return -} - -// Delete takes name of the application and deletes it. Returns an error if one occurs. -func (c *applications) Delete(name string, options *v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("applications"). - Name(name). - Body(options). - Do(). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *applications) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - var timeout time.Duration - if listOptions.TimeoutSeconds != nil { - timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&listOptions, scheme.ParameterCodec). - Timeout(timeout). - Body(options). - Do(). - Error() -} - -// Patch applies the patch and returns the patched application. -func (c *applications) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("applications"). - SubResource(subresources...). - Name(name). - Body(data). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go deleted file mode 100644 index 31b745185..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/application_client.go +++ /dev/null @@ -1,79 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/scheme" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" - rest "k8s.io/client-go/rest" -) - -type ArgoprojV1alpha1Interface interface { - RESTClient() rest.Interface - AppProjectsGetter - ApplicationsGetter -} - -// ArgoprojV1alpha1Client is used to interact with features provided by the argoproj.io group. -type ArgoprojV1alpha1Client struct { - restClient rest.Interface -} - -func (c *ArgoprojV1alpha1Client) AppProjects(namespace string) AppProjectInterface { - return newAppProjects(c, namespace) -} - -func (c *ArgoprojV1alpha1Client) Applications(namespace string) ApplicationInterface { - return newApplications(c, namespace) -} - -// NewForConfig creates a new ArgoprojV1alpha1Client for the given config. -func NewForConfig(c *rest.Config) (*ArgoprojV1alpha1Client, error) { - config := *c - if err := setConfigDefaults(&config); err != nil { - return nil, err - } - client, err := rest.RESTClientFor(&config) - if err != nil { - return nil, err - } - return &ArgoprojV1alpha1Client{client}, nil -} - -// NewForConfigOrDie creates a new ArgoprojV1alpha1Client for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *ArgoprojV1alpha1Client { - client, err := NewForConfig(c) - if err != nil { - panic(err) - } - return client -} - -// New creates a new ArgoprojV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *ArgoprojV1alpha1Client { - return &ArgoprojV1alpha1Client{c} -} - -func setConfigDefaults(config *rest.Config) error { - gv := v1alpha1.SchemeGroupVersion - config.GroupVersion = &gv - config.APIPath = "/apis" - config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} - - if config.UserAgent == "" { - config.UserAgent = rest.DefaultKubernetesUserAgent() - } - - return nil -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *ArgoprojV1alpha1Client) RESTClient() rest.Interface { - if c == nil { - return nil - } - return c.restClient -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go deleted file mode 100644 index b5c96010a..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "time" - - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - scheme "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" -) - -// AppProjectsGetter has a method to return a AppProjectInterface. -// A group's client should implement this interface. -type AppProjectsGetter interface { - AppProjects(namespace string) AppProjectInterface -} - -// AppProjectInterface has methods to work with AppProject resources. -type AppProjectInterface interface { - Create(*v1alpha1.AppProject) (*v1alpha1.AppProject, error) - Update(*v1alpha1.AppProject) (*v1alpha1.AppProject, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1alpha1.AppProject, error) - List(opts v1.ListOptions) (*v1alpha1.AppProjectList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.AppProject, err error) - AppProjectExpansion -} - -// appProjects implements AppProjectInterface -type appProjects struct { - client rest.Interface - ns string -} - -// newAppProjects returns a AppProjects -func newAppProjects(c *ArgoprojV1alpha1Client, namespace string) *appProjects { - return &appProjects{ - client: c.RESTClient(), - ns: namespace, - } -} - -// Get takes name of the appProject, and returns the corresponding appProject object, and an error if there is any. -func (c *appProjects) Get(name string, options v1.GetOptions) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of AppProjects that match those selectors. -func (c *appProjects) List(opts v1.ListOptions) (result *v1alpha1.AppProjectList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.AppProjectList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested appProjects. -func (c *appProjects) Watch(opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch() -} - -// Create takes the representation of a appProject and creates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *appProjects) Create(appProject *v1alpha1.AppProject) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Post(). - Namespace(c.ns). - Resource("appprojects"). - Body(appProject). - Do(). - Into(result) - return -} - -// Update takes the representation of a appProject and updates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *appProjects) Update(appProject *v1alpha1.AppProject) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Put(). - Namespace(c.ns). - Resource("appprojects"). - Name(appProject.Name). - Body(appProject). - Do(). - Into(result) - return -} - -// Delete takes name of the appProject and deletes it. Returns an error if one occurs. -func (c *appProjects) Delete(name string, options *v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("appprojects"). - Name(name). - Body(options). - Do(). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *appProjects) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - var timeout time.Duration - if listOptions.TimeoutSeconds != nil { - timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&listOptions, scheme.ParameterCodec). - Timeout(timeout). - Body(options). - Do(). - Error() -} - -// Patch applies the patch and returns the patched appProject. -func (c *appProjects) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("appprojects"). - SubResource(subresources...). - Name(name). - Body(data). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/doc.go deleted file mode 100644 index 93a7ca4e0..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated typed clients. -package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/doc.go deleted file mode 100644 index 2b5ba4c8e..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// Package fake has the automatically generated clients. -package fake diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go deleted file mode 100644 index 8c936266e..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go +++ /dev/null @@ -1,112 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" -) - -// FakeApplications implements ApplicationInterface -type FakeApplications struct { - Fake *FakeArgoprojV1alpha1 - ns string -} - -var applicationsResource = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "applications"} - -var applicationsKind = schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "Application"} - -// Get takes name of the application, and returns the corresponding application object, and an error if there is any. -func (c *FakeApplications) Get(name string, options v1.GetOptions) (result *v1alpha1.Application, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetAction(applicationsResource, c.ns, name), &v1alpha1.Application{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Application), err -} - -// List takes label and field selectors, and returns the list of Applications that match those selectors. -func (c *FakeApplications) List(opts v1.ListOptions) (result *v1alpha1.ApplicationList, err error) { - obj, err := c.Fake. - Invokes(testing.NewListAction(applicationsResource, applicationsKind, c.ns, opts), &v1alpha1.ApplicationList{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.ApplicationList{ListMeta: obj.(*v1alpha1.ApplicationList).ListMeta} - for _, item := range obj.(*v1alpha1.ApplicationList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested applications. -func (c *FakeApplications) Watch(opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchAction(applicationsResource, c.ns, opts)) - -} - -// Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any. -func (c *FakeApplications) Create(application *v1alpha1.Application) (result *v1alpha1.Application, err error) { - obj, err := c.Fake. - Invokes(testing.NewCreateAction(applicationsResource, c.ns, application), &v1alpha1.Application{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Application), err -} - -// Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any. -func (c *FakeApplications) Update(application *v1alpha1.Application) (result *v1alpha1.Application, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateAction(applicationsResource, c.ns, application), &v1alpha1.Application{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Application), err -} - -// Delete takes name of the application and deletes it. Returns an error if one occurs. -func (c *FakeApplications) Delete(name string, options *v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteAction(applicationsResource, c.ns, name), &v1alpha1.Application{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeApplications) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(applicationsResource, c.ns, listOptions) - - _, err := c.Fake.Invokes(action, &v1alpha1.ApplicationList{}) - return err -} - -// Patch applies the patch and returns the patched application. -func (c *FakeApplications) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Application, err error) { - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(applicationsResource, c.ns, name, pt, data, subresources...), &v1alpha1.Application{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Application), err -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go deleted file mode 100644 index 1e738a3d9..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application_client.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1" - rest "k8s.io/client-go/rest" - testing "k8s.io/client-go/testing" -) - -type FakeArgoprojV1alpha1 struct { - *testing.Fake -} - -func (c *FakeArgoprojV1alpha1) AppProjects(namespace string) v1alpha1.AppProjectInterface { - return &FakeAppProjects{c, namespace} -} - -func (c *FakeArgoprojV1alpha1) Applications(namespace string) v1alpha1.ApplicationInterface { - return &FakeApplications{c, namespace} -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *FakeArgoprojV1alpha1) RESTClient() rest.Interface { - var ret *rest.RESTClient - return ret -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go deleted file mode 100644 index 9cf005cf1..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go +++ /dev/null @@ -1,112 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" -) - -// FakeAppProjects implements AppProjectInterface -type FakeAppProjects struct { - Fake *FakeArgoprojV1alpha1 - ns string -} - -var appprojectsResource = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "appprojects"} - -var appprojectsKind = schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "AppProject"} - -// Get takes name of the appProject, and returns the corresponding appProject object, and an error if there is any. -func (c *FakeAppProjects) Get(name string, options v1.GetOptions) (result *v1alpha1.AppProject, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetAction(appprojectsResource, c.ns, name), &v1alpha1.AppProject{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.AppProject), err -} - -// List takes label and field selectors, and returns the list of AppProjects that match those selectors. -func (c *FakeAppProjects) List(opts v1.ListOptions) (result *v1alpha1.AppProjectList, err error) { - obj, err := c.Fake. - Invokes(testing.NewListAction(appprojectsResource, appprojectsKind, c.ns, opts), &v1alpha1.AppProjectList{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.AppProjectList{ListMeta: obj.(*v1alpha1.AppProjectList).ListMeta} - for _, item := range obj.(*v1alpha1.AppProjectList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested appProjects. -func (c *FakeAppProjects) Watch(opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchAction(appprojectsResource, c.ns, opts)) - -} - -// Create takes the representation of a appProject and creates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *FakeAppProjects) Create(appProject *v1alpha1.AppProject) (result *v1alpha1.AppProject, err error) { - obj, err := c.Fake. - Invokes(testing.NewCreateAction(appprojectsResource, c.ns, appProject), &v1alpha1.AppProject{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.AppProject), err -} - -// Update takes the representation of a appProject and updates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *FakeAppProjects) Update(appProject *v1alpha1.AppProject) (result *v1alpha1.AppProject, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateAction(appprojectsResource, c.ns, appProject), &v1alpha1.AppProject{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.AppProject), err -} - -// Delete takes name of the appProject and deletes it. Returns an error if one occurs. -func (c *FakeAppProjects) Delete(name string, options *v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteAction(appprojectsResource, c.ns, name), &v1alpha1.AppProject{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeAppProjects) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(appprojectsResource, c.ns, listOptions) - - _, err := c.Fake.Invokes(action, &v1alpha1.AppProjectList{}) - return err -} - -// Patch applies the patch and returns the patched appProject. -func (c *FakeAppProjects) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.AppProject, err error) { - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(appprojectsResource, c.ns, name, pt, data, subresources...), &v1alpha1.AppProject{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.AppProject), err -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/generated_expansion.go deleted file mode 100644 index 4afd21db6..000000000 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/generated_expansion.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -type AppProjectExpansion interface{} - -type ApplicationExpansion interface{} diff --git a/pkg/client/informers/externalversions/application/interface.go b/pkg/client/informers/externalversions/application/interface.go deleted file mode 100644 index a04fac0e7..000000000 --- a/pkg/client/informers/externalversions/application/interface.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package argoproj - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/application/v1alpha1" - internalinterfaces "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/internalinterfaces" -) - -// Interface provides access to each of this group's versions. -type Interface interface { - // V1alpha1 provides access to shared informers for resources in V1alpha1. - V1alpha1() v1alpha1.Interface -} - -type group struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// V1alpha1 returns a new v1alpha1.Interface. -func (g *group) V1alpha1() v1alpha1.Interface { - return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/pkg/client/informers/externalversions/application/v1alpha1/application.go b/pkg/client/informers/externalversions/application/v1alpha1/application.go deleted file mode 100644 index cb73100fc..000000000 --- a/pkg/client/informers/externalversions/application/v1alpha1/application.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - time "time" - - applicationv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - versioned "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - internalinterfaces "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" -) - -// ApplicationInformer provides access to a shared informer and lister for -// Applications. -type ApplicationInformer interface { - Informer() cache.SharedIndexInformer - Lister() v1alpha1.ApplicationLister -} - -type applicationInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewApplicationInformer constructs a new informer for Application type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredApplicationInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredApplicationInformer constructs a new informer for Application type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.ArgoprojV1alpha1().Applications(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.ArgoprojV1alpha1().Applications(namespace).Watch(options) - }, - }, - &applicationv1alpha1.Application{}, - resyncPeriod, - indexers, - ) -} - -func (f *applicationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredApplicationInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *applicationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&applicationv1alpha1.Application{}, f.defaultInformer) -} - -func (f *applicationInformer) Lister() v1alpha1.ApplicationLister { - return v1alpha1.NewApplicationLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/externalversions/application/v1alpha1/appproject.go b/pkg/client/informers/externalversions/application/v1alpha1/appproject.go deleted file mode 100644 index bff07996e..000000000 --- a/pkg/client/informers/externalversions/application/v1alpha1/appproject.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - time "time" - - applicationv1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - versioned "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - internalinterfaces "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" -) - -// AppProjectInformer provides access to a shared informer and lister for -// AppProjects. -type AppProjectInformer interface { - Informer() cache.SharedIndexInformer - Lister() v1alpha1.AppProjectLister -} - -type appProjectInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewAppProjectInformer constructs a new informer for AppProject type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewAppProjectInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredAppProjectInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredAppProjectInformer constructs a new informer for AppProject type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredAppProjectInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.ArgoprojV1alpha1().AppProjects(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.ArgoprojV1alpha1().AppProjects(namespace).Watch(options) - }, - }, - &applicationv1alpha1.AppProject{}, - resyncPeriod, - indexers, - ) -} - -func (f *appProjectInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredAppProjectInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *appProjectInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&applicationv1alpha1.AppProject{}, f.defaultInformer) -} - -func (f *appProjectInformer) Lister() v1alpha1.AppProjectLister { - return v1alpha1.NewAppProjectLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/externalversions/application/v1alpha1/interface.go b/pkg/client/informers/externalversions/application/v1alpha1/interface.go deleted file mode 100644 index 920cf6aa4..000000000 --- a/pkg/client/informers/externalversions/application/v1alpha1/interface.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - internalinterfaces "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // AppProjects returns a AppProjectInformer. - AppProjects() AppProjectInformer - // Applications returns a ApplicationInformer. - Applications() ApplicationInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// AppProjects returns a AppProjectInformer. -func (v *version) AppProjects() AppProjectInformer { - return &appProjectInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - -// Applications returns a ApplicationInformer. -func (v *version) Applications() ApplicationInformer { - return &applicationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go deleted file mode 100644 index d5fa38754..000000000 --- a/pkg/client/informers/externalversions/factory.go +++ /dev/null @@ -1,164 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package externalversions - -import ( - reflect "reflect" - sync "sync" - time "time" - - versioned "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - application "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/application" - internalinterfaces "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/internalinterfaces" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - cache "k8s.io/client-go/tools/cache" -) - -// SharedInformerOption defines the functional option type for SharedInformerFactory. -type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory - -type sharedInformerFactory struct { - client versioned.Interface - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc - lock sync.Mutex - defaultResync time.Duration - customResync map[reflect.Type]time.Duration - - informers map[reflect.Type]cache.SharedIndexInformer - // startedInformers is used for tracking which informers have been started. - // This allows Start() to be called multiple times safely. - startedInformers map[reflect.Type]bool -} - -// WithCustomResyncConfig sets a custom resync period for the specified informer types. -func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - for k, v := range resyncConfig { - factory.customResync[reflect.TypeOf(k)] = v - } - return factory - } -} - -// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. -func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.tweakListOptions = tweakListOptions - return factory - } -} - -// WithNamespace limits the SharedInformerFactory to the specified namespace. -func WithNamespace(namespace string) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.namespace = namespace - return factory - } -} - -// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. -func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync) -} - -// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. -// Listers obtained via this SharedInformerFactory will be subject to the same filters -// as specified here. -// Deprecated: Please use NewSharedInformerFactoryWithOptions instead -func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) -} - -// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. -func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { - factory := &sharedInformerFactory{ - client: client, - namespace: v1.NamespaceAll, - defaultResync: defaultResync, - informers: make(map[reflect.Type]cache.SharedIndexInformer), - startedInformers: make(map[reflect.Type]bool), - customResync: make(map[reflect.Type]time.Duration), - } - - // Apply all options - for _, opt := range options { - factory = opt(factory) - } - - return factory -} - -// Start initializes all requested informers. -func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { - f.lock.Lock() - defer f.lock.Unlock() - - for informerType, informer := range f.informers { - if !f.startedInformers[informerType] { - go informer.Run(stopCh) - f.startedInformers[informerType] = true - } - } -} - -// WaitForCacheSync waits for all started informers' cache were synced. -func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { - informers := func() map[reflect.Type]cache.SharedIndexInformer { - f.lock.Lock() - defer f.lock.Unlock() - - informers := map[reflect.Type]cache.SharedIndexInformer{} - for informerType, informer := range f.informers { - if f.startedInformers[informerType] { - informers[informerType] = informer - } - } - return informers - }() - - res := map[reflect.Type]bool{} - for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) - } - return res -} - -// InternalInformerFor returns the SharedIndexInformer for obj using an internal -// client. -func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { - f.lock.Lock() - defer f.lock.Unlock() - - informerType := reflect.TypeOf(obj) - informer, exists := f.informers[informerType] - if exists { - return informer - } - - resyncPeriod, exists := f.customResync[informerType] - if !exists { - resyncPeriod = f.defaultResync - } - - informer = newFunc(f.client, resyncPeriod) - f.informers[informerType] = informer - - return informer -} - -// SharedInformerFactory provides shared informers for resources in all known -// API group versions. -type SharedInformerFactory interface { - internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) - WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool - - Argoproj() application.Interface -} - -func (f *sharedInformerFactory) Argoproj() application.Interface { - return application.New(f, f.namespace, f.tweakListOptions) -} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go deleted file mode 100644 index 057324e5b..000000000 --- a/pkg/client/informers/externalversions/generic.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package externalversions - -import ( - "fmt" - - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - schema "k8s.io/apimachinery/pkg/runtime/schema" - cache "k8s.io/client-go/tools/cache" -) - -// GenericInformer is type of SharedIndexInformer which will locate and delegate to other -// sharedInformers based on type -type GenericInformer interface { - Informer() cache.SharedIndexInformer - Lister() cache.GenericLister -} - -type genericInformer struct { - informer cache.SharedIndexInformer - resource schema.GroupResource -} - -// Informer returns the SharedIndexInformer. -func (f *genericInformer) Informer() cache.SharedIndexInformer { - return f.informer -} - -// Lister returns the GenericLister. -func (f *genericInformer) Lister() cache.GenericLister { - return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) -} - -// ForResource gives generic access to a shared informer of the matching type -// TODO extend this to unknown resources with a client pool -func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { - switch resource { - // Group=argoproj.io, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("appprojects"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Argoproj().V1alpha1().AppProjects().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("applications"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Argoproj().V1alpha1().Applications().Informer()}, nil - - } - - return nil, fmt.Errorf("no informer found for %v", resource) -} diff --git a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go deleted file mode 100644 index b6e21c352..000000000 --- a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by informer-gen. DO NOT EDIT. - -package internalinterfaces - -import ( - time "time" - - versioned "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - cache "k8s.io/client-go/tools/cache" -) - -// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. -type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer - -// SharedInformerFactory a small interface to allow for adding an informer without an import cycle -type SharedInformerFactory interface { - Start(stopCh <-chan struct{}) - InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer -} - -// TweakListOptionsFunc is a function that transforms a v1.ListOptions. -type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/pkg/client/listers/application/v1alpha1/application.go b/pkg/client/listers/application/v1alpha1/application.go deleted file mode 100644 index 3179f32c5..000000000 --- a/pkg/client/listers/application/v1alpha1/application.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// ApplicationLister helps list Applications. -type ApplicationLister interface { - // List lists all Applications in the indexer. - List(selector labels.Selector) (ret []*v1alpha1.Application, err error) - // Applications returns an object that can list and get Applications. - Applications(namespace string) ApplicationNamespaceLister - ApplicationListerExpansion -} - -// applicationLister implements the ApplicationLister interface. -type applicationLister struct { - indexer cache.Indexer -} - -// NewApplicationLister returns a new ApplicationLister. -func NewApplicationLister(indexer cache.Indexer) ApplicationLister { - return &applicationLister{indexer: indexer} -} - -// List lists all Applications in the indexer. -func (s *applicationLister) List(selector labels.Selector) (ret []*v1alpha1.Application, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Application)) - }) - return ret, err -} - -// Applications returns an object that can list and get Applications. -func (s *applicationLister) Applications(namespace string) ApplicationNamespaceLister { - return applicationNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// ApplicationNamespaceLister helps list and get Applications. -type ApplicationNamespaceLister interface { - // List lists all Applications in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1alpha1.Application, err error) - // Get retrieves the Application from the indexer for a given namespace and name. - Get(name string) (*v1alpha1.Application, error) - ApplicationNamespaceListerExpansion -} - -// applicationNamespaceLister implements the ApplicationNamespaceLister -// interface. -type applicationNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Applications in the indexer for a given namespace. -func (s applicationNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Application, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Application)) - }) - return ret, err -} - -// Get retrieves the Application from the indexer for a given namespace and name. -func (s applicationNamespaceLister) Get(name string) (*v1alpha1.Application, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("application"), name) - } - return obj.(*v1alpha1.Application), nil -} diff --git a/pkg/client/listers/application/v1alpha1/appproject.go b/pkg/client/listers/application/v1alpha1/appproject.go deleted file mode 100644 index 2edaf585b..000000000 --- a/pkg/client/listers/application/v1alpha1/appproject.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// AppProjectLister helps list AppProjects. -type AppProjectLister interface { - // List lists all AppProjects in the indexer. - List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) - // AppProjects returns an object that can list and get AppProjects. - AppProjects(namespace string) AppProjectNamespaceLister - AppProjectListerExpansion -} - -// appProjectLister implements the AppProjectLister interface. -type appProjectLister struct { - indexer cache.Indexer -} - -// NewAppProjectLister returns a new AppProjectLister. -func NewAppProjectLister(indexer cache.Indexer) AppProjectLister { - return &appProjectLister{indexer: indexer} -} - -// List lists all AppProjects in the indexer. -func (s *appProjectLister) List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AppProject)) - }) - return ret, err -} - -// AppProjects returns an object that can list and get AppProjects. -func (s *appProjectLister) AppProjects(namespace string) AppProjectNamespaceLister { - return appProjectNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// AppProjectNamespaceLister helps list and get AppProjects. -type AppProjectNamespaceLister interface { - // List lists all AppProjects in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) - // Get retrieves the AppProject from the indexer for a given namespace and name. - Get(name string) (*v1alpha1.AppProject, error) - AppProjectNamespaceListerExpansion -} - -// appProjectNamespaceLister implements the AppProjectNamespaceLister -// interface. -type appProjectNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all AppProjects in the indexer for a given namespace. -func (s appProjectNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AppProject)) - }) - return ret, err -} - -// Get retrieves the AppProject from the indexer for a given namespace and name. -func (s appProjectNamespaceLister) Get(name string) (*v1alpha1.AppProject, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("appproject"), name) - } - return obj.(*v1alpha1.AppProject), nil -} diff --git a/pkg/client/listers/application/v1alpha1/expansion_generated.go b/pkg/client/listers/application/v1alpha1/expansion_generated.go deleted file mode 100644 index 6a821fce8..000000000 --- a/pkg/client/listers/application/v1alpha1/expansion_generated.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -// AppProjectListerExpansion allows custom methods to be added to -// AppProjectLister. -type AppProjectListerExpansion interface{} - -// AppProjectNamespaceListerExpansion allows custom methods to be added to -// AppProjectNamespaceLister. -type AppProjectNamespaceListerExpansion interface{} - -// ApplicationListerExpansion allows custom methods to be added to -// ApplicationLister. -type ApplicationListerExpansion interface{} - -// ApplicationNamespaceListerExpansion allows custom methods to be added to -// ApplicationNamespaceLister. -type ApplicationNamespaceListerExpansion interface{} diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go new file mode 100644 index 000000000..cc61cb0fc --- /dev/null +++ b/pkg/engine/engine.go @@ -0,0 +1,105 @@ +package engine + +import ( + "context" + "fmt" + "io" + "time" + + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/rest" + + ioutil "github.com/argoproj/gitops-engine/pkg/utils/io" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube/cache" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" +) + +const ( + operationRefreshTimeout = time.Second * 1 +) + +type GitOpsEngine interface { + Run() (io.Closer, error) + Sync(ctx context.Context, resources []*unstructured.Unstructured, isManaged func(r *cache.Resource) bool, revision string, namespace string, opts ...sync.SyncOpt) ([]common.ResourceSyncResult, error) +} + +type gitOpsEngine struct { + config *rest.Config + cache cache.ClusterCache + kubectl kube.Kubectl +} + +func NewEngine(config *rest.Config, clusterCache cache.ClusterCache) GitOpsEngine { + return &gitOpsEngine{ + config: config, + kubectl: &kube.KubectlCmd{}, + cache: clusterCache, + } +} + +func (e *gitOpsEngine) Run() (io.Closer, error) { + err := e.cache.EnsureSynced() + if err != nil { + return nil, err + } + + return ioutil.NewCloser(func() error { + e.cache.Invalidate(func(config *rest.Config, ns []string, settings cache.Settings) (*rest.Config, []string, cache.Settings) { + return config, ns, settings + }) + return nil + }), nil +} + +func (e *gitOpsEngine) Sync(ctx context.Context, + resources []*unstructured.Unstructured, + isManaged func(r *cache.Resource) bool, + revision string, + namespace string, + opts ...sync.SyncOpt, +) ([]common.ResourceSyncResult, error) { + managedResources, err := e.cache.GetManagedLiveObjs(resources, isManaged) + if err != nil { + return nil, err + } + result := sync.Reconcile(resources, managedResources, namespace, e.cache) + syncCtx, err := sync.NewSyncContext(revision, result, e.config, e.config, e.kubectl, namespace, log.NewEntry(log.New()), opts...) + if err != nil { + return nil, err + } + + resUpdated := make(chan bool) + unsubscribe := e.cache.OnResourceUpdated(func(newRes *cache.Resource, oldRes *cache.Resource, namespaceResources map[kube.ResourceKey]*cache.Resource) { + var key kube.ResourceKey + if newRes != nil { + key = newRes.ResourceKey() + } else { + key = oldRes.ResourceKey() + } + if _, ok := managedResources[key]; ok { + resUpdated <- true + } + }) + defer unsubscribe() + for { + syncCtx.Sync() + phase, message, resources := syncCtx.GetState() + if phase.Completed() { + if phase == common.OperationError { + err = fmt.Errorf("sync operation failed: %s", message) + } + return resources, err + } + select { + case <-ctx.Done(): + syncCtx.Terminate() + return resources, errors.New("sync operation was terminated") + case <-time.After(operationRefreshTimeout): + case <-resUpdated: + } + } +} diff --git a/pkg/types.go b/pkg/types.go deleted file mode 100644 index 04441b530..000000000 --- a/pkg/types.go +++ /dev/null @@ -1,119 +0,0 @@ -package pkg - -import ( - "context" - - "github.com/argoproj/argo-cd/engine/util/kube" - - "github.com/argoproj/argo-cd/engine/resource" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/watch" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -// The GitOps engine API is represented by two interfaces ReconciliationSettings, CredentialsStore and settings if the Application object. - -type Engine interface { - Run(ctx context.Context, statusProcessors int, operationProcessors int) -} - -type SyncTaskInfo struct { - Phase v1alpha1.SyncPhase - LiveObj *unstructured.Unstructured - TargetObj *unstructured.Unstructured - IsHook bool -} - -// Consider callback registration instead -type Callbacks interface { - OnBeforeSync(appName string, tasks []SyncTaskInfo) ([]SyncTaskInfo, error) - OnSyncCompleted(appName string, state appv1.OperationState) error - - OnResourceUpdated(un *unstructured.Unstructured) - OnResourceRemoved(key kube.ResourceKey) - OnClusterInitialized(server string) -} - -// ReconciliationSettings provides set of methods which expose manifest generation and diffing settings. -type ReconciliationSettings interface { - // TODO: merge into one method - GetAppInstanceLabelKey() (string, error) - GetResourcesFilter() (*resource.ResourcesFilter, error) - GetResourceOverrides() (map[string]appv1.ResourceOverride, error) - - Subscribe(subCh chan<- bool) - Unsubscribe(subCh chan<- bool) - - GetConfigManagementPlugins() ([]appv1.ConfigManagementPlugin, error) // TODO: remove - GetKustomizeBuildOptions() (string, error) // TODO: remove -} - -// ClusterEvent contains information about cluster event -type ClusterEvent struct { - Type watch.EventType - Cluster *appv1.Cluster -} - -// CredentialsStore allows to get repository and cluster credentials -type CredentialsStore interface { - GetCluster(ctx context.Context, name string) (*appv1.Cluster, error) - WatchClusters(ctx context.Context, callback func(event *ClusterEvent)) error - ListHelmRepositories(ctx context.Context) ([]*appv1.Repository, error) // TODO: remove - GetRepository(ctx context.Context, url string) (*appv1.Repository, error) // TODO: remove -} - -type EventInfo struct { - Type string - Reason string -} - -// In addition to main API consumer have to provide infrastructure interfaces: - -const ( - EventReasonStatusRefreshed = "StatusRefreshed" - EventReasonResourceCreated = "ResourceCreated" - EventReasonResourceUpdated = "ResourceUpdated" - EventReasonResourceDeleted = "ResourceDeleted" - EventReasonOperationStarted = "OperationStarted" - EventReasonOperationCompleted = "OperationCompleted" -) - -// AuditLogger allows to react to application events such as sync started, sync failed/completed etc. -type AuditLogger interface { - LogAppEvent(app *appv1.Application, info EventInfo, message string) -} - -// AppStateCache is used to cache intermediate reconciliation results. Engine is tolerant to cache errors, so implementation can just return 'not implemented' error. -type AppStateCache interface { - SetAppResourcesTree(appName string, resourcesTree *appv1.ApplicationTree) error - SetAppManagedResources(appName string, managedResources []*appv1.ResourceDiff) error - GetAppManagedResources(appName string, res *[]*appv1.ResourceDiff) error -} - -type ManifestResponse struct { - Manifests []string - Namespace string - Server string - Revision string - SourceType string -} - -type ManifestGenerationSettings struct { - AppLabelKey string - AppLabelValue string - Namespace string - Repos []*appv1.Repository - Plugins []*appv1.ConfigManagementPlugin - KustomizeOptions *appv1.KustomizeOptions - KubeVersion string - NoCache bool -} - -// ManifestGenerator allows to move manifest generation into separate process if in-process manifest generation does not work for performance reasons. -type ManifestGenerator interface { - // TODO: remove manifest generation related settings - Generate(ctx context.Context, repo *appv1.Repository, revision string, source *appv1.ApplicationSource, setting *ManifestGenerationSettings) (*ManifestResponse, error) -} diff --git a/util/diff/diff.go b/pkg/utils/diff/diff.go similarity index 76% rename from util/diff/diff.go rename to pkg/utils/diff/diff.go index 8d10630ee..de2fbbe44 100644 --- a/util/diff/diff.go +++ b/pkg/utils/diff/diff.go @@ -10,6 +10,7 @@ import ( "path" "reflect" + jsonpatch "github.com/evanphx/json-patch" "github.com/ghodss/yaml" "github.com/google/shlex" log "github.com/sirupsen/logrus" @@ -18,16 +19,24 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/jsonmergepatch" "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/client-go/kubernetes/scheme" "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/kubectl/scheme" - jsonutil "github.com/argoproj/argo-cd/engine/util/json" + jsonutil "github.com/argoproj/gitops-engine/pkg/utils/json" ) +type DiffOptions struct { + IgnoreAggregatedRoles bool `json:"ignoreAggregatedRoles,omitempty"` +} + type DiffResult struct { - Diff gojsondiff.Diff - Modified bool + // Deprecated: Use PredictedLive and NormalizedLive instead + Diff gojsondiff.Diff + Modified bool + PredictedLive []byte + NormalizedLive []byte } type DiffResultList struct { @@ -39,33 +48,37 @@ type Normalizer interface { Normalize(un *unstructured.Unstructured) error } +// Returns the default diff options +func GetDefaultDiffOptions() DiffOptions { + return DiffOptions{ + IgnoreAggregatedRoles: false, + } +} + // Diff performs a diff on two unstructured objects. If the live object happens to have a // "kubectl.kubernetes.io/last-applied-configuration", then perform a three way diff. -func Diff(config, live *unstructured.Unstructured, normalizer Normalizer) *DiffResult { +func Diff(config, live *unstructured.Unstructured, normalizer Normalizer, options DiffOptions) (*DiffResult, error) { if config != nil { config = remarshal(config) - Normalize(config, normalizer) + Normalize(config, normalizer, options) } if live != nil { live = remarshal(live) - Normalize(live, normalizer) + Normalize(live, normalizer, options) } orig := GetLastAppliedConfigAnnotation(live) if orig != nil && config != nil { - Normalize(orig, normalizer) + Normalize(orig, normalizer, options) dr, err := ThreeWayDiff(orig, config, live) if err == nil { - return dr + return dr, nil } log.Debugf("three-way diff calculation failed: %v. Falling back to two-way diff", err) } return TwoWayDiff(config, live) } -// TwoWayDiff performs a normal two-way diff between two unstructured objects. Ignores extra fields -// in the live object. -// Inputs are assumed to be stripped of type information -func TwoWayDiff(config, live *unstructured.Unstructured) *DiffResult { +func getLegacyTwoWayDiff(config, live *unstructured.Unstructured) gojsondiff.Diff { var configObj, liveObj map[string]interface{} if config != nil { config = removeNamespaceAnnotation(config) @@ -74,12 +87,28 @@ func TwoWayDiff(config, live *unstructured.Unstructured) *DiffResult { if live != nil { liveObj = jsonutil.RemoveMapFields(configObj, live.Object) } - gjDiff := gojsondiff.New().CompareObjects(liveObj, configObj) - dr := DiffResult{ - Diff: gjDiff, - Modified: gjDiff.Modified(), + return gojsondiff.New().CompareObjects(liveObj, configObj) +} + +// TwoWayDiff performs a three-way diff and uses specified config as a recently applied config +func TwoWayDiff(config, live *unstructured.Unstructured) (*DiffResult, error) { + if live != nil && config != nil { + return ThreeWayDiff(config, config.DeepCopy(), live) + } else if live != nil { + liveData, err := json.Marshal(live) + if err != nil { + return nil, err + } + return &DiffResult{Modified: false, Diff: getLegacyTwoWayDiff(config, live), NormalizedLive: liveData, PredictedLive: []byte("null")}, nil + } else if config != nil { + predictedLiveData, err := json.Marshal(config.Object) + if err != nil { + return nil, err + } + return &DiffResult{Modified: true, NormalizedLive: []byte("null"), PredictedLive: predictedLiveData, Diff: getLegacyTwoWayDiff(config, live)}, nil + } else { + return nil, errors.New("both live and config are null objects") } - return &dr } // ThreeWayDiff performs a diff with the understanding of how to incorporate the @@ -88,41 +117,51 @@ func TwoWayDiff(config, live *unstructured.Unstructured) *DiffResult { func ThreeWayDiff(orig, config, live *unstructured.Unstructured) (*DiffResult, error) { orig = removeNamespaceAnnotation(orig) config = removeNamespaceAnnotation(config) + // Remove defaulted fields from the live object. // This subtracts any extra fields in the live object which are not present in last-applied-configuration. // This is needed to perform a fair comparison when we send the objects to gojsondiff + // TODO: Remove line below to fix https://github.com/argoproj/argo-cd/issues/2865 and add special case for StatefulSet live = &unstructured.Unstructured{Object: jsonutil.RemoveMapFields(orig.Object, live.Object)} // 1. calculate a 3-way merge patch - patchBytes, err := threeWayMergePatch(orig, config, live) + patchBytes, versionedObject, err := threeWayMergePatch(orig, config, live) if err != nil { return nil, err } - // 2. apply the patch against the live object + // 2. get expected live object by applying the patch against the live object liveBytes, err := json.Marshal(live) if err != nil { return nil, err } - versionedObject, err := scheme.Scheme.New(orig.GroupVersionKind()) - if err != nil { - return nil, err - } - patchedLiveBytes, err := strategicpatch.StrategicMergePatch(liveBytes, patchBytes, versionedObject) - if err != nil { - return nil, err + + var predictedLiveBytes []byte + if versionedObject != nil { + predictedLiveBytes, err = strategicpatch.StrategicMergePatch(liveBytes, patchBytes, versionedObject) + if err != nil { + return nil, err + } + } else { + predictedLiveBytes, err = jsonpatch.MergePatch(liveBytes, patchBytes) + if err != nil { + return nil, err + } } - var patchedLive unstructured.Unstructured - err = json.Unmarshal(patchedLiveBytes, &patchedLive) + + predictedLive := &unstructured.Unstructured{} + err = json.Unmarshal(predictedLiveBytes, predictedLive) if err != nil { return nil, err } - // 3. diff the live object vs. the patched live object - gjDiff := gojsondiff.New().CompareObjects(live.Object, patchedLive.Object) + // 3. compare live and expected live object dr := DiffResult{ - Diff: gjDiff, - Modified: gjDiff.Modified(), + PredictedLive: predictedLiveBytes, + NormalizedLive: liveBytes, + Modified: string(predictedLiveBytes) != string(liveBytes), + // legacy diff for backward compatibility + Diff: gojsondiff.New().CompareObjects(live.Object, predictedLive.Object), } return &dr, nil } @@ -170,29 +209,36 @@ func removeNamespaceAnnotation(orig *unstructured.Unstructured) *unstructured.Un return orig } -func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte, error) { +func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte, runtime.Object, error) { origBytes, err := json.Marshal(orig.Object) if err != nil { - return nil, err + return nil, nil, err } configBytes, err := json.Marshal(config.Object) if err != nil { - return nil, err + return nil, nil, err } liveBytes, err := json.Marshal(live.Object) if err != nil { - return nil, err - } - gvk := orig.GroupVersionKind() - versionedObject, err := scheme.Scheme.New(gvk) - if err != nil { - return nil, err + return nil, nil, err } - lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObject) - if err != nil { - return nil, err + if versionedObject, err := scheme.Scheme.New(orig.GroupVersionKind()); err == nil { + lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObject) + if err != nil { + return nil, nil, err + } + patch, err := strategicpatch.CreateThreeWayMergePatch(origBytes, configBytes, liveBytes, lookupPatchMeta, true) + if err != nil { + return nil, nil, err + } + return patch, versionedObject, nil + } else { + patch, err := jsonmergepatch.CreateThreeWayJSONMergePatch(origBytes, configBytes, liveBytes) + if err != nil { + return nil, nil, err + } + return patch, nil, nil } - return strategicpatch.CreateThreeWayMergePatch(origBytes, configBytes, liveBytes, lookupPatchMeta, true) } func GetLastAppliedConfigAnnotation(live *unstructured.Unstructured) *unstructured.Unstructured { @@ -218,7 +264,7 @@ func GetLastAppliedConfigAnnotation(live *unstructured.Unstructured) *unstructur // DiffArray performs a diff on a list of unstructured objects. Objects are expected to match // environments -func DiffArray(configArray, liveArray []*unstructured.Unstructured, normalizer Normalizer) (*DiffResultList, error) { +func DiffArray(configArray, liveArray []*unstructured.Unstructured, normalizer Normalizer, options DiffOptions) (*DiffResultList, error) { numItems := len(configArray) if len(liveArray) != numItems { return nil, fmt.Errorf("left and right arrays have mismatched lengths") @@ -230,7 +276,10 @@ func DiffArray(configArray, liveArray []*unstructured.Unstructured, normalizer N for i := 0; i < numItems; i++ { config := configArray[i] live := liveArray[i] - diffRes := Diff(config, live, normalizer) + diffRes, err := Diff(config, live, normalizer, options) + if err != nil { + return nil, err + } diffResultList.Diffs[i] = *diffRes if diffRes.Modified { diffResultList.Modified = true @@ -239,19 +288,16 @@ func DiffArray(configArray, liveArray []*unstructured.Unstructured, normalizer N return &diffResultList, nil } -// ASCIIFormat returns the ASCII format of the diff -func (d *DiffResult) ASCIIFormat(left *unstructured.Unstructured, formatOpts formatter.AsciiFormatterConfig) (string, error) { +// JSONFormat returns the diff as a JSON string +func (d *DiffResult) JSONFormat() (string, error) { if !d.Diff.Modified() { return "", nil } - if left == nil { - return "", errors.New("Supplied nil left object") - } - asciiFmt := formatter.NewAsciiFormatter(left.Object, formatOpts) - return asciiFmt.Format(d.Diff) + jsonFmt := formatter.NewDeltaFormatter() + return jsonFmt.Format(d.Diff) } -func Normalize(un *unstructured.Unstructured, normalizer Normalizer) { +func Normalize(un *unstructured.Unstructured, normalizer Normalizer, options DiffOptions) { if un == nil { return } @@ -259,11 +305,12 @@ func Normalize(un *unstructured.Unstructured, normalizer Normalizer) { // creationTimestamp is sometimes set to null in the config when exported (e.g. SealedSecrets) // Removing the field allows a cleaner diff. unstructured.RemoveNestedField(un.Object, "metadata", "creationTimestamp") + gvk := un.GroupVersionKind() if gvk.Group == "" && gvk.Kind == "Secret" { NormalizeSecret(un) } else if gvk.Group == "rbac.authorization.k8s.io" && (gvk.Kind == "ClusterRole" || gvk.Kind == "Role") { - normalizeRole(un) + normalizeRole(un, options) } if normalizer != nil { @@ -318,8 +365,8 @@ func NormalizeSecret(un *unstructured.Unstructured) { } } -// normalizeRole mutates the supplied Role/ClusterRole and sets rules to null if it is an empty list -func normalizeRole(un *unstructured.Unstructured) { +// normalizeRole mutates the supplied Role/ClusterRole and sets rules to null if it is an empty list or an aggregated role +func normalizeRole(un *unstructured.Unstructured, options DiffOptions) { if un == nil { return } @@ -327,6 +374,20 @@ func normalizeRole(un *unstructured.Unstructured) { if gvk.Group != "rbac.authorization.k8s.io" || (gvk.Kind != "Role" && gvk.Kind != "ClusterRole") { return } + + // Check whether the role we're checking is an aggregation role. If it is, we ignore any differences in rules. + if options.IgnoreAggregatedRoles { + aggrIf, ok := un.Object["aggregationRule"] + if ok { + _, ok = aggrIf.(map[string]interface{}) + if !ok { + log.Infof("Malformed aggregrationRule in resource '%s', won't modify.", un.GetName()) + } else { + un.Object["rules"] = nil + } + } + } + rulesIf, ok := un.Object["rules"] if !ok { return @@ -338,15 +399,7 @@ func normalizeRole(un *unstructured.Unstructured) { if rules != nil && len(rules) == 0 { un.Object["rules"] = nil } -} -// JSONFormat returns the diff as a JSON string -func (d *DiffResult) JSONFormat() (string, error) { - if !d.Diff.Modified() { - return "", nil - } - jsonFmt := formatter.NewDeltaFormatter() - return jsonFmt.Format(d.Diff) } // CreateTwoWayMergePatch is a helper to construct a two-way merge patch from objects (instead of bytes) diff --git a/util/diff/diff_test.go b/pkg/utils/diff/diff_test.go similarity index 77% rename from util/diff/diff_test.go rename to pkg/utils/diff/diff_test.go index 08656a56f..2c7d0eb90 100644 --- a/util/diff/diff_test.go +++ b/pkg/utils/diff/diff_test.go @@ -4,14 +4,14 @@ import ( "encoding/json" "io/ioutil" "log" - "os" "strings" "testing" "github.com/ghodss/yaml" "github.com/stretchr/testify/assert" + "github.com/yudai/gojsondiff" "github.com/yudai/gojsondiff/formatter" - "golang.org/x/crypto/ssh/terminal" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" @@ -19,16 +19,33 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - "github.com/argoproj/argo-cd/engine/util/errors" - "github.com/argoproj/argo-cd/test" + "github.com/argoproj/gitops-engine/pkg/utils/errors" ) var ( formatOpts = formatter.AsciiFormatterConfig{ - Coloring: terminal.IsTerminal(int(os.Stdout.Fd())), + Coloring: false, } ) +func printDiff(result *DiffResult, left *unstructured.Unstructured) (string, error) { + leftData, err := json.Marshal(left) + if err != nil { + return "", err + } + + diff, err := gojsondiff.New().Compare(leftData, result.PredictedLive) + if err != nil { + return "", err + } + if !diff.Modified() { + return "", nil + } + + asciiFmt := formatter.NewAsciiFormatter(left.Object, formatOpts) + return asciiFmt.Format(diff) +} + func toUnstructured(obj interface{}) (*unstructured.Unstructured, error) { uObj, err := runtime.NewTestUnstructuredConverter(equality.Semantic).ToUnstructured(obj) if err != nil { @@ -52,13 +69,61 @@ func unmarshalFile(path string) *unstructured.Unstructured { return &un } +func newDeployment() *appsv1.Deployment { + var two int32 = 2 + return &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1beta1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "demo", + Namespace: "test", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &two, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "demo", + }, + }, + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "demo", + }, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "demo", + Image: "gcr.io/kuar-demo/kuard-amd64:1", + Ports: []v1.ContainerPort{ + { + ContainerPort: 80, + }, + }, + }, + }, + }, + }, + }, + } +} + +func diff(t *testing.T, config, live *unstructured.Unstructured, options DiffOptions) *DiffResult { + res, err := Diff(config, live, nil, options) + assert.NoError(t, err) + return res +} + func TestDiff(t *testing.T) { - leftDep := test.DemoDeployment() + leftDep := newDeployment() leftUn := mustToUnstructured(leftDep) - diffRes := Diff(leftUn, leftUn, nil) - assert.False(t, diffRes.Diff.Modified()) - ascii, err := diffRes.ASCIIFormat(leftUn, formatOpts) + diffRes := diff(t, leftUn, leftUn, GetDefaultDiffOptions()) + assert.False(t, diffRes.Modified) + ascii, err := printDiff(diffRes, leftUn) assert.Nil(t, err) if ascii != "" { log.Println(ascii) @@ -66,24 +131,26 @@ func TestDiff(t *testing.T) { } func TestDiffWithNils(t *testing.T) { - dep := test.DemoDeployment() + dep := newDeployment() resource := mustToUnstructured(dep) - diffRes := Diff(nil, resource, nil) + diffRes := diff(t, nil, resource, GetDefaultDiffOptions()) // NOTE: if live is non-nil, and config is nil, this is not considered difference // This "difference" is checked at the comparator. - assert.False(t, diffRes.Diff.Modified()) - diffRes = TwoWayDiff(nil, resource) - assert.False(t, diffRes.Diff.Modified()) + assert.False(t, diffRes.Modified) + diffRes, err := TwoWayDiff(nil, resource) + assert.NoError(t, err) + assert.False(t, diffRes.Modified) - diffRes = Diff(resource, nil, nil) - assert.True(t, diffRes.Diff.Modified()) - diffRes = TwoWayDiff(resource, nil) - assert.True(t, diffRes.Diff.Modified()) + diffRes = diff(t, resource, nil, GetDefaultDiffOptions()) + assert.True(t, diffRes.Modified) + diffRes, err = TwoWayDiff(resource, nil) + assert.NoError(t, err) + assert.True(t, diffRes.Modified) } func TestDiffNilFieldInLive(t *testing.T) { - leftDep := test.DemoDeployment() + leftDep := newDeployment() rightDep := leftDep.DeepCopy() leftUn := mustToUnstructured(leftDep) @@ -91,12 +158,12 @@ func TestDiffNilFieldInLive(t *testing.T) { err := unstructured.SetNestedField(rightUn.Object, nil, "spec") assert.Nil(t, err) - diffRes := Diff(leftUn, rightUn, nil) + diffRes := diff(t, leftUn, rightUn, GetDefaultDiffOptions()) assert.True(t, diffRes.Modified) } func TestDiffArraySame(t *testing.T) { - leftDep := test.DemoDeployment() + leftDep := newDeployment() rightDep := leftDep.DeepCopy() leftUn := mustToUnstructured(leftDep) @@ -104,13 +171,13 @@ func TestDiffArraySame(t *testing.T) { left := []*unstructured.Unstructured{leftUn} right := []*unstructured.Unstructured{rightUn} - diffResList, err := DiffArray(left, right, nil) + diffResList, err := DiffArray(left, right, nil, GetDefaultDiffOptions()) assert.Nil(t, err) assert.False(t, diffResList.Modified) } func TestDiffArrayAdditions(t *testing.T) { - leftDep := test.DemoDeployment() + leftDep := newDeployment() rightDep := leftDep.DeepCopy() rightDep.Status.Replicas = 1 @@ -119,13 +186,13 @@ func TestDiffArrayAdditions(t *testing.T) { left := []*unstructured.Unstructured{leftUn} right := []*unstructured.Unstructured{rightUn} - diffResList, err := DiffArray(left, right, nil) + diffResList, err := DiffArray(left, right, nil, GetDefaultDiffOptions()) assert.Nil(t, err) assert.False(t, diffResList.Modified) } func TestDiffArrayModification(t *testing.T) { - leftDep := test.DemoDeployment() + leftDep := newDeployment() rightDep := leftDep.DeepCopy() ten := int32(10) rightDep.Spec.Replicas = &ten @@ -135,7 +202,7 @@ func TestDiffArrayModification(t *testing.T) { left := []*unstructured.Unstructured{leftUn} right := []*unstructured.Unstructured{rightUn} - diffResList, err := DiffArray(left, right, nil) + diffResList, err := DiffArray(left, right, nil, GetDefaultDiffOptions()) assert.Nil(t, err) assert.True(t, diffResList.Modified) } @@ -144,7 +211,7 @@ func TestDiffArrayModification(t *testing.T) { // present in the live object. func TestThreeWayDiff(t *testing.T) { // 1. get config and live to be the same. Both have a foo annotation. - configDep := test.DemoDeployment() + configDep := newDeployment() configDep.ObjectMeta.Namespace = "" configDep.Annotations = map[string]string{ "foo": "bar", @@ -156,9 +223,9 @@ func TestThreeWayDiff(t *testing.T) { liveDep.SetNamespace("default") configUn := mustToUnstructured(configDep) liveUn := mustToUnstructured(liveDep) - res := Diff(configUn, liveUn, nil) + res := diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.False(t, res.Modified) { - ascii, err := res.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(res, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -170,9 +237,9 @@ func TestThreeWayDiff(t *testing.T) { liveDep.Annotations[v1.LastAppliedConfigAnnotation] = string(configBytes) configUn = mustToUnstructured(configDep) liveUn = mustToUnstructured(liveDep) - res = Diff(configUn, liveUn, nil) + res = diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.False(t, res.Modified) { - ascii, err := res.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(res, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -182,7 +249,7 @@ func TestThreeWayDiff(t *testing.T) { delete(configDep.Annotations, "foo") configUn = mustToUnstructured(configDep) liveUn = mustToUnstructured(liveDep) - res = Diff(configUn, liveUn, nil) + res = diff(t, configUn, liveUn, GetDefaultDiffOptions()) assert.True(t, res.Modified) // 5. Just to prove three way diff incorporates last-applied-configuration, remove the @@ -192,8 +259,8 @@ func TestThreeWayDiff(t *testing.T) { delete(liveDep.Annotations, v1.LastAppliedConfigAnnotation) configUn = mustToUnstructured(configDep) liveUn = mustToUnstructured(liveDep) - res = Diff(configUn, liveUn, nil) - ascii, err := res.ASCIIFormat(liveUn, formatOpts) + res = diff(t, configUn, liveUn, GetDefaultDiffOptions()) + ascii, err := printDiff(res, liveUn) assert.Nil(t, err) if ascii != "" { log.Println(ascii) @@ -250,9 +317,9 @@ func TestThreeWayDiffExample1(t *testing.T) { assert.Nil(t, err) err = json.Unmarshal([]byte(demoLive), &liveUn.Object) assert.Nil(t, err) - dr := Diff(&configUn, &liveUn, nil) + dr := diff(t, &configUn, &liveUn, GetDefaultDiffOptions()) assert.False(t, dr.Modified) - ascii, err := dr.ASCIIFormat(&liveUn, formatOpts) + ascii, err := printDiff(dr, &liveUn) assert.Nil(t, err) if ascii != "" { log.Println(ascii) @@ -260,12 +327,36 @@ func TestThreeWayDiffExample1(t *testing.T) { } +// Test for ignoring aggregated cluster roles +func TestDiffOptionIgnoreAggregateRoles(t *testing.T) { + // Test case 1: Ignore option is true, the rules in the role should be ignored + { + configUn := unmarshalFile("testdata/aggr-clusterrole-config.json") + liveUn := unmarshalFile("testdata/aggr-clusterrole-live.json") + dr := diff(t, configUn, liveUn, DiffOptions{IgnoreAggregatedRoles: true}) + assert.False(t, dr.Modified) + ascii, err := printDiff(dr, liveUn) + assert.Nil(t, err) + log.Println(ascii) + } + // Test case 2: Ignore option is false, the aggregation should produce a diff + { + configUn := unmarshalFile("testdata/aggr-clusterrole-config.json") + liveUn := unmarshalFile("testdata/aggr-clusterrole-live.json") + dr := diff(t, configUn, liveUn, DiffOptions{IgnoreAggregatedRoles: false}) + assert.True(t, dr.Modified) + ascii, err := printDiff(dr, liveUn) + assert.Nil(t, err) + log.Println(ascii) + } +} + func TestThreeWayDiffExample2(t *testing.T) { configUn := unmarshalFile("testdata/elasticsearch-config.json") liveUn := unmarshalFile("testdata/elasticsearch-live.json") - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) assert.False(t, dr.Modified) - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -283,9 +374,9 @@ func TestThreeWayDiffExample2WithDifference(t *testing.T) { delete(labels, "release") configUn.SetLabels(labels) - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) assert.True(t, dr.Modified) - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) @@ -315,9 +406,9 @@ func TestThreeWayDiffExample2WithDifference(t *testing.T) { func TestThreeWayDiffExplicitNamespace(t *testing.T) { configUn := unmarshalFile("testdata/spinnaker-sa-config.json") liveUn := unmarshalFile("testdata/spinnaker-sa-live.json") - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) assert.False(t, dr.Modified) - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -372,7 +463,7 @@ func TestIgnoreNamespaceForClusterScopedResources(t *testing.T) { assert.Nil(t, err) err = yaml.Unmarshal([]byte(customObjConfig), &configUn) assert.Nil(t, err) - dr := Diff(&configUn, &liveUn, nil) + dr := diff(t, &configUn, &liveUn, GetDefaultDiffOptions()) assert.False(t, dr.Modified) } @@ -416,9 +507,9 @@ func TestSecretStringData(t *testing.T) { err = yaml.Unmarshal([]byte(secretLive), &liveUn) assert.Nil(t, err) - dr := Diff(&configUn, &liveUn, nil) + dr := diff(t, &configUn, &liveUn, GetDefaultDiffOptions()) if !assert.False(t, dr.Modified) { - ascii, err := dr.ASCIIFormat(&liveUn, formatOpts) + ascii, err := printDiff(dr, &liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -460,16 +551,16 @@ func TestInvalidSecretStringData(t *testing.T) { err = yaml.Unmarshal([]byte(secretInvalidLive), &liveUn) assert.Nil(t, err) - dr := Diff(&configUn, nil, nil) + dr := diff(t, &configUn, nil, GetDefaultDiffOptions()) assert.True(t, dr.Modified) } func TestNullSecretData(t *testing.T) { configUn := unmarshalFile("testdata/wordpress-config.json") liveUn := unmarshalFile("testdata/wordpress-live.json") - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.False(t, dr.Modified) { - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -486,9 +577,9 @@ func TestRedactedSecretData(t *testing.T) { configData["smtp-password"] = "***" liveData["wordpress-password"] = "******" liveData["smtp-password"] = "******" - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.True(t, dr.Modified) { - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -497,9 +588,9 @@ func TestRedactedSecretData(t *testing.T) { func TestNullRoleRule(t *testing.T) { configUn := unmarshalFile("testdata/grafana-clusterrole-config.json") liveUn := unmarshalFile("testdata/grafana-clusterrole-live.json") - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.False(t, dr.Modified) { - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } @@ -508,9 +599,9 @@ func TestNullRoleRule(t *testing.T) { func TestNullCreationTimestamp(t *testing.T) { configUn := unmarshalFile("testdata/sealedsecret-config.json") liveUn := unmarshalFile("testdata/sealedsecret-live.json") - dr := Diff(configUn, liveUn, nil) + dr := diff(t, configUn, liveUn, GetDefaultDiffOptions()) if !assert.False(t, dr.Modified) { - ascii, err := dr.ASCIIFormat(liveUn, formatOpts) + ascii, err := printDiff(dr, liveUn) assert.Nil(t, err) log.Println(ascii) } diff --git a/pkg/utils/diff/testdata/aggr-clusterrole-config.json b/pkg/utils/diff/testdata/aggr-clusterrole-config.json new file mode 100644 index 000000000..c28eaa139 --- /dev/null +++ b/pkg/utils/diff/testdata/aggr-clusterrole-config.json @@ -0,0 +1,19 @@ +{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRole", + "metadata": { + "name": "test-clusterrole", + "labels": { + "app.kubernetes.io/instance": "clusterroles" + } + }, + "aggregationRule": { + "clusterRoleSelectors": [ + { + "matchLabels": { + "rbac.example.com/aggregate-to-test": "true" + } + } + ] + } +} diff --git a/pkg/utils/diff/testdata/aggr-clusterrole-live.json b/pkg/utils/diff/testdata/aggr-clusterrole-live.json new file mode 100644 index 000000000..5fddf3a98 --- /dev/null +++ b/pkg/utils/diff/testdata/aggr-clusterrole-live.json @@ -0,0 +1,55 @@ +{ + "aggregationRule": { + "clusterRoleSelectors": [ + { + "matchLabels": { + "rbac.example.com/aggregate-to-test": "true" + } + } + ] + }, + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRole", + "metadata": { + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"aggregationRule\":{\"clusterRoleSelectors\":[{\"matchLabels\":{\"rbac.example.com/aggregate-to-test\":\"true\"}}]},\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"ClusterRole\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"clusterroles\"},\"name\":\"test-clusterrole\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"deployments\"],\"verbs\":[\"get\",\"list\"]}]}\n" + }, + "creationTimestamp": "2020-02-02T17:18:54Z", + "labels": { + "app.kubernetes.io/instance": "clusterroles" + }, + "name": "test-clusterrole", + "resourceVersion": "5108751", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/clusterroles/test-clusterrole", + "uid": "418e7818-ec49-49f6-ada0-d1fccf679bf6" + }, + "rules": [ + { + "apiGroups": [ + "" + ], + "resources": [ + "services", + "endpoints" + ], + "verbs": [ + "get", + "list", + "watch" + ] + }, + { + "apiGroups": [ + "" + ], + "resources": [ + "pods" + ], + "verbs": [ + "get", + "list", + "watch" + ] + } + ] +} diff --git a/util/diff/testdata/elasticsearch-config.json b/pkg/utils/diff/testdata/elasticsearch-config.json similarity index 100% rename from util/diff/testdata/elasticsearch-config.json rename to pkg/utils/diff/testdata/elasticsearch-config.json diff --git a/util/diff/testdata/elasticsearch-live.json b/pkg/utils/diff/testdata/elasticsearch-live.json similarity index 100% rename from util/diff/testdata/elasticsearch-live.json rename to pkg/utils/diff/testdata/elasticsearch-live.json diff --git a/util/diff/testdata/grafana-clusterrole-config.json b/pkg/utils/diff/testdata/grafana-clusterrole-config.json similarity index 100% rename from util/diff/testdata/grafana-clusterrole-config.json rename to pkg/utils/diff/testdata/grafana-clusterrole-config.json diff --git a/util/diff/testdata/grafana-clusterrole-live.json b/pkg/utils/diff/testdata/grafana-clusterrole-live.json similarity index 100% rename from util/diff/testdata/grafana-clusterrole-live.json rename to pkg/utils/diff/testdata/grafana-clusterrole-live.json diff --git a/util/diff/testdata/sealedsecret-config.json b/pkg/utils/diff/testdata/sealedsecret-config.json similarity index 100% rename from util/diff/testdata/sealedsecret-config.json rename to pkg/utils/diff/testdata/sealedsecret-config.json diff --git a/util/diff/testdata/sealedsecret-live.json b/pkg/utils/diff/testdata/sealedsecret-live.json similarity index 100% rename from util/diff/testdata/sealedsecret-live.json rename to pkg/utils/diff/testdata/sealedsecret-live.json diff --git a/util/diff/testdata/spinnaker-sa-config.json b/pkg/utils/diff/testdata/spinnaker-sa-config.json similarity index 100% rename from util/diff/testdata/spinnaker-sa-config.json rename to pkg/utils/diff/testdata/spinnaker-sa-config.json diff --git a/util/diff/testdata/spinnaker-sa-live.json b/pkg/utils/diff/testdata/spinnaker-sa-live.json similarity index 100% rename from util/diff/testdata/spinnaker-sa-live.json rename to pkg/utils/diff/testdata/spinnaker-sa-live.json diff --git a/util/diff/testdata/wordpress-config.json b/pkg/utils/diff/testdata/wordpress-config.json similarity index 100% rename from util/diff/testdata/wordpress-config.json rename to pkg/utils/diff/testdata/wordpress-config.json diff --git a/util/diff/testdata/wordpress-live.json b/pkg/utils/diff/testdata/wordpress-live.json similarity index 100% rename from util/diff/testdata/wordpress-live.json rename to pkg/utils/diff/testdata/wordpress-live.json diff --git a/util/errors/errors.go b/pkg/utils/errors/errors.go similarity index 100% rename from util/errors/errors.go rename to pkg/utils/errors/errors.go diff --git a/pkg/utils/exec/exec.go b/pkg/utils/exec/exec.go new file mode 100644 index 000000000..cfd57575c --- /dev/null +++ b/pkg/utils/exec/exec.go @@ -0,0 +1,42 @@ +package exec + +import ( + "fmt" + "os" + "os/exec" + "time" + + argoexec "github.com/argoproj/pkg/exec" + + tracing "github.com/argoproj/gitops-engine/pkg/utils/tracing" +) + +var timeout time.Duration + +func init() { + initTimeout() +} + +func initTimeout() { + var err error + timeout, err = time.ParseDuration(os.Getenv("ARGOCD_EXEC_TIMEOUT")) + if err != nil { + timeout = 90 * time.Second + } +} + +func Run(cmd *exec.Cmd) (string, error) { + return RunWithRedactor(cmd, nil) +} + +func RunWithRedactor(cmd *exec.Cmd, redactor func(text string) string) (string, error) { + span := tracing.StartSpan(fmt.Sprintf("exec %v", cmd.Args[0])) + span.SetBaggageItem("dir", fmt.Sprintf("%v", cmd.Dir)) + span.SetBaggageItem("args", fmt.Sprintf("%v", cmd.Args)) + defer span.Finish() + opts := argoexec.CmdOpts{Timeout: timeout} + if redactor != nil { + opts.Redactor = redactor + } + return argoexec.RunCommandExt(cmd, opts) +} diff --git a/pkg/utils/exec/exec_test.go b/pkg/utils/exec/exec_test.go new file mode 100644 index 000000000..dcef40759 --- /dev/null +++ b/pkg/utils/exec/exec_test.go @@ -0,0 +1,29 @@ +package exec + +import ( + "os" + "os/exec" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func Test_timeout(t *testing.T) { + defer func() { _ = os.Unsetenv("ARGOCD_EXEC_TIMEOUT") }() + t.Run("Default", func(t *testing.T) { + initTimeout() + assert.Equal(t, 90*time.Second, timeout) + }) + t.Run("Default", func(t *testing.T) { + _ = os.Setenv("ARGOCD_EXEC_TIMEOUT", "1s") + initTimeout() + assert.Equal(t, 1*time.Second, timeout) + }) +} + +func TestRun(t *testing.T) { + out, err := Run(exec.Command("ls")) + assert.NoError(t, err) + assert.NotEmpty(t, out) +} diff --git a/util/health/health.go b/pkg/utils/health/health.go similarity index 61% rename from util/health/health.go rename to pkg/utils/health/health.go index 8eb73724d..741b94824 100644 --- a/util/health/health.go +++ b/pkg/utils/health/health.go @@ -4,98 +4,87 @@ import ( "fmt" "strings" - "github.com/argoproj/argo-cd/engine/util/lua" - - "k8s.io/apimachinery/pkg/runtime" - appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" coreV1 "k8s.io/api/core/v1" extv1beta1 "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/apis/apps" - "k8s.io/kubernetes/pkg/kubectl/scheme" - hookutil "github.com/argoproj/argo-cd/engine/hook" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource/ignore" - "github.com/argoproj/argo-cd/engine/util/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) -// SetApplicationHealth updates the health statuses of all resources performed in the comparison -func SetApplicationHealth(resStatuses []appv1.ResourceStatus, liveObjs []*unstructured.Unstructured, vm *lua.VM, filter func(obj *unstructured.Unstructured) bool) (*appv1.HealthStatus, error) { - var savedErr error - appHealth := appv1.HealthStatus{Status: appv1.HealthStatusHealthy} - for i, liveObj := range liveObjs { - var resHealth *appv1.HealthStatus - var err error - if liveObj == nil { - resHealth = &appv1.HealthStatus{Status: appv1.HealthStatusMissing} - } else { - if filter(liveObj) { - resHealth, err = GetResourceHealth(liveObj, vm) - if err != nil && savedErr == nil { - savedErr = err - } - } - } - if resHealth != nil { - resStatuses[i].Health = resHealth - ignore := ignoreLiveObjectHealth(liveObj, *resHealth) - if !ignore && IsWorse(appHealth.Status, resHealth.Status) { - appHealth.Status = resHealth.Status - } - } - } - return &appHealth, savedErr +type HealthStatusCode string + +const ( + HealthStatusUnknown HealthStatusCode = "Unknown" + HealthStatusProgressing HealthStatusCode = "Progressing" + HealthStatusHealthy HealthStatusCode = "Healthy" + HealthStatusSuspended HealthStatusCode = "Suspended" + HealthStatusDegraded HealthStatusCode = "Degraded" + HealthStatusMissing HealthStatusCode = "Missing" +) + +type HealthOverride interface { + GetResourceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) } -// ignoreLiveObjectHealth determines if we should not allow the live object to affect the overall -// health of the application (e.g. hooks, missing child applications) -func ignoreLiveObjectHealth(liveObj *unstructured.Unstructured, resHealth appv1.HealthStatus) bool { - if liveObj != nil { - if hookutil.IsHook(liveObj) { - // Don't allow resource hooks to affect health status - return true - } - if ignore.Ignore(liveObj) { - return true +type HealthStatus struct { + Status HealthStatusCode `json:"status,omitempty"` + Message string `json:"message,omitempty"` +} + +// healthOrder is a list of health codes in order of most healthy to least healthy +var healthOrder = []HealthStatusCode{ + HealthStatusHealthy, + HealthStatusSuspended, + HealthStatusProgressing, + HealthStatusDegraded, + HealthStatusMissing, + HealthStatusUnknown, +} + +// IsWorse returns whether or not the new health status code is a worser condition than the current +func IsWorse(current, new HealthStatusCode) bool { + currentIndex := 0 + newIndex := 0 + for i, code := range healthOrder { + if current == code { + currentIndex = i } - gvk := liveObj.GroupVersionKind() - if gvk.Group == "argoproj.io" && gvk.Kind == "Application" && resHealth.Status == appv1.HealthStatusMissing { - // 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 - return true + if new == code { + newIndex = i } } - return false + return newIndex > currentIndex } // GetResourceHealth returns the health of a k8s resource -func GetResourceHealth(obj *unstructured.Unstructured, vm *lua.VM) (*appv1.HealthStatus, error) { - +func GetResourceHealth(obj *unstructured.Unstructured, healthOverride HealthOverride) (health *HealthStatus, err error) { if obj.GetDeletionTimestamp() != nil { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Pending deletion", }, nil } - health, err := getResourceHealthFromLuaScript(obj, vm) - if err != nil { - health = &appv1.HealthStatus{ - Status: appv1.HealthStatusUnknown, - Message: err.Error(), + if healthOverride != nil { + health, err := healthOverride.GetResourceHealth(obj) + if err != nil { + health = &HealthStatus{ + Status: HealthStatusUnknown, + Message: err.Error(), + } + return health, err + } + if health != nil { + return health, nil } - return health, err - } - if health != nil { - return health, nil } gvk := obj.GroupVersionKind() @@ -116,13 +105,20 @@ func GetResourceHealth(obj *unstructured.Unstructured, vm *lua.VM) (*appv1.Healt case "argoproj.io": switch gvk.Kind { case "Application": - health, err = getApplicationHealth(obj) + health = getApplicationHealth(obj) + case "Workflow": + health, err = getArgoWorkflowHealth(obj) } case "apiregistration.k8s.io": switch gvk.Kind { case kube.APIServiceKind: health, err = getAPIServiceHealth(obj) } + case "networking.k8s.io": + switch gvk.Kind { + case kube.IngressKind: + health, err = getIngressHealth(obj) + } case "": switch gvk.Kind { case kube.ServiceKind: @@ -139,55 +135,15 @@ func GetResourceHealth(obj *unstructured.Unstructured, vm *lua.VM) (*appv1.Healt } } if err != nil { - health = &appv1.HealthStatus{ - Status: appv1.HealthStatusUnknown, + health = &HealthStatus{ + Status: HealthStatusUnknown, Message: err.Error(), } } return health, err } -// healthOrder is a list of health codes in order of most healthy to least healthy -var healthOrder = []appv1.HealthStatusCode{ - appv1.HealthStatusHealthy, - appv1.HealthStatusSuspended, - appv1.HealthStatusProgressing, - appv1.HealthStatusDegraded, - appv1.HealthStatusMissing, - appv1.HealthStatusUnknown, -} - -// IsWorse returns whether or not the new health status code is a worser condition than the current -func IsWorse(current, new appv1.HealthStatusCode) bool { - currentIndex := 0 - newIndex := 0 - for i, code := range healthOrder { - if current == code { - currentIndex = i - } - if new == code { - newIndex = i - } - } - return newIndex > currentIndex -} - -func getResourceHealthFromLuaScript(obj *unstructured.Unstructured, vm *lua.VM) (*appv1.HealthStatus, error) { - script, err := vm.GetHealthScript(obj) - if err != nil { - return nil, err - } - if script == "" { - return nil, nil - } - result, err := vm.ExecuteHealthLua(obj, script) - if err != nil { - return nil, err - } - return result, nil -} - -func getPVCHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getPVCHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { pvc := &coreV1.PersistentVolumeClaim{} err := scheme.Scheme.Convert(obj, pvc, nil) if err != nil { @@ -195,57 +151,57 @@ func getPVCHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { } switch pvc.Status.Phase { case coreV1.ClaimLost: - return &appv1.HealthStatus{Status: appv1.HealthStatusDegraded}, nil + return &HealthStatus{Status: HealthStatusDegraded}, nil case coreV1.ClaimPending: - return &appv1.HealthStatus{Status: appv1.HealthStatusProgressing}, nil + return &HealthStatus{Status: HealthStatusProgressing}, nil case coreV1.ClaimBound: - return &appv1.HealthStatus{Status: appv1.HealthStatusHealthy}, nil + return &HealthStatus{Status: HealthStatusHealthy}, nil default: - return &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, nil + return &HealthStatus{Status: HealthStatusUnknown}, nil } } -func getIngressHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getIngressHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { ingress := &extv1beta1.Ingress{} err := scheme.Scheme.Convert(obj, ingress, nil) if err != nil { return nil, fmt.Errorf("failed to convert %T to %T: %v", obj, ingress, err) } - health := appv1.HealthStatus{} + health := HealthStatus{} if len(ingress.Status.LoadBalancer.Ingress) > 0 { - health.Status = appv1.HealthStatusHealthy + health.Status = HealthStatusHealthy } else { - health.Status = appv1.HealthStatusProgressing + health.Status = HealthStatusProgressing } return &health, nil } -func getServiceHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { service := &coreV1.Service{} err := scheme.Scheme.Convert(obj, service, nil) if err != nil { return nil, fmt.Errorf("failed to convert %T to %T: %v", obj, service, err) } - health := appv1.HealthStatus{Status: appv1.HealthStatusHealthy} + health := HealthStatus{Status: HealthStatusHealthy} if service.Spec.Type == coreV1.ServiceTypeLoadBalancer { if len(service.Status.LoadBalancer.Ingress) > 0 { - health.Status = appv1.HealthStatusHealthy + health.Status = HealthStatusHealthy } else { - health.Status = appv1.HealthStatusProgressing + health.Status = HealthStatusProgressing } } return &health, nil } -func getDeploymentHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getDeploymentHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { deployment := &appsv1.Deployment{} err := scheme.Scheme.Convert(obj, deployment, nil) if err != nil { return nil, fmt.Errorf("failed to convert %T to %T: %v", obj, deployment, err) } if deployment.Spec.Paused { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusSuspended, + return &HealthStatus{ + Status: HealthStatusSuspended, Message: "Deployment is paused", }, nil } @@ -253,55 +209,50 @@ func getDeploymentHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, e if deployment.Generation <= deployment.Status.ObservedGeneration { cond := getDeploymentCondition(deployment.Status, v1.DeploymentProgressing) if cond != nil && cond.Reason == "ProgressDeadlineExceeded" { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusDegraded, + return &HealthStatus{ + Status: HealthStatusDegraded, Message: fmt.Sprintf("Deployment %q exceeded its progress deadline", obj.GetName()), }, nil } else if deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for rollout to finish: %d out of %d new replicas have been updated...", deployment.Status.UpdatedReplicas, *deployment.Spec.Replicas), }, nil } else if deployment.Status.Replicas > deployment.Status.UpdatedReplicas { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for rollout to finish: %d old replicas are pending termination...", deployment.Status.Replicas-deployment.Status.UpdatedReplicas), }, nil } else if deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for rollout to finish: %d of %d updated replicas are available...", deployment.Status.AvailableReplicas, deployment.Status.UpdatedReplicas), }, nil } } else { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Waiting for rollout to finish: observed deployment generation less then desired generation", }, nil } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, }, nil } func init() { - _ = appv1.SchemeBuilder.AddToScheme(scheme.Scheme) _ = apiregistrationv1.SchemeBuilder.AddToScheme(scheme.Scheme) _ = apiregistrationv1beta1.SchemeBuilder.AddToScheme(scheme.Scheme) } -func getApplicationHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { - application := &appv1.Application{} - err := scheme.Scheme.Convert(obj, application, nil) - if err != nil { - return nil, fmt.Errorf("failed to convert %T to %T: %v", obj, application, err) - } - - return &application.Status.Health, nil +func getApplicationHealth(obj *unstructured.Unstructured) *HealthStatus { + status, _, _ := unstructured.NestedString(obj.Object, "status", "health", "status") + message, _, _ := unstructured.NestedString(obj.Object, "status", "health", "message") + return &HealthStatus{Status: HealthStatusCode(status), Message: message} } -func getDaemonSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getDaemonSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { daemon := &appsv1.DaemonSet{} err := scheme.Scheme.Convert(obj, daemon, nil) if err != nil { @@ -310,30 +261,30 @@ func getDaemonSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, er // Borrowed at kubernetes/kubectl/rollout_status.go https://github.com/kubernetes/kubernetes/blob/5232ad4a00ec93942d0b2c6359ee6cd1201b46bc/pkg/kubectl/rollout_status.go#L110 if daemon.Generation <= daemon.Status.ObservedGeneration { if daemon.Status.UpdatedNumberScheduled < daemon.Status.DesiredNumberScheduled { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for daemon set %q rollout to finish: %d out of %d new pods have been updated...", daemon.Name, daemon.Status.UpdatedNumberScheduled, daemon.Status.DesiredNumberScheduled), }, nil } if daemon.Status.NumberAvailable < daemon.Status.DesiredNumberScheduled { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for daemon set %q rollout to finish: %d of %d updated pods are available...", daemon.Name, daemon.Status.NumberAvailable, daemon.Status.DesiredNumberScheduled), }, nil } } else { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Waiting for rollout to finish: observed daemon set generation less then desired generation", }, nil } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, }, nil } -func getStatefulSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getStatefulSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { sts := &appsv1.StatefulSet{} err := scheme.Scheme.Convert(obj, sts, nil) if err != nil { @@ -341,45 +292,45 @@ func getStatefulSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, } // Borrowed at kubernetes/kubectl/rollout_status.go https://github.com/kubernetes/kubernetes/blob/5232ad4a00ec93942d0b2c6359ee6cd1201b46bc/pkg/kubectl/rollout_status.go#L131 if sts.Status.ObservedGeneration == 0 || sts.Generation > sts.Status.ObservedGeneration { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Waiting for statefulset spec update to be observed...", }, nil } if sts.Spec.Replicas != nil && sts.Status.ReadyReplicas < *sts.Spec.Replicas { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for %d pods to be ready...", *sts.Spec.Replicas-sts.Status.ReadyReplicas), }, nil } - if sts.Spec.UpdateStrategy.Type == apps.RollingUpdateStatefulSetStrategyType && sts.Spec.UpdateStrategy.RollingUpdate != nil { + if sts.Spec.UpdateStrategy.Type == appsv1.RollingUpdateStatefulSetStrategyType && sts.Spec.UpdateStrategy.RollingUpdate != nil { if sts.Spec.Replicas != nil && sts.Spec.UpdateStrategy.RollingUpdate.Partition != nil { if sts.Status.UpdatedReplicas < (*sts.Spec.Replicas - *sts.Spec.UpdateStrategy.RollingUpdate.Partition) { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for partitioned roll out to finish: %d out of %d new pods have been updated...", sts.Status.UpdatedReplicas, (*sts.Spec.Replicas - *sts.Spec.UpdateStrategy.RollingUpdate.Partition)), }, nil } } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: fmt.Sprintf("partitioned roll out complete: %d new pods have been updated...", sts.Status.UpdatedReplicas), }, nil } if sts.Status.UpdateRevision != sts.Status.CurrentRevision { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("waiting for statefulset rolling update to complete %d pods at revision %s...", sts.Status.UpdatedReplicas, sts.Status.UpdateRevision), }, nil } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: fmt.Sprintf("statefulset rolling update complete %d pods at revision %s...", sts.Status.CurrentReplicas, sts.Status.CurrentRevision), }, nil } -func getReplicaSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getReplicaSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { replicaSet := &appsv1.ReplicaSet{} err := scheme.Scheme.Convert(obj, replicaSet, nil) if err != nil { @@ -388,25 +339,25 @@ func getReplicaSetHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, e if replicaSet.Generation <= replicaSet.Status.ObservedGeneration { cond := getReplicaSetCondition(replicaSet.Status, v1.ReplicaSetReplicaFailure) if cond != nil && cond.Status == coreV1.ConditionTrue { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusDegraded, + return &HealthStatus{ + Status: HealthStatusDegraded, Message: cond.Message, }, nil } else if replicaSet.Spec.Replicas != nil && replicaSet.Status.AvailableReplicas < *replicaSet.Spec.Replicas { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("Waiting for rollout to finish: %d out of %d new replicas are available...", replicaSet.Status.AvailableReplicas, *replicaSet.Spec.Replicas), }, nil } } else { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Waiting for rollout to finish: observed replica set generation less then desired generation", }, nil } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, }, nil } @@ -430,7 +381,7 @@ func getReplicaSetCondition(status v1.ReplicaSetStatus, condType v1.ReplicaSetCo return nil } -func getJobHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getJobHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { job := &batchv1.Job{} err := scheme.Scheme.Convert(obj, job, nil) if err != nil { @@ -452,24 +403,24 @@ func getJobHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { } } if !complete { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: message, }, nil } else if failed { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusDegraded, + return &HealthStatus{ + Status: HealthStatusDegraded, Message: failMsg, }, nil } else { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: message, }, nil } } -func getPodHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getPodHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { pod := &coreV1.Pod{} err := scheme.Scheme.Convert(obj, pod, nil) if err != nil { @@ -483,83 +434,105 @@ func getPodHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { // (e.g. the image is available), the resource hook pod will unexpectedly be executed even though the sync has // completed. if pod.Spec.RestartPolicy == coreV1.RestartPolicyAlways { - var status appv1.HealthStatusCode + var status HealthStatusCode var messages []string for _, containerStatus := range pod.Status.ContainerStatuses { waiting := containerStatus.State.Waiting // Article listing common container errors: https://medium.com/kokster/debugging-crashloopbackoffs-with-init-containers-26f79e9fb5bf if waiting != nil && (strings.HasPrefix(waiting.Reason, "Err") || strings.HasSuffix(waiting.Reason, "Error") || strings.HasSuffix(waiting.Reason, "BackOff")) { - status = appv1.HealthStatusDegraded + status = HealthStatusDegraded messages = append(messages, waiting.Message) } } if status != "" { - return &appv1.HealthStatus{ + return &HealthStatus{ Status: status, Message: strings.Join(messages, ", "), }, nil } } + getFailMessage := func(ctr *coreV1.ContainerStatus) string { + if ctr.State.Terminated != nil { + if ctr.State.Terminated.Message != "" { + return ctr.State.Terminated.Message + } + if ctr.State.Terminated.Reason == "OOMKilled" { + return ctr.State.Terminated.Reason + } + if ctr.State.Terminated.ExitCode != 0 { + return fmt.Sprintf("container %q failed with exit code %d", ctr.Name, ctr.State.Terminated.ExitCode) + } + } + return "" + } + switch pod.Status.Phase { case coreV1.PodPending: - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: pod.Status.Message, }, nil case coreV1.PodSucceeded: - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: pod.Status.Message, }, nil case coreV1.PodFailed: - return &appv1.HealthStatus{ - Status: appv1.HealthStatusDegraded, - Message: pod.Status.Message, - }, nil + if pod.Status.Message != "" { + // Pod has a nice error message. Use that. + return &HealthStatus{Status: HealthStatusDegraded, Message: pod.Status.Message}, nil + } + for _, ctr := range append(pod.Status.InitContainerStatuses, pod.Status.ContainerStatuses...) { + if msg := getFailMessage(&ctr); msg != "" { + return &HealthStatus{Status: HealthStatusDegraded, Message: msg}, nil + } + } + + return &HealthStatus{Status: HealthStatusDegraded, Message: ""}, nil case coreV1.PodRunning: switch pod.Spec.RestartPolicy { case coreV1.RestartPolicyAlways: // if pod is ready, it is automatically healthy if podutil.IsPodReady(pod) { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: pod.Status.Message, }, nil } // if it's not ready, check to see if any container terminated, if so, it's degraded for _, ctrStatus := range pod.Status.ContainerStatuses { if ctrStatus.LastTerminationState.Terminated != nil { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusDegraded, + return &HealthStatus{ + Status: HealthStatusDegraded, Message: pod.Status.Message, }, nil } } // otherwise we are progressing towards a ready state - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: pod.Status.Message, }, nil case coreV1.RestartPolicyOnFailure, coreV1.RestartPolicyNever: // pods set with a restart policy of OnFailure or Never, have a finite life. // These pods are typically resource hooks. Thus, we consider these as Progressing // instead of healthy. - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: pod.Status.Message, }, nil } } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusUnknown, + return &HealthStatus{ + Status: HealthStatusUnknown, Message: pod.Status.Message, }, nil } -func getAPIServiceHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { +func getAPIServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { apiservice := &apiregistrationv1.APIService{} err := scheme.Scheme.Convert(obj, apiservice, nil) if err != nil { @@ -570,20 +543,20 @@ func getAPIServiceHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, e switch c.Type { case apiregistrationv1.Available: if c.Status == apiregistrationv1.ConditionTrue { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusHealthy, + return &HealthStatus{ + Status: HealthStatusHealthy, Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), }, nil } else { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), }, nil } } } - return &appv1.HealthStatus{ - Status: appv1.HealthStatusProgressing, + return &HealthStatus{ + Status: HealthStatusProgressing, Message: "Waiting to be processed", }, nil } @@ -609,21 +582,19 @@ type ArgoWorkflow struct { } } -func GetStatusFromArgoWorkflow(hook *unstructured.Unstructured) (operation appv1.OperationPhase, message string) { +func getArgoWorkflowHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var wf ArgoWorkflow - err := runtime.DefaultUnstructuredConverter.FromUnstructured(hook.Object, &wf) + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &wf) if err != nil { - return appv1.OperationError, err.Error() + return nil, err } switch wf.Status.Phase { case NodePending, NodeRunning: - return appv1.OperationRunning, wf.Status.Message + return &HealthStatus{Status: HealthStatusProgressing, Message: wf.Status.Message}, nil case NodeSucceeded: - return appv1.OperationSucceeded, wf.Status.Message - case NodeFailed: - return appv1.OperationFailed, wf.Status.Message - case NodeError: - return appv1.OperationError, wf.Status.Message + return &HealthStatus{Status: HealthStatusHealthy, Message: wf.Status.Message}, nil + case NodeFailed, NodeError: + return &HealthStatus{Status: HealthStatusDegraded, Message: wf.Status.Message}, nil } - return appv1.OperationSucceeded, wf.Status.Message + return &HealthStatus{Status: HealthStatusHealthy, Message: wf.Status.Message}, nil } diff --git a/pkg/utils/health/health_test.go b/pkg/utils/health/health_test.go new file mode 100644 index 000000000..2618894e4 --- /dev/null +++ b/pkg/utils/health/health_test.go @@ -0,0 +1,128 @@ +package health + +import ( + "io/ioutil" + "testing" + + "github.com/ghodss/yaml" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func assertAppHealth(t *testing.T, yamlPath string, expectedStatus HealthStatusCode) { + health := getHealthStatus(yamlPath, t) + assert.NotNil(t, health) + assert.Equal(t, expectedStatus, health.Status) +} + +func getHealthStatus(yamlPath string, t *testing.T) *HealthStatus { + yamlBytes, err := ioutil.ReadFile(yamlPath) + assert.Nil(t, err) + var obj unstructured.Unstructured + err = yaml.Unmarshal(yamlBytes, &obj) + assert.Nil(t, err) + health, err := GetResourceHealth(&obj, nil) + assert.Nil(t, err) + return health +} + +func TestDeploymentHealth(t *testing.T) { + assertAppHealth(t, "../kube/testdata/nginx.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/deployment-progressing.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/deployment-suspended.yaml", HealthStatusSuspended) + assertAppHealth(t, "./testdata/deployment-degraded.yaml", HealthStatusDegraded) +} + +func TestStatefulSetHealth(t *testing.T) { + assertAppHealth(t, "./testdata/statefulset.yaml", HealthStatusHealthy) +} + +func TestPVCHealth(t *testing.T) { + assertAppHealth(t, "./testdata/pvc-bound.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/pvc-pending.yaml", HealthStatusProgressing) +} + +func TestServiceHealth(t *testing.T) { + assertAppHealth(t, "./testdata/svc-clusterip.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/svc-loadbalancer.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/svc-loadbalancer-unassigned.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/svc-loadbalancer-nonemptylist.yaml", HealthStatusHealthy) +} + +func TestIngressHealth(t *testing.T) { + assertAppHealth(t, "./testdata/ingress.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/ingress-unassigned.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/ingress-nonemptylist.yaml", HealthStatusHealthy) +} + +func TestCRD(t *testing.T) { + assert.Nil(t, getHealthStatus("./testdata/knative-service.yaml", t)) +} + +func TestJob(t *testing.T) { + assertAppHealth(t, "./testdata/job-running.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/job-failed.yaml", HealthStatusDegraded) + assertAppHealth(t, "./testdata/job-succeeded.yaml", HealthStatusHealthy) +} + +func TestPod(t *testing.T) { + assertAppHealth(t, "./testdata/pod-pending.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/pod-running-not-ready.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/pod-crashloop.yaml", HealthStatusDegraded) + assertAppHealth(t, "./testdata/pod-imagepullbackoff.yaml", HealthStatusDegraded) + assertAppHealth(t, "./testdata/pod-error.yaml", HealthStatusDegraded) + assertAppHealth(t, "./testdata/pod-running-restart-always.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/pod-running-restart-never.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/pod-running-restart-onfailure.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/pod-failed.yaml", HealthStatusDegraded) + assertAppHealth(t, "./testdata/pod-succeeded.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/pod-deletion.yaml", HealthStatusProgressing) +} + +func TestApplication(t *testing.T) { + assertAppHealth(t, "./testdata/application-healthy.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/application-degraded.yaml", HealthStatusDegraded) +} + +func TestAPIService(t *testing.T) { + assertAppHealth(t, "./testdata/apiservice-v1-true.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/apiservice-v1-false.yaml", HealthStatusProgressing) + assertAppHealth(t, "./testdata/apiservice-v1beta1-true.yaml", HealthStatusHealthy) + assertAppHealth(t, "./testdata/apiservice-v1beta1-false.yaml", HealthStatusProgressing) +} + +func TestGetArgoWorkflowHealth(t *testing.T) { + sampleWorkflow := unstructured.Unstructured{Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "entrypoint": "sampleEntryPoint", + "extraneousKey": "we are agnostic to extraneous keys", + }, + "status": map[string]interface{}{ + "phase": "Running", + "message": "This node is running", + }, + }, + } + + health, err := getArgoWorkflowHealth(&sampleWorkflow) + assert.NoError(t, err) + assert.Equal(t, HealthStatusProgressing, health.Status) + assert.Equal(t, "This node is running", health.Message) + + sampleWorkflow = unstructured.Unstructured{Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "entrypoint": "sampleEntryPoint", + "extraneousKey": "we are agnostic to extraneous keys", + }, + "status": map[string]interface{}{ + "phase": "Succeeded", + "message": "This node is has succeeded", + }, + }, + } + + health, err = getArgoWorkflowHealth(&sampleWorkflow) + assert.NoError(t, err) + assert.Equal(t, HealthStatusHealthy, health.Status) + assert.Equal(t, "This node is has succeeded", health.Message) +} diff --git a/util/health/testdata/apiservice-v1-false.yaml b/pkg/utils/health/testdata/apiservice-v1-false.yaml similarity index 86% rename from util/health/testdata/apiservice-v1-false.yaml rename to pkg/utils/health/testdata/apiservice-v1-false.yaml index 38401f7f0..a448823b9 100644 --- a/util/health/testdata/apiservice-v1-false.yaml +++ b/pkg/utils/health/testdata/apiservice-v1-false.yaml @@ -1,12 +1,12 @@ apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: - name: v1beta1.admission.certmanager.k8s.io + name: v1beta1.admission.cert-manager.io labels: app: webhook app.kubernetes.io/instance: external-dns spec: - group: admission.certmanager.k8s.io + group: admission.cert-manager.io groupPriorityMinimum: 1000 versionPriority: 15 service: diff --git a/util/health/testdata/apiservice-v1-true.yaml b/pkg/utils/health/testdata/apiservice-v1-true.yaml similarity index 84% rename from util/health/testdata/apiservice-v1-true.yaml rename to pkg/utils/health/testdata/apiservice-v1-true.yaml index a86309ee7..9bc6e478c 100644 --- a/util/health/testdata/apiservice-v1-true.yaml +++ b/pkg/utils/health/testdata/apiservice-v1-true.yaml @@ -1,12 +1,12 @@ apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: - name: v1beta1.admission.certmanager.k8s.io + name: v1beta1.admission.cert-manager.io labels: app: webhook app.kubernetes.io/instance: external-dns spec: - group: admission.certmanager.k8s.io + group: admission.cert-manager.io groupPriorityMinimum: 1000 versionPriority: 15 service: diff --git a/util/health/testdata/apiservice-v1beta1-false.yaml b/pkg/utils/health/testdata/apiservice-v1beta1-false.yaml similarity index 86% rename from util/health/testdata/apiservice-v1beta1-false.yaml rename to pkg/utils/health/testdata/apiservice-v1beta1-false.yaml index d3e271192..28436bb88 100644 --- a/util/health/testdata/apiservice-v1beta1-false.yaml +++ b/pkg/utils/health/testdata/apiservice-v1beta1-false.yaml @@ -1,12 +1,12 @@ apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: - name: v1beta1.admission.certmanager.k8s.io + name: v1beta1.admission.cert-manager.io labels: app: webhook app.kubernetes.io/instance: external-dns spec: - group: admission.certmanager.k8s.io + group: admission.cert-manager.io groupPriorityMinimum: 1000 versionPriority: 15 service: diff --git a/util/health/testdata/apiservice-v1beta1-true.yaml b/pkg/utils/health/testdata/apiservice-v1beta1-true.yaml similarity index 84% rename from util/health/testdata/apiservice-v1beta1-true.yaml rename to pkg/utils/health/testdata/apiservice-v1beta1-true.yaml index d85e52be4..45e60b350 100644 --- a/util/health/testdata/apiservice-v1beta1-true.yaml +++ b/pkg/utils/health/testdata/apiservice-v1beta1-true.yaml @@ -1,12 +1,12 @@ apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: - name: v1beta1.admission.certmanager.k8s.io + name: v1beta1.admission.cert-manager.io labels: app: webhook app.kubernetes.io/instance: external-dns spec: - group: admission.certmanager.k8s.io + group: admission.cert-manager.io groupPriorityMinimum: 1000 versionPriority: 15 service: diff --git a/util/health/testdata/application-degraded.yaml b/pkg/utils/health/testdata/application-degraded.yaml similarity index 100% rename from util/health/testdata/application-degraded.yaml rename to pkg/utils/health/testdata/application-degraded.yaml diff --git a/util/health/testdata/application-healthy.yaml b/pkg/utils/health/testdata/application-healthy.yaml similarity index 100% rename from util/health/testdata/application-healthy.yaml rename to pkg/utils/health/testdata/application-healthy.yaml diff --git a/util/health/testdata/deployment-degraded.yaml b/pkg/utils/health/testdata/deployment-degraded.yaml similarity index 100% rename from util/health/testdata/deployment-degraded.yaml rename to pkg/utils/health/testdata/deployment-degraded.yaml diff --git a/util/health/testdata/deployment-progressing.yaml b/pkg/utils/health/testdata/deployment-progressing.yaml similarity index 100% rename from util/health/testdata/deployment-progressing.yaml rename to pkg/utils/health/testdata/deployment-progressing.yaml diff --git a/util/health/testdata/deployment-suspended.yaml b/pkg/utils/health/testdata/deployment-suspended.yaml similarity index 100% rename from util/health/testdata/deployment-suspended.yaml rename to pkg/utils/health/testdata/deployment-suspended.yaml diff --git a/util/health/testdata/ingress-nonemptylist.yaml b/pkg/utils/health/testdata/ingress-nonemptylist.yaml similarity index 100% rename from util/health/testdata/ingress-nonemptylist.yaml rename to pkg/utils/health/testdata/ingress-nonemptylist.yaml diff --git a/util/health/testdata/ingress-unassigned.yaml b/pkg/utils/health/testdata/ingress-unassigned.yaml similarity index 100% rename from util/health/testdata/ingress-unassigned.yaml rename to pkg/utils/health/testdata/ingress-unassigned.yaml diff --git a/util/health/testdata/ingress.yaml b/pkg/utils/health/testdata/ingress.yaml similarity index 100% rename from util/health/testdata/ingress.yaml rename to pkg/utils/health/testdata/ingress.yaml diff --git a/util/health/testdata/job-failed.yaml b/pkg/utils/health/testdata/job-failed.yaml similarity index 100% rename from util/health/testdata/job-failed.yaml rename to pkg/utils/health/testdata/job-failed.yaml diff --git a/util/health/testdata/job-running.yaml b/pkg/utils/health/testdata/job-running.yaml similarity index 100% rename from util/health/testdata/job-running.yaml rename to pkg/utils/health/testdata/job-running.yaml diff --git a/util/health/testdata/job-succeeded.yaml b/pkg/utils/health/testdata/job-succeeded.yaml similarity index 100% rename from util/health/testdata/job-succeeded.yaml rename to pkg/utils/health/testdata/job-succeeded.yaml diff --git a/util/health/testdata/knative-service.yaml b/pkg/utils/health/testdata/knative-service.yaml similarity index 100% rename from util/health/testdata/knative-service.yaml rename to pkg/utils/health/testdata/knative-service.yaml diff --git a/util/health/testdata/pod-crashloop.yaml b/pkg/utils/health/testdata/pod-crashloop.yaml similarity index 100% rename from util/health/testdata/pod-crashloop.yaml rename to pkg/utils/health/testdata/pod-crashloop.yaml diff --git a/util/health/testdata/pod-deletion.yaml b/pkg/utils/health/testdata/pod-deletion.yaml similarity index 100% rename from util/health/testdata/pod-deletion.yaml rename to pkg/utils/health/testdata/pod-deletion.yaml diff --git a/util/health/testdata/pod-error.yaml b/pkg/utils/health/testdata/pod-error.yaml similarity index 100% rename from util/health/testdata/pod-error.yaml rename to pkg/utils/health/testdata/pod-error.yaml diff --git a/util/health/testdata/pod-failed.yaml b/pkg/utils/health/testdata/pod-failed.yaml similarity index 100% rename from util/health/testdata/pod-failed.yaml rename to pkg/utils/health/testdata/pod-failed.yaml diff --git a/util/health/testdata/pod-imagepullbackoff.yaml b/pkg/utils/health/testdata/pod-imagepullbackoff.yaml similarity index 100% rename from util/health/testdata/pod-imagepullbackoff.yaml rename to pkg/utils/health/testdata/pod-imagepullbackoff.yaml diff --git a/util/health/testdata/pod-pending.yaml b/pkg/utils/health/testdata/pod-pending.yaml similarity index 100% rename from util/health/testdata/pod-pending.yaml rename to pkg/utils/health/testdata/pod-pending.yaml diff --git a/util/health/testdata/pod-running-not-ready.yaml b/pkg/utils/health/testdata/pod-running-not-ready.yaml similarity index 100% rename from util/health/testdata/pod-running-not-ready.yaml rename to pkg/utils/health/testdata/pod-running-not-ready.yaml diff --git a/util/health/testdata/pod-running-restart-always.yaml b/pkg/utils/health/testdata/pod-running-restart-always.yaml similarity index 100% rename from util/health/testdata/pod-running-restart-always.yaml rename to pkg/utils/health/testdata/pod-running-restart-always.yaml diff --git a/util/health/testdata/pod-running-restart-never.yaml b/pkg/utils/health/testdata/pod-running-restart-never.yaml similarity index 100% rename from util/health/testdata/pod-running-restart-never.yaml rename to pkg/utils/health/testdata/pod-running-restart-never.yaml diff --git a/util/health/testdata/pod-running-restart-onfailure.yaml b/pkg/utils/health/testdata/pod-running-restart-onfailure.yaml similarity index 100% rename from util/health/testdata/pod-running-restart-onfailure.yaml rename to pkg/utils/health/testdata/pod-running-restart-onfailure.yaml diff --git a/util/health/testdata/pod-succeeded.yaml b/pkg/utils/health/testdata/pod-succeeded.yaml similarity index 100% rename from util/health/testdata/pod-succeeded.yaml rename to pkg/utils/health/testdata/pod-succeeded.yaml diff --git a/util/health/testdata/pvc-bound.yaml b/pkg/utils/health/testdata/pvc-bound.yaml similarity index 100% rename from util/health/testdata/pvc-bound.yaml rename to pkg/utils/health/testdata/pvc-bound.yaml diff --git a/util/health/testdata/pvc-pending.yaml b/pkg/utils/health/testdata/pvc-pending.yaml similarity index 100% rename from util/health/testdata/pvc-pending.yaml rename to pkg/utils/health/testdata/pvc-pending.yaml diff --git a/util/health/testdata/statefulset.yaml b/pkg/utils/health/testdata/statefulset.yaml similarity index 100% rename from util/health/testdata/statefulset.yaml rename to pkg/utils/health/testdata/statefulset.yaml diff --git a/util/health/testdata/svc-clusterip.yaml b/pkg/utils/health/testdata/svc-clusterip.yaml similarity index 100% rename from util/health/testdata/svc-clusterip.yaml rename to pkg/utils/health/testdata/svc-clusterip.yaml diff --git a/util/health/testdata/svc-loadbalancer-nonemptylist.yaml b/pkg/utils/health/testdata/svc-loadbalancer-nonemptylist.yaml similarity index 100% rename from util/health/testdata/svc-loadbalancer-nonemptylist.yaml rename to pkg/utils/health/testdata/svc-loadbalancer-nonemptylist.yaml diff --git a/util/health/testdata/svc-loadbalancer-unassigned.yaml b/pkg/utils/health/testdata/svc-loadbalancer-unassigned.yaml similarity index 100% rename from util/health/testdata/svc-loadbalancer-unassigned.yaml rename to pkg/utils/health/testdata/svc-loadbalancer-unassigned.yaml diff --git a/util/health/testdata/svc-loadbalancer.yaml b/pkg/utils/health/testdata/svc-loadbalancer.yaml similarity index 100% rename from util/health/testdata/svc-loadbalancer.yaml rename to pkg/utils/health/testdata/svc-loadbalancer.yaml diff --git a/pkg/utils/io/io.go b/pkg/utils/io/io.go new file mode 100644 index 000000000..72546896f --- /dev/null +++ b/pkg/utils/io/io.go @@ -0,0 +1,53 @@ +package io + +import ( + "os" + + log "github.com/sirupsen/logrus" +) + +var ( + TempDir string + NopCloser = NewCloser(func() error { + return nil + }) +) + +func init() { + fileInfo, err := os.Stat("/dev/shm") + if err == nil && fileInfo.IsDir() { + TempDir = "/dev/shm" + } +} + +// DeleteFile is best effort deletion of a file +func DeleteFile(path string) { + if _, err := os.Stat(path); os.IsNotExist(err) { + return + } + _ = os.Remove(path) +} + +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) { + if err := c.Close(); err != nil { + log.Warnf("failed to close %v: %v", c, err) + } +} diff --git a/util/json/json.go b/pkg/utils/json/json.go similarity index 100% rename from util/json/json.go rename to pkg/utils/json/json.go diff --git a/pkg/utils/kube/cache/cluster.go b/pkg/utils/kube/cache/cluster.go new file mode 100644 index 000000000..5186e1b5e --- /dev/null +++ b/pkg/utils/kube/cache/cluster.go @@ -0,0 +1,767 @@ +package cache + +import ( + "context" + "fmt" + "runtime/debug" + "sort" + "strings" + "sync" + "sync/atomic" + "time" + + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/pager" + + "github.com/argoproj/gitops-engine/pkg/utils/health" + "github.com/argoproj/gitops-engine/pkg/utils/kube" +) + +const ( + clusterSyncTimeout = 24 * time.Hour + watchResourcesRetryTimeout = 1 * time.Second + ClusterRetryTimeout = 10 * time.Second +) + +type apiMeta struct { + namespaced bool + resourceVersion string + watchCancel context.CancelFunc +} + +type ClusterInfo struct { + Server string + K8SVersion string + ResourcesCount int + APIsCount int + LastCacheSyncTime *time.Time +} + +type Settings struct { + ResourceHealthOverride health.HealthOverride + ResourcesFilter kube.ResourceFilter +} + +var handlerKey uint64 + +type OnEventHandler func(event watch.EventType, un *unstructured.Unstructured) +type OnPopulateResourceInfoHandler func(un *unstructured.Unstructured, isRoot bool) (info interface{}, cacheManifest bool) +type OnResourceUpdatedHandler func(newRes *Resource, oldRes *Resource, namespaceResources map[kube.ResourceKey]*Resource) +type Unsubscribe func() + +type ClusterCache interface { + EnsureSynced() error + GetServerVersion() string + GetAPIGroups() []metav1.APIGroup + Invalidate(settingsCallback func(*rest.Config, []string, Settings) (*rest.Config, []string, Settings)) + GetNamespaceTopLevelResources(namespace string) map[kube.ResourceKey]*Resource + IterateHierarchy(key kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource)) + IsNamespaced(gk schema.GroupKind) (bool, error) + GetManagedLiveObjs(targetObjs []*unstructured.Unstructured, isManaged func(r *Resource) bool) (map[kube.ResourceKey]*unstructured.Unstructured, error) + GetClusterInfo() ClusterInfo + SetPopulateResourceInfoHandler(handler OnPopulateResourceInfoHandler) + OnResourceUpdated(handler OnResourceUpdatedHandler) Unsubscribe + OnEvent(handler OnEventHandler) Unsubscribe +} + +func NewClusterCache(settings Settings, config *rest.Config, namespaces []string, kubectl kube.Kubectl) *clusterCache { + return &clusterCache{ + settings: settings, + apisMeta: make(map[schema.GroupKind]*apiMeta), + resources: make(map[kube.ResourceKey]*Resource), + nsIndex: make(map[string]map[kube.ResourceKey]*Resource), + config: config, + namespaces: namespaces, + kubectl: kubectl, + syncTime: nil, + resourceUpdatedHandlers: map[uint64]OnResourceUpdatedHandler{}, + eventHandlers: map[uint64]OnEventHandler{}, + log: log.WithField("server", config.Host), + } +} + +type clusterCache struct { + syncTime *time.Time + syncError error + apisMeta map[schema.GroupKind]*apiMeta + serverVersion string + apiGroups []metav1.APIGroup + // namespacedResources is a simple map which indicates a groupKind is namespaced + namespacedResources map[schema.GroupKind]bool + + // lock is a rw lock which protects the fields of clusterInfo + lock sync.RWMutex + resources map[kube.ResourceKey]*Resource + nsIndex map[string]map[kube.ResourceKey]*Resource + + kubectl kube.Kubectl + log *log.Entry + config *rest.Config + namespaces []string + settings Settings + + handlersLock sync.Mutex + populateResourceInfoHandler OnPopulateResourceInfoHandler + resourceUpdatedHandlers map[uint64]OnResourceUpdatedHandler + eventHandlers map[uint64]OnEventHandler +} + +func (c *clusterCache) SetPopulateResourceInfoHandler(handler OnPopulateResourceInfoHandler) { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + c.populateResourceInfoHandler = handler +} + +func (c *clusterCache) OnResourceUpdated(handler OnResourceUpdatedHandler) Unsubscribe { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + key := atomic.AddUint64(&handlerKey, 1) + c.resourceUpdatedHandlers[key] = handler + return func() { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + delete(c.resourceUpdatedHandlers, key) + } +} + +func (c *clusterCache) getResourceUpdatedHandlers() []OnResourceUpdatedHandler { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + var handlers []OnResourceUpdatedHandler + for _, h := range c.resourceUpdatedHandlers { + handlers = append(handlers, h) + } + return handlers +} + +func (c *clusterCache) OnEvent(handler OnEventHandler) Unsubscribe { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + key := atomic.AddUint64(&handlerKey, 1) + c.eventHandlers[key] = handler + return func() { + c.lock.Lock() + defer c.lock.Unlock() + delete(c.eventHandlers, key) + } +} + +func (c *clusterCache) getEventHandlers() []OnEventHandler { + c.handlersLock.Lock() + defer c.handlersLock.Unlock() + var handlers []OnEventHandler + for _, h := range c.eventHandlers { + handlers = append(handlers, h) + } + return handlers +} + +func (c *clusterCache) GetServerVersion() string { + return c.serverVersion +} + +func (c *clusterCache) GetAPIGroups() []metav1.APIGroup { + return c.apiGroups +} + +func (c *clusterCache) replaceResourceCache(gk schema.GroupKind, resourceVersion string, objs []unstructured.Unstructured, ns string) { + info, ok := c.apisMeta[gk] + if ok { + objByKey := make(map[kube.ResourceKey]*unstructured.Unstructured) + for i := range objs { + objByKey[kube.GetResourceKey(&objs[i])] = &objs[i] + } + + // update existing nodes + for i := range objs { + obj := &objs[i] + key := kube.GetResourceKey(&objs[i]) + c.onNodeUpdated(c.resources[key], obj) + } + + for key := range c.resources { + if key.Kind != gk.Kind || key.Group != gk.Group || ns != "" && key.Namespace != ns { + continue + } + + if _, ok := objByKey[key]; !ok { + c.onNodeRemoved(key) + } + } + info.resourceVersion = resourceVersion + } +} + +func isServiceAccountTokenSecret(un *unstructured.Unstructured) (bool, metav1.OwnerReference) { + ref := metav1.OwnerReference{ + APIVersion: "v1", + Kind: kube.ServiceAccountKind, + } + if un.GetKind() != kube.SecretKind || un.GroupVersionKind().Group != "" { + return false, ref + } + + if typeVal, ok, err := unstructured.NestedString(un.Object, "type"); !ok || err != nil || typeVal != "kubernetes.io/service-account-token" { + return false, ref + } + + annotations := un.GetAnnotations() + if annotations == nil { + return false, ref + } + + id, okId := annotations["kubernetes.io/service-account.uid"] + name, okName := annotations["kubernetes.io/service-account.name"] + if okId && okName { + ref.Name = name + ref.UID = types.UID(id) + } + return ref.Name != "" && ref.UID != "", ref +} + +func (c *clusterCache) newResource(un *unstructured.Unstructured) *Resource { + ownerRefs := un.GetOwnerReferences() + gvk := un.GroupVersionKind() + // Special case for endpoint. Remove after https://github.com/kubernetes/kubernetes/issues/28483 is fixed + if gvk.Group == "" && gvk.Kind == kube.EndpointsKind && len(un.GetOwnerReferences()) == 0 { + ownerRefs = append(ownerRefs, metav1.OwnerReference{ + Name: un.GetName(), + Kind: kube.ServiceKind, + APIVersion: "v1", + }) + } + + // Special case for Operator Lifecycle Manager ClusterServiceVersion: + if un.GroupVersionKind().Group == "operators.coreos.com" && un.GetKind() == "ClusterServiceVersion" { + if un.GetAnnotations()["olm.operatorGroup"] != "" { + ownerRefs = append(ownerRefs, metav1.OwnerReference{ + Name: un.GetAnnotations()["olm.operatorGroup"], + Kind: "OperatorGroup", + APIVersion: "operators.coreos.com/v1", + }) + } + } + + // edge case. Consider auto-created service account tokens as a child of service account objects + if yes, ref := isServiceAccountTokenSecret(un); yes { + ownerRefs = append(ownerRefs, ref) + } + + cacheManifest := false + var info interface{} + if c.populateResourceInfoHandler != nil { + info, cacheManifest = c.populateResourceInfoHandler(un, len(ownerRefs) == 0) + } + resource := &Resource{ + ResourceVersion: un.GetResourceVersion(), + Ref: kube.GetObjectRef(un), + OwnerRefs: ownerRefs, + Info: info, + } + if cacheManifest { + resource.Resource = un + } + + return resource +} + +func (c *clusterCache) setNode(n *Resource) { + key := n.ResourceKey() + c.resources[key] = n + ns, ok := c.nsIndex[key.Namespace] + if !ok { + ns = make(map[kube.ResourceKey]*Resource) + c.nsIndex[key.Namespace] = ns + } + ns[key] = n +} + +func (c *clusterCache) Invalidate(settingsCallback func(*rest.Config, []string, Settings) (*rest.Config, []string, Settings)) { + c.lock.Lock() + defer c.lock.Unlock() + c.syncTime = nil + for i := range c.apisMeta { + c.apisMeta[i].watchCancel() + } + if settingsCallback != nil { + c.config, c.namespaces, c.settings = settingsCallback(c.config, c.namespaces, c.settings) + } + c.apisMeta = nil + c.namespacedResources = nil + c.log.Warnf("invalidated cluster") +} + +func (c *clusterCache) synced() bool { + syncTime := c.syncTime + if syncTime == nil { + return false + } + if c.syncError != nil { + return time.Now().Before(syncTime.Add(ClusterRetryTimeout)) + } + return time.Now().Before(syncTime.Add(clusterSyncTimeout)) +} + +func (c *clusterCache) stopWatching(gk schema.GroupKind, ns string) { + c.lock.Lock() + defer c.lock.Unlock() + if info, ok := c.apisMeta[gk]; ok { + info.watchCancel() + delete(c.apisMeta, gk) + c.replaceResourceCache(gk, "", []unstructured.Unstructured{}, ns) + c.log.Warnf("Stop watching: %s not found", gk) + } +} + +// startMissingWatches lists supported cluster resources and start watching for changes unless watch is already running +func (c *clusterCache) startMissingWatches() error { + apis, err := c.kubectl.GetAPIResources(c.config, c.settings.ResourcesFilter) + if err != nil { + return err + } + client, err := c.kubectl.NewDynamicClient(c.config) + if err != nil { + return err + } + namespacedResources := make(map[schema.GroupKind]bool) + for i := range apis { + api := apis[i] + namespacedResources[api.GroupKind] = api.Meta.Namespaced + if _, ok := c.apisMeta[api.GroupKind]; !ok { + ctx, cancel := context.WithCancel(context.Background()) + info := &apiMeta{namespaced: api.Meta.Namespaced, watchCancel: cancel} + c.apisMeta[api.GroupKind] = info + + err = c.processApi(client, api, func(resClient dynamic.ResourceInterface, ns string) error { + go c.watchEvents(ctx, api, info, resClient, ns) + return nil + }) + if err != nil { + return err + } + } + } + c.namespacedResources = namespacedResources + return nil +} + +func runSynced(lock sync.Locker, action func() error) error { + lock.Lock() + defer lock.Unlock() + return action() +} + +func (c *clusterCache) watchEvents(ctx context.Context, api kube.APIResourceInfo, info *apiMeta, resClient dynamic.ResourceInterface, ns string) { + kube.RetryUntilSucceed(func() (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) + } + }() + + err = runSynced(&c.lock, func() error { + if info.resourceVersion == "" { + listPager := pager.New(func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + res, err := resClient.List(opts) + if err == nil { + info.resourceVersion = res.GetResourceVersion() + } + return res, err + }) + var items []unstructured.Unstructured + err = listPager.EachListItem(ctx, metav1.ListOptions{}, func(obj runtime.Object) error { + if un, ok := obj.(*unstructured.Unstructured); !ok { + return fmt.Errorf("object %s/%s has an unexpected type", un.GroupVersionKind().String(), un.GetName()) + } else { + items = append(items, *un) + } + return nil + }) + if err != nil { + return fmt.Errorf("failed to load initial state of resource %s: %v", api.GroupKind.String(), err) + } + c.replaceResourceCache(api.GroupKind, info.resourceVersion, items, ns) + } + return nil + }) + + if err != nil { + return err + } + + w, err := resClient.Watch(metav1.ListOptions{ResourceVersion: info.resourceVersion}) + if errors.IsNotFound(err) { + c.stopWatching(api.GroupKind, ns) + return nil + } + + if errors.IsGone(err) { + info.resourceVersion = "" + c.log.Warnf("Resource version of %s is too old", api.GroupKind) + } + + if err != nil { + return err + } + + defer w.Stop() + for { + select { + case <-ctx.Done(): + return nil + case event, ok := <-w.ResultChan(): + if ok { + obj := event.Object.(*unstructured.Unstructured) + info.resourceVersion = obj.GetResourceVersion() + c.processEvent(event.Type, obj) + if kube.IsCRD(obj) { + if event.Type == watch.Deleted { + group, groupOk, groupErr := unstructured.NestedString(obj.Object, "spec", "group") + kind, kindOk, kindErr := unstructured.NestedString(obj.Object, "spec", "names", "kind") + + if groupOk && groupErr == nil && kindOk && kindErr == nil { + gk := schema.GroupKind{Group: group, Kind: kind} + c.stopWatching(gk, ns) + } + } else { + err = runSynced(&c.lock, func() error { + return c.startMissingWatches() + }) + + } + } + if err != nil { + c.log.Warnf("Failed to start missing watch: %v", err) + } + } else { + return fmt.Errorf("Watch %s on %s has closed", api.GroupKind, c.config.Host) + } + } + } + + }, fmt.Sprintf("watch %s on %s", api.GroupKind, c.config.Host), ctx, watchResourcesRetryTimeout) +} + +func (c *clusterCache) processApi(client dynamic.Interface, api kube.APIResourceInfo, callback func(resClient dynamic.ResourceInterface, ns string) error) error { + resClient := client.Resource(api.GroupVersionResource) + if len(c.namespaces) == 0 { + return callback(resClient, "") + } + + if !api.Meta.Namespaced { + return nil + } + + for _, ns := range c.namespaces { + err := callback(resClient.Namespace(ns), ns) + if err != nil { + return err + } + } + return nil +} + +func (c *clusterCache) sync() (err error) { + c.log.Info("Start syncing cluster") + + for i := range c.apisMeta { + c.apisMeta[i].watchCancel() + } + c.apisMeta = make(map[schema.GroupKind]*apiMeta) + c.resources = make(map[kube.ResourceKey]*Resource) + c.namespacedResources = make(map[schema.GroupKind]bool) + config := c.config + version, err := c.kubectl.GetServerVersion(config) + + if err != nil { + return err + } + c.serverVersion = version + groups, err := c.kubectl.GetAPIGroups(config) + if err != nil { + return err + } + c.apiGroups = groups + apis, err := c.kubectl.GetAPIResources(c.config, c.settings.ResourcesFilter) + + if err != nil { + return err + } + client, err := c.kubectl.NewDynamicClient(c.config) + if err != nil { + return err + } + lock := sync.Mutex{} + err = kube.RunAllAsync(len(apis), func(i int) error { + api := apis[i] + + lock.Lock() + ctx, cancel := context.WithCancel(context.Background()) + info := &apiMeta{namespaced: api.Meta.Namespaced, watchCancel: cancel} + c.apisMeta[api.GroupKind] = info + c.namespacedResources[api.GroupKind] = api.Meta.Namespaced + lock.Unlock() + + return c.processApi(client, api, func(resClient dynamic.ResourceInterface, ns string) error { + + listPager := pager.New(func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + res, err := resClient.List(opts) + if err == nil { + lock.Lock() + info.resourceVersion = res.GetResourceVersion() + lock.Unlock() + } + return res, err + }) + + err = listPager.EachListItem(context.Background(), metav1.ListOptions{}, func(obj runtime.Object) error { + if un, ok := obj.(*unstructured.Unstructured); !ok { + return fmt.Errorf("object %s/%s has an unexpected type", un.GroupVersionKind().String(), un.GetName()) + } else { + lock.Lock() + c.setNode(c.newResource(un)) + lock.Unlock() + } + return nil + }) + + if err != nil { + return fmt.Errorf("failed to load initial state of resource %s: %v", api.GroupKind.String(), err) + } + + go c.watchEvents(ctx, api, info, resClient, ns) + + return nil + }) + }) + + if err != nil { + log.Errorf("Failed to sync cluster %s: %v", c.config.Host, err) + return err + } + + c.log.Info("Cluster successfully synced") + return nil +} + +func (c *clusterCache) EnsureSynced() error { + // first check if cluster is synced *without lock* + if c.synced() { + return c.syncError + } + + c.lock.Lock() + defer c.lock.Unlock() + // before doing any work, check once again now that we have the lock, to see if it got + // synced between the first check and now + if c.synced() { + return c.syncError + } + err := c.sync() + syncTime := time.Now() + c.syncTime = &syncTime + c.syncError = err + return c.syncError +} + +func (c *clusterCache) GetNamespaceTopLevelResources(namespace string) map[kube.ResourceKey]*Resource { + c.lock.RLock() + defer c.lock.RUnlock() + resources := make(map[kube.ResourceKey]*Resource) + for _, res := range c.nsIndex[namespace] { + if len(res.OwnerRefs) == 0 { + resources[res.ResourceKey()] = res + } + } + return resources +} + +func (c *clusterCache) IterateHierarchy(key kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource)) { + c.lock.Lock() + defer c.lock.Unlock() + if res, ok := c.resources[key]; ok { + nsNodes := c.nsIndex[key.Namespace] + action(res, nsNodes) + childrenByUID := make(map[types.UID][]*Resource) + for _, child := range nsNodes { + if res.isParentOf(child) { + childrenByUID[child.Ref.UID] = append(childrenByUID[child.Ref.UID], child) + } + } + // make sure children has no duplicates + for _, children := range childrenByUID { + if len(children) > 0 { + // The object might have multiple children with the same UID (e.g. replicaset from apps and extensions group). It is ok to pick any object but we need to make sure + // we pick the same child after every refresh. + sort.Slice(children, func(i, j int) bool { + key1 := children[i].ResourceKey() + key2 := children[j].ResourceKey() + return strings.Compare(key1.String(), key2.String()) < 0 + }) + child := children[0] + action(child, nsNodes) + child.iterateChildren(nsNodes, map[kube.ResourceKey]bool{res.ResourceKey(): true}, action) + } + } + } +} + +func (c *clusterCache) IsNamespaced(gk schema.GroupKind) (bool, error) { + if isNamespaced, ok := c.namespacedResources[gk]; ok { + return isNamespaced, nil + } + return false, errors.NewNotFound(schema.GroupResource{Group: gk.Group}, "") +} + +func (c *clusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructured, isManaged func(r *Resource) bool) (map[kube.ResourceKey]*unstructured.Unstructured, error) { + c.lock.RLock() + defer c.lock.RUnlock() + + managedObjs := make(map[kube.ResourceKey]*unstructured.Unstructured) + // iterate all objects in live state cache to find ones associated with app + for key, o := range c.resources { + if isManaged(o) && o.Resource != nil && len(o.OwnerRefs) == 0 { + managedObjs[key] = o.Resource + } + } + // but are simply missing our label + lock := &sync.Mutex{} + err := kube.RunAllAsync(len(targetObjs), func(i int) error { + targetObj := targetObjs[i] + key := kube.GetResourceKey(targetObj) + lock.Lock() + managedObj := managedObjs[key] + lock.Unlock() + + if managedObj == nil { + if existingObj, exists := c.resources[key]; exists { + if existingObj.Resource != nil { + managedObj = existingObj.Resource + } else { + var err error + managedObj, err = c.kubectl.GetResource(c.config, targetObj.GroupVersionKind(), existingObj.Ref.Name, existingObj.Ref.Namespace) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + } + } else if _, watched := c.apisMeta[key.GroupKind()]; !watched { + var err error + managedObj, err = c.kubectl.GetResource(c.config, targetObj.GroupVersionKind(), targetObj.GetName(), targetObj.GetNamespace()) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + } + } + + if managedObj != nil { + converted, err := c.kubectl.ConvertToVersion(managedObj, targetObj.GroupVersionKind().Group, targetObj.GroupVersionKind().Version) + if err != nil { + // fallback to loading resource from kubernetes if conversion fails + log.Warnf("Failed to convert resource: %v", err) + managedObj, err = c.kubectl.GetResource(c.config, targetObj.GroupVersionKind(), managedObj.GetName(), managedObj.GetNamespace()) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + } else { + managedObj = converted + } + lock.Lock() + managedObjs[key] = managedObj + lock.Unlock() + } + return nil + }) + if err != nil { + return nil, err + } + + return managedObjs, nil +} + +func (c *clusterCache) processEvent(event watch.EventType, un *unstructured.Unstructured) { + for _, h := range c.getEventHandlers() { + h(event, un) + } + key := kube.GetResourceKey(un) + if event == watch.Modified && skipAppRequeing(key) { + return + } + + c.lock.Lock() + defer c.lock.Unlock() + existingNode, exists := c.resources[key] + if event == watch.Deleted { + if exists { + c.onNodeRemoved(key) + } + } else if event != watch.Deleted { + c.onNodeUpdated(existingNode, un) + } +} + +func (c *clusterCache) onNodeUpdated(oldRes *Resource, un *unstructured.Unstructured) { + newRes := c.newResource(un) + c.setNode(newRes) + for _, h := range c.getResourceUpdatedHandlers() { + h(newRes, oldRes, c.nsIndex[newRes.Ref.Namespace]) + } +} + +func (c *clusterCache) onNodeRemoved(key kube.ResourceKey) { + existing, ok := c.resources[key] + if ok { + delete(c.resources, key) + ns, ok := c.nsIndex[key.Namespace] + if ok { + delete(ns, key) + if len(ns) == 0 { + delete(c.nsIndex, key.Namespace) + } + } + for _, h := range c.getResourceUpdatedHandlers() { + h(nil, existing, ns) + } + } +} + +var ( + ignoredRefreshResources = map[string]bool{ + "/" + kube.EndpointsKind: true, + } +) + +func (c *clusterCache) GetClusterInfo() ClusterInfo { + c.lock.RLock() + defer c.lock.RUnlock() + return ClusterInfo{ + APIsCount: len(c.apisMeta), + K8SVersion: c.serverVersion, + ResourcesCount: len(c.resources), + Server: c.config.Host, + LastCacheSyncTime: c.syncTime, + } +} + +// skipAppRequeing checks if the object is an API type which we want to skip requeuing against. +// We ignore API types which have a high churn rate, and/or whose updates are irrelevant to the app +func skipAppRequeing(key kube.ResourceKey) bool { + return ignoredRefreshResources[key.Group+"/"+key.Kind] +} diff --git a/pkg/utils/kube/cache/cluster_test.go b/pkg/utils/kube/cache/cluster_test.go new file mode 100644 index 000000000..28807f466 --- /dev/null +++ b/pkg/utils/kube/cache/cluster_test.go @@ -0,0 +1,427 @@ +package cache + +import ( + "sort" + "strings" + "testing" + + "github.com/ghodss/yaml" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/rest" + + "github.com/argoproj/gitops-engine/pkg/utils/errors" + "github.com/argoproj/gitops-engine/pkg/utils/health" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" +) + +func strToUnstructured(jsonStr string) *unstructured.Unstructured { + obj := make(map[string]interface{}) + err := yaml.Unmarshal([]byte(jsonStr), &obj) + errors.CheckError(err) + return &unstructured.Unstructured{Object: obj} +} + +var ( + testPod = strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + uid: "1" + name: helm-guestbook-pod + namespace: default + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: helm-guestbook-rs + uid: "2" + resourceVersion: "123"`) + + testRS = strToUnstructured(` + apiVersion: apps/v1 + kind: ReplicaSet + metadata: + uid: "2" + name: helm-guestbook-rs + namespace: default + annotations: + deployment.kubernetes.io/revision: "2" + ownerReferences: + - apiVersion: apps/v1beta1 + kind: Deployment + name: helm-guestbook + uid: "3" + resourceVersion: "123"`) + + testDeploy = strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: helm-guestbook + uid: "3" + name: helm-guestbook + namespace: default + resourceVersion: "123"`) + + testService = strToUnstructured(` + apiVersion: v1 + kind: Service + metadata: + name: helm-guestbook + namespace: default + resourceVersion: "123" + uid: "4" + spec: + selector: + app: guestbook + type: LoadBalancer + status: + loadBalancer: + ingress: + - hostname: localhost`) +) + +func newCluster(objs ...*unstructured.Unstructured) *clusterCache { + runtimeObjs := make([]runtime.Object, len(objs)) + for i := range objs { + runtimeObjs[i] = objs[i] + } + scheme := runtime.NewScheme() + client := fake.NewSimpleDynamicClient(scheme, runtimeObjs...) + + apiResources := []kube.APIResourceInfo{{ + GroupKind: schema.GroupKind{Group: "", Kind: "Pod"}, + GroupVersionResource: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}, + Meta: metav1.APIResource{Namespaced: true}, + }, { + GroupKind: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}, + GroupVersionResource: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "replicasets"}, + Meta: metav1.APIResource{Namespaced: true}, + }, { + GroupKind: schema.GroupKind{Group: "apps", Kind: "Deployment"}, + GroupVersionResource: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}, + Meta: metav1.APIResource{Namespaced: true}, + }} + + return newClusterExt(&kubetest.MockKubectlCmd{APIResources: apiResources, DynamicClient: client}) +} + +func newClusterExt(kubectl kube.Kubectl) *clusterCache { + return &clusterCache{ + resources: make(map[kube.ResourceKey]*Resource), + kubectl: kubectl, + nsIndex: make(map[string]map[kube.ResourceKey]*Resource), + apisMeta: make(map[schema.GroupKind]*apiMeta), + log: log.WithField("cluster", "test"), + settings: Settings{ + ResourceHealthOverride: &fakeSettings{}, + ResourcesFilter: &fakeSettings{}, + }, + config: &rest.Config{Host: "https://test"}, + } +} + +type fakeSettings struct { +} + +func (f *fakeSettings) GetResourceHealth(obj *unstructured.Unstructured) (*health.HealthStatus, error) { + return nil, nil +} + +func (f *fakeSettings) IsExcludedResource(group, kind, cluster string) bool { + return false +} + +func getChildren(cluster *clusterCache, un *unstructured.Unstructured) []*Resource { + hierarchy := make([]*Resource, 0) + cluster.IterateHierarchy(kube.GetResourceKey(un), func(child *Resource, _ map[kube.ResourceKey]*Resource) { + hierarchy = append(hierarchy, child) + }) + return hierarchy[1:] +} + +func TestEnsureSynced(t *testing.T) { + obj1 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook1", "namespace": "default1"} +`) + obj2 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook2", "namespace": "default2"} +`) + + cluster := newCluster(obj1, obj2) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + assert.Len(t, cluster.resources, 2) + var names []string + for k := range cluster.resources { + names = append(names, k.Name) + } + assert.ElementsMatch(t, []string{"helm-guestbook1", "helm-guestbook2"}, names) +} + +func TestEnsureSyncedSingleNamespace(t *testing.T) { + obj1 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook1", "namespace": "default1"} +`) + obj2 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook2", "namespace": "default2"} +`) + + cluster := newCluster(obj1, obj2) + cluster.namespaces = []string{"default1"} + err := cluster.EnsureSynced() + assert.Nil(t, err) + + assert.Len(t, cluster.resources, 1) + var names []string + for k := range cluster.resources { + names = append(names, k.Name) + } + assert.ElementsMatch(t, []string{"helm-guestbook1"}, names) +} + +func TestGetNamespaceResources(t *testing.T) { + defaultNamespaceTopLevel1 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook1", "namespace": "default"} +`) + defaultNamespaceTopLevel2 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook2", "namespace": "default"} +`) + kubesystemNamespaceTopLevel2 := strToUnstructured(` + apiVersion: apps/v1 + kind: Deployment + metadata: {"name": "helm-guestbook3", "namespace": "kube-system"} +`) + + cluster := newCluster(defaultNamespaceTopLevel1, defaultNamespaceTopLevel2, kubesystemNamespaceTopLevel2) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + resources := cluster.GetNamespaceTopLevelResources("default") + assert.Len(t, resources, 2) + assert.Equal(t, resources[kube.GetResourceKey(defaultNamespaceTopLevel1)].Ref.Name, "helm-guestbook1") + assert.Equal(t, resources[kube.GetResourceKey(defaultNamespaceTopLevel2)].Ref.Name, "helm-guestbook2") + + resources = cluster.GetNamespaceTopLevelResources("kube-system") + assert.Len(t, resources, 1) + assert.Equal(t, resources[kube.GetResourceKey(kubesystemNamespaceTopLevel2)].Ref.Name, "helm-guestbook3") +} + +func TestGetChildren(t *testing.T) { + cluster := newCluster(testPod, testRS, testDeploy) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + rsChildren := getChildren(cluster, testRS) + assert.Equal(t, []*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod", + APIVersion: "v1", + UID: "1", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + }}, rsChildren) + deployChildren := getChildren(cluster, testDeploy) + + assert.Equal(t, append([]*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "ReplicaSet", + Namespace: "default", + Name: "helm-guestbook-rs", + APIVersion: "apps/v1", + UID: "2", + }, + ResourceVersion: "123", + OwnerRefs: []metav1.OwnerReference{{APIVersion: "apps/v1beta1", Kind: "Deployment", Name: "helm-guestbook", UID: "3"}}, + }}, rsChildren...), deployChildren) +} + +func TestGetManagedLiveObjs(t *testing.T) { + cluster := newCluster(testPod, testRS, testDeploy) + cluster.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (info interface{}, cacheManifest bool) { + return nil, true + }) + + err := cluster.EnsureSynced() + assert.Nil(t, err) + + targetDeploy := strToUnstructured(` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: helm-guestbook + labels: + app: helm-guestbook`) + + managedObjs, err := cluster.GetManagedLiveObjs([]*unstructured.Unstructured{targetDeploy}, func(r *Resource) bool { + return len(r.OwnerRefs) == 0 + }) + assert.Nil(t, err) + assert.Equal(t, managedObjs, map[kube.ResourceKey]*unstructured.Unstructured{ + kube.NewResourceKey("apps", "Deployment", "default", "helm-guestbook"): testDeploy, + }) +} + +func TestChildDeletedEvent(t *testing.T) { + cluster := newCluster(testPod, testRS, testDeploy) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + cluster.processEvent(watch.Deleted, testPod) + + rsChildren := getChildren(cluster, testRS) + assert.Equal(t, []*Resource{}, rsChildren) +} + +func TestProcessNewChildEvent(t *testing.T) { + cluster := newCluster(testPod, testRS, testDeploy) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + newPod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + uid: "4" + name: helm-guestbook-pod2 + namespace: default + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: helm-guestbook-rs + uid: "2" + resourceVersion: "123"`) + + cluster.processEvent(watch.Added, newPod) + + rsChildren := getChildren(cluster, testRS) + sort.Slice(rsChildren, func(i, j int) bool { + return strings.Compare(rsChildren[i].Ref.Name, rsChildren[j].Ref.Name) < 0 + }) + assert.Equal(t, []*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod", + APIVersion: "v1", + UID: "1", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + }, { + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod2", + APIVersion: "v1", + UID: "4", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + }}, rsChildren) +} + +func TestWatchCacheUpdated(t *testing.T) { + removed := testPod.DeepCopy() + removed.SetName(testPod.GetName() + "-removed-pod") + + updated := testPod.DeepCopy() + updated.SetName(testPod.GetName() + "-updated-pod") + updated.SetResourceVersion("updated-pod-version") + + cluster := newCluster(removed, updated) + err := cluster.EnsureSynced() + + assert.Nil(t, err) + + added := testPod.DeepCopy() + added.SetName(testPod.GetName() + "-new-pod") + + podGroupKind := testPod.GroupVersionKind().GroupKind() + + cluster.lock.Lock() + cluster.replaceResourceCache(podGroupKind, "updated-list-version", []unstructured.Unstructured{*updated, *added}, "") + + _, ok := cluster.resources[kube.GetResourceKey(removed)] + assert.False(t, ok) +} + +func TestNamespaceModeReplace(t *testing.T) { + ns1Pod := testPod.DeepCopy() + ns1Pod.SetNamespace("ns1") + ns1Pod.SetName("pod1") + + ns2Pod := testPod.DeepCopy() + ns2Pod.SetNamespace("ns2") + podGroupKind := testPod.GroupVersionKind().GroupKind() + + cluster := newCluster(ns1Pod, ns2Pod) + err := cluster.EnsureSynced() + assert.Nil(t, err) + + cluster.replaceResourceCache(podGroupKind, "", nil, "ns1") + + _, ok := cluster.resources[kube.GetResourceKey(ns1Pod)] + assert.False(t, ok) + + _, ok = cluster.resources[kube.GetResourceKey(ns2Pod)] + assert.True(t, ok) +} + +func TestGetDuplicatedChildren(t *testing.T) { + extensionsRS := testRS.DeepCopy() + extensionsRS.SetGroupVersionKind(schema.GroupVersionKind{Group: "extensions", Kind: kube.ReplicaSetKind, Version: "v1beta1"}) + cluster := newCluster(testDeploy, testRS, extensionsRS) + err := cluster.EnsureSynced() + + assert.Nil(t, err) + + // Get children multiple times to make sure the right child is picked up every time. + for i := 0; i < 5; i++ { + children := getChildren(cluster, testDeploy) + assert.Len(t, children, 1) + assert.Equal(t, "apps/v1", children[0].Ref.APIVersion) + assert.Equal(t, kube.ReplicaSetKind, children[0].Ref.Kind) + assert.Equal(t, testRS.GetName(), children[0].Ref.Name) + } +} diff --git a/pkg/utils/kube/cache/mocks/ClusterCache.go b/pkg/utils/kube/cache/mocks/ClusterCache.go new file mode 100644 index 000000000..01532cd63 --- /dev/null +++ b/pkg/utils/kube/cache/mocks/ClusterCache.go @@ -0,0 +1,188 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package mocks + +import ( + kube "github.com/argoproj/gitops-engine/pkg/utils/kube" + cache "github.com/argoproj/gitops-engine/pkg/utils/kube/cache" + + mock "github.com/stretchr/testify/mock" + + rest "k8s.io/client-go/rest" + + schema "k8s.io/apimachinery/pkg/runtime/schema" + + unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClusterCache is an autogenerated mock type for the ClusterCache type +type ClusterCache struct { + mock.Mock +} + +// EnsureSynced provides a mock function with given fields: +func (_m *ClusterCache) EnsureSynced() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetAPIGroups provides a mock function with given fields: +func (_m *ClusterCache) GetAPIGroups() []v1.APIGroup { + ret := _m.Called() + + var r0 []v1.APIGroup + if rf, ok := ret.Get(0).(func() []v1.APIGroup); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]v1.APIGroup) + } + } + + return r0 +} + +// GetClusterInfo provides a mock function with given fields: +func (_m *ClusterCache) GetClusterInfo() cache.ClusterInfo { + ret := _m.Called() + + var r0 cache.ClusterInfo + if rf, ok := ret.Get(0).(func() cache.ClusterInfo); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(cache.ClusterInfo) + } + + return r0 +} + +// GetManagedLiveObjs provides a mock function with given fields: targetObjs, isManaged +func (_m *ClusterCache) GetManagedLiveObjs(targetObjs []*unstructured.Unstructured, isManaged func(*cache.Resource) bool) (map[kube.ResourceKey]*unstructured.Unstructured, error) { + ret := _m.Called(targetObjs, isManaged) + + var r0 map[kube.ResourceKey]*unstructured.Unstructured + if rf, ok := ret.Get(0).(func([]*unstructured.Unstructured, func(*cache.Resource) bool) map[kube.ResourceKey]*unstructured.Unstructured); ok { + r0 = rf(targetObjs, isManaged) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[kube.ResourceKey]*unstructured.Unstructured) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]*unstructured.Unstructured, func(*cache.Resource) bool) error); ok { + r1 = rf(targetObjs, isManaged) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNamespaceTopLevelResources provides a mock function with given fields: namespace +func (_m *ClusterCache) GetNamespaceTopLevelResources(namespace string) map[kube.ResourceKey]*cache.Resource { + ret := _m.Called(namespace) + + var r0 map[kube.ResourceKey]*cache.Resource + if rf, ok := ret.Get(0).(func(string) map[kube.ResourceKey]*cache.Resource); ok { + r0 = rf(namespace) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[kube.ResourceKey]*cache.Resource) + } + } + + return r0 +} + +// GetServerVersion provides a mock function with given fields: +func (_m *ClusterCache) GetServerVersion() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Invalidate provides a mock function with given fields: settingsCallback +func (_m *ClusterCache) Invalidate(settingsCallback func(*rest.Config, []string, cache.Settings) (*rest.Config, []string, cache.Settings)) { + _m.Called(settingsCallback) +} + +// IsNamespaced provides a mock function with given fields: gk +func (_m *ClusterCache) IsNamespaced(gk schema.GroupKind) (bool, error) { + ret := _m.Called(gk) + + var r0 bool + if rf, ok := ret.Get(0).(func(schema.GroupKind) bool); ok { + r0 = rf(gk) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(schema.GroupKind) error); ok { + r1 = rf(gk) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IterateHierarchy provides a mock function with given fields: key, action +func (_m *ClusterCache) IterateHierarchy(key kube.ResourceKey, action func(*cache.Resource, map[kube.ResourceKey]*cache.Resource)) { + _m.Called(key, action) +} + +// OnEvent provides a mock function with given fields: handler +func (_m *ClusterCache) OnEvent(handler cache.OnEventHandler) cache.Unsubscribe { + ret := _m.Called(handler) + + var r0 cache.Unsubscribe + if rf, ok := ret.Get(0).(func(cache.OnEventHandler) cache.Unsubscribe); ok { + r0 = rf(handler) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.Unsubscribe) + } + } + + return r0 +} + +// OnResourceUpdated provides a mock function with given fields: handler +func (_m *ClusterCache) OnResourceUpdated(handler cache.OnResourceUpdatedHandler) cache.Unsubscribe { + ret := _m.Called(handler) + + var r0 cache.Unsubscribe + if rf, ok := ret.Get(0).(func(cache.OnResourceUpdatedHandler) cache.Unsubscribe); ok { + r0 = rf(handler) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.Unsubscribe) + } + } + + return r0 +} + +// SetPopulateResourceInfoHandler provides a mock function with given fields: handler +func (_m *ClusterCache) SetPopulateResourceInfoHandler(handler cache.OnPopulateResourceInfoHandler) { + _m.Called(handler) +} diff --git a/pkg/utils/kube/cache/resource.go b/pkg/utils/kube/cache/resource.go new file mode 100644 index 000000000..9985871b2 --- /dev/null +++ b/pkg/utils/kube/cache/resource.go @@ -0,0 +1,67 @@ +package cache + +import ( + log "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" +) + +type Resource struct { + ResourceVersion string + Ref v1.ObjectReference + OwnerRefs []metav1.OwnerReference + Info interface{} + + // available only for root application nodes + Resource *unstructured.Unstructured +} + +func (r *Resource) ResourceKey() kube.ResourceKey { + return kube.NewResourceKey(r.Ref.GroupVersionKind().Group, r.Ref.Kind, r.Ref.Namespace, r.Ref.Name) +} + +func (r *Resource) isParentOf(child *Resource) bool { + for i, ownerRef := range child.OwnerRefs { + + // backfill UID of inferred owner child references + if ownerRef.UID == "" && r.Ref.Kind == ownerRef.Kind && r.Ref.APIVersion == ownerRef.APIVersion && r.Ref.Name == ownerRef.Name { + ownerRef.UID = r.Ref.UID + child.OwnerRefs[i] = ownerRef + return true + } + + if r.Ref.UID == ownerRef.UID { + return true + } + } + + return false +} + +func newResourceKeySet(set map[kube.ResourceKey]bool, keys ...kube.ResourceKey) map[kube.ResourceKey]bool { + newSet := make(map[kube.ResourceKey]bool) + for k, v := range set { + newSet[k] = v + } + for i := range keys { + newSet[keys[i]] = true + } + return newSet +} + +func (r *Resource) iterateChildren(ns map[kube.ResourceKey]*Resource, parents map[kube.ResourceKey]bool, action func(child *Resource, namespaceResources map[kube.ResourceKey]*Resource)) { + for childKey, child := range ns { + if r.isParentOf(ns[childKey]) { + if parents[childKey] { + key := r.ResourceKey() + log.Warnf("Circular dependency detected. %s is child and parent of %s", childKey.String(), key.String()) + } else { + action(child, ns) + child.iterateChildren(ns, newResourceKeySet(parents, r.ResourceKey()), action) + } + } + } +} diff --git a/controller/cache/node_test.go b/pkg/utils/kube/cache/resource_test.go similarity index 55% rename from controller/cache/node_test.go rename to pkg/utils/kube/cache/resource_test.go index 06faacf00..021d8e746 100644 --- a/controller/cache/node_test.go +++ b/pkg/utils/kube/cache/resource_test.go @@ -3,29 +3,15 @@ package cache import ( "testing" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/stretchr/testify/assert" ) -var c = &clusterInfo{ - cacheSettingsSrc: func() *cacheSettings { - return &cacheSettings{AppInstanceLabelKey: common.LabelKeyAppInstance} - }, - luaVMFactory: func(overrides map[string]v1alpha1.ResourceOverride) *lua.VM { - return &lua.VM{ - ResourceOverrides: overrides, - } - }, -} +var c = &clusterCache{} func TestIsParentOf(t *testing.T) { - child := c.createObjInfo(testPod, "") - parent := c.createObjInfo(testRS, "") - grandParent := c.createObjInfo(testDeploy, "") + child := c.newResource(testPod) + parent := c.newResource(testRS) + grandParent := c.newResource(testDeploy) assert.True(t, parent.isParentOf(child)) assert.False(t, grandParent.isParentOf(child)) @@ -35,38 +21,38 @@ func TestIsParentOfSameKindDifferentGroupAndUID(t *testing.T) { rs := testRS.DeepCopy() rs.SetAPIVersion("somecrd.io/v1") rs.SetUID("123") - child := c.createObjInfo(testPod, "") - invalidParent := c.createObjInfo(rs, "") + child := c.newResource(testPod) + invalidParent := c.newResource(rs) assert.False(t, invalidParent.isParentOf(child)) } func TestIsServiceParentOfEndPointWithTheSameName(t *testing.T) { - nonMatchingNameEndPoint := c.createObjInfo(strToUnstructured(` + nonMatchingNameEndPoint := c.newResource(strToUnstructured(` apiVersion: v1 kind: Endpoints metadata: name: not-matching-name namespace: default -`), "") +`)) - matchingNameEndPoint := c.createObjInfo(strToUnstructured(` + matchingNameEndPoint := c.newResource(strToUnstructured(` apiVersion: v1 kind: Endpoints metadata: name: helm-guestbook namespace: default -`), "") +`)) - parent := c.createObjInfo(testService, "") + parent := c.newResource(testService) assert.True(t, parent.isParentOf(matchingNameEndPoint)) - assert.Equal(t, parent.ref.UID, matchingNameEndPoint.ownerRefs[0].UID) + assert.Equal(t, parent.Ref.UID, matchingNameEndPoint.OwnerRefs[0].UID) assert.False(t, parent.isParentOf(nonMatchingNameEndPoint)) } func TestIsServiceAccoountParentOfSecret(t *testing.T) { - serviceAccount := c.createObjInfo(strToUnstructured(` + serviceAccount := c.newResource(strToUnstructured(` apiVersion: v1 kind: ServiceAccount metadata: @@ -75,8 +61,8 @@ metadata: uid: '123' secrets: - name: default-token-123 -`), "") - tokenSecret := c.createObjInfo(strToUnstructured(` +`)) + tokenSecret := c.newResource(strToUnstructured(` apiVersion: v1 kind: Secret metadata: @@ -87,7 +73,7 @@ metadata: namespace: default uid: '345' type: kubernetes.io/service-account-token -`), "") +`)) assert.True(t, serviceAccount.isParentOf(tokenSecret)) } diff --git a/pkg/utils/kube/convert.go b/pkg/utils/kube/convert.go new file mode 100644 index 000000000..028e5c241 --- /dev/null +++ b/pkg/utils/kube/convert.go @@ -0,0 +1,25 @@ +package kube + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/api/legacyscheme" +) + +func convertToVersionWithScheme(obj *unstructured.Unstructured, group string, version string) (*unstructured.Unstructured, error) { + s := legacyscheme.Scheme + object, err := s.ConvertToVersion(obj, runtime.InternalGroupVersioner) + if err != nil { + return nil, err + } + unmarshalledObj, err := s.ConvertToVersion(object, schema.GroupVersion{Group: group, Version: version}) + if err != nil { + return nil, err + } + unstrBody, err := runtime.DefaultUnstructuredConverter.ToUnstructured(unmarshalledObj) + if err != nil { + return nil, err + } + return &unstructured.Unstructured{Object: unstrBody}, nil +} diff --git a/pkg/utils/kube/convert_test.go b/pkg/utils/kube/convert_test.go new file mode 100644 index 000000000..8add175cc --- /dev/null +++ b/pkg/utils/kube/convert_test.go @@ -0,0 +1,93 @@ +package kube + +import ( + "testing" + + testingutils "github.com/argoproj/gitops-engine/pkg/utils/testing" + + "github.com/ghodss/yaml" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type testcase struct { + name string + file string + outputVersion string + fields []checkField +} + +type checkField struct { + expected string +} + +func Test_convertToVersionWithScheme(t *testing.T) { + for _, tt := range []testcase{ + { + name: "apps deployment to extensions deployment", + file: "appsdeployment.yaml", + outputVersion: "extensions/v1beta1", + fields: []checkField{ + { + expected: "apiVersion: extensions/v1beta1", + }, + }, + }, + { + name: "extensions deployment to apps deployment", + file: "extensionsdeployment.yaml", + outputVersion: "apps/v1beta2", + fields: []checkField{ + { + expected: "apiVersion: apps/v1beta2", + }, + }, + }, + { + name: "v1 HPA to v2beta1 HPA", + file: "v1HPA.yaml", + outputVersion: "autoscaling/v2beta1", + fields: []checkField{ + { + expected: "apiVersion: autoscaling/v2beta1", + }, + { + expected: "name: cpu", + }, + { + expected: "targetAverageUtilization: 50", + }, + }, + }, + { + name: "v2beta1 HPA to v1 HPA", + file: "v2beta1HPA.yaml", + outputVersion: "autoscaling/v1", + fields: []checkField{ + { + expected: "apiVersion: autoscaling/v1", + }, + { + expected: "targetCPUUtilizationPercentage: 50", + }, + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + obj := testingutils.UnstructuredFromFile("testdata/" + tt.file) + target, err := schema.ParseGroupVersion(tt.outputVersion) + assert.NoError(t, err) + out, err := convertToVersionWithScheme(obj, target.Group, target.Version) + if assert.NoError(t, err) { + assert.NotNil(t, out) + assert.Equal(t, target.Group, out.GroupVersionKind().Group) + assert.Equal(t, target.Version, out.GroupVersionKind().Version) + bytes, err := yaml.Marshal(out) + assert.NoError(t, err) + for _, field := range tt.fields { + assert.Contains(t, string(bytes), field.expected) + } + } + }) + } +} diff --git a/pkg/utils/kube/ctl.go b/pkg/utils/kube/ctl.go new file mode 100644 index 000000000..2b75fd2e1 --- /dev/null +++ b/pkg/utils/kube/ctl.go @@ -0,0 +1,528 @@ +package kube + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os/exec" + "regexp" + "runtime/debug" + "strings" + "sync" + + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/cli-runtime/pkg/printers" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/kubectl/pkg/cmd/apply" + cmdutil "k8s.io/kubectl/pkg/cmd/util" + "k8s.io/kubectl/pkg/scheme" + "k8s.io/kubernetes/pkg/kubectl/cmd/auth" + + "github.com/argoproj/gitops-engine/pkg/utils/diff" + executil "github.com/argoproj/gitops-engine/pkg/utils/exec" + "github.com/argoproj/gitops-engine/pkg/utils/io" + "github.com/argoproj/gitops-engine/pkg/utils/tracing" +) + +type Kubectl interface { + ApplyResource(config *rest.Config, obj *unstructured.Unstructured, namespace string, dryRun, force, validate bool) (string, error) + ConvertToVersion(obj *unstructured.Unstructured, group, version string) (*unstructured.Unstructured, error) + DeleteResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, forceDelete bool) error + GetResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error) + PatchResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, patchType types.PatchType, patchBytes []byte) (*unstructured.Unstructured, error) + GetAPIResources(config *rest.Config, resourceFilter ResourceFilter) ([]APIResourceInfo, error) + GetAPIGroups(config *rest.Config) ([]metav1.APIGroup, error) + GetServerVersion(config *rest.Config) (string, error) + NewDynamicClient(config *rest.Config) (dynamic.Interface, error) + SetOnKubectlRun(onKubectlRun func(command string) (io.Closer, error)) +} + +type KubectlCmd struct { + OnKubectlRun func(command string) (io.Closer, error) +} + +type APIResourceInfo struct { + GroupKind schema.GroupKind + Meta metav1.APIResource + GroupVersionResource schema.GroupVersionResource +} + +type filterFunc func(apiResource *metav1.APIResource) bool + +func filterAPIResources(config *rest.Config, resourceFilter ResourceFilter, filter filterFunc) ([]APIResourceInfo, error) { + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + + serverResources, err := disco.ServerPreferredResources() + if err != nil { + if len(serverResources) == 0 { + return nil, err + } + log.Warnf("Partial success when performing preferred resource discovery: %v", err) + } + apiResIfs := make([]APIResourceInfo, 0) + for _, apiResourcesList := range serverResources { + gv, err := schema.ParseGroupVersion(apiResourcesList.GroupVersion) + if err != nil { + gv = schema.GroupVersion{} + } + for _, apiResource := range apiResourcesList.APIResources { + + if resourceFilter.IsExcludedResource(gv.Group, apiResource.Kind, config.Host) { + continue + } + + if filter(&apiResource) { + resource := ToGroupVersionResource(apiResourcesList.GroupVersion, &apiResource) + gv, err := schema.ParseGroupVersion(apiResourcesList.GroupVersion) + if err != nil { + return nil, err + } + apiResIf := APIResourceInfo{ + GroupKind: schema.GroupKind{Group: gv.Group, Kind: apiResource.Kind}, + Meta: apiResource, + GroupVersionResource: resource, + } + apiResIfs = append(apiResIfs, apiResIf) + } + } + } + return apiResIfs, nil +} + +// isSupportedVerb returns whether or not a APIResource supports a specific verb +func isSupportedVerb(apiResource *metav1.APIResource, verb string) bool { + for _, v := range apiResource.Verbs { + if v == verb { + return true + } + } + return false +} + +func (k *KubectlCmd) GetAPIGroups(config *rest.Config) ([]metav1.APIGroup, error) { + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + serverGroupList, err := disco.ServerGroups() + if err != nil { + return nil, err + } + return serverGroupList.Groups, nil +} + +func (k *KubectlCmd) GetAPIResources(config *rest.Config, resourceFilter ResourceFilter) ([]APIResourceInfo, error) { + span := tracing.StartSpan("GetAPIResources") + defer span.Finish() + apiResIfs, err := filterAPIResources(config, resourceFilter, func(apiResource *metav1.APIResource) bool { + return isSupportedVerb(apiResource, listVerb) && isSupportedVerb(apiResource, watchVerb) + }) + if err != nil { + return nil, err + } + return apiResIfs, err +} + +// GetResource returns resource +func (k *KubectlCmd) GetResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error) { + span := tracing.StartSpan("GetResource") + span.SetBaggageItem("kind", gvk.Kind) + span.SetBaggageItem("name", name) + defer span.Finish() + dynamicIf, err := dynamic.NewForConfig(config) + if err != nil { + return nil, err + } + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) + if err != nil { + return nil, err + } + resource := gvk.GroupVersion().WithResource(apiResource.Name) + resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) + return resourceIf.Get(name, metav1.GetOptions{}) +} + +// PatchResource patches resource +func (k *KubectlCmd) PatchResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, patchType types.PatchType, patchBytes []byte) (*unstructured.Unstructured, error) { + span := tracing.StartSpan("PatchResource") + span.SetBaggageItem("kind", gvk.Kind) + span.SetBaggageItem("name", name) + defer span.Finish() + dynamicIf, err := dynamic.NewForConfig(config) + if err != nil { + return nil, err + } + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) + if err != nil { + return nil, err + } + resource := gvk.GroupVersion().WithResource(apiResource.Name) + resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) + return resourceIf.Patch(name, patchType, patchBytes, metav1.PatchOptions{}) +} + +// DeleteResource deletes resource +func (k *KubectlCmd) DeleteResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, forceDelete bool) error { + span := tracing.StartSpan("DeleteResource") + span.SetBaggageItem("kind", gvk.Kind) + span.SetBaggageItem("name", name) + defer span.Finish() + dynamicIf, err := dynamic.NewForConfig(config) + if err != nil { + return err + } + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return err + } + apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) + if err != nil { + return err + } + resource := gvk.GroupVersion().WithResource(apiResource.Name) + resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) + propagationPolicy := metav1.DeletePropagationForeground + deleteOptions := &metav1.DeleteOptions{PropagationPolicy: &propagationPolicy} + if forceDelete { + propagationPolicy = metav1.DeletePropagationBackground + zeroGracePeriod := int64(0) + deleteOptions.GracePeriodSeconds = &zeroGracePeriod + } + + return resourceIf.Delete(name, deleteOptions) +} + +// ApplyResource performs an apply of a unstructured resource +func (k *KubectlCmd) ApplyResource(config *rest.Config, obj *unstructured.Unstructured, namespace string, dryRun, force, validate bool) (string, error) { + span := tracing.StartSpan("ApplyResource") + span.SetBaggageItem("kind", obj.GetKind()) + span.SetBaggageItem("name", obj.GetName()) + defer span.Finish() + log.Infof("Applying resource %s/%s in cluster: %s, namespace: %s", obj.GetKind(), obj.GetName(), config.Host, namespace) + f, err := ioutil.TempFile(io.TempDir, "") + if err != nil { + return "", fmt.Errorf("Failed to generate temp file for kubeconfig: %v", err) + } + _ = f.Close() + err = WriteKubeConfig(config, namespace, f.Name()) + if err != nil { + return "", fmt.Errorf("Failed to write kubeconfig: %v", err) + } + defer io.DeleteFile(f.Name()) + manifestBytes, err := json.Marshal(obj) + if err != nil { + return "", err + } + manifestFile, err := ioutil.TempFile(io.TempDir, "") + if err != nil { + return "", fmt.Errorf("Failed to generate temp file for manifest: %v", err) + } + if _, err = manifestFile.Write(manifestBytes); err != nil { + return "", fmt.Errorf("Failed to write manifest: %v", err) + } + if err = manifestFile.Close(); err != nil { + return "", fmt.Errorf("Failed to close manifest: %v", err) + } + defer io.DeleteFile(manifestFile.Name()) + + // log manifest + if log.IsLevelEnabled(log.DebugLevel) { + var obj unstructured.Unstructured + err := json.Unmarshal(manifestBytes, &obj) + if err != nil { + return "", err + } + redacted, _, err := diff.HideSecretData(&obj, nil) + if err != nil { + return "", err + } + redactedBytes, err := json.Marshal(redacted) + if err != nil { + return "", err + } + log.Debug(string(redactedBytes)) + } + + var out []string + if obj.GetAPIVersion() == "rbac.authorization.k8s.io/v1" { + // If it is an RBAC resource, run `kubectl auth reconcile`. This is preferred over + // `kubectl apply`, which cannot tolerate changes in roleRef, which is an immutable field. + // See: https://github.com/kubernetes/kubernetes/issues/66353 + // `auth reconcile` will delete and recreate the resource if necessary + closer, err := k.processKubectlRun("auth") + if err != nil { + return "", err + } + outReconcile, err := k.authReconcile(config, f.Name(), manifestFile.Name(), namespace, dryRun) + io.Close(closer) + if err != nil { + return "", err + } + out = append(out, outReconcile) + // We still want to fallthrough and run `kubectl apply` in order set the + // last-applied-configuration annotation in the object. + } + + closer, err := k.processKubectlRun("apply") + if err != nil { + return "", err + } + defer io.Close(closer) + + // Run kubectl apply + fact, ioStreams := kubeCmdFactory(f.Name(), namespace) + applyOpts, err := newApplyOptions(config, fact, ioStreams, manifestFile.Name(), namespace, validate, force, dryRun) + if err != nil { + return "", err + } + err = applyOpts.Run() + if err != nil { + return "", errors.New(cleanKubectlOutput(err.Error())) + } + if buf := strings.TrimSpace(ioStreams.Out.(*bytes.Buffer).String()); len(buf) > 0 { + out = append(out, buf) + } + if buf := strings.TrimSpace(ioStreams.ErrOut.(*bytes.Buffer).String()); len(buf) > 0 { + out = append(out, buf) + } + return strings.Join(out, ". "), nil +} + +func kubeCmdFactory(kubeconfig, ns string) (cmdutil.Factory, genericclioptions.IOStreams) { + kubeConfigFlags := genericclioptions.NewConfigFlags(true) + if ns != "" { + kubeConfigFlags.Namespace = &ns + } + kubeConfigFlags.KubeConfig = &kubeconfig + matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags) + f := cmdutil.NewFactory(matchVersionKubeConfigFlags) + ioStreams := genericclioptions.IOStreams{ + In: &bytes.Buffer{}, + Out: &bytes.Buffer{}, + ErrOut: &bytes.Buffer{}, + } + return f, ioStreams +} + +func newApplyOptions(config *rest.Config, f cmdutil.Factory, ioStreams genericclioptions.IOStreams, fileName string, namespace string, validate bool, force bool, dryRun bool) (*apply.ApplyOptions, error) { + o := apply.NewApplyOptions(ioStreams) + dynamicClient, err := dynamic.NewForConfig(config) + if err != nil { + return nil, err + } + o.DynamicClient = dynamicClient + o.DeleteOptions = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + o.OpenAPISchema, _ = f.OpenAPISchema() + o.Validator, err = f.Validator(validate) + if err != nil { + return nil, err + } + o.Builder = f.NewBuilder() + o.Mapper, err = f.ToRESTMapper() + if err != nil { + return nil, err + } + + o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) { + o.PrintFlags.NamePrintFlags.Operation = operation + if o.DryRun { + err = o.PrintFlags.Complete("%s (dry run)") + if err != nil { + return nil, err + } + } + if o.ServerDryRun { + err = o.PrintFlags.Complete("%s (server dry run)") + if err != nil { + return nil, err + } + } + return o.PrintFlags.ToPrinter() + } + o.DeleteOptions.FilenameOptions.Filenames = []string{fileName} + o.Namespace = namespace + o.DeleteOptions.ForceDeletion = force + o.DryRun = dryRun + return o, nil +} + +func newReconcileOptions(f cmdutil.Factory, kubeClient *kubernetes.Clientset, fileName string, ioStreams genericclioptions.IOStreams, namespace string, dryRun bool) (*auth.ReconcileOptions, error) { + o := auth.NewReconcileOptions(ioStreams) + o.RBACClient = kubeClient.RbacV1() + o.NamespaceClient = kubeClient.CoreV1() + o.FilenameOptions.Filenames = []string{fileName} + o.DryRun = dryRun + + r := f.NewBuilder(). + WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). + NamespaceParam(namespace).DefaultNamespace(). + FilenameParam(false, o.FilenameOptions). + Flatten(). + Do() + o.Visitor = r + + if o.DryRun { + err := o.PrintFlags.Complete("%s (dry run)") + if err != nil { + return nil, err + } + } + printer, err := o.PrintFlags.ToPrinter() + if err != nil { + return nil, err + } + o.PrintObject = printer.PrintObj + return o, nil +} + +func (k *KubectlCmd) authReconcile(config *rest.Config, kubeconfigPath string, manifestFile string, namespace string, dryRun bool) (string, error) { + kubeClient, err := kubernetes.NewForConfig(config) + if err != nil { + return "", err + } + // `kubectl auth reconcile` has a side effect of auto-creating namespaces if it doesn't exist. + // See: https://github.com/kubernetes/kubernetes/issues/71185. This is behavior which we do + // not want. We need to check if the namespace exists, before know if it is safe to run this + // command. Skip this for dryRuns. + if !dryRun && namespace != "" { + _, err = kubeClient.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) + if err != nil { + return "", err + } + } + fact, ioStreams := kubeCmdFactory(kubeconfigPath, namespace) + reconcileOpts, err := newReconcileOptions(fact, kubeClient, manifestFile, ioStreams, namespace, dryRun) + if err != nil { + return "", err + } + + err = reconcileOpts.Validate() + if err != nil { + return "", errors.New(cleanKubectlOutput(err.Error())) + } + err = reconcileOpts.RunReconcile() + if err != nil { + return "", errors.New(cleanKubectlOutput(err.Error())) + } + + var out []string + if buf := strings.TrimSpace(ioStreams.Out.(*bytes.Buffer).String()); len(buf) > 0 { + out = append(out, buf) + } + if buf := strings.TrimSpace(ioStreams.ErrOut.(*bytes.Buffer).String()); len(buf) > 0 { + out = append(out, buf) + } + return strings.Join(out, ". "), nil +} + +func Version() (string, error) { + span := tracing.StartSpan("Version") + defer span.Finish() + cmd := exec.Command("kubectl", "version", "--client") + out, err := executil.Run(cmd) + if err != nil { + return "", fmt.Errorf("could not get kubectl version: %s", err) + } + re := regexp.MustCompile(`GitVersion:"([a-zA-Z0-9\.\-]+)"`) + matches := re.FindStringSubmatch(out) + if len(matches) != 2 { + return "", errors.New("could not get kubectl version") + } + version := matches[1] + if version[0] != 'v' { + version = "v" + version + } + return strings.TrimSpace(version), nil +} + +// ConvertToVersion converts an unstructured object into the specified group/version +func (k *KubectlCmd) ConvertToVersion(obj *unstructured.Unstructured, group string, version string) (*unstructured.Unstructured, error) { + span := tracing.StartSpan("ConvertToVersion") + from := obj.GroupVersionKind().GroupVersion() + span.SetBaggageItem("from", from.String()) + span.SetBaggageItem("to", schema.GroupVersion{Group: group, Version: version}.String()) + defer span.Finish() + if from.Group == group && from.Version == version { + return obj.DeepCopy(), nil + } + return convertToVersionWithScheme(obj, group, version) +} + +func (k *KubectlCmd) GetServerVersion(config *rest.Config) (string, error) { + span := tracing.StartSpan("GetServerVersion") + defer span.Finish() + client, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return "", err + } + v, err := client.ServerVersion() + if err != nil { + return "", err + } + return fmt.Sprintf("%s.%s", v.Major, v.Minor), nil +} + +func (k *KubectlCmd) NewDynamicClient(config *rest.Config) (dynamic.Interface, error) { + return dynamic.NewForConfig(config) +} + +func (k *KubectlCmd) processKubectlRun(cmd string) (io.Closer, error) { + if k.OnKubectlRun != nil { + return k.OnKubectlRun(cmd) + } + return io.NewCloser(func() error { + return nil + // do nothing + }), nil +} + +func (k *KubectlCmd) SetOnKubectlRun(onKubectlRun func(command string) (io.Closer, error)) { + k.OnKubectlRun = onKubectlRun +} + +func RunAllAsync(count int, action func(i int) error) (err error) { + defer func() { + if r := recover(); r != nil { + message := fmt.Sprintf("Recovered from panic: %+v\n%s", r, debug.Stack()) + log.Error(message) + err = errors.New(message) + } + }() + var wg sync.WaitGroup + for i := 0; i < count; i++ { + wg.Add(1) + go func(index int) { + defer wg.Done() + actionErr := action(index) + if actionErr != nil { + err = actionErr + } + }(i) + if err != nil { + break + } + } + wg.Wait() + return err +} diff --git a/pkg/utils/kube/ctl_test.go b/pkg/utils/kube/ctl_test.go new file mode 100644 index 000000000..412f3b4df --- /dev/null +++ b/pkg/utils/kube/ctl_test.go @@ -0,0 +1,61 @@ +package kube + +import ( + "regexp" + "testing" + + testingutils "github.com/argoproj/gitops-engine/pkg/utils/testing" + + "github.com/stretchr/testify/assert" +) + +func TestConvertToVersion(t *testing.T) { + kubectl := KubectlCmd{} + t.Run("AppsDeployment", func(t *testing.T) { + newObj, err := kubectl.ConvertToVersion(testingutils.UnstructuredFromFile("testdata/appsdeployment.yaml"), "extensions", "v1beta1") + if assert.NoError(t, err) { + gvk := newObj.GroupVersionKind() + assert.Equal(t, "extensions", gvk.Group) + assert.Equal(t, "v1beta1", gvk.Version) + } + }) + t.Run("CustomResource", func(t *testing.T) { + _, err := kubectl.ConvertToVersion(testingutils.UnstructuredFromFile("testdata/cr.yaml"), "argoproj.io", "v1") + assert.Error(t, err) + }) + t.Run("ExtensionsDeployment", func(t *testing.T) { + obj := testingutils.UnstructuredFromFile("testdata/nginx.yaml") + + // convert an extensions/v1beta1 object into itself + newObj, err := kubectl.ConvertToVersion(obj, "extensions", "v1beta1") + if assert.NoError(t, err) { + gvk := newObj.GroupVersionKind() + assert.Equal(t, "extensions", gvk.Group) + assert.Equal(t, "v1beta1", gvk.Version) + } + + // convert an extensions/v1beta1 object into an apps/v1 + newObj, err = kubectl.ConvertToVersion(obj, "apps", "v1") + if assert.NoError(t, err) { + gvk := newObj.GroupVersionKind() + assert.Equal(t, "apps", gvk.Group) + assert.Equal(t, "v1", gvk.Version) + } + + // converting it again should not have any affect + newObj, err = kubectl.ConvertToVersion(obj, "apps", "v1") + if assert.NoError(t, err) { + gvk := newObj.GroupVersionKind() + assert.Equal(t, "apps", gvk.Group) + assert.Equal(t, "v1", gvk.Version) + } + }) +} + +func TestVersion(t *testing.T) { + ver, err := Version() + assert.NoError(t, err) + SemverRegexValidation := `^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$` + re := regexp.MustCompile(SemverRegexValidation) + assert.True(t, re.MatchString(ver)) +} diff --git a/pkg/utils/kube/import_known_versions.go b/pkg/utils/kube/import_known_versions.go new file mode 100644 index 000000000..d3469a4f5 --- /dev/null +++ b/pkg/utils/kube/import_known_versions.go @@ -0,0 +1,19 @@ +package kube + +import ( + _ "k8s.io/kubernetes/pkg/apis/apps/install" + _ "k8s.io/kubernetes/pkg/apis/authentication/install" + _ "k8s.io/kubernetes/pkg/apis/authorization/install" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" + _ "k8s.io/kubernetes/pkg/apis/batch/install" + _ "k8s.io/kubernetes/pkg/apis/certificates/install" + _ "k8s.io/kubernetes/pkg/apis/coordination/install" + _ "k8s.io/kubernetes/pkg/apis/core/install" + _ "k8s.io/kubernetes/pkg/apis/events/install" + _ "k8s.io/kubernetes/pkg/apis/extensions/install" + _ "k8s.io/kubernetes/pkg/apis/policy/install" + _ "k8s.io/kubernetes/pkg/apis/rbac/install" + _ "k8s.io/kubernetes/pkg/apis/scheduling/install" + _ "k8s.io/kubernetes/pkg/apis/settings/install" + _ "k8s.io/kubernetes/pkg/apis/storage/install" +) diff --git a/util/kube/kube.go b/pkg/utils/kube/kube.go similarity index 76% rename from util/kube/kube.go rename to pkg/utils/kube/kube.go index 1e244704c..3e17a07d7 100644 --- a/util/kube/kube.go +++ b/pkg/utils/kube/kube.go @@ -24,8 +24,6 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - - "github.com/argoproj/argo-cd/engine/common" ) const ( @@ -50,6 +48,15 @@ const ( APIServiceKind = "APIService" ) +type ResourceInfoProvider interface { + IsNamespaced(gk schema.GroupKind) (bool, error) +} + +func IsNamespacedOrUnknown(provider ResourceInfoProvider, gk schema.GroupKind) bool { + namespaced, err := provider.IsNamespaced(gk) + return namespaced || err != nil +} + type ResourceKey struct { Group string Kind string @@ -137,82 +144,6 @@ func UnsetLabel(target *unstructured.Unstructured, key string) { } } -// SetAppInstanceLabel the recommended app.kubernetes.io/instance label against an unstructured object -// Uses the legacy labeling if environment variable is set -func SetAppInstanceLabel(target *unstructured.Unstructured, key, val string) error { - labels := target.GetLabels() - if labels == nil { - labels = make(map[string]string) - } - labels[key] = val - target.SetLabels(labels) - if key != common.LabelKeyLegacyApplicationName { - // we no longer label the pod template sub resources in v0.11 - return nil - } - - gvk := schema.FromAPIVersionAndKind(target.GetAPIVersion(), target.GetKind()) - // special case for deployment and job types: make sure that derived replicaset, and pod has - // the application label - switch gvk.Group { - case "apps", "extensions": - switch gvk.Kind { - case DeploymentKind, ReplicaSetKind, StatefulSetKind, DaemonSetKind: - templateLabels, ok, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "template", "metadata", "labels") - if err != nil { - return err - } - if !ok || templateLabels == nil { - templateLabels = make(map[string]interface{}) - } - templateLabels[key] = val - err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels") - if err != nil { - return err - } - // The following is a workaround for issue #335. In API version extensions/v1beta1 or - // apps/v1beta1, if a spec omits spec.selector then k8s will default the - // spec.selector.matchLabels to match spec.template.metadata.labels. This means Argo CD - // labels can potentially make their way into spec.selector.matchLabels, which is a bad - // thing. The following logic prevents this behavior. - switch target.GetAPIVersion() { - case "apps/v1beta1", "extensions/v1beta1": - selector, _, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "selector") - if err != nil { - return err - } - if len(selector) == 0 { - // If we get here, user did not set spec.selector in their manifest. We do not want - // our Argo CD labels to get defaulted by kubernetes, so we explicitly set the labels - // for them (minus the Argo CD labels). - delete(templateLabels, key) - err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "selector", "matchLabels") - if err != nil { - return err - } - } - } - } - case "batch": - switch gvk.Kind { - case JobKind: - templateLabels, ok, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "template", "metadata", "labels") - if err != nil { - return err - } - if !ok || templateLabels == nil { - templateLabels = make(map[string]interface{}) - } - templateLabels[key] = val - err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels") - if err != nil { - return err - } - } - } - return nil -} - func ToGroupVersionResource(groupVersion string, apiResource *metav1.APIResource) schema.GroupVersionResource { gvk := schema.FromAPIVersionAndKind(groupVersion, apiResource.Kind) gv := gvk.GroupVersion() @@ -249,14 +180,20 @@ func ServerResourceForGroupVersionKind(disco discovery.DiscoveryInterface, gvk s return nil, apierr.NewNotFound(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, "") } +var ( + kubectlErrOutRegexp = regexp.MustCompile(`^(error: )?(error validating|error when creating|error when creating) "\S+": `) + + // See ApplyOpts::Run() + // cmdutil.AddSourceToErr(fmt.Sprintf("applying patch:\n%s\nto:\n%v\nfor:", patchBytes, info), info.Source, err) + kubectlApplyPatchErrOutRegexp = regexp.MustCompile(`(?s)^error when applying patch:.*\nfor: "\S+": `) +) + // cleanKubectlOutput makes the error output of kubectl a little better to read func cleanKubectlOutput(s string) string { s = strings.TrimSpace(s) - s = strings.Replace(s, ": error validating \"STDIN\"", "", -1) - s = strings.Replace(s, ": unable to recognize \"STDIN\"", "", -1) - s = strings.Replace(s, ": error when creating \"STDIN\"", "", -1) + s = kubectlErrOutRegexp.ReplaceAllString(s, "") + s = kubectlApplyPatchErrOutRegexp.ReplaceAllString(s, "") s = strings.Replace(s, "; if you choose to ignore these errors, turn validation off with --validate=false", "", -1) - s = strings.Replace(s, "error: error", "error", -1) return s } @@ -429,3 +366,32 @@ func GetDeploymentReplicas(u *unstructured.Unstructured) *int64 { } return &val } + +// RetryUntilSucceed keep retrying given action with specified timeout until action succeed or specified context is done. +func RetryUntilSucceed(action func() error, desc string, ctx context.Context, timeout time.Duration) { + ctxCompleted := false + stop := make(chan bool) + defer close(stop) + go func() { + select { + case <-ctx.Done(): + ctxCompleted = true + case <-stop: + } + }() + for { + log.Debugf("Start %s", desc) + err := action() + if err == nil { + log.Debugf("Completed %s", desc) + return + } + if ctxCompleted { + log.Debugf("Stop retrying %s", desc) + return + } + log.Debugf("Failed to %s: %+v, retrying in %v", desc, err, timeout) + time.Sleep(timeout) + + } +} diff --git a/pkg/utils/kube/kube_test.go b/pkg/utils/kube/kube_test.go new file mode 100644 index 000000000..b51fda72d --- /dev/null +++ b/pkg/utils/kube/kube_test.go @@ -0,0 +1,140 @@ +package kube + +import ( + "encoding/json" + "log" + "testing" + + "github.com/ghodss/yaml" + "github.com/stretchr/testify/assert" + extv1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/rest" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +const depWithLabel = ` +apiVersion: extensions/v1beta2 +kind: Deployment +metadata: + name: nginx-deployment + labels: + foo: bar +spec: + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx:1.7.9 + name: nginx + ports: + - containerPort: 80 +` + +func TestUnsetLabels(t *testing.T) { + for _, yamlStr := range []string{depWithLabel} { + var obj unstructured.Unstructured + err := yaml.Unmarshal([]byte(yamlStr), &obj) + assert.Nil(t, err) + + UnsetLabel(&obj, "foo") + + manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") + assert.Nil(t, err) + log.Println(string(manifestBytes)) + + var dep extv1beta1.Deployment + err = json.Unmarshal(manifestBytes, &dep) + assert.Nil(t, err) + assert.Equal(t, 0, len(dep.ObjectMeta.Labels)) + } + +} + +func TestCleanKubectlOutput(t *testing.T) { + { + s := `error: error validating "STDIN": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1beta2.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false` + assert.Equal(t, cleanKubectlOutput(s), `error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1beta2.DeploymentSpec`) + } + { + s := `error when applying patch: +{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"test-immutable-change\"},\"name\":\"my-service\",\"namespace\":\"argocd-e2e--test-immutable-change-ysfud\"},\"spec\":{\"clusterIP\":\"10.96.0.44\",\"ports\":[{\"port\":80,\"protocol\":\"TCP\",\"targetPort\":9376}],\"selector\":{\"app\":\"MyApp\"}}}\n"}},"spec":{"clusterIP":"10.96.0.44"}} +to: +Resource: "/v1, Resource=services", GroupVersionKind: "/v1, Kind=Service" +Name: "my-service", Namespace: "argocd-e2e--test-immutable-change-ysfud" +Object: &{map["apiVersion":"v1" "kind":"Service" "metadata":map["annotations":map["kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"test-immutable-change\"},\"name\":\"my-service\",\"namespace\":\"argocd-e2e--test-immutable-change-ysfud\"},\"spec\":{\"clusterIP\":\"10.96.0.43\",\"ports\":[{\"port\":80,\"protocol\":\"TCP\",\"targetPort\":9376}],\"selector\":{\"app\":\"MyApp\"}}}\n"] "creationTimestamp":"2019-12-11T15:29:56Z" "labels":map["app.kubernetes.io/instance":"test-immutable-change"] "name":"my-service" "namespace":"argocd-e2e--test-immutable-change-ysfud" "resourceVersion":"157426" "selfLink":"/api/v1/namespaces/argocd-e2e--test-immutable-change-ysfud/services/my-service" "uid":"339cf96f-47eb-4759-ac95-30a169dce004"] "spec":map["clusterIP":"10.96.0.43" "ports":[map["port":'P' "protocol":"TCP" "targetPort":'\u24a0']] "selector":map["app":"MyApp"] "sessionAffinity":"None" "type":"ClusterIP"] "status":map["loadBalancer":map[]]]} +for: "/var/folders/_m/991sn1ds7g39lnbhp6wvqp9d_j5476/T/224503547": Service "my-service" is invalid: spec.clusterIP: Invalid value: "10.96.0.44": field is immutable` + assert.Equal(t, cleanKubectlOutput(s), `Service "my-service" is invalid: spec.clusterIP: Invalid value: "10.96.0.44": field is immutable`) + } +} + +func TestInClusterKubeConfig(t *testing.T) { + restConfig := &rest.Config{} + kubeConfig := NewKubeConfig(restConfig, "") + assert.NotEmpty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) + + restConfig = &rest.Config{ + Password: "foo", + } + kubeConfig = NewKubeConfig(restConfig, "") + assert.Empty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) + + restConfig = &rest.Config{ + ExecProvider: &clientcmdapi.ExecConfig{ + APIVersion: "client.authentication.k8s.io/v1alpha1", + Command: "aws", + }, + } + kubeConfig = NewKubeConfig(restConfig, "") + assert.Empty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) +} + +func TestGetDeploymentReplicas(t *testing.T) { + manifest := []byte(` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + replicas: 2 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 +`) + deployment := unstructured.Unstructured{} + err := yaml.Unmarshal(manifest, &deployment) + assert.NoError(t, err) + assert.Equal(t, int64(2), *GetDeploymentReplicas(&deployment)) +} + +func TestGetNilDeploymentReplicas(t *testing.T) { + manifest := []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: my-pod +spec: + containers: + - image: nginx:1.7.9 + name: nginx + resources: + requests: + cpu: 0.2 +`) + noDeployment := unstructured.Unstructured{} + err := yaml.Unmarshal(manifest, &noDeployment) + assert.NoError(t, err) + assert.Nil(t, GetDeploymentReplicas(&noDeployment)) +} diff --git a/util/kube/kubetest/mock.go b/pkg/utils/kube/kubetest/mock.go similarity index 69% rename from util/kube/kubetest/mock.go rename to pkg/utils/kube/kubetest/mock.go index 9180526b0..c6f124759 100644 --- a/util/kube/kubetest/mock.go +++ b/pkg/utils/kube/kubetest/mock.go @@ -1,13 +1,16 @@ package kubetest import ( - kube2 "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/engine/util/misc" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" + + "github.com/argoproj/gitops-engine/pkg/utils/io" + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) type KubectlOutput struct { @@ -16,13 +19,20 @@ type KubectlOutput struct { } type MockKubectlCmd struct { - APIResources []kube2.APIResourceInfo - Commands map[string]KubectlOutput - Events chan watch.Event - LastValidate bool + APIResources []kube.APIResourceInfo + Commands map[string]KubectlOutput + Events chan watch.Event + LastValidate bool + Version string + DynamicClient dynamic.Interface + APIGroups []metav1.APIGroup +} + +func (k *MockKubectlCmd) NewDynamicClient(config *rest.Config) (dynamic.Interface, error) { + return k.DynamicClient, nil } -func (k *MockKubectlCmd) GetAPIResources(config *rest.Config, resourceFilter kube2.ResourceFilter) ([]kube2.APIResourceInfo, error) { +func (k *MockKubectlCmd) GetAPIResources(config *rest.Config, resourceFilter kube.ResourceFilter) ([]kube.APIResourceInfo, error) { return k.APIResources, nil } @@ -57,8 +67,12 @@ func (k *MockKubectlCmd) ConvertToVersion(obj *unstructured.Unstructured, group, } func (k *MockKubectlCmd) GetServerVersion(config *rest.Config) (string, error) { - return "", nil + return k.Version, nil +} + +func (k *MockKubectlCmd) GetAPIGroups(config *rest.Config) ([]metav1.APIGroup, error) { + return k.APIGroups, nil } -func (k *MockKubectlCmd) SetOnKubectlRun(onKubectlRun func(command string) (misc.Closer, error)) { +func (k *MockKubectlCmd) SetOnKubectlRun(onKubectlRun func(command string) (io.Closer, error)) { } diff --git a/util/kube/resource_filter.go b/pkg/utils/kube/resource_filter.go similarity index 100% rename from util/kube/resource_filter.go rename to pkg/utils/kube/resource_filter.go diff --git a/pkg/utils/kube/sync/common/types.go b/pkg/utils/kube/sync/common/types.go new file mode 100644 index 000000000..081906eb6 --- /dev/null +++ b/pkg/utils/kube/sync/common/types.go @@ -0,0 +1,124 @@ +package common + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" +) + +const ( + // AnnotationSyncOptions is a comma-separated list of options for syncing + AnnotationSyncOptions = "argocd.argoproj.io/sync-options" + // AnnotationSyncWave indicates which wave of the sync the resource or hook should be in + AnnotationSyncWave = "argocd.argoproj.io/sync-wave" + // AnnotationKeyHook contains the hook type of a resource + AnnotationKeyHook = "argocd.argoproj.io/hook" + // AnnotationKeyHookDeletePolicy is the policy of deleting a hook + AnnotationKeyHookDeletePolicy = "argocd.argoproj.io/hook-delete-policy" +) + +type PermissionValidator func(un *unstructured.Unstructured, res *metav1.APIResource) error + +type SyncPhase string + +const ( + SyncPhasePreSync = "PreSync" + SyncPhaseSync = "Sync" + SyncPhasePostSync = "PostSync" + SyncPhaseSyncFail = "SyncFail" +) + +type OperationPhase string + +const ( + OperationRunning OperationPhase = "Running" + OperationTerminating OperationPhase = "Terminating" + OperationFailed OperationPhase = "Failed" + OperationError OperationPhase = "Error" + OperationSucceeded OperationPhase = "Succeeded" +) + +func (os OperationPhase) Completed() bool { + switch os { + case OperationFailed, OperationError, OperationSucceeded: + return true + } + return false +} + +func (os OperationPhase) Running() bool { + return os == OperationRunning +} + +func (os OperationPhase) Successful() bool { + return os == OperationSucceeded +} + +func (os OperationPhase) Failed() bool { + return os == OperationFailed +} + +type ResultCode string + +const ( + ResultCodeSynced ResultCode = "Synced" + ResultCodeSyncFailed ResultCode = "SyncFailed" + ResultCodePruned ResultCode = "Pruned" + ResultCodePruneSkipped ResultCode = "PruneSkipped" +) + +type HookType string + +const ( + HookTypePreSync HookType = "PreSync" + HookTypeSync HookType = "Sync" + HookTypePostSync HookType = "PostSync" + HookTypeSkip HookType = "Skip" + HookTypeSyncFail HookType = "SyncFail" +) + +func NewHookType(t string) (HookType, bool) { + return HookType(t), + t == string(HookTypePreSync) || + t == string(HookTypeSync) || + t == string(HookTypePostSync) || + t == string(HookTypeSyncFail) || + t == string(HookTypeSkip) + +} + +type HookDeletePolicy string + +const ( + HookDeletePolicyHookSucceeded HookDeletePolicy = "HookSucceeded" + HookDeletePolicyHookFailed HookDeletePolicy = "HookFailed" + HookDeletePolicyBeforeHookCreation HookDeletePolicy = "BeforeHookCreation" +) + +func NewHookDeletePolicy(p string) (HookDeletePolicy, bool) { + return HookDeletePolicy(p), + p == string(HookDeletePolicyHookSucceeded) || + p == string(HookDeletePolicyHookFailed) || + p == string(HookDeletePolicyBeforeHookCreation) +} + +type ResourceSyncResult struct { + // holds associated resource key + ResourceKey kube.ResourceKey + // holds resource version + Version string + // holds the execution order + Order int + // result code + Status ResultCode + // message for the last sync OR operation + Message string + // the type of the hook, empty for non-hook resources + HookType HookType + // the state of any operation associated with this resource OR hook + // note: can contain values for non-hook resources + HookPhase OperationPhase + // indicates the particular phase of the sync that this is for + SyncPhase SyncPhase +} diff --git a/pkg/utils/kube/sync/common/types_test.go b/pkg/utils/kube/sync/common/types_test.go new file mode 100644 index 000000000..339650a74 --- /dev/null +++ b/pkg/utils/kube/sync/common/types_test.go @@ -0,0 +1,51 @@ +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewHookType(t *testing.T) { + t.Run("Garbage", func(t *testing.T) { + _, ok := NewHookType("Garbage") + assert.False(t, ok) + }) + t.Run("PreSync", func(t *testing.T) { + hookType, ok := NewHookType("PreSync") + assert.True(t, ok) + assert.Equal(t, HookTypePreSync, hookType) + }) + t.Run("Sync", func(t *testing.T) { + hookType, ok := NewHookType("Sync") + assert.True(t, ok) + assert.Equal(t, HookTypeSync, hookType) + }) + t.Run("PostSync", func(t *testing.T) { + hookType, ok := NewHookType("PostSync") + assert.True(t, ok) + assert.Equal(t, HookTypePostSync, hookType) + }) +} + +func TestNewHookDeletePolicy(t *testing.T) { + t.Run("Garbage", func(t *testing.T) { + _, ok := NewHookDeletePolicy("Garbage") + assert.False(t, ok) + }) + t.Run("HookSucceeded", func(t *testing.T) { + p, ok := NewHookDeletePolicy("HookSucceeded") + assert.True(t, ok) + assert.Equal(t, HookDeletePolicyHookSucceeded, p) + }) + t.Run("HookFailed", func(t *testing.T) { + p, ok := NewHookDeletePolicy("HookFailed") + assert.True(t, ok) + assert.Equal(t, HookDeletePolicyHookFailed, p) + }) + t.Run("BeforeHookCreation", func(t *testing.T) { + p, ok := NewHookDeletePolicy("BeforeHookCreation") + assert.True(t, ok) + assert.Equal(t, HookDeletePolicyBeforeHookCreation, p) + }) +} diff --git a/pkg/utils/kube/sync/hook/delete_policy.go b/pkg/utils/kube/sync/hook/delete_policy.go new file mode 100644 index 000000000..c0d1ad64f --- /dev/null +++ b/pkg/utils/kube/sync/hook/delete_policy.go @@ -0,0 +1,26 @@ +package hook + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + helmhook "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook/helm" + resourceutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/resource" +) + +func DeletePolicies(obj *unstructured.Unstructured) []common.HookDeletePolicy { + var policies []common.HookDeletePolicy + for _, text := range resourceutil.GetAnnotationCSVs(obj, common.AnnotationKeyHookDeletePolicy) { + p, ok := common.NewHookDeletePolicy(text) + if ok { + policies = append(policies, p) + } + } + for _, p := range helmhook.DeletePolicies(obj) { + policies = append(policies, p.DeletePolicy()) + } + if len(policies) == 0 { + policies = append(policies, common.HookDeletePolicyBeforeHookCreation) + } + return policies +} diff --git a/pkg/utils/kube/sync/hook/delete_policy_test.go b/pkg/utils/kube/sync/hook/delete_policy_test.go new file mode 100644 index 000000000..13effb3bb --- /dev/null +++ b/pkg/utils/kube/sync/hook/delete_policy_test.go @@ -0,0 +1,20 @@ +package hook + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" +) + +func TestDeletePolicies(t *testing.T) { + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyBeforeHookCreation}, DeletePolicies(NewPod())) + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyBeforeHookCreation}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "garbage"))) + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyBeforeHookCreation}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation"))) + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyHookSucceeded}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded"))) + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyHookFailed}, DeletePolicies(Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "HookFailed"))) + // Helm test + assert.Equal(t, []common.HookDeletePolicy{common.HookDeletePolicyHookSucceeded}, DeletePolicies(Annotate(NewPod(), "helm.sh/hook-delete-policy", "hook-succeeded"))) +} diff --git a/hook/helm/delete_policy.go b/pkg/utils/kube/sync/hook/helm/delete_policy.go similarity index 58% rename from hook/helm/delete_policy.go rename to pkg/utils/kube/sync/hook/helm/delete_policy.go index 475786830..399681015 100644 --- a/hook/helm/delete_policy.go +++ b/pkg/utils/kube/sync/hook/helm/delete_policy.go @@ -1,10 +1,10 @@ package helm import ( - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + resourceutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/resource" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) type DeletePolicy string @@ -20,19 +20,19 @@ func NewDeletePolicy(p string) (DeletePolicy, bool) { return DeletePolicy(p), p == string(BeforeHookCreation) || p == string(HookSucceeded) || p == string(HookFailed) } -var hookDeletePolicies = map[DeletePolicy]v1alpha1.HookDeletePolicy{ - BeforeHookCreation: v1alpha1.HookDeletePolicyBeforeHookCreation, - HookSucceeded: v1alpha1.HookDeletePolicyHookSucceeded, - HookFailed: v1alpha1.HookDeletePolicyHookFailed, +var hookDeletePolicies = map[DeletePolicy]common.HookDeletePolicy{ + BeforeHookCreation: common.HookDeletePolicyBeforeHookCreation, + HookSucceeded: common.HookDeletePolicyHookSucceeded, + HookFailed: common.HookDeletePolicyHookFailed, } -func (p DeletePolicy) DeletePolicy() v1alpha1.HookDeletePolicy { +func (p DeletePolicy) DeletePolicy() common.HookDeletePolicy { return hookDeletePolicies[p] } func DeletePolicies(obj *unstructured.Unstructured) []DeletePolicy { var policies []DeletePolicy - for _, text := range resource.GetAnnotationCSVs(obj, "helm.sh/hook-delete-policy") { + for _, text := range resourceutil.GetAnnotationCSVs(obj, "helm.sh/hook-delete-policy") { p, ok := NewDeletePolicy(text) if ok { policies = append(policies, p) diff --git a/hook/helm/delete_policy_test.go b/pkg/utils/kube/sync/hook/helm/delete_policy_test.go similarity index 61% rename from hook/helm/delete_policy_test.go rename to pkg/utils/kube/sync/hook/helm/delete_policy_test.go index 7e07767c8..b1f292dde 100644 --- a/hook/helm/delete_policy_test.go +++ b/pkg/utils/kube/sync/hook/helm/delete_policy_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestDeletePolicies(t *testing.T) { @@ -17,7 +17,7 @@ func TestDeletePolicies(t *testing.T) { } func TestDeletePolicy_DeletePolicy(t *testing.T) { - assert.Equal(t, v1alpha1.HookDeletePolicyBeforeHookCreation, BeforeHookCreation.DeletePolicy()) - assert.Equal(t, v1alpha1.HookDeletePolicyHookSucceeded, HookSucceeded.DeletePolicy()) - assert.Equal(t, v1alpha1.HookDeletePolicyHookFailed, HookFailed.DeletePolicy()) + assert.Equal(t, common.HookDeletePolicyBeforeHookCreation, BeforeHookCreation.DeletePolicy()) + assert.Equal(t, common.HookDeletePolicyHookSucceeded, HookSucceeded.DeletePolicy()) + assert.Equal(t, common.HookDeletePolicyHookFailed, HookFailed.DeletePolicy()) } diff --git a/pkg/utils/kube/sync/hook/helm/hook.go b/pkg/utils/kube/sync/hook/helm/hook.go new file mode 100644 index 000000000..9b3339919 --- /dev/null +++ b/pkg/utils/kube/sync/hook/helm/hook.go @@ -0,0 +1,9 @@ +package helm + +import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + +func IsHook(obj *unstructured.Unstructured) bool { + value, ok := obj.GetAnnotations()["helm.sh/hook"] + // Helm use the same annotation to identify CRD as hooks, but they are not. + return ok && value != "crd-install" +} diff --git a/hook/helm/hook_test.go b/pkg/utils/kube/sync/hook/helm/hook_test.go similarity index 51% rename from hook/helm/hook_test.go rename to pkg/utils/kube/sync/hook/helm/hook_test.go index baac314f1..a3668f37d 100644 --- a/hook/helm/hook_test.go +++ b/pkg/utils/kube/sync/hook/helm/hook_test.go @@ -5,10 +5,12 @@ import ( "github.com/stretchr/testify/assert" - . "github.com/argoproj/argo-cd/test" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestIsHook(t *testing.T) { assert.False(t, IsHook(NewPod())) assert.True(t, IsHook(Annotate(NewPod(), "helm.sh/hook", "anything"))) + // helm calls "crd-install" a hook, but it really can't be treated as such + assert.False(t, IsHook(Annotate(NewCRD(), "helm.sh/hook", "crd-install"))) } diff --git a/hook/helm/type.go b/pkg/utils/kube/sync/hook/helm/type.go similarity index 50% rename from hook/helm/type.go rename to pkg/utils/kube/sync/hook/helm/type.go index ec60616da..9376844a1 100644 --- a/hook/helm/type.go +++ b/pkg/utils/kube/sync/hook/helm/type.go @@ -3,14 +3,13 @@ package helm import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + resourceutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/resource" ) type Type string const ( - CRDInstall Type = "crd-install" PreInstall Type = "pre-install" PreUpgrade Type = "pre-upgrade" PostUpgrade Type = "post-upgrade" @@ -19,28 +18,26 @@ const ( func NewType(t string) (Type, bool) { return Type(t), - t == string(CRDInstall) || - t == string(PreInstall) || + t == string(PreInstall) || t == string(PreUpgrade) || t == string(PostUpgrade) || t == string(PostInstall) } -var hookTypes = map[Type]v1alpha1.HookType{ - CRDInstall: v1alpha1.HookTypePreSync, - PreInstall: v1alpha1.HookTypePreSync, - PreUpgrade: v1alpha1.HookTypePreSync, - PostUpgrade: v1alpha1.HookTypePostSync, - PostInstall: v1alpha1.HookTypePostSync, +var hookTypes = map[Type]common.HookType{ + PreInstall: common.HookTypePreSync, + PreUpgrade: common.HookTypePreSync, + PostUpgrade: common.HookTypePostSync, + PostInstall: common.HookTypePostSync, } -func (t Type) HookType() v1alpha1.HookType { +func (t Type) HookType() common.HookType { return hookTypes[t] } func Types(obj *unstructured.Unstructured) []Type { var types []Type - for _, text := range resource.GetAnnotationCSVs(obj, "helm.sh/hook") { + for _, text := range resourceutil.GetAnnotationCSVs(obj, "helm.sh/hook") { t, ok := NewType(text) if ok { types = append(types, t) diff --git a/hook/helm/type_test.go b/pkg/utils/kube/sync/hook/helm/type_test.go similarity index 63% rename from hook/helm/type_test.go rename to pkg/utils/kube/sync/hook/helm/type_test.go index e817b82bd..af7956c08 100644 --- a/hook/helm/type_test.go +++ b/pkg/utils/kube/sync/hook/helm/type_test.go @@ -5,17 +5,18 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestTypes(t *testing.T) { assert.Nil(t, Types(NewPod())) - assert.Equal(t, []Type{CRDInstall}, Types(Annotate(NewPod(), "helm.sh/hook", "crd-install"))) assert.Equal(t, []Type{PreInstall}, Types(Annotate(NewPod(), "helm.sh/hook", "pre-install"))) assert.Equal(t, []Type{PreUpgrade}, Types(Annotate(NewPod(), "helm.sh/hook", "pre-upgrade"))) assert.Equal(t, []Type{PostUpgrade}, Types(Annotate(NewPod(), "helm.sh/hook", "post-upgrade"))) assert.Equal(t, []Type{PostInstall}, Types(Annotate(NewPod(), "helm.sh/hook", "post-install"))) + // helm calls "crd-install" a hook, but it really can't be treated as such + assert.Empty(t, Types(Annotate(NewPod(), "helm.sh/hook", "crd-install"))) // we do not consider these supported hooks assert.Nil(t, Types(Annotate(NewPod(), "helm.sh/hook", "pre-rollback"))) assert.Nil(t, Types(Annotate(NewPod(), "helm.sh/hook", "post-rollback"))) @@ -24,9 +25,8 @@ func TestTypes(t *testing.T) { } func TestType_HookType(t *testing.T) { - assert.Equal(t, v1alpha1.HookTypePreSync, CRDInstall.HookType()) - assert.Equal(t, v1alpha1.HookTypePreSync, PreInstall.HookType()) - assert.Equal(t, v1alpha1.HookTypePreSync, PreUpgrade.HookType()) - assert.Equal(t, v1alpha1.HookTypePostSync, PostUpgrade.HookType()) - assert.Equal(t, v1alpha1.HookTypePostSync, PostInstall.HookType()) + assert.Equal(t, common.HookTypePreSync, PreInstall.HookType()) + assert.Equal(t, common.HookTypePreSync, PreUpgrade.HookType()) + assert.Equal(t, common.HookTypePostSync, PostUpgrade.HookType()) + assert.Equal(t, common.HookTypePostSync, PostInstall.HookType()) } diff --git a/hook/helm/weight.go b/pkg/utils/kube/sync/hook/helm/weight.go similarity index 100% rename from hook/helm/weight.go rename to pkg/utils/kube/sync/hook/helm/weight.go diff --git a/hook/helm/weight_test.go b/pkg/utils/kube/sync/hook/helm/weight_test.go similarity index 79% rename from hook/helm/weight_test.go rename to pkg/utils/kube/sync/hook/helm/weight_test.go index 0784bb376..cfeec535d 100644 --- a/hook/helm/weight_test.go +++ b/pkg/utils/kube/sync/hook/helm/weight_test.go @@ -3,9 +3,9 @@ package helm import ( "testing" - "github.com/stretchr/testify/assert" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" - . "github.com/argoproj/argo-cd/test" + "github.com/stretchr/testify/assert" ) func TestWeight(t *testing.T) { diff --git a/pkg/utils/kube/sync/hook/hook.go b/pkg/utils/kube/sync/hook/hook.go new file mode 100644 index 000000000..efddc06e4 --- /dev/null +++ b/pkg/utils/kube/sync/hook/hook.go @@ -0,0 +1,43 @@ +package hook + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + helmhook "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook/helm" + resourceutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/resource" +) + +func IsHook(obj *unstructured.Unstructured) bool { + _, ok := obj.GetAnnotations()[common.AnnotationKeyHook] + if ok { + return !Skip(obj) + } + return helmhook.IsHook(obj) +} + +func Skip(obj *unstructured.Unstructured) bool { + for _, hookType := range Types(obj) { + if hookType == common.HookTypeSkip { + return len(Types(obj)) == 1 + } + } + return false +} + +func Types(obj *unstructured.Unstructured) []common.HookType { + var types []common.HookType + for _, text := range resourceutil.GetAnnotationCSVs(obj, common.AnnotationKeyHook) { + t, ok := common.NewHookType(text) + if ok { + types = append(types, t) + } + } + // we ignore Helm hooks if we have Argo hook + if len(types) == 0 { + for _, t := range helmhook.Types(obj) { + types = append(types, t.HookType()) + } + } + return types +} diff --git a/hook/hook_test.go b/pkg/utils/kube/sync/hook/hook_test.go similarity index 71% rename from hook/hook_test.go rename to pkg/utils/kube/sync/hook/hook_test.go index 16d5d297c..270696c6e 100644 --- a/hook/hook_test.go +++ b/pkg/utils/kube/sync/hook/hook_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestNoHooks(t *testing.T) { @@ -19,12 +19,12 @@ func TestNoHooks(t *testing.T) { func TestOneHook(t *testing.T) { hookTypesString := []string{"PreSync", "Sync", "PostSync", "SyncFail"} - hookTypes := []HookType{HookTypePreSync, HookTypeSync, HookTypePostSync, HookTypeSyncFail} + hookTypes := []common.HookType{common.HookTypePreSync, common.HookTypeSync, common.HookTypePostSync, common.HookTypeSyncFail} for i, hook := range hookTypesString { obj := example(hook) assert.True(t, IsHook(obj)) assert.False(t, Skip(obj)) - assert.Equal(t, []HookType{hookTypes[i]}, Types(obj)) + assert.Equal(t, []common.HookType{hookTypes[i]}, Types(obj)) } } @@ -35,7 +35,7 @@ func TestSkipHook(t *testing.T) { obj := example("Skip") assert.False(t, IsHook(obj)) assert.True(t, Skip(obj)) - assert.Equal(t, []HookType{HookTypeSkip}, Types(obj)) + assert.Equal(t, []common.HookType{common.HookTypeSkip}, Types(obj)) } // we treat garbage as the user intended you to be a hook, but spelled it wrong, so you are a hook, but we don't @@ -51,11 +51,11 @@ func TestTwoHooks(t *testing.T) { obj := example("PreSync,PostSync") assert.True(t, IsHook(obj)) assert.False(t, Skip(obj)) - assert.ElementsMatch(t, []HookType{HookTypePreSync, HookTypePostSync}, Types(obj)) + assert.ElementsMatch(t, []common.HookType{common.HookTypePreSync, common.HookTypePostSync}, Types(obj)) } func TestDupHookTypes(t *testing.T) { - assert.Equal(t, []HookType{HookTypeSync}, Types(example("Sync,Sync"))) + assert.Equal(t, []common.HookType{common.HookTypeSync}, Types(example("Sync,Sync"))) } // horrible edge case @@ -63,21 +63,21 @@ func TestSkipAndHook(t *testing.T) { obj := example("Skip,PreSync,PostSync") assert.True(t, IsHook(obj)) assert.False(t, Skip(obj)) - assert.ElementsMatch(t, []HookType{HookTypeSkip, HookTypePreSync, HookTypePostSync}, Types(obj)) + assert.ElementsMatch(t, []common.HookType{common.HookTypeSkip, common.HookTypePreSync, common.HookTypePostSync}, Types(obj)) } func TestGarbageAndHook(t *testing.T) { obj := example("Sync,Garbage") assert.True(t, IsHook(obj)) assert.False(t, Skip(obj)) - assert.Equal(t, []HookType{HookTypeSync}, Types(obj)) + assert.Equal(t, []common.HookType{common.HookTypeSync}, Types(obj)) } func TestHelmHook(t *testing.T) { obj := Annotate(NewPod(), "helm.sh/hook", "pre-install") assert.True(t, IsHook(obj)) assert.False(t, Skip(obj)) - assert.Equal(t, []HookType{HookTypePreSync}, Types(obj)) + assert.Equal(t, []common.HookType{common.HookTypePreSync}, Types(obj)) } func TestGarbageHelmHook(t *testing.T) { @@ -90,7 +90,7 @@ func TestGarbageHelmHook(t *testing.T) { // we should ignore Helm hooks if we have an Argo CD hook func TestBothHooks(t *testing.T) { obj := Annotate(example("Sync"), "helm.sh/hook", "pre-install") - assert.Equal(t, []HookType{HookTypeSync}, Types(obj)) + assert.Equal(t, []common.HookType{common.HookTypeSync}, Types(obj)) } func example(hook string) *unstructured.Unstructured { diff --git a/resource/ignore/ignore.go b/pkg/utils/kube/sync/ignore/ignore.go similarity index 78% rename from resource/ignore/ignore.go rename to pkg/utils/kube/sync/ignore/ignore.go index 17cc17623..baa618520 100644 --- a/resource/ignore/ignore.go +++ b/pkg/utils/kube/sync/ignore/ignore.go @@ -3,7 +3,7 @@ package ignore import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/engine/hook" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook" ) // should we Ignore this resource? diff --git a/pkg/utils/kube/sync/ignore/ignore_test.go b/pkg/utils/kube/sync/ignore/ignore_test.go new file mode 100644 index 000000000..40b589e1c --- /dev/null +++ b/pkg/utils/kube/sync/ignore/ignore_test.go @@ -0,0 +1,25 @@ +package ignore + +import ( + "testing" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + + "github.com/stretchr/testify/assert" + + . "github.com/argoproj/gitops-engine/pkg/utils/testing" +) + +func newHook(obj *unstructured.Unstructured, hookType common.HookType) *unstructured.Unstructured { + return Annotate(obj, "argocd.argoproj.io/hook", string(hookType)) +} + +func TestIgnore(t *testing.T) { + assert.False(t, Ignore(NewPod())) + assert.False(t, Ignore(newHook(NewPod(), "Sync"))) + assert.True(t, Ignore(newHook(NewPod(), "garbage"))) + assert.False(t, Ignore(HelmHook(NewPod(), "pre-install"))) + assert.True(t, Ignore(HelmHook(NewPod(), "garbage"))) +} diff --git a/pkg/utils/kube/sync/reconcile.go b/pkg/utils/kube/sync/reconcile.go new file mode 100644 index 000000000..bb911413d --- /dev/null +++ b/pkg/utils/kube/sync/reconcile.go @@ -0,0 +1,100 @@ +package sync + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" + kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube" + hookutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/ignore" + "github.com/argoproj/gitops-engine/pkg/utils/text" +) + +func splitHooks(target []*unstructured.Unstructured) ([]*unstructured.Unstructured, []*unstructured.Unstructured) { + targetObjs := make([]*unstructured.Unstructured, 0) + hooks := make([]*unstructured.Unstructured, 0) + for _, obj := range target { + if obj == nil || ignore.Ignore(obj) { + continue + } + if hookutil.IsHook(obj) { + hooks = append(hooks, obj) + } else { + targetObjs = append(targetObjs, obj) + } + } + return targetObjs, hooks +} + +// dedupLiveResources handles removes live resource duplicates with the same UID. Duplicates are created in a separate resource groups. +// E.g. apps/Deployment produces duplicate in extensions/Deployment, authorization.openshift.io/ClusterRole produces duplicate in rbac.authorization.k8s.io/ClusterRole etc. +// The method removes such duplicates unless it was defined in git ( exists in target resources list ). At least one duplicate stays. +// If non of duplicates are in git at random one stays +func dedupLiveResources(targetObjs []*unstructured.Unstructured, liveObjsByKey map[kubeutil.ResourceKey]*unstructured.Unstructured) { + targetObjByKey := make(map[kubeutil.ResourceKey]*unstructured.Unstructured) + for i := range targetObjs { + targetObjByKey[kubeutil.GetResourceKey(targetObjs[i])] = targetObjs[i] + } + liveObjsById := make(map[types.UID][]*unstructured.Unstructured) + for k := range liveObjsByKey { + obj := liveObjsByKey[k] + if obj != nil { + liveObjsById[obj.GetUID()] = append(liveObjsById[obj.GetUID()], obj) + } + } + for id := range liveObjsById { + objs := liveObjsById[id] + + if len(objs) > 1 { + duplicatesLeft := len(objs) + for i := range objs { + obj := objs[i] + resourceKey := kubeutil.GetResourceKey(obj) + if _, ok := targetObjByKey[resourceKey]; !ok { + delete(liveObjsByKey, resourceKey) + duplicatesLeft-- + if duplicatesLeft == 1 { + break + } + } + } + } + } +} + +type ReconciliationResult struct { + Live []*unstructured.Unstructured + Target []*unstructured.Unstructured + Hooks []*unstructured.Unstructured +} + +func Reconcile(targetObjs []*unstructured.Unstructured, liveObjByKey map[kube.ResourceKey]*unstructured.Unstructured, namespace string, resInfo kubeutil.ResourceInfoProvider) ReconciliationResult { + targetObjs, hooks := splitHooks(targetObjs) + dedupLiveResources(targetObjs, liveObjByKey) + + managedLiveObj := make([]*unstructured.Unstructured, len(targetObjs)) + for i, obj := range targetObjs { + gvk := obj.GroupVersionKind() + ns := text.FirstNonEmpty(obj.GetNamespace(), namespace) + if namespaced := kubeutil.IsNamespacedOrUnknown(resInfo, obj.GroupVersionKind().GroupKind()); !namespaced { + ns = "" + } + key := kubeutil.NewResourceKey(gvk.Group, gvk.Kind, ns, obj.GetName()) + if liveObj, ok := liveObjByKey[key]; ok { + managedLiveObj[i] = liveObj + delete(liveObjByKey, key) + } else { + managedLiveObj[i] = nil + } + } + for _, obj := range liveObjByKey { + targetObjs = append(targetObjs, nil) + managedLiveObj = append(managedLiveObj, obj) + } + return ReconciliationResult{ + Target: targetObjs, + Hooks: hooks, + Live: managedLiveObj, + } +} diff --git a/resource/annotations.go b/pkg/utils/kube/sync/resource/annotations.go similarity index 100% rename from resource/annotations.go rename to pkg/utils/kube/sync/resource/annotations.go diff --git a/resource/annotations_test.go b/pkg/utils/kube/sync/resource/annotations_test.go similarity index 87% rename from resource/annotations_test.go rename to pkg/utils/kube/sync/resource/annotations_test.go index e2ec6a9aa..83853f667 100644 --- a/resource/annotations_test.go +++ b/pkg/utils/kube/sync/resource/annotations_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/test" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestHasAnnotationOption(t *testing.T) { @@ -21,7 +21,7 @@ func TestHasAnnotationOption(t *testing.T) { wantVals []string want bool }{ - {"Nil", args{test.NewPod(), "foo", "bar"}, nil, false}, + {"Nil", args{NewPod(), "foo", "bar"}, nil, false}, {"Empty", args{example(""), "foo", "bar"}, nil, false}, {"Single", args{example("bar"), "foo", "bar"}, []string{"bar"}, true}, {"DeDup", args{example("bar,bar"), "foo", "bar"}, []string{"bar"}, true}, @@ -37,5 +37,5 @@ func TestHasAnnotationOption(t *testing.T) { } func example(val string) *unstructured.Unstructured { - return test.Annotate(test.NewPod(), "foo", val) + return Annotate(NewPod(), "foo", val) } diff --git a/pkg/utils/kube/sync/sync_context.go b/pkg/utils/kube/sync/sync_context.go new file mode 100644 index 000000000..d8df2b705 --- /dev/null +++ b/pkg/utils/kube/sync/sync_context.go @@ -0,0 +1,832 @@ +package sync + +import ( + "fmt" + "sort" + "strings" + "sync" + "time" + + log "github.com/sirupsen/logrus" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/apimachinery/pkg/api/errors" + apierr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" + + "github.com/argoproj/gitops-engine/pkg/utils/health" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook" + resourceutil "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/resource" +) + +type reconciledResource struct { + Target *unstructured.Unstructured + Live *unstructured.Unstructured +} + +func (r *reconciledResource) key() kube.ResourceKey { + if r.Live != nil { + return kube.GetResourceKey(r.Live) + } + return kube.GetResourceKey(r.Target) +} + +type SyncContext interface { + Terminate() + Sync() + GetState() (common.OperationPhase, string, []common.ResourceSyncResult) +} + +type SyncOpt func(ctx *syncContext) + +func WithPermissionValidator(validator common.PermissionValidator) SyncOpt { + return func(ctx *syncContext) { + ctx.permissionValidator = validator + } +} + +func WithHealthOverride(override health.HealthOverride) SyncOpt { + return func(ctx *syncContext) { + ctx.healthOverride = override + } +} + +func WithInitialState(phase common.OperationPhase, message string, results []common.ResourceSyncResult) SyncOpt { + return func(ctx *syncContext) { + ctx.phase = phase + ctx.message = message + ctx.syncRes = map[string]common.ResourceSyncResult{} + for i := range results { + ctx.syncRes[resourceResultKey(results[i].ResourceKey, results[i].SyncPhase)] = results[i] + } + } +} + +func WithResourcesFilter(resourcesFilter func(key kube.ResourceKey, target *unstructured.Unstructured, live *unstructured.Unstructured) bool) SyncOpt { + return func(ctx *syncContext) { + ctx.resourcesFilter = resourcesFilter + } +} + +func WithOperationSettings(dryRun bool, prune bool, force bool, skipHooks bool) SyncOpt { + return func(ctx *syncContext) { + ctx.prune = prune + ctx.skipHooks = skipHooks + ctx.dryRun = dryRun + ctx.force = force + } +} + +func WithManifestValidation(enabled bool) SyncOpt { + return func(ctx *syncContext) { + ctx.validate = enabled + } +} + +func NewSyncContext( + revision string, + reconciliationResult ReconciliationResult, + restConfig *rest.Config, + rawConfig *rest.Config, + kubectl kubeutil.Kubectl, + namespace string, + log *log.Entry, + opts ...SyncOpt, +) (SyncContext, error) { + dynamicIf, err := dynamic.NewForConfig(restConfig) + if err != nil { + return nil, err + } + disco, err := discovery.NewDiscoveryClientForConfig(restConfig) + if err != nil { + return nil, err + } + extensionsclientset, err := clientset.NewForConfig(restConfig) + if err != nil { + return nil, err + } + ctx := &syncContext{ + revision: revision, + resources: groupResources(reconciliationResult), + hooks: reconciliationResult.Hooks, + config: restConfig, + rawConfig: rawConfig, + dynamicIf: dynamicIf, + disco: disco, + extensionsclientset: extensionsclientset, + kubectl: kubectl, + namespace: namespace, + log: log, + validate: true, + syncRes: map[string]common.ResourceSyncResult{}, + permissionValidator: func(_ *unstructured.Unstructured, _ *metav1.APIResource) error { + return nil + }, + } + for _, opt := range opts { + opt(ctx) + } + return ctx, nil +} + +func groupResources(reconciliationResult ReconciliationResult) map[kubeutil.ResourceKey]reconciledResource { + resources := make(map[kube.ResourceKey]reconciledResource) + for i := 0; i < len(reconciliationResult.Target); i++ { + res := reconciledResource{ + Target: reconciliationResult.Target[i], + Live: reconciliationResult.Live[i], + } + + var obj *unstructured.Unstructured + if res.Live != nil { + obj = res.Live + } else { + obj = res.Target + } + resources[kube.GetResourceKey(obj)] = res + } + return resources +} + +const ( + crdReadinessTimeout = time.Duration(3) * time.Second +) + +// getOperationPhase returns a hook status from an _live_ unstructured object +func (sc *syncContext) getOperationPhase(hook *unstructured.Unstructured) (common.OperationPhase, string, error) { + phase := common.OperationSucceeded + message := fmt.Sprintf("%s created", hook.GetName()) + + resHealth, err := health.GetResourceHealth(hook, sc.healthOverride) + if err != nil { + return "", "", err + } + if resHealth != nil { + switch resHealth.Status { + case health.HealthStatusUnknown, health.HealthStatusDegraded: + phase = common.OperationFailed + message = resHealth.Message + case health.HealthStatusProgressing, health.HealthStatusSuspended: + phase = common.OperationRunning + message = resHealth.Message + case health.HealthStatusHealthy: + phase = common.OperationSucceeded + message = resHealth.Message + } + } + return phase, message, nil +} + +type syncContext struct { + healthOverride health.HealthOverride + permissionValidator common.PermissionValidator + resources map[kube.ResourceKey]reconciledResource + hooks []*unstructured.Unstructured + config *rest.Config + rawConfig *rest.Config + dynamicIf dynamic.Interface + disco discovery.DiscoveryInterface + extensionsclientset *clientset.Clientset + kubectl kube.Kubectl + namespace string + + dryRun bool + force bool + validate bool + skipHooks bool + resourcesFilter func(key kube.ResourceKey, target *unstructured.Unstructured, live *unstructured.Unstructured) bool + prune bool + + syncRes map[string]common.ResourceSyncResult + startedAt time.Time + revision string + phase common.OperationPhase + message string + + log *log.Entry + // lock to protect concurrent updates of the result list + lock sync.Mutex +} + +// sync has performs the actual apply or hook based sync +func (sc *syncContext) Sync() { + sc.log.WithFields(log.Fields{"skipHooks": sc.skipHooks, "started": sc.started()}).Info("syncing") + tasks, ok := sc.getSyncTasks() + if !ok { + sc.setOperationPhase(common.OperationFailed, "one or more synchronization tasks are not valid") + return + } + + sc.log.WithFields(log.Fields{"tasks": tasks}).Info("tasks") + + // Perform a `kubectl apply --dry-run` against all the manifests. This will detect most (but + // not all) validation issues with the user's manifests (e.g. will detect syntax issues, but + // will not not detect if they are mutating immutable fields). If anything fails, we will refuse + // to perform the sync. we only wish to do this once per operation, performing additional dry-runs + // is harmless, but redundant. The indicator we use to detect if we have already performed + // the dry-run for this operation, is if the resource or hook list is empty. + if !sc.started() { + sc.log.Debug("dry-run") + if sc.runTasks(tasks, true) == failed { + sc.setOperationPhase(common.OperationFailed, "one or more objects failed to apply (dry run)") + return + } + } + + // update status of any tasks that are running, note that this must exclude pruning tasks + for _, task := range tasks.Filter(func(t *syncTask) bool { + // just occasionally, you can be running yet not have a live resource + return t.running() && t.liveObj != nil + }) { + if task.isHook() { + // update the hook's result + operationState, message, err := sc.getOperationPhase(task.liveObj) + if err != nil { + sc.setResourceResult(task, "", common.OperationError, fmt.Sprintf("failed to get resource health: %v", err)) + } else { + sc.setResourceResult(task, "", operationState, message) + + // maybe delete the hook + if task.needsDeleting() { + err := sc.deleteResource(task) + if err != nil && !errors.IsNotFound(err) { + sc.setResourceResult(task, "", common.OperationError, fmt.Sprintf("failed to delete resource: %v", err)) + } + } + } + + } else { + // this must be calculated on the live object + healthStatus, err := health.GetResourceHealth(task.liveObj, sc.healthOverride) + if err == nil { + log.WithFields(log.Fields{"task": task, "healthStatus": healthStatus}).Debug("attempting to update health of running task") + if healthStatus == nil { + // some objects (e.g. secret) do not have health, and they automatically success + sc.setResourceResult(task, task.syncStatus, common.OperationSucceeded, task.message) + } else { + switch healthStatus.Status { + case health.HealthStatusHealthy: + sc.setResourceResult(task, task.syncStatus, common.OperationSucceeded, healthStatus.Message) + case health.HealthStatusDegraded: + sc.setResourceResult(task, task.syncStatus, common.OperationFailed, healthStatus.Message) + } + } + } + } + } + + // if (a) we are multi-step and we have any running tasks, + // or (b) there are any running hooks, + // then wait... + multiStep := tasks.multiStep() + if tasks.Any(func(t *syncTask) bool { return (multiStep || t.isHook()) && t.running() }) { + sc.setOperationPhase(common.OperationRunning, "one or more tasks are running") + return + } + + // syncFailTasks only run during failure, so separate them from regular tasks + syncFailTasks, tasks := tasks.Split(func(t *syncTask) bool { return t.phase == common.SyncPhaseSyncFail }) + + // if there are any completed but unsuccessful tasks, sync is a failure. + if tasks.Any(func(t *syncTask) bool { return t.completed() && !t.successful() }) { + sc.setOperationFailed(syncFailTasks, "one or more synchronization tasks completed unsuccessfully") + return + } + + sc.log.WithFields(log.Fields{"tasks": tasks}).Debug("filtering out non-pending tasks") + // remove tasks that are completed, we can assume that there are no running tasks + tasks = tasks.Filter(func(t *syncTask) bool { return t.pending() }) + + // If no sync tasks were generated (e.g., in case all application manifests have been removed), + // the sync operation is successful. + if len(tasks) == 0 { + sc.setOperationPhase(common.OperationSucceeded, "successfully synced (no more tasks)") + return + } + + // remove any tasks not in this wave + phase := tasks.phase() + wave := tasks.wave() + + // if it is the last phase/wave and the only remaining tasks are non-hooks, the we are successful + // EVEN if those objects subsequently degraded + // This handles the common case where neither hooks or waves are used and a sync equates to simply an (asynchronous) kubectl apply of manifests, which succeeds immediately. + complete := !tasks.Any(func(t *syncTask) bool { return t.phase != phase || wave != t.wave() || t.isHook() }) + + sc.log.WithFields(log.Fields{"phase": phase, "wave": wave, "tasks": tasks, "syncFailTasks": syncFailTasks}).Debug("filtering tasks in correct phase and wave") + tasks = tasks.Filter(func(t *syncTask) bool { return t.phase == phase && t.wave() == wave }) + + sc.setOperationPhase(common.OperationRunning, "one or more tasks are running") + + sc.log.WithFields(log.Fields{"tasks": tasks}).Debug("wet-run") + runState := sc.runTasks(tasks, false) + switch runState { + case failed: + sc.setOperationFailed(syncFailTasks, "one or more objects failed to apply") + case successful: + if complete { + sc.setOperationPhase(common.OperationSucceeded, "successfully synced (all tasks run)") + } + } +} + +func (sc *syncContext) GetState() (common.OperationPhase, string, []common.ResourceSyncResult) { + var resourceRes []common.ResourceSyncResult + for _, v := range sc.syncRes { + resourceRes = append(resourceRes, v) + } + sort.Slice(resourceRes, func(i, j int) bool { + return resourceRes[i].Order < resourceRes[j].Order + }) + return sc.phase, sc.message, resourceRes +} + +func (sc *syncContext) setOperationFailed(syncFailTasks syncTasks, message string) { + if len(syncFailTasks) > 0 { + // if all the failure hooks are completed, don't run them again, and mark the sync as failed + if syncFailTasks.All(func(task *syncTask) bool { return task.completed() }) { + sc.setOperationPhase(common.OperationFailed, message) + return + } + // otherwise, we need to start the failure hooks, and then return without setting + // the phase, so we make sure we have at least one more sync + sc.log.WithFields(log.Fields{"syncFailTasks": syncFailTasks}).Debug("running sync fail tasks") + if sc.runTasks(syncFailTasks, false) == failed { + sc.setOperationPhase(common.OperationFailed, message) + } + } else { + sc.setOperationPhase(common.OperationFailed, message) + } +} + +func (sc *syncContext) started() bool { + return len(sc.syncRes) > 0 +} + +func (sc *syncContext) containsResource(resource reconciledResource) bool { + return sc.resourcesFilter == nil || sc.resourcesFilter(resource.key(), resource.Live, resource.Target) +} + +// generates the list of sync tasks we will be performing during this sync. +func (sc *syncContext) getSyncTasks() (_ syncTasks, successful bool) { + resourceTasks := syncTasks{} + successful = true + + for k, resource := range sc.resources { + if !sc.containsResource(resource) { + sc.log.WithFields(log.Fields{"group": k.Group, "kind": k.Kind, "name": k.Name}). + Debug("skipping") + continue + } + + obj := obj(resource.Target, resource.Live) + + // this creates garbage tasks + if hook.IsHook(obj) { + sc.log.WithFields(log.Fields{"group": obj.GroupVersionKind().Group, "kind": obj.GetKind(), "namespace": obj.GetNamespace(), "name": obj.GetName()}). + Debug("skipping hook") + continue + } + + for _, phase := range syncPhases(obj) { + resourceTasks = append(resourceTasks, &syncTask{phase: phase, targetObj: resource.Target, liveObj: resource.Live}) + } + } + + sc.log.WithFields(log.Fields{"resourceTasks": resourceTasks}).Debug("tasks from managed resources") + + hookTasks := syncTasks{} + if !sc.skipHooks { + for _, obj := range sc.hooks { + for _, phase := range syncPhases(obj) { + // Hook resources names are deterministic, whether they are defined by the user (metadata.name), + // or formulated at the time of the operation (metadata.generateName). If user specifies + // metadata.generateName, then we will generate a formulated metadata.name before submission. + targetObj := obj.DeepCopy() + if targetObj.GetName() == "" { + var syncRevision string + if len(sc.revision) >= 8 { + syncRevision = sc.revision[0:7] + } else { + syncRevision = sc.revision + } + postfix := strings.ToLower(fmt.Sprintf("%s-%s-%d", syncRevision, phase, sc.startedAt.UTC().Unix())) + generateName := obj.GetGenerateName() + targetObj.SetName(fmt.Sprintf("%s%s", generateName, postfix)) + } + + hookTasks = append(hookTasks, &syncTask{phase: phase, targetObj: targetObj}) + } + } + } + + sc.log.WithFields(log.Fields{"hookTasks": hookTasks}).Debug("tasks from hooks") + + tasks := resourceTasks + tasks = append(tasks, hookTasks...) + + // enrich target objects with the namespace + for _, task := range tasks { + if task.targetObj == nil { + continue + } + + if task.targetObj.GetNamespace() == "" { + // If target object's namespace is empty, we set namespace in the object. We do + // this even though it might be a cluster-scoped resource. This prevents any + // possibility of the resource from unintentionally becoming created in the + // namespace during the `kubectl apply` + task.targetObj = task.targetObj.DeepCopy() + task.targetObj.SetNamespace(sc.namespace) + } + } + + // enrich task with live obj + for _, task := range tasks { + if task.targetObj == nil || task.liveObj != nil { + continue + } + task.liveObj = sc.liveObj(task.targetObj) + } + + // enrich tasks with the result + for _, task := range tasks { + result, ok := sc.syncRes[task.resultKey()] + if ok { + task.syncStatus = result.Status + task.operationState = result.HookPhase + task.message = result.Message + } + } + + // check permissions + for _, task := range tasks { + serverRes, err := kube.ServerResourceForGroupVersionKind(sc.disco, task.groupVersionKind()) + if err != nil { + // Special case for custom resources: if CRD is not yet known by the K8s API server, + // and the CRD is part of this sync or the resource is annotated with SkipDryRunOnMissingResource=true, + // then skip verification during `kubectl apply --dry-run` since we expect the CRD + // to be created during app synchronization. + skipDryRunOnMissingResource := resourceutil.HasAnnotationOption(task.targetObj, common.AnnotationSyncOptions, "SkipDryRunOnMissingResource=true") + if apierr.IsNotFound(err) && (skipDryRunOnMissingResource || sc.hasCRDOfGroupKind(task.group(), task.kind())) { + sc.log.WithFields(log.Fields{"task": task}).Debug("skip dry-run for custom resource") + task.skipDryRun = true + } else { + sc.setResourceResult(task, common.ResultCodeSyncFailed, "", err.Error()) + successful = false + } + } else { + if err := sc.permissionValidator(task.obj(), serverRes); err != nil { + sc.setResourceResult(task, common.ResultCodeSyncFailed, "", err.Error()) + successful = false + } + } + } + + sort.Sort(tasks) + + return tasks, successful +} + +func obj(a, b *unstructured.Unstructured) *unstructured.Unstructured { + if a != nil { + return a + } else { + return b + } +} + +func (sc *syncContext) liveObj(obj *unstructured.Unstructured) *unstructured.Unstructured { + for k, resource := range sc.resources { + if k.Group == obj.GroupVersionKind().Group && + k.Kind == obj.GetKind() && + // cluster scoped objects will not have a namespace, even if the user has defined it + (k.Namespace == "" || k.Namespace == obj.GetNamespace()) && + k.Name == obj.GetName() { + return resource.Live + } + } + return nil +} + +func (sc *syncContext) setOperationPhase(phase common.OperationPhase, message string) { + if sc.phase != phase || sc.message != message { + sc.log.Infof("Updating operation state. phase: %s -> %s, message: '%s' -> '%s'", sc.phase, phase, sc.message, message) + } + sc.phase = phase + sc.message = message +} + +// ensureCRDReady waits until specified CRD is ready (established condition is true). Method is best effort - it does not fail even if CRD is not ready without timeout. +func (sc *syncContext) ensureCRDReady(name string) { + _ = wait.PollImmediate(time.Duration(100)*time.Millisecond, crdReadinessTimeout, func() (bool, error) { + crd, err := sc.extensionsclientset.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{}) + if err != nil { + return false, err + } + for _, condition := range crd.Status.Conditions { + if condition.Type == v1beta1.Established { + return condition.Status == v1beta1.ConditionTrue, nil + } + } + return false, nil + }) +} + +func (sc *syncContext) applyObject(targetObj *unstructured.Unstructured, dryRun bool, force bool, validate bool) (common.ResultCode, string) { + message, err := sc.kubectl.ApplyResource(sc.rawConfig, targetObj, targetObj.GetNamespace(), dryRun, force, validate) + if err != nil { + return common.ResultCodeSyncFailed, err.Error() + } + if kube.IsCRD(targetObj) && !dryRun { + sc.ensureCRDReady(targetObj.GetName()) + } + return common.ResultCodeSynced, message +} + +// pruneObject deletes the object if both prune is true and dryRun is false. Otherwise appropriate message +func (sc *syncContext) pruneObject(liveObj *unstructured.Unstructured, prune, dryRun bool) (common.ResultCode, string) { + if !prune { + return common.ResultCodePruneSkipped, "ignored (requires pruning)" + } else if resourceutil.HasAnnotationOption(liveObj, common.AnnotationSyncOptions, "Prune=false") { + return common.ResultCodePruneSkipped, "ignored (no prune)" + } else { + if dryRun { + return common.ResultCodePruned, "pruned (dry run)" + } else { + // Skip deletion if object is already marked for deletion, so we don't cause a resource update hotloop + deletionTimestamp := liveObj.GetDeletionTimestamp() + if deletionTimestamp == nil || deletionTimestamp.IsZero() { + err := sc.kubectl.DeleteResource(sc.config, liveObj.GroupVersionKind(), liveObj.GetName(), liveObj.GetNamespace(), false) + if err != nil { + return common.ResultCodeSyncFailed, err.Error() + } + } + return common.ResultCodePruned, "pruned" + } + } +} + +func (sc *syncContext) targetObjs() []*unstructured.Unstructured { + objs := sc.hooks + for _, r := range sc.resources { + if r.Target != nil { + objs = append(objs, r.Target) + } + } + return objs +} + +func (sc *syncContext) hasCRDOfGroupKind(group string, kind string) bool { + for _, obj := range sc.targetObjs() { + if kube.IsCRD(obj) { + crdGroup, ok, err := unstructured.NestedString(obj.Object, "spec", "group") + if err != nil || !ok { + continue + } + crdKind, ok, err := unstructured.NestedString(obj.Object, "spec", "names", "kind") + if err != nil || !ok { + continue + } + if group == crdGroup && crdKind == kind { + return true + } + } + } + return false +} + +// terminate looks for any running jobs/workflow hooks and deletes the resource +func (sc *syncContext) Terminate() { + terminateSuccessful := true + sc.log.Debug("terminating") + tasks, _ := sc.getSyncTasks() + for _, task := range tasks { + if !task.isHook() || task.liveObj == nil { + continue + } + phase, msg, err := sc.getOperationPhase(task.liveObj) + if err != nil { + sc.setOperationPhase(common.OperationError, fmt.Sprintf("Failed to get hook health: %v", err)) + return + } + if phase == common.OperationRunning { + err := sc.deleteResource(task) + if err != nil { + sc.setResourceResult(task, "", common.OperationFailed, fmt.Sprintf("Failed to delete: %v", err)) + terminateSuccessful = false + } else { + sc.setResourceResult(task, "", common.OperationSucceeded, fmt.Sprintf("Deleted")) + } + } else { + sc.setResourceResult(task, "", phase, msg) + } + } + if terminateSuccessful { + sc.setOperationPhase(common.OperationFailed, "Operation terminated") + } else { + sc.setOperationPhase(common.OperationError, "Operation termination had errors") + } +} + +func (sc *syncContext) deleteResource(task *syncTask) error { + sc.log.WithFields(log.Fields{"task": task}).Debug("deleting resource") + resIf, err := sc.getResourceIf(task) + if err != nil { + return err + } + propagationPolicy := metav1.DeletePropagationForeground + return resIf.Delete(task.name(), &metav1.DeleteOptions{PropagationPolicy: &propagationPolicy}) +} + +func (sc *syncContext) getResourceIf(task *syncTask) (dynamic.ResourceInterface, error) { + apiResource, err := kube.ServerResourceForGroupVersionKind(sc.disco, task.groupVersionKind()) + if err != nil { + return nil, err + } + res := kube.ToGroupVersionResource(task.groupVersionKind().GroupVersion().String(), apiResource) + resIf := kube.ToResourceInterface(sc.dynamicIf, apiResource, res, task.namespace()) + return resIf, err +} + +var operationPhases = map[common.ResultCode]common.OperationPhase{ + common.ResultCodeSynced: common.OperationRunning, + common.ResultCodeSyncFailed: common.OperationFailed, + common.ResultCodePruned: common.OperationSucceeded, + common.ResultCodePruneSkipped: common.OperationSucceeded, +} + +// tri-state +type runState = int + +const ( + successful = iota + pending + failed +) + +func (sc *syncContext) runTasks(tasks syncTasks, dryRun bool) runState { + + dryRun = dryRun || sc.dryRun + + sc.log.WithFields(log.Fields{"numTasks": len(tasks), "dryRun": dryRun}).Debug("running tasks") + + runState := successful + var createTasks syncTasks + var pruneTasks syncTasks + + for _, task := range tasks { + if task.isPrune() { + pruneTasks = append(pruneTasks, task) + } else { + createTasks = append(createTasks, task) + } + } + // prune first + { + var wg sync.WaitGroup + for _, task := range pruneTasks { + wg.Add(1) + go func(t *syncTask) { + defer wg.Done() + logCtx := sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}) + logCtx.Debug("pruning") + result, message := sc.pruneObject(t.liveObj, sc.prune, dryRun) + if result == common.ResultCodeSyncFailed { + runState = failed + logCtx.WithField("message", message).Info("pruning failed") + } + if !dryRun || sc.dryRun || result == common.ResultCodeSyncFailed { + sc.setResourceResult(t, result, operationPhases[result], message) + } + }(task) + } + wg.Wait() + } + + // delete anything that need deleting + if runState == successful && createTasks.Any(func(t *syncTask) bool { return t.needsDeleting() }) { + var wg sync.WaitGroup + for _, task := range createTasks.Filter(func(t *syncTask) bool { return t.needsDeleting() }) { + wg.Add(1) + go func(t *syncTask) { + defer wg.Done() + sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}).Debug("deleting") + if !dryRun { + err := sc.deleteResource(t) + if err != nil { + // it is possible to get a race condition here, such that the resource does not exist when + // delete is requested, we treat this as a nop + if !apierr.IsNotFound(err) { + runState = failed + sc.setResourceResult(t, "", common.OperationError, fmt.Sprintf("failed to delete resource: %v", err)) + } + } else { + // if there is anything that needs deleting, we are at best now in pending and + // want to return and wait for sync to be invoked again + runState = pending + } + } + }(task) + } + wg.Wait() + } + // finally create resources + if runState == successful { + processCreateTasks := func(tasks syncTasks) { + var createWg sync.WaitGroup + for _, task := range tasks { + if dryRun && task.skipDryRun { + continue + } + createWg.Add(1) + go func(t *syncTask) { + defer createWg.Done() + logCtx := sc.log.WithFields(log.Fields{"dryRun": dryRun, "task": t}) + logCtx.Debug("applying") + validate := sc.validate && !resourceutil.HasAnnotationOption(t.targetObj, common.AnnotationSyncOptions, "Validate=false") + result, message := sc.applyObject(t.targetObj, dryRun, sc.force, validate) + if result == common.ResultCodeSyncFailed { + logCtx.WithField("message", message).Info("apply failed") + runState = failed + } + if !dryRun || sc.dryRun || result == common.ResultCodeSyncFailed { + sc.setResourceResult(t, result, operationPhases[result], message) + } + }(task) + } + createWg.Wait() + } + + var tasksGroup syncTasks + for _, task := range createTasks { + //Only wait if the type of the next task is different than the previous type + if len(tasksGroup) > 0 && tasksGroup[0].targetObj.GetKind() != task.kind() { + processCreateTasks(tasksGroup) + tasksGroup = syncTasks{task} + } else { + tasksGroup = append(tasksGroup, task) + } + } + if len(tasksGroup) > 0 { + processCreateTasks(tasksGroup) + } + } + return runState +} + +// setResourceResult sets a resource details in the SyncResult.Resources list +func (sc *syncContext) setResourceResult(task *syncTask, syncStatus common.ResultCode, operationState common.OperationPhase, message string) { + task.syncStatus = syncStatus + task.operationState = operationState + // we always want to keep the latest message + if message != "" { + task.message = message + } + + sc.lock.Lock() + defer sc.lock.Unlock() + existing, ok := sc.syncRes[task.resultKey()] + + res := common.ResourceSyncResult{ + ResourceKey: kube.GetResourceKey(task.obj()), + Version: task.version(), + Status: task.syncStatus, + Message: task.message, + HookType: task.hookType(), + HookPhase: task.operationState, + SyncPhase: task.phase, + } + + logCtx := sc.log.WithFields(log.Fields{"namespace": task.namespace(), "kind": task.kind(), "name": task.name(), "phase": task.phase}) + + if ok { + // update existing value + if res.Status != existing.Status || res.HookPhase != existing.HookPhase || res.Message != existing.Message { + logCtx.Infof("updating resource result, status: '%s' -> '%s', phase '%s' -> '%s', message '%s' -> '%s'", + existing.Status, res.Status, + existing.HookPhase, res.HookPhase, + existing.Message, res.Message) + existing.Status = res.Status + existing.HookPhase = res.HookPhase + existing.Message = res.Message + } + sc.syncRes[task.resultKey()] = existing + } else { + logCtx.Infof("adding resource result, status: '%s', phase: '%s', message: '%s'", res.Status, res.HookPhase, res.Message) + res.Order = len(sc.syncRes) + 1 + sc.syncRes[task.resultKey()] = res + } +} + +func resourceResultKey(key kubeutil.ResourceKey, phase common.SyncPhase) string { + return fmt.Sprintf("%s:%s", key.String(), phase) +} diff --git a/pkg/utils/kube/sync/sync_context_test.go b/pkg/utils/kube/sync/sync_context_test.go new file mode 100644 index 000000000..46b680c6d --- /dev/null +++ b/pkg/utils/kube/sync/sync_context_test.go @@ -0,0 +1,647 @@ +package sync + +import ( + "fmt" + "reflect" + "testing" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + fakedisco "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/rest" + testcore "k8s.io/client-go/testing" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + synccommon "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" + testingutils "github.com/argoproj/gitops-engine/pkg/utils/testing" +) + +func newTestSyncCtx(opts ...SyncOpt) *syncContext { + fakeDisco := &fakedisco.FakeDiscovery{Fake: &testcore.Fake{}} + fakeDisco.Resources = append(make([]*v1.APIResourceList, 0), + &v1.APIResourceList{ + GroupVersion: "v1", + APIResources: []v1.APIResource{ + {Kind: "Pod", Group: "", Version: "v1", Namespaced: true}, + {Kind: "Service", Group: "", Version: "v1", Namespaced: true}, + }, + }, + &v1.APIResourceList{ + GroupVersion: "apps/v1", + APIResources: []v1.APIResource{ + {Kind: "Deployment", Group: "apps", Version: "v1", Namespaced: true}, + }, + }) + sc := syncContext{ + config: &rest.Config{}, + rawConfig: &rest.Config{}, + namespace: FakeArgoCDNamespace, + revision: "FooBarBaz", + disco: fakeDisco, + log: log.WithFields(log.Fields{"application": "fake-app"}), + resources: map[kube.ResourceKey]reconciledResource{}, + syncRes: map[string]synccommon.ResourceSyncResult{}, + validate: true, + } + sc.permissionValidator = func(un *unstructured.Unstructured, res *v1.APIResource) error { + return nil + } + sc.kubectl = &kubetest.MockKubectlCmd{} + for _, opt := range opts { + opt(&sc) + } + return &sc +} + +// make sure Validate means we don't validate +func TestSyncValidate(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + pod.SetNamespace("fake-argocd-ns") + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{pod}, + Target: []*unstructured.Unstructured{pod}, + }) + syncCtx.validate = false + + syncCtx.Sync() + + kubectl := syncCtx.kubectl.(*kubetest.MockKubectlCmd) + assert.False(t, kubectl.LastValidate) +} + +func TestSyncNotPermittedNamespace(t *testing.T) { + syncCtx := newTestSyncCtx(WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error { + return fmt.Errorf("not permitted in project") + })) + targetPod := NewPod() + targetPod.SetNamespace("kube-system") + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil, nil}, + Target: []*unstructured.Unstructured{targetPod, NewService()}, + }) + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + assert.Equal(t, synccommon.OperationFailed, phase) + assert.Contains(t, resources[0].Message, "not permitted in project") +} + +func TestSyncCreateInSortedOrder(t *testing.T) { + syncCtx := newTestSyncCtx() + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil, nil}, + Target: []*unstructured.Unstructured{NewPod(), NewService()}, + }) + syncCtx.Sync() + + phase, _, resources := syncCtx.GetState() + + assert.Equal(t, synccommon.OperationSucceeded, phase) + assert.Len(t, resources, 2) + for i := range resources { + result := resources[i] + if result.ResourceKey.Kind == "Pod" { + assert.Equal(t, synccommon.ResultCodeSynced, result.Status) + assert.Equal(t, "", result.Message) + } else if result.ResourceKey.Kind == "Service" { + assert.Equal(t, "", result.Message) + } else { + t.Error("Resource isn't a pod or a service") + } + } +} + +func TestSyncCustomResources(t *testing.T) { + type fields struct { + skipDryRunAnnotationPresent bool + crdAlreadyPresent bool + crdInSameSync bool + } + + tests := []struct { + name string + fields fields + wantDryRun bool + wantSuccess bool + }{ + + {"unknown crd", fields{ + skipDryRunAnnotationPresent: false, crdAlreadyPresent: false, crdInSameSync: false, + }, true, false}, + {"crd present in same sync", fields{ + skipDryRunAnnotationPresent: false, crdAlreadyPresent: false, crdInSameSync: true, + }, false, true}, + {"crd is already present in cluster", fields{ + skipDryRunAnnotationPresent: false, crdAlreadyPresent: true, crdInSameSync: false, + }, true, true}, + {"crd is already present in cluster, skip dry run annotated", fields{ + skipDryRunAnnotationPresent: true, crdAlreadyPresent: true, crdInSameSync: false, + }, true, true}, + {"unknown crd, skip dry run annotated", fields{ + skipDryRunAnnotationPresent: true, crdAlreadyPresent: false, crdInSameSync: false, + }, false, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + knownCustomResourceTypes := []v1.APIResource{} + if tt.fields.crdAlreadyPresent { + knownCustomResourceTypes = append(knownCustomResourceTypes, v1.APIResource{Kind: "TestCrd", Group: "argoproj.io", Version: "v1", Namespaced: true}) + } + + syncCtx := newTestSyncCtx() + fakeDisco := syncCtx.disco.(*fakedisco.FakeDiscovery) + fakeDisco.Resources = []*v1.APIResourceList{{ + GroupVersion: "argoproj.io/v1", + APIResources: knownCustomResourceTypes, + }, + { + GroupVersion: "apiextensions.k8s.io/v1beta1", + APIResources: []v1.APIResource{ + {Kind: "CustomResourceDefinition", Group: "apiextensions.k8s.io", Version: "v1beta1", Namespaced: true}, + }, + }, + } + + cr := testingutils.Unstructured(` +{ + "apiVersion": "argoproj.io/v1", + "kind": "TestCrd", + "metadata": { + "name": "my-resource" + } +} +`) + + if tt.fields.skipDryRunAnnotationPresent { + cr.SetAnnotations(map[string]string{common.AnnotationSyncOptions: "SkipDryRunOnMissingResource=true"}) + } + + resources := []*unstructured.Unstructured{cr} + if tt.fields.crdInSameSync { + resources = append(resources, NewCRD()) + } + + syncCtx.resources = groupResources(ReconciliationResult{ + Live: make([]*unstructured.Unstructured, len(resources)), + Target: resources, + }) + + tasks, successful := syncCtx.getSyncTasks() + + if successful != tt.wantSuccess { + t.Errorf("successful = %v, want: %v", successful, tt.wantSuccess) + return + } + + skipDryRun := false + for _, task := range tasks { + if task.targetObj.GetKind() == cr.GetKind() { + skipDryRun = task.skipDryRun + break + } + } + + if tt.wantDryRun != !skipDryRun { + t.Errorf("dryRun = %v, want: %v", !skipDryRun, tt.wantDryRun) + } + }) + } + +} + +func TestSyncSuccessfully(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) + pod := NewPod() + pod.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil, pod}, + Target: []*unstructured.Unstructured{NewService(), nil}, + }) + + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + + assert.Equal(t, synccommon.OperationSucceeded, phase) + assert.Len(t, resources, 2) + for i := range resources { + result := resources[i] + if result.ResourceKey.Kind == "Pod" { + assert.Equal(t, synccommon.ResultCodePruned, result.Status) + assert.Equal(t, "pruned", result.Message) + } else if result.ResourceKey.Kind == "Service" { + assert.Equal(t, synccommon.ResultCodeSynced, result.Status) + assert.Equal(t, "", result.Message) + } else { + t.Error("Resource isn't a pod or a service") + } + } +} + +func TestSyncDeleteSuccessfully(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) + svc := NewService() + svc.SetNamespace(FakeArgoCDNamespace) + pod := NewPod() + pod.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{svc, pod}, + Target: []*unstructured.Unstructured{nil, nil}, + }) + + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + + assert.Equal(t, synccommon.OperationSucceeded, phase) + for i := range resources { + result := resources[i] + if result.ResourceKey.Kind == "Pod" { + assert.Equal(t, synccommon.ResultCodePruned, result.Status) + assert.Equal(t, "pruned", result.Message) + } else if result.ResourceKey.Kind == "Service" { + assert.Equal(t, synccommon.ResultCodePruned, result.Status) + assert.Equal(t, "pruned", result.Message) + } else { + t.Error("Resource isn't a pod or a service") + } + } +} + +func TestSyncCreateFailure(t *testing.T) { + syncCtx := newTestSyncCtx() + testSvc := NewService() + syncCtx.kubectl = &kubetest.MockKubectlCmd{ + Commands: map[string]kubetest.KubectlOutput{ + testSvc.GetName(): { + Output: "", + Err: fmt.Errorf("foo"), + }, + }, + } + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{testSvc}, + }) + + syncCtx.Sync() + _, _, resources := syncCtx.GetState() + + assert.Len(t, resources, 1) + result := resources[0] + assert.Equal(t, synccommon.ResultCodeSyncFailed, result.Status) + assert.Equal(t, "foo", result.Message) +} + +func TestSyncPruneFailure(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) + syncCtx.kubectl = &kubetest.MockKubectlCmd{ + Commands: map[string]kubetest.KubectlOutput{ + "test-service": { + Output: "", + Err: fmt.Errorf("foo"), + }, + }, + } + testSvc := NewService() + testSvc.SetName("test-service") + testSvc.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{testSvc}, + Target: []*unstructured.Unstructured{testSvc}, + }) + + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + + assert.Equal(t, synccommon.OperationFailed, phase) + assert.Len(t, resources, 1) + result := resources[0] + assert.Equal(t, synccommon.ResultCodeSyncFailed, result.Status) + assert.Equal(t, "foo", result.Message) +} + +func TestDontSyncOrPruneHooks(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, false, false, true)) + targetPod := NewPod() + targetPod.SetName("dont-create-me") + targetPod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) + liveSvc := NewService() + liveSvc.SetName("dont-prune-me") + liveSvc.SetNamespace(FakeArgoCDNamespace) + liveSvc.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) + + syncCtx.hooks = []*unstructured.Unstructured{targetPod, liveSvc} + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + assert.Len(t, resources, 0) + assert.Equal(t, synccommon.OperationSucceeded, phase) +} + +// make sure that we do not prune resources with Prune=false +func TestDontPrunePruneFalse(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) + pod := NewPod() + pod.SetAnnotations(map[string]string{common.AnnotationSyncOptions: "Prune=false"}) + pod.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{pod}, + Target: []*unstructured.Unstructured{nil}, + }) + + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + + assert.Equal(t, synccommon.OperationSucceeded, phase) + assert.Len(t, resources, 1) + assert.Equal(t, synccommon.ResultCodePruneSkipped, resources[0].Status) + assert.Equal(t, "ignored (no prune)", resources[0].Message) + + syncCtx.Sync() + + phase, _, _ = syncCtx.GetState() + assert.Equal(t, synccommon.OperationSucceeded, phase) +} + +//// make sure Validate=false means we don't validate +func TestSyncOptionValidate(t *testing.T) { + tests := []struct { + name string + annotationVal string + want bool + }{ + {"Empty", "", true}, + {"True", "Validate=true", true}, + {"False", "Validate=false", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + pod.SetAnnotations(map[string]string{common.AnnotationSyncOptions: tt.annotationVal}) + pod.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{pod}, + Target: []*unstructured.Unstructured{pod}, + }) + + syncCtx.Sync() + + kubectl, _ := syncCtx.kubectl.(*kubetest.MockKubectlCmd) + assert.Equal(t, tt.want, kubectl.LastValidate) + }) + } +} + +func TestSelectiveSyncOnly(t *testing.T) { + pod1 := NewPod() + pod1.SetName("pod-1") + pod2 := NewPod() + pod2.SetName("pod-2") + syncCtx := newTestSyncCtx(WithResourcesFilter(func(key kube.ResourceKey, _ *unstructured.Unstructured, _ *unstructured.Unstructured) bool { + return key.Kind == pod1.GetKind() && key.Name == pod1.GetName() + })) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod1}, + }) + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 1) + assert.Equal(t, "pod-1", tasks[0].name()) +} + +func TestUnnamedHooksGetUniqueNames(t *testing.T) { + t.Run("Truncated revision", func(t *testing.T) { + syncCtx := newTestSyncCtx() + + pod := NewPod() + pod.SetName("") + pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync,PostSync"}) + syncCtx.hooks = []*unstructured.Unstructured{pod} + + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 2) + assert.Contains(t, tasks[0].name(), "foobarb-presync-") + assert.Contains(t, tasks[1].name(), "foobarb-postsync-") + assert.Equal(t, "", pod.GetName()) + }) + + t.Run("Short revision", func(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + pod.SetName("") + pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync,PostSync"}) + syncCtx.hooks = []*unstructured.Unstructured{pod} + syncCtx.revision = "foobar" + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 2) + assert.Contains(t, tasks[0].name(), "foobar-presync-") + assert.Contains(t, tasks[1].name(), "foobar-postsync-") + assert.Equal(t, "", pod.GetName()) + }) +} + +func TestManagedResourceAreNotNamed(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + pod.SetName("") + + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod}, + }) + + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 1) + assert.Equal(t, "", tasks[0].name()) + assert.Equal(t, "", pod.GetName()) +} + +func TestDeDupingTasks(t *testing.T) { + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) + pod := NewPod() + pod.SetAnnotations(map[string]string{common.AnnotationKeyHook: "Sync"}) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod}, + }) + syncCtx.hooks = []*unstructured.Unstructured{pod} + + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 1) +} + +func TestObjectsGetANamespace(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod}, + }) + + tasks, successful := syncCtx.getSyncTasks() + + assert.True(t, successful) + assert.Len(t, tasks, 1) + assert.Equal(t, FakeArgoCDNamespace, tasks[0].namespace()) + assert.Equal(t, "", pod.GetNamespace()) +} + +func TestSyncFailureHookWithSuccessfulSync(t *testing.T) { + syncCtx := newTestSyncCtx() + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{NewPod()}, + }) + syncCtx.hooks = []*unstructured.Unstructured{newHook(synccommon.HookTypeSyncFail)} + + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + assert.Equal(t, synccommon.OperationSucceeded, phase) + // only one result, we did not run the failure failureHook + assert.Len(t, resources, 1) +} + +func TestSyncFailureHookWithFailedSync(t *testing.T) { + syncCtx := newTestSyncCtx() + pod := NewPod() + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod}, + }) + syncCtx.hooks = []*unstructured.Unstructured{newHook(synccommon.HookTypeSyncFail)} + syncCtx.kubectl = &kubetest.MockKubectlCmd{ + Commands: map[string]kubetest.KubectlOutput{pod.GetName(): {Err: fmt.Errorf("")}}, + } + + syncCtx.Sync() + syncCtx.Sync() + + phase, _, resources := syncCtx.GetState() + assert.Equal(t, synccommon.OperationFailed, phase) + assert.Len(t, resources, 2) +} + +func TestBeforeHookCreation(t *testing.T) { + syncCtx := newTestSyncCtx() + hook := Annotate(Annotate(NewPod(), common.AnnotationKeyHook, "Sync"), common.AnnotationKeyHookDeletePolicy, "BeforeHookCreation") + hook.SetNamespace(FakeArgoCDNamespace) + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{hook}, + Target: []*unstructured.Unstructured{nil}, + }) + syncCtx.hooks = []*unstructured.Unstructured{hook} + syncCtx.dynamicIf = fake.NewSimpleDynamicClient(runtime.NewScheme()) + + syncCtx.Sync() + + _, _, resources := syncCtx.GetState() + assert.Len(t, resources, 1) + assert.Empty(t, resources[0].Message) +} + +func TestRunSyncFailHooksFailed(t *testing.T) { + // Tests that other SyncFail Hooks run even if one of them fail. + + syncCtx := newTestSyncCtx() + pod := NewPod() + successfulSyncFailHook := newHook(synccommon.HookTypeSyncFail) + successfulSyncFailHook.SetName("successful-sync-fail-hook") + failedSyncFailHook := newHook(synccommon.HookTypeSyncFail) + failedSyncFailHook.SetName("failed-sync-fail-hook") + syncCtx.resources = groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{pod}, + }) + syncCtx.hooks = []*unstructured.Unstructured{successfulSyncFailHook, failedSyncFailHook} + + syncCtx.kubectl = &kubetest.MockKubectlCmd{ + Commands: map[string]kubetest.KubectlOutput{ + // Fail operation + pod.GetName(): {Err: fmt.Errorf("")}, + // Fail a single SyncFail hook + failedSyncFailHook.GetName(): {Err: fmt.Errorf("")}}, + } + + syncCtx.Sync() + syncCtx.Sync() + phase, _, resources := syncCtx.GetState() + + // Operation as a whole should fail + assert.Equal(t, synccommon.OperationFailed, phase) + // failedSyncFailHook should fail + assert.Equal(t, synccommon.OperationFailed, resources[1].HookPhase) + assert.Equal(t, synccommon.ResultCodeSyncFailed, resources[1].Status) + // successfulSyncFailHook should be synced running (it is an nginx pod) + assert.Equal(t, synccommon.OperationRunning, resources[2].HookPhase) + assert.Equal(t, synccommon.ResultCodeSynced, resources[2].Status) +} + +func Test_syncContext_liveObj(t *testing.T) { + type fields struct { + compareResult ReconciliationResult + } + type args struct { + obj *unstructured.Unstructured + } + obj := NewPod() + obj.SetNamespace("my-ns") + + found := NewPod() + foundNoNamespace := NewPod() + foundNoNamespace.SetNamespace("") + + tests := []struct { + name string + fields fields + args args + want *unstructured.Unstructured + }{ + {"None", fields{compareResult: ReconciliationResult{}}, args{obj: &unstructured.Unstructured{}}, nil}, + {"Found", fields{compareResult: ReconciliationResult{Target: []*unstructured.Unstructured{nil}, Live: []*unstructured.Unstructured{found}}}, args{obj: obj}, found}, + {"EmptyNamespace", fields{compareResult: ReconciliationResult{Target: []*unstructured.Unstructured{nil}, Live: []*unstructured.Unstructured{foundNoNamespace}}}, args{obj: obj}, found}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sc := &syncContext{ + resources: groupResources(tt.fields.compareResult), + hooks: tt.fields.compareResult.Hooks, + } + if got := sc.liveObj(tt.args.obj); !reflect.DeepEqual(got, tt.want) { + t.Errorf("syncContext.liveObj() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_syncContext_hasCRDOfGroupKind(t *testing.T) { + // target + assert.False(t, (&syncContext{resources: groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{NewCRD()}, + })}).hasCRDOfGroupKind("", "")) + assert.True(t, (&syncContext{resources: groupResources(ReconciliationResult{ + Live: []*unstructured.Unstructured{nil}, + Target: []*unstructured.Unstructured{NewCRD()}, + })}).hasCRDOfGroupKind("argoproj.io", "TestCrd")) + + // hook + assert.False(t, (&syncContext{hooks: []*unstructured.Unstructured{NewCRD()}}).hasCRDOfGroupKind("", "")) + assert.True(t, (&syncContext{hooks: []*unstructured.Unstructured{NewCRD()}}).hasCRDOfGroupKind("argoproj.io", "TestCrd")) +} diff --git a/pkg/utils/kube/sync/sync_phase.go b/pkg/utils/kube/sync/sync_phase.go new file mode 100644 index 000000000..46dce777d --- /dev/null +++ b/pkg/utils/kube/sync/sync_phase.go @@ -0,0 +1,29 @@ +package sync + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook" +) + +func syncPhases(obj *unstructured.Unstructured) []common.SyncPhase { + if hook.Skip(obj) { + return nil + } else if hook.IsHook(obj) { + phasesMap := make(map[common.SyncPhase]bool) + for _, hookType := range hook.Types(obj) { + switch hookType { + case common.HookTypePreSync, common.HookTypeSync, common.HookTypePostSync, common.HookTypeSyncFail: + phasesMap[common.SyncPhase(hookType)] = true + } + } + var phases []common.SyncPhase + for phase := range phasesMap { + phases = append(phases, phase) + } + return phases + } else { + return []common.SyncPhase{common.SyncPhaseSync} + } +} diff --git a/pkg/utils/kube/sync/sync_phase_test.go b/pkg/utils/kube/sync/sync_phase_test.go new file mode 100644 index 000000000..4c9b02a47 --- /dev/null +++ b/pkg/utils/kube/sync/sync_phase_test.go @@ -0,0 +1,57 @@ +package sync + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" +) + +func TestSyncPhaseNone(t *testing.T) { + assert.Equal(t, []common.SyncPhase{common.SyncPhaseSync}, syncPhases(&unstructured.Unstructured{})) +} + +func TestSyncPhasePreSync(t *testing.T) { + assert.Equal(t, []common.SyncPhase{common.SyncPhasePreSync}, syncPhases(pod("PreSync"))) +} + +func TestSyncPhaseSync(t *testing.T) { + assert.Equal(t, []common.SyncPhase{common.SyncPhaseSync}, syncPhases(pod("Sync"))) +} + +func TestSyncPhaseSkip(t *testing.T) { + assert.Nil(t, syncPhases(pod("Skip"))) +} + +// garbage hooks are still hooks, but have no phases, because some user spelled something wrong +func TestSyncPhaseGarbage(t *testing.T) { + assert.Nil(t, syncPhases(pod("Garbage"))) +} + +func TestSyncPhasePost(t *testing.T) { + assert.Equal(t, []common.SyncPhase{common.SyncPhasePostSync}, syncPhases(pod("PostSync"))) +} + +func TestSyncPhaseFail(t *testing.T) { + assert.Equal(t, []common.SyncPhase{common.SyncPhaseSyncFail}, syncPhases(pod("SyncFail"))) +} + +func TestSyncPhaseTwoPhases(t *testing.T) { + assert.ElementsMatch(t, []common.SyncPhase{common.SyncPhasePreSync, common.SyncPhasePostSync}, syncPhases(pod("PreSync,PostSync"))) +} + +func TestSyncDuplicatedPhases(t *testing.T) { + assert.ElementsMatch(t, []common.SyncPhase{common.SyncPhasePreSync}, syncPhases(pod("PreSync,PreSync"))) + assert.ElementsMatch(t, []common.SyncPhase{common.SyncPhasePreSync}, syncPhases(podWithHelmHook("pre-install,pre-upgrade"))) +} + +func pod(hookType string) *unstructured.Unstructured { + return Annotate(NewPod(), "argocd.argoproj.io/hook", hookType) +} + +func podWithHelmHook(hookType string) *unstructured.Unstructured { + return Annotate(NewPod(), "helm.sh/hook", hookType) +} diff --git a/controller/sync_task.go b/pkg/utils/kube/sync/sync_task.go similarity index 66% rename from controller/sync_task.go rename to pkg/utils/kube/sync/sync_task.go index b22f13a2c..7ec07e077 100644 --- a/controller/sync_task.go +++ b/pkg/utils/kube/sync/sync_task.go @@ -1,26 +1,27 @@ -package controller +package sync import ( "fmt" - "github.com/argoproj/argo-cd/engine/pkg" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/argoproj/argo-cd/engine/hook" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource/syncwaves" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/syncwaves" ) // syncTask holds the live and target object. At least one should be non-nil. A targetObj of nil // indicates the live object needs to be pruned. A liveObj of nil indicates the object has yet to // be deployed type syncTask struct { - pkg.SyncTaskInfo + phase common.SyncPhase + liveObj *unstructured.Unstructured + targetObj *unstructured.Unstructured skipDryRun bool - syncStatus v1alpha1.ResultCode - operationState v1alpha1.OperationPhase + syncStatus common.ResultCode + operationState common.OperationPhase message string } @@ -34,21 +35,25 @@ func ternary(val bool, a, b string) string { func (t *syncTask) String() string { return fmt.Sprintf("%s/%d %s %s/%s:%s/%s %s->%s (%s,%s,%s)", - t.Phase, t.wave(), + t.phase, t.wave(), ternary(t.isHook(), "hook", "resource"), t.group(), t.kind(), t.namespace(), t.name(), - ternary(t.LiveObj != nil, "obj", "nil"), ternary(t.TargetObj != nil, "obj", "nil"), + ternary(t.liveObj != nil, "obj", "nil"), ternary(t.targetObj != nil, "obj", "nil"), t.syncStatus, t.operationState, t.message, ) } func (t *syncTask) isPrune() bool { - return t.TargetObj == nil + return t.targetObj == nil +} + +func (t *syncTask) resultKey() string { + return resourceResultKey(kube.GetResourceKey(t.obj()), t.phase) } // return the target object (if this exists) otherwise the live object // some caution - often you explicitly want the live object not the target object func (t *syncTask) obj() *unstructured.Unstructured { - return obj(t.TargetObj, t.LiveObj) + return obj(t.targetObj, t.liveObj) } func (t *syncTask) wave() int { @@ -102,15 +107,15 @@ func (t *syncTask) failed() bool { return t.operationState.Failed() } -func (t *syncTask) hookType() v1alpha1.HookType { +func (t *syncTask) hookType() common.HookType { if t.isHook() { - return v1alpha1.HookType(t.Phase) + return common.HookType(t.phase) } else { return "" } } -func (t *syncTask) hasHookDeletePolicy(policy v1alpha1.HookDeletePolicy) bool { +func (t *syncTask) hasHookDeletePolicy(policy common.HookDeletePolicy) bool { // cannot have a policy if it is not a hook, it is meaningless if !t.isHook() { return false @@ -124,7 +129,7 @@ func (t *syncTask) hasHookDeletePolicy(policy v1alpha1.HookDeletePolicy) bool { } func (t *syncTask) needsDeleting() bool { - return t.LiveObj != nil && (t.pending() && t.hasHookDeletePolicy(v1alpha1.HookDeletePolicyBeforeHookCreation) || - t.successful() && t.hasHookDeletePolicy(v1alpha1.HookDeletePolicyHookSucceeded) || - t.failed() && t.hasHookDeletePolicy(v1alpha1.HookDeletePolicyHookFailed)) + return t.liveObj != nil && (t.pending() && t.hasHookDeletePolicy(common.HookDeletePolicyBeforeHookCreation) || + t.successful() && t.hasHookDeletePolicy(common.HookDeletePolicyHookSucceeded) || + t.failed() && t.hasHookDeletePolicy(common.HookDeletePolicyHookFailed)) } diff --git a/pkg/utils/kube/sync/sync_task_test.go b/pkg/utils/kube/sync/sync_task_test.go new file mode 100644 index 000000000..3b3b1bc8b --- /dev/null +++ b/pkg/utils/kube/sync/sync_task_test.go @@ -0,0 +1,70 @@ +package sync + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" +) + +func newHook(hookType common.HookType) *unstructured.Unstructured { + return Annotate(NewPod(), "argocd.argoproj.io/hook", string(hookType)) +} + +func Test_syncTask_hookType(t *testing.T) { + type fields struct { + phase common.SyncPhase + liveObj *unstructured.Unstructured + } + tests := []struct { + name string + fields fields + want common.HookType + }{ + {"Empty", fields{common.SyncPhaseSync, NewPod()}, ""}, + {"PreSyncHook", fields{common.SyncPhasePreSync, newHook(common.HookTypePreSync)}, common.HookTypePreSync}, + {"SyncHook", fields{common.SyncPhaseSync, newHook(common.HookTypeSync)}, common.HookTypeSync}, + {"PostSyncHook", fields{common.SyncPhasePostSync, newHook(common.HookTypePostSync)}, common.HookTypePostSync}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + task := &syncTask{ + phase: tt.fields.phase, + liveObj: tt.fields.liveObj, + } + hookType := task.hookType() + assert.EqualValues(t, tt.want, hookType) + }) + } +} + +func Test_syncTask_hasHookDeletePolicy(t *testing.T) { + assert.False(t, (&syncTask{targetObj: NewPod()}).hasHookDeletePolicy(common.HookDeletePolicyBeforeHookCreation)) + assert.False(t, (&syncTask{targetObj: NewPod()}).hasHookDeletePolicy(common.HookDeletePolicyHookSucceeded)) + assert.False(t, (&syncTask{targetObj: NewPod()}).hasHookDeletePolicy(common.HookDeletePolicyHookFailed)) + // must be hook + assert.False(t, (&syncTask{targetObj: Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).hasHookDeletePolicy(common.HookDeletePolicyBeforeHookCreation)) + assert.True(t, (&syncTask{targetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).hasHookDeletePolicy(common.HookDeletePolicyBeforeHookCreation)) + assert.True(t, (&syncTask{targetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded")}).hasHookDeletePolicy(common.HookDeletePolicyHookSucceeded)) + assert.True(t, (&syncTask{targetObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookFailed")}).hasHookDeletePolicy(common.HookDeletePolicyHookFailed)) +} + +func Test_syncTask_needsDeleting(t *testing.T) { + assert.False(t, (&syncTask{liveObj: NewPod()}).needsDeleting()) + // must be hook + assert.False(t, (&syncTask{liveObj: Annotate(NewPod(), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).needsDeleting()) + // no need to delete if no live obj + assert.False(t, (&syncTask{targetObj: Annotate(Annotate(NewPod(), "argoocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).needsDeleting()) + assert.True(t, (&syncTask{liveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).needsDeleting()) + assert.True(t, (&syncTask{liveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "BeforeHookCreation")}).needsDeleting()) + assert.True(t, (&syncTask{operationState: common.OperationSucceeded, liveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookSucceeded")}).needsDeleting()) + assert.True(t, (&syncTask{operationState: common.OperationFailed, liveObj: Annotate(Annotate(NewPod(), "argocd.argoproj.io/hook", "Sync"), "argocd.argoproj.io/hook-delete-policy", "HookFailed")}).needsDeleting()) +} + +func Test_syncTask_wave(t *testing.T) { + assert.Equal(t, 0, (&syncTask{targetObj: NewPod()}).wave()) + assert.Equal(t, 1, (&syncTask{targetObj: Annotate(NewPod(), "argocd.argoproj.io/sync-wave", "1")}).wave()) +} diff --git a/controller/sync_tasks.go b/pkg/utils/kube/sync/sync_tasks.go similarity index 86% rename from controller/sync_tasks.go rename to pkg/utils/kube/sync/sync_tasks.go index 77c7bc577..a4adc84ff 100644 --- a/controller/sync_tasks.go +++ b/pkg/utils/kube/sync/sync_tasks.go @@ -1,17 +1,17 @@ -package controller +package sync import ( "strings" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" ) // kindOrder represents the correct order of Kubernetes resources within a manifest -var syncPhaseOrder = map[v1alpha1.SyncPhase]int{ - v1alpha1.SyncPhasePreSync: -1, - v1alpha1.SyncPhaseSync: 0, - v1alpha1.SyncPhasePostSync: 1, - v1alpha1.SyncPhaseSyncFail: 2, +var syncPhaseOrder = map[common.SyncPhase]int{ + common.SyncPhasePreSync: -1, + common.SyncPhaseSync: 0, + common.SyncPhasePostSync: 1, + common.SyncPhaseSyncFail: 2, } // kindOrder represents the correct order of Kubernetes resources within a manifest @@ -74,7 +74,7 @@ func (s syncTasks) Less(i, j int) bool { tA := s[i] tB := s[j] - d := syncPhaseOrder[tA.Phase] - syncPhaseOrder[tB.Phase] + d := syncPhaseOrder[tA.phase] - syncPhaseOrder[tB.phase] if d != 0 { return d < 0 } @@ -152,9 +152,9 @@ func (s syncTasks) String() string { return "[" + strings.Join(values, ", ") + "]" } -func (s syncTasks) phase() v1alpha1.SyncPhase { +func (s syncTasks) phase() common.SyncPhase { if len(s) > 0 { - return s[0].Phase + return s[0].phase } return "" } @@ -166,9 +166,9 @@ func (s syncTasks) wave() int { return 0 } -func (s syncTasks) lastPhase() v1alpha1.SyncPhase { +func (s syncTasks) lastPhase() common.SyncPhase { if len(s) > 0 { - return s[len(s)-1].Phase + return s[len(s)-1].phase } return "" } diff --git a/controller/sync_tasks_test.go b/pkg/utils/kube/sync/sync_tasks_test.go similarity index 56% rename from controller/sync_tasks_test.go rename to pkg/utils/kube/sync/sync_tasks_test.go index b355d7ef7..7e4138f03 100644 --- a/controller/sync_tasks_test.go +++ b/pkg/utils/kube/sync/sync_tasks_test.go @@ -1,18 +1,15 @@ -package controller +package sync import ( "sort" "testing" - "github.com/argoproj/argo-cd/engine/pkg" - "github.com/stretchr/testify/assert" apiv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/engine/common" - . "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - . "github.com/argoproj/argo-cd/test" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func Test_syncTasks_kindOrder(t *testing.T) { @@ -60,35 +57,35 @@ func TestSplitSyncTasks(t *testing.T) { } var unsortedTasks = syncTasks{ - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Pod", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Service", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "PersistentVolume", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhaseSyncFail, TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + phase: common.SyncPhaseSyncFail, targetObj: &unstructured.Unstructured{}, + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -97,27 +94,27 @@ var unsortedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "b", }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "a", }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -126,38 +123,38 @@ var unsortedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePreSync, - TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePostSync, TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + phase: common.SyncPhasePreSync, + targetObj: &unstructured.Unstructured{}, + }, + { + phase: common.SyncPhasePostSync, targetObj: &unstructured.Unstructured{}, + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "ConfigMap", }, }, - }}, + }, } var sortedTasks = syncTasks{ - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePreSync, - TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + { + phase: common.SyncPhasePreSync, + targetObj: &unstructured.Unstructured{}, + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -166,66 +163,66 @@ var sortedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "ConfigMap", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "PersistentVolume", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Service", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Pod", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "a", }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "b", }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -234,45 +231,45 @@ var sortedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePostSync, - TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhaseSyncFail, - TargetObj: &unstructured.Unstructured{}, - }}, + }, + { + phase: common.SyncPhasePostSync, + targetObj: &unstructured.Unstructured{}, + }, + { + phase: common.SyncPhaseSyncFail, + targetObj: &unstructured.Unstructured{}, + }, } var namedObjTasks = syncTasks{ - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "a", }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "name": "b", }, }, }, - }}, + }, } var unnamedTasks = syncTasks{ - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePreSync, - TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + { + phase: common.SyncPhasePreSync, + targetObj: &unstructured.Unstructured{}, + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -281,48 +278,48 @@ var unnamedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "ConfigMap", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "PersistentVolume", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Service", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), "kind": "Pod", }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "GroupVersion": apiv1.SchemeGroupVersion.String(), }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }, + { + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ @@ -331,38 +328,38 @@ var unnamedTasks = syncTasks{ }, }, }, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhasePostSync, - TargetObj: &unstructured.Unstructured{}, - }}, - {SyncTaskInfo: pkg.SyncTaskInfo{ - Phase: SyncPhaseSyncFail, - TargetObj: &unstructured.Unstructured{}, - }}, + }, + { + phase: common.SyncPhasePostSync, + targetObj: &unstructured.Unstructured{}, + }, + { + phase: common.SyncPhaseSyncFail, + targetObj: &unstructured.Unstructured{}, + }, } func Test_syncTasks_Filter(t *testing.T) { - tasks := syncTasks{{SyncTaskInfo: pkg.SyncTaskInfo{Phase: SyncPhaseSync}}, {SyncTaskInfo: pkg.SyncTaskInfo{Phase: SyncPhasePostSync}}} + tasks := syncTasks{{phase: common.SyncPhaseSync}, {phase: common.SyncPhasePostSync}} - assert.Equal(t, syncTasks{{SyncTaskInfo: pkg.SyncTaskInfo{Phase: SyncPhaseSync}}}, tasks.Filter(func(t *syncTask) bool { - return t.Phase == SyncPhaseSync + assert.Equal(t, syncTasks{{phase: common.SyncPhaseSync}}, tasks.Filter(func(t *syncTask) bool { + return t.phase == common.SyncPhaseSync })) } func TestSyncNamespaceAgainstCRD(t *testing.T) { - crd := &syncTask{SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + crd := &syncTask{ + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "kind": "Workflow", }, - }}} - namespace := &syncTask{SyncTaskInfo: pkg.SyncTaskInfo{ - TargetObj: &unstructured.Unstructured{ + }} + namespace := &syncTask{ + targetObj: &unstructured.Unstructured{ Object: map[string]interface{}{ "kind": "Namespace", }, - }}, + }, } unsorted := syncTasks{crd, namespace} @@ -373,21 +370,21 @@ func TestSyncNamespaceAgainstCRD(t *testing.T) { func Test_syncTasks_multiStep(t *testing.T) { t.Run("Single", func(t *testing.T) { - tasks := syncTasks{{SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(NewPod(), common.AnnotationSyncWave, "-1"), Phase: SyncPhaseSync}}} - assert.Equal(t, SyncPhaseSync, tasks.phase()) + tasks := syncTasks{{liveObj: Annotate(NewPod(), common.AnnotationSyncWave, "-1"), phase: common.SyncPhaseSync}} + assert.Equal(t, common.SyncPhaseSync, string(tasks.phase())) assert.Equal(t, -1, tasks.wave()) - assert.Equal(t, SyncPhaseSync, tasks.lastPhase()) + assert.Equal(t, common.SyncPhaseSync, string(tasks.lastPhase())) assert.Equal(t, -1, tasks.lastWave()) assert.False(t, tasks.multiStep()) }) t.Run("Double", func(t *testing.T) { tasks := syncTasks{ - {SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(NewPod(), common.AnnotationSyncWave, "-1"), Phase: SyncPhasePreSync}}, - {SyncTaskInfo: pkg.SyncTaskInfo{LiveObj: Annotate(NewPod(), common.AnnotationSyncWave, "1"), Phase: SyncPhasePostSync}}, + {liveObj: Annotate(NewPod(), common.AnnotationSyncWave, "-1"), phase: common.SyncPhasePreSync}, + {liveObj: Annotate(NewPod(), common.AnnotationSyncWave, "1"), phase: common.SyncPhasePostSync}, } - assert.Equal(t, SyncPhasePreSync, tasks.phase()) + assert.Equal(t, common.SyncPhasePreSync, string(tasks.phase())) assert.Equal(t, -1, tasks.wave()) - assert.Equal(t, SyncPhasePostSync, tasks.lastPhase()) + assert.Equal(t, common.SyncPhasePostSync, string(tasks.lastPhase())) assert.Equal(t, 1, tasks.lastWave()) assert.True(t, tasks.multiStep()) }) diff --git a/resource/syncwaves/waves.go b/pkg/utils/kube/sync/syncwaves/waves.go similarity index 69% rename from resource/syncwaves/waves.go rename to pkg/utils/kube/sync/syncwaves/waves.go index dc823f4ea..b620e1e03 100644 --- a/resource/syncwaves/waves.go +++ b/pkg/utils/kube/sync/syncwaves/waves.go @@ -5,8 +5,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/argoproj/argo-cd/engine/common" - helmhook "github.com/argoproj/argo-cd/engine/hook/helm" + "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/common" + helmhook "github.com/argoproj/gitops-engine/pkg/utils/kube/sync/hook/helm" ) func Wave(obj *unstructured.Unstructured) int { diff --git a/resource/syncwaves/waves_test.go b/pkg/utils/kube/sync/syncwaves/waves_test.go similarity index 84% rename from resource/syncwaves/waves_test.go rename to pkg/utils/kube/sync/syncwaves/waves_test.go index 6a0d24d53..b7ff440b9 100644 --- a/resource/syncwaves/waves_test.go +++ b/pkg/utils/kube/sync/syncwaves/waves_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - . "github.com/argoproj/argo-cd/test" + . "github.com/argoproj/gitops-engine/pkg/utils/testing" ) func TestWave(t *testing.T) { diff --git a/pkg/utils/kube/testdata/appsdeployment.yaml b/pkg/utils/kube/testdata/appsdeployment.yaml new file mode 100644 index 000000000..7e44d8ea8 --- /dev/null +++ b/pkg/utils/kube/testdata/appsdeployment.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx-deployment +spec: + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx diff --git a/pkg/utils/kube/testdata/cr.yaml b/pkg/utils/kube/testdata/cr.yaml new file mode 100644 index 000000000..122bd4cdc --- /dev/null +++ b/pkg/utils/kube/testdata/cr.yaml @@ -0,0 +1,13 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: custom-resource + namespace: default +spec: + destination: + namespace: default + server: https://kubernetes.default.svc + project: default + source: + path: guestbook + repoURL: https://github.com/argoproj/argocd-example-apps.git \ No newline at end of file diff --git a/pkg/utils/kube/testdata/extensionsdeployment.yaml b/pkg/utils/kube/testdata/extensionsdeployment.yaml new file mode 100644 index 000000000..d295072d4 --- /dev/null +++ b/pkg/utils/kube/testdata/extensionsdeployment.yaml @@ -0,0 +1,13 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx diff --git a/util/kube/testdata/nginx.yaml b/pkg/utils/kube/testdata/nginx.yaml similarity index 100% rename from util/kube/testdata/nginx.yaml rename to pkg/utils/kube/testdata/nginx.yaml diff --git a/pkg/utils/kube/testdata/v1HPA.yaml b/pkg/utils/kube/testdata/v1HPA.yaml new file mode 100644 index 000000000..f3f1ef5d4 --- /dev/null +++ b/pkg/utils/kube/testdata/v1HPA.yaml @@ -0,0 +1,12 @@ +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: php-apache +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: php-apache + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 50 diff --git a/pkg/utils/kube/testdata/v2beta1HPA.yaml b/pkg/utils/kube/testdata/v2beta1HPA.yaml new file mode 100644 index 000000000..88a5dc700 --- /dev/null +++ b/pkg/utils/kube/testdata/v2beta1HPA.yaml @@ -0,0 +1,16 @@ +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: php-apache +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: php-apache + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: 50 diff --git a/pkg/utils/testing/testdata.go b/pkg/utils/testing/testdata.go new file mode 100644 index 000000000..21ec4b699 --- /dev/null +++ b/pkg/utils/testing/testdata.go @@ -0,0 +1,91 @@ +package testing + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +const ( + FakeArgoCDNamespace = "fake-argocd-ns" +) + +func HelmHook(obj *unstructured.Unstructured, hookType string) *unstructured.Unstructured { + return Annotate(obj, "helm.sh/hook", hookType) +} + +func Annotate(obj *unstructured.Unstructured, key, val string) *unstructured.Unstructured { + annotations := obj.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations[key] = val + obj.SetAnnotations(annotations) + return obj +} + +var PodManifest = ` +{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "my-pod" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.7.9", + "name": "nginx", + "resources": { + "requests": { + "cpu": 0.2 + } + } + } + ] + } +} +` + +func NewPod() *unstructured.Unstructured { + return Unstructured(PodManifest) +} + +var ServiceManifest = ` +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "my-service" + }, + "spec": { + "ports": [ + { + "name": "http", + "protocol": "TCP", + "port": 80, + "targetPort": 8080 + } + ], + "selector": { + "app": "my-service" + } + } +} +` + +func NewService() *unstructured.Unstructured { + return Unstructured(ServiceManifest) +} + +func NewCRD() *unstructured.Unstructured { + return Unstructured(`apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: testcrds.argoproj.io +spec: + group: argoproj.io + version: v1 + scope: Namespaced + names: + plural: testcrds + kind: TestCrd`) +} diff --git a/pkg/utils/testing/unstructured.go b/pkg/utils/testing/unstructured.go new file mode 100644 index 000000000..5d02176c8 --- /dev/null +++ b/pkg/utils/testing/unstructured.go @@ -0,0 +1,32 @@ +package testing + +import ( + "encoding/json" + "io/ioutil" + "strings" + + "github.com/ghodss/yaml" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func UnstructuredFromFile(path string) *unstructured.Unstructured { + file, err := ioutil.ReadFile(path) + if err != nil { + panic(err) + } + return Unstructured(string(file)) +} + +func Unstructured(text string) *unstructured.Unstructured { + un := &unstructured.Unstructured{} + var err error + if strings.HasPrefix(text, "{") { + err = json.Unmarshal([]byte(text), &un) + } else { + err = yaml.Unmarshal([]byte(text), &un) + } + if err != nil { + panic(err) + } + return un +} diff --git a/pkg/utils/text/text.go b/pkg/utils/text/text.go new file mode 100644 index 000000000..5b83b7b42 --- /dev/null +++ b/pkg/utils/text/text.go @@ -0,0 +1,10 @@ +package text + +func FirstNonEmpty(args ...string) string { + for _, value := range args { + if len(value) > 0 { + return value + } + } + return "" +} diff --git a/pkg/utils/tracing/span.go b/pkg/utils/tracing/span.go new file mode 100644 index 000000000..e66633591 --- /dev/null +++ b/pkg/utils/tracing/span.go @@ -0,0 +1,44 @@ +package tracing + +import ( + "os" + "time" + + log "github.com/sirupsen/logrus" +) + +/* + Poor Mans OpenTracing. + + Standardizes logging of operation duration. +*/ + +var enabled = false +var logger = log.New() + +func init() { + enabled = os.Getenv("ARGOCD_TRACING_ENABLED") == "1" +} + +type Span struct { + operationName string + baggage map[string]interface{} + start time.Time +} + +func (s Span) Finish() { + if enabled { + logger.WithFields(s.baggage). + WithField("operation_name", s.operationName). + WithField("time_ms", time.Since(s.start).Seconds()*1e3). + Info() + } +} + +func (s Span) SetBaggageItem(key string, value interface{}) { + s.baggage[key] = value +} + +func StartSpan(operationName string) Span { + return Span{operationName, make(map[string]interface{}), time.Now()} +} diff --git a/pkg/utils/tracing/span_test.go b/pkg/utils/tracing/span_test.go new file mode 100644 index 000000000..f4ddccaf0 --- /dev/null +++ b/pkg/utils/tracing/span_test.go @@ -0,0 +1,42 @@ +package tracing + +import ( + "testing" + + log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" +) + +func TestStartSpan(t *testing.T) { + + testLogger, hook := test.NewNullLogger() + defer hook.Reset() + logger = testLogger + defer func() { logger = log.New() }() + + t.Run("Disabled", func(t *testing.T) { + span := StartSpan("my-operation") + span.SetBaggageItem("my-key", "my-value") + span.Finish() + + assert.Empty(t, hook.Entries) + + }) + hook.Reset() + t.Run("Enabled", func(t *testing.T) { + enabled = true + defer func() { enabled = false }() + span := StartSpan("my-operation") + span.SetBaggageItem("my-key", "my-value") + span.Finish() + + e := hook.LastEntry() + if assert.NotNil(t, e) { + assert.Empty(t, e.Message) + assert.Equal(t, "my-operation", e.Data["operation_name"]) + assert.Equal(t, "my-value", e.Data["my-key"]) + assert.Contains(t, e.Data, "time_ms") + } + }) +} diff --git a/resource/filtered_resource.go b/resource/filtered_resource.go deleted file mode 100644 index c2a2292a2..000000000 --- a/resource/filtered_resource.go +++ /dev/null @@ -1,52 +0,0 @@ -package resource - -import ( - "github.com/gobwas/glob" - log "github.com/sirupsen/logrus" -) - -type FilteredResource struct { - APIGroups []string `json:"apiGroups,omitempty"` - Kinds []string `json:"kinds,omitempty"` - Clusters []string `json:"clusters,omitempty"` -} - -func (r FilteredResource) matchGroup(apiGroup string) bool { - for _, excludedApiGroup := range r.APIGroups { - if match(excludedApiGroup, apiGroup) { - return true - } - } - return len(r.APIGroups) == 0 -} - -func match(pattern, text string) bool { - compiledGlob, err := glob.Compile(pattern) - if err != nil { - log.Warnf("failed to compile pattern %s due to error %v", pattern, err) - return false - } - return compiledGlob.Match(text) -} - -func (r FilteredResource) matchKind(kind string) bool { - for _, excludedKind := range r.Kinds { - if excludedKind == "*" || excludedKind == kind { - return true - } - } - return len(r.Kinds) == 0 -} - -func (r FilteredResource) matchCluster(cluster string) bool { - for _, excludedCluster := range r.Clusters { - if match(excludedCluster, cluster) { - return true - } - } - return len(r.Clusters) == 0 -} - -func (r FilteredResource) Match(apiGroup, kind, cluster string) bool { - return r.matchGroup(apiGroup) && r.matchKind(kind) && r.matchCluster(cluster) -} diff --git a/resource/filtered_resource_test.go b/resource/filtered_resource_test.go deleted file mode 100644 index 095e554b9..000000000 --- a/resource/filtered_resource_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package resource - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestExcludeResource(t *testing.T) { - apiGroup := "foo.com" - kind := "bar" - cluster := "baz.com" - - // matches with missing values - assert.True(t, FilteredResource{Kinds: []string{kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{"*"}}.Match(apiGroup, kind, cluster)) - - // simple matches - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{"*.com"}, Kinds: []string{kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{"*"}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{kind}, Clusters: []string{"*.com"}}.Match(apiGroup, kind, cluster)) - - // negative matches - assert.False(t, FilteredResource{APIGroups: []string{""}, Kinds: []string{kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.False(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{""}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.False(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{kind}, Clusters: []string{""}}.Match(apiGroup, kind, cluster)) - - // complex matches - assert.True(t, FilteredResource{APIGroups: []string{apiGroup, apiGroup}, Kinds: []string{kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{kind, kind}, Clusters: []string{cluster}}.Match(apiGroup, kind, cluster)) - assert.True(t, FilteredResource{APIGroups: []string{apiGroup}, Kinds: []string{kind}, Clusters: []string{cluster, cluster}}.Match(apiGroup, kind, cluster)) - - // rubbish patterns - assert.False(t, FilteredResource{APIGroups: []string{"["}, Kinds: []string{""}, Clusters: []string{""}}.Match("", "", "")) - assert.False(t, FilteredResource{APIGroups: []string{""}, Kinds: []string{"["}, Clusters: []string{""}}.Match("", "", "")) - assert.False(t, FilteredResource{APIGroups: []string{""}, Kinds: []string{""}, Clusters: []string{"["}}.Match("", "", "")) -} diff --git a/resource/ignore/ignore_test.go b/resource/ignore/ignore_test.go deleted file mode 100644 index af6f3b58c..000000000 --- a/resource/ignore/ignore_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package ignore - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/argoproj/argo-cd/test" -) - -func TestIgnore(t *testing.T) { - assert.False(t, Ignore(NewPod())) - assert.False(t, Ignore(Hook(NewPod(), "Sync"))) - assert.True(t, Ignore(Hook(NewPod(), "garbage"))) - assert.False(t, Ignore(HelmHook(NewPod(), "pre-install"))) - assert.True(t, Ignore(HelmHook(NewPod(), "garbage"))) -} diff --git a/resource/resources_filter.go b/resource/resources_filter.go deleted file mode 100644 index f27936964..000000000 --- a/resource/resources_filter.go +++ /dev/null @@ -1,70 +0,0 @@ -package resource - -type ResourcesFilter struct { - // ResourceExclusions holds the api groups, kinds per cluster to exclude from Argo CD's watch - ResourceExclusions []FilteredResource - // ResourceInclusions holds the only api groups, kinds per cluster that Argo CD will watch - ResourceInclusions []FilteredResource -} - -func (rf *ResourcesFilter) getExcludedResources() []FilteredResource { - coreExcludedResources := []FilteredResource{ - {APIGroups: []string{"events.k8s.io", "metrics.k8s.io"}}, - {APIGroups: []string{""}, Kinds: []string{"Event"}}, - } - return append(coreExcludedResources, rf.ResourceExclusions...) -} - -func (rf *ResourcesFilter) checkResourcePresence(apiGroup, kind, cluster string, filteredResources []FilteredResource) bool { - - for _, includedResource := range filteredResources { - if includedResource.Match(apiGroup, kind, cluster) { - return true - } - } - - return false -} - -func (rf *ResourcesFilter) isIncludedResource(apiGroup, kind, cluster string) bool { - return rf.checkResourcePresence(apiGroup, kind, cluster, rf.ResourceInclusions) -} - -func (rf *ResourcesFilter) isExcludedResource(apiGroup, kind, cluster string) bool { - return rf.checkResourcePresence(apiGroup, kind, cluster, rf.getExcludedResources()) -} - -// Behavior of this function is as follows: -// +-------------+-------------+-------------+ -// | Inclusions | Exclusions | Result | -// +-------------+-------------+-------------+ -// | Empty | Empty | Allowed | -// +-------------+-------------+-------------+ -// | Present | Empty | Allowed | -// +-------------+-------------+-------------+ -// | Not Present | Empty | Not Allowed | -// +-------------+-------------+-------------+ -// | Empty | Present | Not Allowed | -// +-------------+-------------+-------------+ -// | Empty | Not Present | Allowed | -// +-------------+-------------+-------------+ -// | Present | Not Present | Allowed | -// +-------------+-------------+-------------+ -// | Not Present | Present | Not Allowed | -// +-------------+-------------+-------------+ -// | Not Present | Not Present | Not Allowed | -// +-------------+-------------+-------------+ -// | Present | Present | Not Allowed | -// +-------------+-------------+-------------+ -// -func (rf *ResourcesFilter) IsExcludedResource(apiGroup, kind, cluster string) bool { - if len(rf.ResourceInclusions) > 0 { - if rf.isIncludedResource(apiGroup, kind, cluster) { - return rf.isExcludedResource(apiGroup, kind, cluster) - } else { - return true - } - } else { - return rf.isExcludedResource(apiGroup, kind, cluster) - } -} diff --git a/resource/resources_filter_test.go b/resource/resources_filter_test.go deleted file mode 100644 index 7e4f00136..000000000 --- a/resource/resources_filter_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package resource - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestIsExcludedResource(t *testing.T) { - settings := &ResourcesFilter{} - assert.True(t, settings.IsExcludedResource("events.k8s.io", "", "")) - assert.True(t, settings.IsExcludedResource("metrics.k8s.io", "", "")) - assert.False(t, settings.IsExcludedResource("rubbish.io", "", "")) -} - -func TestResourceInclusions(t *testing.T) { - filter := ResourcesFilter{ - ResourceInclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}}}, - } - - assert.True(t, filter.IsExcludedResource("non-whitelisted-resource", "", "")) - assert.False(t, filter.IsExcludedResource("whitelisted-resource", "", "")) -} - -func TestResourceInclusionsExclusionNonMutex(t *testing.T) { - filter := ResourcesFilter{ - ResourceInclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}}}, - ResourceExclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}, Kinds: []string{"blacklisted-kind"}}}, - } - - assert.True(t, filter.IsExcludedResource("whitelisted-resource", "blacklisted-kind", "")) - assert.False(t, filter.IsExcludedResource("whitelisted-resource", "", "")) - assert.False(t, filter.IsExcludedResource("whitelisted-resource", "non-blacklisted-kind", "")) - - filter = ResourcesFilter{ - ResourceInclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}, Kinds: []string{"whitelisted-kind"}}}, - ResourceExclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}}}, - } - - assert.True(t, filter.IsExcludedResource("whitelisted-resource", "whitelisted-kind", "")) - assert.True(t, filter.IsExcludedResource("whitelisted-resource", "", "")) - assert.True(t, filter.IsExcludedResource("whitelisted-resource", "non-whitelisted-kind", "")) - - filter = ResourcesFilter{ - ResourceInclusions: []FilteredResource{{APIGroups: []string{"foo-bar"}, Kinds: []string{"whitelisted-kind"}}}, - ResourceExclusions: []FilteredResource{{APIGroups: []string{"whitelisted-resource"}}}, - } - - assert.True(t, filter.IsExcludedResource("not-whitelisted-resource", "whitelisted-kind", "")) - assert.True(t, filter.IsExcludedResource("not-whitelisted-resource", "", "")) -} diff --git a/resource/revision.go b/resource/revision.go deleted file mode 100644 index 93eea446c..000000000 --- a/resource/revision.go +++ /dev/null @@ -1,21 +0,0 @@ -package resource - -import ( - "strconv" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -func GetRevision(obj *unstructured.Unstructured) int64 { - if obj == nil { - return 0 - } - for _, name := range []string{"deployment.kubernetes.io/revision", "rollout.argoproj.io/revision"} { - text, ok := obj.GetAnnotations()[name] - if ok { - revision, _ := strconv.ParseInt(text, 10, 64) - return revision - } - } - return 0 -} diff --git a/resource/revision_test.go b/resource/revision_test.go deleted file mode 100644 index f9c2a40cb..000000000 --- a/resource/revision_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package resource - -import ( - "testing" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/test" -) - -func TestGetRevision(t *testing.T) { - type args struct { - obj *unstructured.Unstructured - } - tests := []struct { - name string - args args - want int64 - }{ - {"Nil", args{}, 0}, - {"Empty", args{obj: test.NewPod()}, 0}, - {"Invalid", args{obj: revisionExample("deployment.kubernetes.io/revision", "garbage")}, 0}, - {"Garbage", args{obj: revisionExample("garbage.kubernetes.io/revision", "1")}, 0}, - {"Deployments", args{obj: revisionExample("deployment.kubernetes.io/revision", "1")}, 1}, - {"Rollouts", args{obj: revisionExample("rollout.argoproj.io/revision", "1")}, 1}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := GetRevision(tt.args.obj); got != tt.want { - t.Errorf("GetRevision() = %v, want %v", got, tt.want) - } - }) - } -} - -func revisionExample(name, value string) *unstructured.Unstructured { - pod := test.NewPod() - pod.SetAnnotations(map[string]string{name: value}) - return pod -} diff --git a/util/argo/argo.go b/util/argo/argo.go deleted file mode 100644 index 60e70dc6f..000000000 --- a/util/argo/argo.go +++ /dev/null @@ -1,188 +0,0 @@ -package argo - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "time" - - "k8s.io/apimachinery/pkg/types" - - "github.com/argoproj/argo-cd/engine/pkg" - - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/sirupsen/logrus" - "k8s.io/apimachinery/pkg/api/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/argoproj/argo-cd/engine/common" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" -) - -const ( - errDestinationMissing = "Destination server and/or namespace missing from app spec" -) - -// FormatAppConditions returns string representation of give app condition list -func FormatAppConditions(conditions []v1alpha1.ApplicationCondition) string { - formattedConditions := make([]string, 0) - for _, condition := range conditions { - formattedConditions = append(formattedConditions, fmt.Sprintf("%s: %s", condition.Type, condition.Message)) - } - return strings.Join(formattedConditions, ";") -} - -// GetAppProject returns a project from an application -func GetAppProject(spec *v1alpha1.ApplicationSpec, projLister applisters.AppProjectLister, ns string) (*v1alpha1.AppProject, error) { - return projLister.AppProjects(ns).Get(spec.GetProject()) -} - -// ValidatePermissions ensures that the referenced cluster has been added to Argo CD and the app source repo and destination namespace/cluster are permitted in app project -func ValidatePermissions(ctx context.Context, spec *v1alpha1.ApplicationSpec, proj *v1alpha1.AppProject, db pkg.CredentialsStore) ([]v1alpha1.ApplicationCondition, error) { - conditions := make([]v1alpha1.ApplicationCondition, 0) - if spec.Source.RepoURL == "" || (spec.Source.Path == "" && spec.Source.Chart == "") { - conditions = append(conditions, v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionInvalidSpecError, - Message: "spec.source.repoURL and spec.source.path either spec.source.chart are required", - }) - return conditions, nil - } - if spec.Source.Chart != "" && spec.Source.TargetRevision == "" { - conditions = append(conditions, v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionInvalidSpecError, - Message: "spec.source.targetRevision is required if the manifest source is a helm chart", - }) - return conditions, nil - } - - if !proj.IsSourcePermitted(spec.Source) { - conditions = append(conditions, v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.Source.RepoURL, spec.Project), - }) - } - - if spec.Destination.Server != "" && spec.Destination.Namespace != "" { - if !proj.IsDestinationPermitted(spec.Destination) { - conditions = append(conditions, v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("application destination %v is not permitted in project '%s'", spec.Destination, spec.Project), - }) - } - // Ensure the k8s cluster the app is referencing, is configured in Argo CD - _, err := db.GetCluster(ctx, spec.Destination.Server) - if err != nil { - if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound { - conditions = append(conditions, v1alpha1.ApplicationCondition{ - Type: v1alpha1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("cluster '%s' has not been configured", spec.Destination.Server), - }) - } else { - return nil, err - } - } - } else { - conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionInvalidSpecError, Message: errDestinationMissing}) - } - return conditions, nil -} - -// NormalizeApplicationSpec will normalize an application spec to a preferred state. This is used -// for migrating application objects which are using deprecated legacy fields into the new fields, -// and defaulting fields in the spec (e.g. spec.project) -func NormalizeApplicationSpec(spec *v1alpha1.ApplicationSpec) *v1alpha1.ApplicationSpec { - spec = spec.DeepCopy() - if spec.Project == "" { - spec.Project = common.DefaultAppProjectName - } - - // 3. If any app sources are their zero values, then nil out the pointers to the source spec. - // This makes it easier for users to switch between app source types if they are not using - // any of the source-specific parameters. - if spec.Source.Kustomize != nil && spec.Source.Kustomize.IsZero() { - spec.Source.Kustomize = nil - } - if spec.Source.Helm != nil && spec.Source.Helm.IsZero() { - spec.Source.Helm = nil - } - if spec.Source.Ksonnet != nil && spec.Source.Ksonnet.IsZero() { - spec.Source.Ksonnet = nil - } - if spec.Source.Directory != nil && spec.Source.Directory.IsZero() { - spec.Source.Directory = nil - } - return spec -} - -// SetAppOperation updates an application with the specified operation, retrying conflict errors -func SetAppOperation(appIf appclientset.ApplicationInterface, appName string, op *v1alpha1.Operation) (*v1alpha1.Application, error) { - for { - a, err := appIf.Get(appName, v1.GetOptions{}) - if err != nil { - return nil, err - } - if a.Operation != nil { - return nil, status.Errorf(codes.FailedPrecondition, "another operation is already in progress") - } - a.Operation = op - a.Status.OperationState = nil - a, err = appIf.Update(a) - if op.Sync == nil { - return nil, status.Errorf(codes.InvalidArgument, "Operation unspecified") - } - if err == nil { - return a, nil - } - if !errors.IsConflict(err) { - return nil, err - } - logrus.Warnf("Failed to set operation for app '%s' due to update conflict. Retrying again...", appName) - } -} - -// ContainsSyncResource determines if the given resource exists in the provided slice of sync operation resources. -func ContainsSyncResource(name string, gvk schema.GroupVersionKind, rr []v1alpha1.SyncOperationResource) bool { - for _, r := range rr { - if r.HasIdentity(name, gvk) { - return true - } - } - return false -} - -// RefreshApp updates the refresh annotation of an application to coerce the controller to process it -func RefreshApp(appIf appclientset.ApplicationInterface, name string, refreshType v1alpha1.RefreshType) (*v1alpha1.Application, error) { - metadata := map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]string{ - common.AnnotationKeyRefresh: string(refreshType), - }, - }, - } - var err error - patch, err := json.Marshal(metadata) - if err != nil { - return nil, err - } - for attempt := 0; attempt < 5; attempt++ { - app, err := appIf.Patch(name, types.MergePatchType, patch) - if err != nil { - if !errors.IsConflict(err) { - return nil, err - } - } else { - logrus.Infof("Requested app '%s' refresh", name) - return app, nil - } - time.Sleep(100 * time.Millisecond) - } - return nil, err -} diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go deleted file mode 100644 index 20ddf815f..000000000 --- a/util/argo/argo_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package argo - -import ( - "context" - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - argoappv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/fake" - "github.com/argoproj/argo-cd/engine/pkg/client/informers/externalversions/application/v1alpha1" - applisters "github.com/argoproj/argo-cd/engine/pkg/client/listers/application/v1alpha1" - - "github.com/stretchr/testify/assert" - "k8s.io/client-go/tools/cache" -) - -func TestGetAppProjectWithNoProjDefined(t *testing.T) { - projName := "default" - namespace := "default" - - testProj := &argoappv1.AppProject{ - ObjectMeta: metav1.ObjectMeta{Name: projName, Namespace: namespace}, - } - - var testApp argoappv1.Application - testApp.Name = "test-app" - testApp.Namespace = namespace - appClientset := appclientset.NewSimpleClientset(testProj) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - informer := v1alpha1.NewAppProjectInformer(appClientset, namespace, 0, cache.Indexers{}) - go informer.Run(ctx.Done()) - cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) - proj, err := GetAppProject(&testApp.Spec, applisters.NewAppProjectLister(informer.GetIndexer()), namespace) - assert.Nil(t, err) - assert.Equal(t, proj.Name, projName) -} - -func TestContainsSyncResource(t *testing.T) { - var ( - blankUnstructured unstructured.Unstructured - blankResource argoappv1.SyncOperationResource - helloResource = argoappv1.SyncOperationResource{Name: "hello"} - ) - tables := []struct { - u *unstructured.Unstructured - rr []argoappv1.SyncOperationResource - expected bool - }{ - {&blankUnstructured, []argoappv1.SyncOperationResource{}, false}, - {&blankUnstructured, []argoappv1.SyncOperationResource{blankResource}, true}, - {&blankUnstructured, []argoappv1.SyncOperationResource{helloResource}, false}, - } - - for _, table := range tables { - if out := ContainsSyncResource(table.u.GetName(), table.u.GroupVersionKind(), table.rr); out != table.expected { - t.Errorf("Expected %t for slice %+v conains resource %+v; instead got %t", table.expected, table.rr, table.u, out) - } - } -} - -// TestNilOutZerValueAppSources verifies we will nil out app source specs when they are their zero-value -func TestNilOutZerValueAppSources(t *testing.T) { - var spec *argoappv1.ApplicationSpec - { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: "foo"}}}) - assert.NotNil(t, spec.Source.Kustomize) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: ""}}}) - assert.Nil(t, spec.Source.Kustomize) - } - { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{"values.yaml"}}}}) - assert.NotNil(t, spec.Source.Helm) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{}}}}) - assert.Nil(t, spec.Source.Helm) - } - { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Ksonnet: &argoappv1.ApplicationSourceKsonnet{Environment: "foo"}}}) - assert.NotNil(t, spec.Source.Ksonnet) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Ksonnet: &argoappv1.ApplicationSourceKsonnet{Environment: ""}}}) - assert.Nil(t, spec.Source.Ksonnet) - } - { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}}}) - assert.NotNil(t, spec.Source.Directory) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: false}}}) - assert.Nil(t, spec.Source.Directory) - } -} - -func TestValidatePermissionsEmptyDestination(t *testing.T) { - conditions, err := ValidatePermissions(context.Background(), &argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd", Path: "."}, - }, &argoappv1.AppProject{ - Spec: argoappv1.AppProjectSpec{ - SourceRepos: []string{"*"}, - Destinations: []argoappv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, - }, - }, nil) - assert.NoError(t, err) - assert.ElementsMatch(t, conditions, []argoappv1.ApplicationCondition{{Type: argoappv1.ApplicationConditionInvalidSpecError, Message: "Destination server and/or namespace missing from app spec"}}) -} - -func TestValidateChartWithoutRevision(t *testing.T) { - conditions, err := ValidatePermissions(context.Background(), &argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{RepoURL: "https://kubernetes-charts-incubator.storage.googleapis.com/", Chart: "myChart", TargetRevision: ""}, - Destination: argoappv1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", Namespace: "default", - }, - }, &argoappv1.AppProject{ - Spec: argoappv1.AppProjectSpec{ - SourceRepos: []string{"*"}, - Destinations: []argoappv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, - }, - }, nil) - assert.NoError(t, err) - assert.ElementsMatch(t, conditions, []argoappv1.ApplicationCondition{{ - Type: argoappv1.ApplicationConditionInvalidSpecError, Message: "spec.source.targetRevision is required if the manifest source is a helm chart"}}) -} diff --git a/util/argo/diff_normalizer.go b/util/argo/diff_normalizer.go deleted file mode 100644 index 04004fbae..000000000 --- a/util/argo/diff_normalizer.go +++ /dev/null @@ -1,113 +0,0 @@ -package argo - -import ( - "encoding/json" - "strings" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/diff" - - jsonpatch "github.com/evanphx/json-patch" - log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -type normalizerPatch struct { - groupKind schema.GroupKind - namespace string - name string - patch jsonpatch.Patch -} - -type normalizer struct { - patches []normalizerPatch -} - -type overrideIgnoreDiff struct { - JSONPointers []string `yaml:"jsonPointers"` -} - -// NewDiffNormalizer creates diff normalizer which removes ignored fields according to given application spec and resource overrides -func NewDiffNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride) (diff.Normalizer, error) { - for key, override := range overrides { - parts := strings.Split(key, "/") - if len(parts) < 2 { - continue - } - group := parts[0] - kind := parts[1] - if override.IgnoreDifferences != "" { - ignoreSettings := overrideIgnoreDiff{} - err := yaml.Unmarshal([]byte(override.IgnoreDifferences), &ignoreSettings) - if err != nil { - return nil, err - } - - ignore = append(ignore, v1alpha1.ResourceIgnoreDifferences{ - Group: group, - Kind: kind, - JSONPointers: ignoreSettings.JSONPointers, - }) - } - } - patches := make([]normalizerPatch, 0) - for i := range ignore { - for _, path := range ignore[i].JSONPointers { - patchData, err := json.Marshal([]map[string]string{{"op": "remove", "path": path}}) - if err != nil { - return nil, err - } - patch, err := jsonpatch.DecodePatch(patchData) - if err != nil { - return nil, err - } - patches = append(patches, normalizerPatch{ - groupKind: schema.GroupKind{Group: ignore[i].Group, Kind: ignore[i].Kind}, - name: ignore[i].Name, - namespace: ignore[i].Namespace, - patch: patch, - }) - } - - } - return &normalizer{patches: patches}, nil -} - -// Normalize removes fields from supplied resource using json paths from matching items of specified resources ignored differences list -func (n *normalizer) Normalize(un *unstructured.Unstructured) error { - matched := make([]normalizerPatch, 0) - for _, patch := range n.patches { - groupKind := un.GroupVersionKind().GroupKind() - if groupKind == patch.groupKind && - (patch.name == "" || patch.name == un.GetName()) && - (patch.namespace == "" || patch.namespace == un.GetNamespace()) { - - matched = append(matched, patch) - } - } - if len(matched) == 0 { - return nil - } - - docData, err := json.Marshal(un) - if err != nil { - return err - } - - for _, patch := range matched { - patchedData, err := patch.patch.Apply(docData) - if err != nil { - log.Debugf("Failed to apply normalization: %v", err) - continue - } - docData = patchedData - } - - err = json.Unmarshal(docData, un) - if err != nil { - return err - } - return nil -} diff --git a/util/argo/diff_normalizer_test.go b/util/argo/diff_normalizer_test.go deleted file mode 100644 index c33d22af1..000000000 --- a/util/argo/diff_normalizer_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package argo - -import ( - "testing" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" - "github.com/argoproj/argo-cd/test" -) - -func TestNormalizeObjectWithMatchedGroupKind(t *testing.T) { - normalizer, err := NewDiffNormalizer([]v1alpha1.ResourceIgnoreDifferences{{ - Group: "apps", - Kind: "Deployment", - JSONPointers: []string{"/not-matching-path", "/spec/template/spec/containers"}, - }}, make(map[string]v1alpha1.ResourceOverride)) - - assert.Nil(t, err) - - deployment := kube.MustToUnstructured(test.DemoDeployment()) - - _, has, err := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") - assert.Nil(t, err) - assert.True(t, has) - - err = normalizer.Normalize(deployment) - assert.Nil(t, err) - _, has, err = unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") - assert.Nil(t, err) - assert.False(t, has) -} - -func TestNormalizeNoMatchedGroupKinds(t *testing.T) { - normalizer, err := NewDiffNormalizer([]v1alpha1.ResourceIgnoreDifferences{{ - Group: "", - Kind: "Service", - JSONPointers: []string{"/spec"}, - }}, make(map[string]v1alpha1.ResourceOverride)) - - assert.Nil(t, err) - - deployment := kube.MustToUnstructured(test.DemoDeployment()) - - err = normalizer.Normalize(deployment) - assert.Nil(t, err) - - _, hasSpec, err := unstructured.NestedMap(deployment.Object, "spec") - assert.Nil(t, err) - assert.True(t, hasSpec) -} - -func TestNormalizeMatchedResourceOverrides(t *testing.T) { - normalizer, err := NewDiffNormalizer([]v1alpha1.ResourceIgnoreDifferences{}, map[string]v1alpha1.ResourceOverride{ - "apps/Deployment": { - IgnoreDifferences: `jsonPointers: ["/spec/template/spec/containers"]`, - }, - }) - - assert.Nil(t, err) - - deployment := kube.MustToUnstructured(test.DemoDeployment()) - - _, has, err := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") - assert.Nil(t, err) - assert.True(t, has) - - err = normalizer.Normalize(deployment) - assert.Nil(t, err) - _, has, err = unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers") - assert.Nil(t, err) - assert.False(t, has) -} - -const testCRDYAML = ` -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: certificates.certmanager.k8s.io -spec: - group: certmanager.k8s.io - names: - kind: Certificate - listKind: CertificateList - plural: certificates - shortNames: - - cert - - certs - singular: certificate - scope: Namespaced - version: v1alpha1` - -func TestNormalizeMissingJsonPointer(t *testing.T) { - normalizer, err := NewDiffNormalizer([]v1alpha1.ResourceIgnoreDifferences{}, map[string]v1alpha1.ResourceOverride{ - "apps/Deployment": { - IgnoreDifferences: `jsonPointers: ["/garbage"]`, - }, - "apiextensions.k8s.io/CustomResourceDefinition": { - IgnoreDifferences: `jsonPointers: ["/spec/additionalPrinterColumns/0/priority"]`, - }, - }) - assert.NoError(t, err) - - deployment := kube.MustToUnstructured(test.DemoDeployment()) - - err = normalizer.Normalize(deployment) - assert.NoError(t, err) - - crd := unstructured.Unstructured{} - err = yaml.Unmarshal([]byte(testCRDYAML), &crd) - assert.NoError(t, err) - - err = normalizer.Normalize(&crd) - assert.NoError(t, err) -} diff --git a/util/cert/cert.go b/util/cert/cert.go deleted file mode 100644 index 4ccf76417..000000000 --- a/util/cert/cert.go +++ /dev/null @@ -1,340 +0,0 @@ -// Utility functions for managing HTTPS server certificates and SSH known host -// entries for ArgoCD -package cert - -import ( - "bufio" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "regexp" - "strings" - - "golang.org/x/crypto/ssh" - - "github.com/argoproj/argo-cd/engine/common" -) - -// A struct representing an entry in the list of SSH known hosts. -type SSHKnownHostsEntry struct { - // Hostname the key is for - Host string - // The type of the key - SubType string - // The data of the key, including the type - Data string - // The SHA256 fingerprint of the key - Fingerprint string -} - -// A representation of a TLS certificate -type TLSCertificate struct { - // Subject of the certificate - Subject string - // Issuer of the certificate - Issuer string - // Certificate data - Data string -} - -// Helper struct for certificate selection -type CertificateListSelector struct { - // Pattern to match the hostname with - HostNamePattern string - // Type of certificate to match - CertType string - // Subtype of certificate to match - CertSubType string -} - -const ( - // Text marker indicating start of certificate in PEM format - CertificateBeginMarker = "-----BEGIN CERTIFICATE-----" - // Text marker indicating end of certificate in PEM format - CertificateEndMarker = "-----END CERTIFICATE-----" - // Maximum number of lines for a single certificate - CertificateMaxLines = 128 - // Maximum number of certificates or known host entries in a stream - CertificateMaxEntriesPerStream = 256 -) - -// Regular expression that matches a valid hostname -var validHostNameRegexp = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))*(\.){0,1}$`) - -// Regular expression that matches a valid FQDN -var validFQDNRegexp = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))*(\.){1}$`) - -// Can be used to test whether a given string represents a valid hostname -// If fqdn is true, given string must also be a FQDN representation. -func IsValidHostname(hostname string, fqdn bool) bool { - if !fqdn { - return validHostNameRegexp.Match([]byte(hostname)) - } else { - return validFQDNRegexp.Match([]byte(hostname)) - } -} - -// Get the configured path to where TLS certificates are stored on the local -// filesystem. If ARGOCD_TLS_DATA_PATH environment is set, path is taken from -// there, otherwise the default will be returned. -func GetTLSCertificateDataPath() string { - envPath := os.Getenv(common.EnvVarTLSDataPath) - if envPath != "" { - return envPath - } else { - return common.DefaultPathTLSConfig - } -} - -// Get the configured path to where SSH certificates are stored on the local -// filesystem. If ARGOCD_SSH_DATA_PATH environment is set, path is taken from -// there, otherwise the default will be returned. -func GetSSHKnownHostsDataPath() string { - envPath := os.Getenv(common.EnvVarSSHDataPath) - if envPath != "" { - return envPath + "/" + common.DefaultSSHKnownHostsName - } else { - return common.DefaultPathSSHConfig + "/" + common.DefaultSSHKnownHostsName - } -} - -// Decode a certificate in PEM format to X509 data structure -func DecodePEMCertificateToX509(pemData string) (*x509.Certificate, error) { - decodedData, _ := pem.Decode([]byte(pemData)) - if decodedData == nil { - return nil, errors.New("Could not decode PEM data from input.") - } - x509Cert, err := x509.ParseCertificate(decodedData.Bytes) - if err != nil { - return nil, errors.New("Could not parse X509 data from input.") - } - return x509Cert, nil -} - -// Parse TLS certificates from a multiline string -func ParseTLSCertificatesFromData(data string) ([]string, error) { - return ParseTLSCertificatesFromStream(strings.NewReader(data)) -} - -// Parse TLS certificates from a file -func ParseTLSCertificatesFromPath(sourceFile string) ([]string, error) { - fileHandle, err := os.Open(sourceFile) - if err != nil { - return nil, err - } - defer fileHandle.Close() - return ParseTLSCertificatesFromStream(fileHandle) -} - -// Parse TLS certificate data from a data stream. The stream may contain more -// than one certificate. Each found certificate will generate a unique entry -// in the returned slice, so the length of the slice indicates how many -// certificates have been found. -func ParseTLSCertificatesFromStream(stream io.Reader) ([]string, error) { - scanner := bufio.NewScanner(stream) - inCertData := false - pemData := "" - curLine := 0 - certLine := 0 - - certificateList := make([]string, 0) - - // TODO: Implement maximum amount of data to parse - // TODO: Implement error heuristics - - for scanner.Scan() { - curLine += 1 - if !inCertData { - if strings.HasPrefix(scanner.Text(), CertificateBeginMarker) { - certLine = 1 - inCertData = true - pemData += scanner.Text() + "\n" - } - } else { - certLine += 1 - pemData += scanner.Text() + "\n" - if strings.HasPrefix(scanner.Text(), CertificateEndMarker) { - inCertData = false - certificateList = append(certificateList, pemData) - pemData = "" - } - } - - if certLine > CertificateMaxLines { - return nil, errors.New("Maximum number of lines exceeded during certificate parsing.") - } - } - - return certificateList, nil -} - -// Parse SSH Known Hosts data from a multiline string -func ParseSSHKnownHostsFromData(data string) ([]string, error) { - return ParseSSHKnownHostsFromStream(strings.NewReader(data)) -} - -// Parse SSH Known Hosts data from a file -func ParseSSHKnownHostsFromPath(sourceFile string) ([]string, error) { - fileHandle, err := os.Open(sourceFile) - if err != nil { - return nil, err - } - defer fileHandle.Close() - return ParseSSHKnownHostsFromStream(fileHandle) -} - -// Parses a list of strings in SSH's known host data format from a stream and -// returns the valid entries in an array. -func ParseSSHKnownHostsFromStream(stream io.Reader) ([]string, error) { - scanner := bufio.NewScanner(stream) - knownHostsLists := make([]string, 0) - curLine := 0 - numEntries := 0 - - for scanner.Scan() { - curLine += 1 - lineData := scanner.Text() - if IsValidSSHKnownHostsEntry(lineData) { - numEntries += 1 - knownHostsLists = append(knownHostsLists, lineData) - } - } - - return knownHostsLists, nil -} - -// Checks whether we can use a line from ssh_known_hosts data as an actual data -// source for a RepoCertificate object. This function only checks for syntactic -// validity, not if the data in the line is valid. -func IsValidSSHKnownHostsEntry(line string) bool { - trimmedEntry := strings.TrimSpace(line) - // We ignore commented out lines - usually happens when copy and pasting - // to the ConfigMap from a known_hosts file or from ssh-keyscan output. - if len(trimmedEntry) == 0 || trimmedEntry[0] == '#' { - return false - } - - // Each line should consist of three fields: host, type, data - keyData := strings.SplitN(trimmedEntry, " ", 3) - return len(keyData) == 3 -} - -// Tokenize a known_hosts entry into hostname, key sub type and actual key data -func TokenizeSSHKnownHostsEntry(knownHostsEntry string) (string, string, []byte, error) { - knownHostsToken := strings.SplitN(knownHostsEntry, " ", 3) - if len(knownHostsToken) != 3 { - return "", "", nil, fmt.Errorf("Error while tokenizing input data.") - } - return knownHostsToken[0], knownHostsToken[1], []byte(knownHostsToken[2]), nil -} - -// Parse a raw known hosts line into a PublicKey object and a list of hosts the -// key would be valid for. -func KnownHostsLineToPublicKey(line string) ([]string, ssh.PublicKey, error) { - _, hostnames, keyData, _, _, err := ssh.ParseKnownHosts([]byte(line)) - if err != nil { - return nil, nil, err - } - return hostnames, keyData, nil -} - -func TokenizedDataToPublicKey(hostname string, subType string, rawKeyData string) ([]string, ssh.PublicKey, error) { - hostnames, keyData, err := KnownHostsLineToPublicKey(fmt.Sprintf("%s %s %s", hostname, subType, rawKeyData)) - if err != nil { - return nil, nil, err - } - return hostnames, keyData, nil -} - -// Returns the requested pattern with all possible square brackets escaped -func nonBracketedPattern(pattern string) string { - ret := strings.Replace(pattern, "[", `\[`, -1) - return strings.Replace(ret, "]", `\]`, -1) -} - -// We do not use full fledged regular expression for matching the hostname. -// Instead, we use a less expensive file system glob, which should be fully -// sufficient for our use case. -func MatchHostName(hostname, pattern string) bool { - // If pattern is empty, we always return a match - if pattern == "" { - return true - } - match, err := filepath.Match(nonBracketedPattern(pattern), hostname) - if err != nil { - return false - } - return match -} - -// Convinience wrapper around SSHFingerprintSHA256 -func SSHFingerprintSHA256FromString(key string) string { - pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(key)) - if err != nil { - return "" - } - return SSHFingerprintSHA256(pubKey) -} - -// base64 sha256 hash with the trailing equal sign removed -func SSHFingerprintSHA256(key ssh.PublicKey) string { - hash := sha256.Sum256(key.Marshal()) - b64hash := base64.StdEncoding.EncodeToString(hash[:]) - return strings.TrimRight(b64hash, "=") -} - -// Remove possible port number from hostname and return just the FQDN -func ServerNameWithoutPort(serverName string) string { - return strings.Split(serverName, ":")[0] -} - -// Load certificate data from a file. If the file does not exist, we do not -// consider it an error and just return empty data. -func GetCertificateForConnect(serverName string) ([]string, error) { - certPath := fmt.Sprintf("%s/%s", GetTLSCertificateDataPath(), ServerNameWithoutPort(serverName)) - certificates, err := ParseTLSCertificatesFromPath(certPath) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } else { - return nil, err - } - } - - if len(certificates) == 0 { - return nil, fmt.Errorf("No certificates found in existing file.") - } - - return certificates, nil -} - -// Gets the full path for a certificate bundle configured from a ConfigMap -// mount. This function makes sure that the path returned actually contain -// at least one valid certificate, and no invalid data. -func GetCertBundlePathForRepository(serverName string) (string, error) { - certPath := fmt.Sprintf("%s/%s", GetTLSCertificateDataPath(), ServerNameWithoutPort(serverName)) - certs, err := GetCertificateForConnect(serverName) - if err != nil { - return "", nil - } - if len(certs) == 0 { - return "", nil - } - return certPath, nil -} - -// Convert a list of certificates in PEM format to a x509.CertPool object, -// usable for most golang TLS functions. -func GetCertPoolFromPEMData(pemData []string) *x509.CertPool { - certPool := x509.NewCertPool() - for _, pem := range pemData { - certPool.AppendCertsFromPEM([]byte(pem)) - } - return certPool -} diff --git a/util/cert/cert_test.go b/util/cert/cert_test.go deleted file mode 100644 index aa3a85177..000000000 --- a/util/cert/cert_test.go +++ /dev/null @@ -1,429 +0,0 @@ -package cert - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -const Test_Cert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US" -const Test_Cert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE" -const Test_TLSValidSingleCert = ` ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL -BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMB4XDTE5MDcwODEzNTUwNVoXDTIwMDcwNzEzNTUw -NVowbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEA3csSO13w7qQXKeSLNcpeuAe6wAjXYbRkRl6ariqzTEDcFTKmy2QiXJTKoEGn -bvwxq0T91var7rxY88SGL/qi8Zmo0tVSR0XvKSKcghFIkQOTyDmVgMPZGCvixt4q -gQ7hUVSk4KkFmtcqBVuvnzI1d/DKfZAGKdmGcfRpuAsnVhac3swP0w4Tl1BFrK9U -vuIkz4KwXG77s5oB8rMUnyuLasLsGNpvpvXhkcQRhp6vpcCO2bS7kOTTelAPIucw -P37qkOEdZdiWCLrr57dmhg6tmcVlmBMg6JtmfLxn2HQd9ZrCKlkWxMk5NYs6CAW5 -kgbDZUWQTAsnHeoJKbcgtPkIbxDRxNpPukFMtbA4VEWv1EkODXy9FyEKDOI/PV6K -/80oLkgCIhCkP2mvwSFheU0RHTuZ0o0vVolP5TEOq5iufnDN4wrxqb12o//XLRc0 -RiLqGVVxhFdyKCjVxcLfII9AAp5Tse4PMh6bf6jDfB3OMvGkhMbJWhKXdR2NUTl0 -esKawMPRXIn5g3oBdNm8kyRsTTnvB567pU8uNSmA8j3jxfGCPynI8JdiwKQuW/+P -WgLIflgxqAfG85dVVOsFmF9o5o24dDslvv9yHnHH102c6ijPCg1EobqlyFzqqxOD -Wf2OPjIkzoTH+O27VRugnY/maIU1nshNO7ViRX5zIxEUtNMCAwEAAaNTMFEwHQYD -VR0OBBYEFNY4gDLgPBidogkmpO8nq5yAq5g+MB8GA1UdIwQYMBaAFNY4gDLgPBid -ogkmpO8nq5yAq5g+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB -AJ0WGioNtGNg3m6ywpmxNThorQD5ZvDMlmZlDVk78E2wfNyMhwbVhKhlAnONv0wv -kmsGjibY75nRZ+EK9PxSJ644841fryQXQ+bli5fhr7DW3uTKwaRsnzETJXRJuljq -6+c6Zyg1/mqwnyx7YvPgVh3w496DYx/jm6Fm1IEq3BzOmn6H/gGPq3gbURzEqI3h -P+kC2vJa8RZWrpa05Xk/Q1QUkErDX9vJghb9z3+GgirISZQzqWRghII/znv3NOE6 -zoIgaaWNFn8KPeBVpUoboH+IhpgibsnbTbI0G7AMtFq6qm3kn/4DZ2N2tuh1G2tT -zR2Fh7hJbU7CrqxANrgnIoHG/nLSvzE24ckLb0Vj69uGQlwnZkn9fz6F7KytU+Az -NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/ -6AcG6TtK2/K+LHuhymiAwZM2qE6VD2odvb+tCzDkZOIeoIz/JcVlNpXE9FuVl250 -9NWvugeghq7tUv81iJ8ninBefJ4lUfxAehTPQqX+zXcfxgjvMRCi/ig73nLyhmjx -r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP -xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L ------END CERTIFICATE----- -` - -const Test_TLSInvalidPEMData = ` -MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL -BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE -BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 -c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda -Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT -YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES -MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5 -NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc -CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u -P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G -ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+ -YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E -Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko -` - -const Test_TLSInvalidSingleCert = ` ------BEGIN CERTIFICATE----- -MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL -BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE -BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 -c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda -Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT -YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES -MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5 -NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc -CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u -P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G -ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+ -YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E -Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko -Ml1L4zCU+xEsMcvb1iQ2n7PZdacqhkFRUVVVmJ56th8aYyX7KNX6M9CD+kMpNm6J -kKC1li/Iy+RI138bAvaFplajMF551kt44dSvIoJIbTr1LigudzWPqk31QaZXV/4u -kD1n4p/XMc9HYU/was/CmQBFqmIZedTLTtK7clkuFN6wbwzdo1wmUNgnySQuMacO -gxhHxxzRWxd24uLyk9Px+9U3BfVPaRLiOPaPoC58lyVOykjSgfpgbus7JS69fCq7 -bEH4Jatp/10zkco+UQIDAQABo1MwUTAdBgNVHQ4EFgQUjXH6PHi92y4C4hQpey86 -r6+x1ewwHwYDVR0jBBgwFoAUjXH6PHi92y4C4hQpey86r6+x1ewwDwYDVR0TAQH/ -BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFE4SdKsX9UsLy+Z0xuHSxhTd0jfn -Iih5mtzb8CDNO5oTw4z0aMeAvpsUvjJ/XjgxnkiRACXh7K9hsG2r+ageRWGevyvx -CaRXFbherV1kTnZw4Y9/pgZTYVWs9jlqFOppz5sStkfjsDQ5lmPJGDii/StENAz2 -XmtiPOgfG9Upb0GAJBCuKnrU9bIcT4L20gd2F4Y14ccyjlf8UiUi192IX6yM9OjT -+TuXwZgqnTOq6piVgr+FTSa24qSvaXb5z/mJDLlk23npecTouLg83TNSn3R6fYQr -d/Y9eXuUJ8U7/qTh2Ulz071AO9KzPOmleYPTx4Xty4xAtWi1QE5NHW9/Ajlv5OtO -OnMNWIs7ssDJBsB7VFC8hcwf79jz7kC0xmQqDfw51Xhhk04kla+v+HZcFW2AO9so -6ZdVHHQnIbJa7yQJKZ+hK49IOoBR6JgdB5kymoplLLiuqZSYTcwSBZ72FYTm3iAr -jzvt1hxpxVDmXvRnkhRrIRhK4QgJL0jRmirBjDY+PYYd7bdRIjN7WNZLFsgplnS8 -9w6CwG32pRlm0c8kkiQ7FXA6BYCqOsDI8f1VGQv331OpR2Ck+FTv+L7DAmg6l37W -+LB9LGh4OAp68ImTjqfoGKG0RBSznwME+r4nXtT1S/qLR6ASWUS4ViWRhbRlNK -XWyb96wrUlv+E8I= ------END CERTIFICATE----- -` - -const Test_TLSValidMultiCert = ` ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL -BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMB4XDTE5MDcwODEzNTUwNVoXDTIwMDcwNzEzNTUw -NVowbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEA3csSO13w7qQXKeSLNcpeuAe6wAjXYbRkRl6ariqzTEDcFTKmy2QiXJTKoEGn -bvwxq0T91var7rxY88SGL/qi8Zmo0tVSR0XvKSKcghFIkQOTyDmVgMPZGCvixt4q -gQ7hUVSk4KkFmtcqBVuvnzI1d/DKfZAGKdmGcfRpuAsnVhac3swP0w4Tl1BFrK9U -vuIkz4KwXG77s5oB8rMUnyuLasLsGNpvpvXhkcQRhp6vpcCO2bS7kOTTelAPIucw -P37qkOEdZdiWCLrr57dmhg6tmcVlmBMg6JtmfLxn2HQd9ZrCKlkWxMk5NYs6CAW5 -kgbDZUWQTAsnHeoJKbcgtPkIbxDRxNpPukFMtbA4VEWv1EkODXy9FyEKDOI/PV6K -/80oLkgCIhCkP2mvwSFheU0RHTuZ0o0vVolP5TEOq5iufnDN4wrxqb12o//XLRc0 -RiLqGVVxhFdyKCjVxcLfII9AAp5Tse4PMh6bf6jDfB3OMvGkhMbJWhKXdR2NUTl0 -esKawMPRXIn5g3oBdNm8kyRsTTnvB567pU8uNSmA8j3jxfGCPynI8JdiwKQuW/+P -WgLIflgxqAfG85dVVOsFmF9o5o24dDslvv9yHnHH102c6ijPCg1EobqlyFzqqxOD -Wf2OPjIkzoTH+O27VRugnY/maIU1nshNO7ViRX5zIxEUtNMCAwEAAaNTMFEwHQYD -VR0OBBYEFNY4gDLgPBidogkmpO8nq5yAq5g+MB8GA1UdIwQYMBaAFNY4gDLgPBid -ogkmpO8nq5yAq5g+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB -AJ0WGioNtGNg3m6ywpmxNThorQD5ZvDMlmZlDVk78E2wfNyMhwbVhKhlAnONv0wv -kmsGjibY75nRZ+EK9PxSJ644841fryQXQ+bli5fhr7DW3uTKwaRsnzETJXRJuljq -6+c6Zyg1/mqwnyx7YvPgVh3w496DYx/jm6Fm1IEq3BzOmn6H/gGPq3gbURzEqI3h -P+kC2vJa8RZWrpa05Xk/Q1QUkErDX9vJghb9z3+GgirISZQzqWRghII/znv3NOE6 -zoIgaaWNFn8KPeBVpUoboH+IhpgibsnbTbI0G7AMtFq6qm3kn/4DZ2N2tuh1G2tT -zR2Fh7hJbU7CrqxANrgnIoHG/nLSvzE24ckLb0Vj69uGQlwnZkn9fz6F7KytU+Az -NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/ -6AcG6TtK2/K+LHuhymiAwZM2qE6VD2odvb+tCzDkZOIeoIz/JcVlNpXE9FuVl250 -9NWvugeghq7tUv81iJ8ninBefJ4lUfxAehTPQqX+zXcfxgjvMRCi/ig73nLyhmjx -r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP -xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL -BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE -BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 -c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda -Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT -YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES -MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5 -NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc -CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u -P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G -ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+ -YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E -Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko -Ml1L4zCU+xEsMcvb1iQ2n7PZdacqhkFRUVVVmJ56th8aYyX7KNX6M9CD+kMpNm6J -kKC1li/Iy+RI138bAvaFplajMF551kt44dSvIoJIbTr1LigudzWPqk31QaZXV/4u -kD1n4p/XMc9HYU/was/CmQBFqmIZedTLTtK7clkuFN6wbwzdo1wmUNgnySQuMacO -gxhHxxzRWxd24uLyk9Px+9U3BfVPaRLiOPaPoC58lyVOykjSgfpgbus7JS69fCq7 -bEH4Jatp/10zkco+UQIDAQABo1MwUTAdBgNVHQ4EFgQUjXH6PHi92y4C4hQpey86 -r6+x1ewwHwYDVR0jBBgwFoAUjXH6PHi92y4C4hQpey86r6+x1ewwDwYDVR0TAQH/ -BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFE4SdKsX9UsLy+Z0xuHSxhTd0jfn -Iih5mtzb8CDNO5oTw4z0aMeAvpsUvjJ/XjgxnkiRACXh7K9hsG2r+ageRWGevyvx -CaRXFbherV1kTnZw4Y9/pgZTYVWs9jlqFOppz5sStkfjsDQ5lmPJGDii/StENAz2 -XmtiPOgfG9Upb0GAJBCuKnrU9bIcT4L20gd2F4Y14ccyjlf8UiUi192IX6yM9OjT -+TuXwZgqnTOq6piVgr+FTSa24qSvaXb5z/mJDLlk23npecTouLg83TNSn3R6fYQr -d/Y9eXuUJ8U7/qTh2Ulz071AO9KzPOmleYPTx4Xty4xAtWi1QE5NHW9/Ajlv5OtO -OnMNWIs7ssDJBsB7VFC8hcwf79jz7kC0xmQqDfw51Xhhk04kla+v+HZcFW2AO9so -6ZdVHHQnIbJa7yQJKZ+hK49IOoBR6JgdB5kymoplLLiuqZSYTcwSBZ72FYTm3iAr -jzvt1hxpxVDmXvRnkhRrIRhK4QgJL0jRmirBjDY+PYYd7bdRIjN7WNZLFsgplnS8 -9w6CwG32pRlm0c8kkiQ7FXA6BYCqOsDI8f1VGQv331OpR2Ck+FTv+L7DAmg6l37W -+LB9LGh4OAp68ImTjqf6ioGKG0RBSznwME+r4nXtT1S/qLR6ASWUS4ViWRhbRlNK -XWyb96wrUlv+E8I= ------END CERTIFICATE----- -` - -// Taken from hack/ssh_known_hosts -const Test_ValidSSHKnownHostsData = ` -# BitBucket -bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== -# GitHub -github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== -# GitLab -gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= -gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf -gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 -# Azure -ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H -vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H -` - -const Test_InvalidSSHKnownHostsData = ` -bitbucket.org AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== -# GitHub -github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== -# GitLab -gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= -gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf -gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 -# Azure -ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H -vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H -` - -func Test_TLSCertificate_ValidPEM_ValidCert(t *testing.T) { - // Valid PEM data, single certificate, expect array of length 1 - certificates, err := ParseTLSCertificatesFromData(Test_TLSValidSingleCert) - assert.Nil(t, err) - assert.Equal(t, len(certificates), 1) - // Expect good decode - x509Cert, err := DecodePEMCertificateToX509(certificates[0]) - assert.Nil(t, err) - assert.Equal(t, x509Cert.Subject.String(), Test_Cert1CN) -} - -func Test_TLSCertificate_ValidPEM_InvalidCert(t *testing.T) { - // Valid PEM data, but invalid certificate - certificates, err := ParseTLSCertificatesFromData(Test_TLSInvalidSingleCert) - assert.Nil(t, err) - assert.Equal(t, len(certificates), 1) - // Expect bad decode - _, err = DecodePEMCertificateToX509(certificates[0]) - assert.NotNil(t, err) -} - -func Test_TLSCertificate_InvalidPEM(t *testing.T) { - // Invalid PEM data, expect array of length 0 - certificates, err := ParseTLSCertificatesFromData(Test_TLSInvalidPEMData) - assert.Nil(t, err) - assert.Equal(t, len(certificates), 0) -} - -func Test_TLSCertificate_ValidPEM_ValidCert_Multi(t *testing.T) { - // Valid PEM data, two certificates, expect array of length 2 - certificates, err := ParseTLSCertificatesFromData(Test_TLSValidMultiCert) - assert.Nil(t, err) - assert.Equal(t, len(certificates), 2) - // Expect good decode - x509Cert, err := DecodePEMCertificateToX509(certificates[0]) - assert.Nil(t, err) - assert.Equal(t, x509Cert.Subject.String(), Test_Cert1CN) - x509Cert, err = DecodePEMCertificateToX509(certificates[1]) - assert.Nil(t, err) - assert.Equal(t, x509Cert.Subject.String(), Test_Cert2CN) -} - -func Test_TLSCertificate_ValidPEM_ValidCert_FromFile(t *testing.T) { - // Valid PEM data, single certificate from file, expect array of length 1 - certificates, err := ParseTLSCertificatesFromPath("./testdata/cert1.pem") - assert.Nil(t, err) - assert.Equal(t, len(certificates), 1) - // Expect good decode - x509Cert, err := DecodePEMCertificateToX509(certificates[0]) - assert.Nil(t, err) - assert.Equal(t, x509Cert.Subject.String(), Test_Cert1CN) -} - -func Test_TLSCertPool(t *testing.T) { - certificates, err := ParseTLSCertificatesFromData(Test_TLSValidMultiCert) - assert.Nil(t, err) - assert.Equal(t, len(certificates), 2) - certPool := GetCertPoolFromPEMData(certificates) - assert.NotNil(t, certPool) -} - -func Test_TLSCertificate_CertFromNonExistingFile(t *testing.T) { - // Non-existing file, expect err - _, err := ParseTLSCertificatesFromPath("../../test/certificates/cert_nonexisting.pem") - assert.NotNil(t, err) -} - -func Test_SSHKnownHostsData_ParseData(t *testing.T) { - // Expect valid data with 7 known host entries - entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) - assert.Nil(t, err) - assert.Equal(t, len(entries), 7) -} - -func Test_SSHKnownHostsData_ParseFile(t *testing.T) { - // Expect valid data with 7 known host entries - entries, err := ParseSSHKnownHostsFromPath("./testdata/ssh_known_hosts") - assert.Nil(t, err) - assert.Equal(t, len(entries), 7) -} - -func Test_SSHKnownHostsData_ParseNonExistingFile(t *testing.T) { - // Expect valid data with 7 known host entries - entries, err := ParseSSHKnownHostsFromPath("../../test/certificates/ssh_known_hosts_invalid") - assert.NotNil(t, err) - assert.Nil(t, entries) -} - -func Test_SSHKnownHostsData_Tokenize(t *testing.T) { - // All entries should parse to valid SSH public keys - // All entries should be tokenizable, and tokens should be feedable to decoder - entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) - assert.Nil(t, err) - for _, entry := range entries { - hosts, _, err := KnownHostsLineToPublicKey(entry) - assert.Nil(t, err) - assert.Equal(t, len(hosts), 1) - hoststring, subtype, certdata, err := TokenizeSSHKnownHostsEntry(entry) - assert.Nil(t, err) - hosts, _, err = TokenizedDataToPublicKey(hoststring, subtype, string(certdata)) - assert.Nil(t, err) - assert.Equal(t, len(hosts), 1) - } -} - -func Test_MatchHostName(t *testing.T) { - matchHostName := "foo.example.com" - assert.Equal(t, MatchHostName(matchHostName, "*"), true) - assert.Equal(t, MatchHostName(matchHostName, "*.example.com"), true) - assert.Equal(t, MatchHostName(matchHostName, "foo.*"), true) - assert.Equal(t, MatchHostName(matchHostName, "foo.*.com"), true) - assert.Equal(t, MatchHostName(matchHostName, "fo?.example.com"), true) - assert.Equal(t, MatchHostName(matchHostName, "foo?.example.com"), false) - assert.Equal(t, MatchHostName(matchHostName, "bar.example.com"), false) - assert.Equal(t, MatchHostName(matchHostName, "*.otherexample.com"), false) - assert.Equal(t, MatchHostName(matchHostName, "foo.otherexample.*"), false) -} - -func Test_SSHFingerprintSHA256(t *testing.T) { - // actual SHA256 fingerprints for keys defined above - fingerprints := [...]string{ - "zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A", - "nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8", - "HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw", - "eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8", - "ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ", - "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", - "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", - } - entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) - assert.Nil(t, err) - assert.Equal(t, len(entries), 7) - for idx, entry := range entries { - _, pubKey, err := KnownHostsLineToPublicKey(entry) - assert.Nil(t, err) - fp := SSHFingerprintSHA256(pubKey) - assert.Equal(t, fp, fingerprints[idx]) - } -} - -func Test_SSHFingerPrintSHA256FromString(t *testing.T) { - // actual SHA256 fingerprints for keys defined above - fingerprints := [...]string{ - "zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A", - "nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8", - "HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw", - "eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8", - "ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ", - "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", - "ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og", - } - entries, err := ParseSSHKnownHostsFromData(Test_ValidSSHKnownHostsData) - assert.Nil(t, err) - assert.Equal(t, len(entries), 7) - for idx, entry := range entries { - fp := SSHFingerprintSHA256FromString(entry) - assert.Equal(t, fp, fingerprints[idx]) - } -} - -func Test_ServerNameWithoutPort(t *testing.T) { - hostNames := map[string]string{ - "localhost": "localhost", - "localhost:9443": "localhost", - "localhost:": "localhost", - "localhost:abc": "localhost", - "localhost.:22": "localhost.", - "foo.example.com:443": "foo.example.com", - "foo.example.com.:443": "foo.example.com.", - } - for inp, res := range hostNames { - assert.Equal(t, res, ServerNameWithoutPort(inp)) - } -} - -func Test_ValidHostnames(t *testing.T) { - hostNames := map[string]bool{ - "localhost": true, - "localhost.localdomain": true, - "foo.example.com": true, - "argocd-server.svc.kubernetes.local": true, - "localhost.": true, - "github.com.": true, - "localhost..": false, - "localhost..localdomain": false, - ".localhost": false, - "local_host": false, - "localhost.local_domain": false, - } - - for hostName, valid := range hostNames { - assert.Equal(t, valid, IsValidHostname(hostName, false)) - } -} - -func Test_ValidFQDNs(t *testing.T) { - hostNames := map[string]bool{ - "localhost": false, - "localhost.localdomain": false, - "foo.example.com.": true, - "argocd-server.svc.kubernetes.local": false, - "localhost.": true, - "github.com.": true, - "localhost..": false, - "localhost..localdomain": false, - "localhost..localdomain.": false, - ".localhost": false, - "local_host": false, - "localhost.local_domain": false, - "localhost.local_domain.": false, - } - - for hostName, valid := range hostNames { - assert.Equal(t, valid, IsValidHostname(hostName, true)) - } -} - -func Test_EscapeBracketPattern(t *testing.T) { - // input: expected output - patternList := map[string]string{ - "foo.bar": "foo.bar", - "[foo.bar]": `\[foo.bar\]`, - "foo[bar]baz": `foo\[bar\]baz`, - `foo\[bar\]baz`: `foo\\[bar\\]baz`, - "foo[[[bar]]]baz": `foo\[\[\[bar\]\]\]baz`, - } - - for original, expected := range patternList { - assert.Equal(t, nonBracketedPattern(original), expected) - } -} diff --git a/util/cert/testdata/cert1.pem b/util/cert/testdata/cert1.pem deleted file mode 100644 index 3959a3f3d..000000000 --- a/util/cert/testdata/cert1.pem +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL -BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMB4XDTE5MDcwODEzNTUwNVoXDTIwMDcwNzEzNTUw -NVowbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv -MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE -AwwPZm9vLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEA3csSO13w7qQXKeSLNcpeuAe6wAjXYbRkRl6ariqzTEDcFTKmy2QiXJTKoEGn -bvwxq0T91var7rxY88SGL/qi8Zmo0tVSR0XvKSKcghFIkQOTyDmVgMPZGCvixt4q -gQ7hUVSk4KkFmtcqBVuvnzI1d/DKfZAGKdmGcfRpuAsnVhac3swP0w4Tl1BFrK9U -vuIkz4KwXG77s5oB8rMUnyuLasLsGNpvpvXhkcQRhp6vpcCO2bS7kOTTelAPIucw -P37qkOEdZdiWCLrr57dmhg6tmcVlmBMg6JtmfLxn2HQd9ZrCKlkWxMk5NYs6CAW5 -kgbDZUWQTAsnHeoJKbcgtPkIbxDRxNpPukFMtbA4VEWv1EkODXy9FyEKDOI/PV6K -/80oLkgCIhCkP2mvwSFheU0RHTuZ0o0vVolP5TEOq5iufnDN4wrxqb12o//XLRc0 -RiLqGVVxhFdyKCjVxcLfII9AAp5Tse4PMh6bf6jDfB3OMvGkhMbJWhKXdR2NUTl0 -esKawMPRXIn5g3oBdNm8kyRsTTnvB567pU8uNSmA8j3jxfGCPynI8JdiwKQuW/+P -WgLIflgxqAfG85dVVOsFmF9o5o24dDslvv9yHnHH102c6ijPCg1EobqlyFzqqxOD -Wf2OPjIkzoTH+O27VRugnY/maIU1nshNO7ViRX5zIxEUtNMCAwEAAaNTMFEwHQYD -VR0OBBYEFNY4gDLgPBidogkmpO8nq5yAq5g+MB8GA1UdIwQYMBaAFNY4gDLgPBid -ogkmpO8nq5yAq5g+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB -AJ0WGioNtGNg3m6ywpmxNThorQD5ZvDMlmZlDVk78E2wfNyMhwbVhKhlAnONv0wv -kmsGjibY75nRZ+EK9PxSJ644841fryQXQ+bli5fhr7DW3uTKwaRsnzETJXRJuljq -6+c6Zyg1/mqwnyx7YvPgVh3w496DYx/jm6Fm1IEq3BzOmn6H/gGPq3gbURzEqI3h -P+kC2vJa8RZWrpa05Xk/Q1QUkErDX9vJghb9z3+GgirISZQzqWRghII/znv3NOE6 -zoIgaaWNFn8KPeBVpUoboH+IhpgibsnbTbI0G7AMtFq6qm3kn/4DZ2N2tuh1G2tT -zR2Fh7hJbU7CrqxANrgnIoHG/nLSvzE24ckLb0Vj69uGQlwnZkn9fz6F7KytU+Az -NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/ -6AcG6TtK2/K+LHuhymiAwZM2qE6VD2odvb+tCzDkZOIeoIz/JcVlNpXE9FuVl250 -9NWvugeghq7tUv81iJ8ninBefJ4lUfxAehTPQqX+zXcfxgjvMRCi/ig73nLyhmjx -r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP -xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L ------END CERTIFICATE----- diff --git a/util/cert/testdata/cert2.pem b/util/cert/testdata/cert2.pem deleted file mode 100644 index ae615e850..000000000 --- a/util/cert/testdata/cert2.pem +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL -BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE -BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 -c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda -Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT -YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES -MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5 -NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc -CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u -P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G -ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+ -YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E -Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko -Ml1L4zCU+xEsMcvb1iQ2n7PZdacqhkFRUVVVmJ56th8aYyX7KNX6M9CD+kMpNm6J -kKC1li/Iy+RI138bAvaFplajMF551kt44dSvIoJIbTr1LigudzWPqk31QaZXV/4u -kD1n4p/XMc9HYU/was/CmQBFqmIZedTLTtK7clkuFN6wbwzdo1wmUNgnySQuMacO -gxhHxxzRWxd24uLyk9Px+9U3BfVPaRLiOPaPoC58lyVOykjSgfpgbus7JS69fCq7 -bEH4Jatp/10zkco+UQIDAQABo1MwUTAdBgNVHQ4EFgQUjXH6PHi92y4C4hQpey86 -r6+x1ewwHwYDVR0jBBgwFoAUjXH6PHi92y4C4hQpey86r6+x1ewwDwYDVR0TAQH/ -BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFE4SdKsX9UsLy+Z0xuHSxhTd0jfn -Iih5mtzb8CDNO5oTw4z0aMeAvpsUvjJ/XjgxnkiRACXh7K9hsG2r+ageRWGevyvx -CaRXFbherV1kTnZw4Y9/pgZTYVWs9jlqFOppz5sStkfjsDQ5lmPJGDii/StENAz2 -XmtiPOgfG9Upb0GAJBCuKnrU9bIcT4L20gd2F4Y14ccyjlf8UiUi192IX6yM9OjT -+TuXwZgqnTOq6piVgr+FTSa24qSvaXb5z/mJDLlk23npecTouLg83TNSn3R6fYQr -d/Y9eXuUJ8U7/qTh2Ulz071AO9KzPOmleYPTx4Xty4xAtWi1QE5NHW9/Ajlv5OtO -OnMNWIs7ssDJBsB7VFC8hcwf79jz7kC0xmQqDfw51Xhhk04kla+v+HZcFW2AO9so -6ZdVHHQnIbJa7yQJKZ+hK49IOoBR6JgdB5kymoplLLiuqZSYTcwSBZ72FYTm3iAr -jzvt1hxpxVDmXvRnkhRrIRhK4QgJL0jRmirBjDY+PYYd7bdRIjN7WNZLFsgplnS8 -9w6CwG32pRlm0c8kkiQ7FXA6BYCqOsDI8f1VGQv331OpR2Ck+FTv+L7DAmg6l37W -+LB9LGh4OAp68ImTjqf6ioGKG0RBSznwME+r4nXtT1S/qLR6ASWUS4ViWRhbRlNK -XWyb96wrUlv+E8I= ------END CERTIFICATE----- diff --git a/util/cert/testdata/ssh_known_hosts b/util/cert/testdata/ssh_known_hosts deleted file mode 100644 index 31a7bae3f..000000000 --- a/util/cert/testdata/ssh_known_hosts +++ /dev/null @@ -1,8 +0,0 @@ -# This file was automatically generated. DO NOT EDIT -bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== -github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== -gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= -gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf -gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 -ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H -vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H diff --git a/util/config/env.go b/util/config/env.go deleted file mode 100644 index 5fdf146cd..000000000 --- a/util/config/env.go +++ /dev/null @@ -1,59 +0,0 @@ -package config - -import ( - "errors" - "os" - "strings" - - "github.com/kballard/go-shellquote" - log "github.com/sirupsen/logrus" -) - -var flags map[string]string - -func init() { - err := loadFlags() - if err != nil { - log.Fatal(err) - } -} - -func loadFlags() error { - flags = make(map[string]string) - - opts, err := shellquote.Split(os.Getenv("ARGOCD_OPTS")) - if err != nil { - return err - } - - var key string - for _, opt := range opts { - if strings.HasPrefix(opt, "--") { - if key != "" { - flags[key] = "true" - } - key = strings.TrimPrefix(opt, "--") - } else if key != "" { - flags[key] = opt - key = "" - } else { - return errors.New("ARGOCD_OPTS invalid at '" + opt + "'") - } - } - if key != "" { - flags[key] = "true" - } - return nil -} - -func GetFlag(key, fallback string) string { - val, ok := flags[key] - if ok { - return val - } - return fallback -} - -func GetBoolFlag(key string) bool { - return GetFlag(key, "false") == "true" -} diff --git a/util/config/env_test.go b/util/config/env_test.go deleted file mode 100644 index 1f784b55d..000000000 --- a/util/config/env_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package config - -import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -func loadOpts(t *testing.T, opts string) { - assert.Nil(t, os.Setenv("ARGOCD_OPTS", opts)) - assert.Nil(t, loadFlags()) -} -func loadInvalidOpts(t *testing.T, opts string) { - assert.Nil(t, os.Setenv("ARGOCD_OPTS", opts)) - assert.Error(t, loadFlags()) -} - -func TestNilOpts(t *testing.T) { - assert.Equal(t, "foo", GetFlag("foo", "foo")) -} - -func TestEmptyOpts(t *testing.T) { - loadOpts(t, "") - - assert.Equal(t, "foo", GetFlag("foo", "foo")) -} - -func TestRubbishOpts(t *testing.T) { - loadInvalidOpts(t, "rubbish") -} - -func TestBoolFlag(t *testing.T) { - loadOpts(t, "--foo") - - assert.True(t, GetBoolFlag("foo")) -} - -func TestBoolFlagAtStart(t *testing.T) { - loadOpts(t, "--foo --bar baz") - - assert.True(t, GetBoolFlag("foo")) -} -func TestBoolFlagInMiddle(t *testing.T) { - loadOpts(t, "--bar baz --foo --qux") - - assert.True(t, GetBoolFlag("foo")) -} - -func TestBooleanFlagAtEnd(t *testing.T) { - loadOpts(t, "--bar baz --foo") - - assert.True(t, GetBoolFlag("foo")) -} - -func TestFlagAtStart(t *testing.T) { - loadOpts(t, "--foo bar") - - assert.Equal(t, "bar", GetFlag("foo", "")) -} - -func TestFlagInTheMiddle(t *testing.T) { - loadOpts(t, "--baz --foo bar --qux") - - assert.Equal(t, "bar", GetFlag("foo", "")) -} - -func TestFlagAtTheEnd(t *testing.T) { - loadOpts(t, "--baz --foo bar") - - assert.Equal(t, "bar", GetFlag("foo", "")) -} - -func TestFlagWithSingleQuotes(t *testing.T) { - loadOpts(t, "--foo 'bar baz'") - - assert.Equal(t, "bar baz", GetFlag("foo", "")) -} -func TestFlagWithDoubleQuotes(t *testing.T) { - loadOpts(t, "--foo \"bar baz\"") - - assert.Equal(t, "bar baz", GetFlag("foo", "")) -} diff --git a/util/config/exec.go b/util/config/exec.go deleted file mode 100644 index 1a5b31613..000000000 --- a/util/config/exec.go +++ /dev/null @@ -1,26 +0,0 @@ -package config - -import ( - "os" - "time" - - "github.com/argoproj/pkg/exec" -) - -var timeout time.Duration - -func init() { - initTimeout() -} - -func initTimeout() { - var err error - timeout, err = time.ParseDuration(os.Getenv("ARGOCD_EXEC_TIMEOUT")) - if err != nil { - timeout = 90 * time.Second - } -} - -func CmdOpts() exec.CmdOpts { - return exec.CmdOpts{Timeout: timeout} -} diff --git a/util/config/exec_test.go b/util/config/exec_test.go deleted file mode 100644 index a34f5a412..000000000 --- a/util/config/exec_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package config - -import ( - "os" - "testing" - "time" - - "github.com/argoproj/pkg/exec" - "github.com/stretchr/testify/assert" -) - -func Test_timeout(t *testing.T) { - defer func() { _ = os.Unsetenv("ARGOCD_EXEC_TIMEOUT") }() - tests := []struct { - name string - text string - want time.Duration - }{ - {"Default", "", 90 * time.Second}, - {"OneSecond", "1s", 1 * time.Second}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - _ = os.Setenv("ARGOCD_EXEC_TIMEOUT", tt.text) - initTimeout() - assert.Equal(t, tt.want, timeout) - }) - } -} - -func TestCmdOpts(t *testing.T) { - initTimeout() - assert.Equal(t, exec.CmdOpts{Timeout: 90 * time.Second}, CmdOpts()) -} diff --git a/util/config/reader.go b/util/config/reader.go deleted file mode 100644 index 7d4f93fe9..000000000 --- a/util/config/reader.go +++ /dev/null @@ -1,84 +0,0 @@ -package config - -import ( - "encoding/json" - "io" - "io/ioutil" - "net/http" - - "github.com/ghodss/yaml" -) - -// UnmarshalReader is used to read manifests from stdin -func UnmarshalReader(reader io.Reader, obj interface{}) error { - data, err := ioutil.ReadAll(reader) - if err != nil { - return err - } - return unmarshalObject(data, obj) -} - -// unmarshalObject tries to convert a YAML or JSON byte array into the provided type. -func unmarshalObject(data []byte, obj interface{}) error { - // first, try unmarshaling as JSON - // Based on technique from Kubectl, which supports both YAML and JSON: - // https://mlafeldt.github.io/blog/teaching-go-programs-to-love-json-and-yaml/ - // http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/ - // Short version: JSON unmarshaling won't zero out null fields; YAML unmarshaling will. - // This may have unintended effects or hard-to-catch issues when populating our application object. - jsonData, err := yaml.YAMLToJSON(data) - if err != nil { - return err - } - - err = json.Unmarshal(jsonData, &obj) - if err != nil { - return err - } - - return err -} - -// MarshalLocalYAMLFile writes JSON or YAML to a file on disk. -// The caller is responsible for checking error return values. -func MarshalLocalYAMLFile(path string, obj interface{}) error { - yamlData, err := yaml.Marshal(obj) - if err == nil { - err = ioutil.WriteFile(path, yamlData, 0600) - } - return err -} - -// UnmarshalLocalFile retrieves JSON or YAML from a file on disk. -// The caller is responsible for checking error return values. -func UnmarshalLocalFile(path string, obj interface{}) error { - data, err := ioutil.ReadFile(path) - if err == nil { - err = unmarshalObject(data, obj) - } - return err -} - -// UnmarshalRemoteFile retrieves JSON or YAML through a GET request. -// The caller is responsible for checking error return values. -func UnmarshalRemoteFile(url string, obj interface{}) error { - data, err := ReadRemoteFile(url) - if err == nil { - err = unmarshalObject(data, obj) - } - return err -} - -// ReadRemoteFile issues a GET request to retrieve the contents of the specified URL as a byte array. -// The caller is responsible for checking error return values. -func ReadRemoteFile(url string) ([]byte, error) { - var data []byte - resp, err := http.Get(url) - if err == nil { - defer func() { - _ = resp.Body.Close() - }() - data, err = ioutil.ReadAll(resp.Body) - } - return data, err -} diff --git a/util/config/reader_test.go b/util/config/reader_test.go deleted file mode 100644 index 90779891e..000000000 --- a/util/config/reader_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package config - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestUnmarshalLocalFile(t *testing.T) { - const ( - field1 = "Hello, world!" - field2 = 42 - ) - sentinel := fmt.Sprintf("---\nfield1: %q\nfield2: %d", field1, field2) - - file, err := ioutil.TempFile(os.TempDir(), "") - if err != nil { - panic(err) - } - defer func() { - _ = os.Remove(file.Name()) - }() - - _, _ = file.WriteString(sentinel) - _ = file.Sync() - - var testStruct struct { - Field1 string - Field2 int - } - err = UnmarshalLocalFile(file.Name(), &testStruct) - if err != nil { - t.Errorf("Could not unmarshal test data: %s", err) - } - - if testStruct.Field1 != field1 || testStruct.Field2 != field2 { - t.Errorf("Test data did not match! Expected {%s %d} but got: %v", field1, field2, testStruct) - } -} - -func TestUnmarshalRemoteFile(t *testing.T) { - const ( - field1 = "Hello, world!" - field2 = 42 - ) - sentinel := fmt.Sprintf("---\nfield1: %q\nfield2: %d", field1, field2) - - serve := func(c chan<- string) { - // listen on first available dynamic (unprivileged) port - listener, err := net.Listen("tcp", ":0") - if err != nil { - panic(err) - } - - // send back the address so that it can be used - c <- listener.Addr().String() - - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // return the sentinel text at root URL - fmt.Fprint(w, sentinel) - }) - - panic(http.Serve(listener, nil)) - } - - c := make(chan string, 1) - - // run a local webserver to test data retrieval - go serve(c) - - address := <-c - t.Logf("Listening at address: %s", address) - - data, err := ReadRemoteFile("http://" + address) - if string(data) != sentinel { - t.Errorf("Test data did not match (err = %v)! Expected %q and received %q", err, sentinel, string(data)) - } - - var testStruct struct { - Field1 string - Field2 int - } - err = UnmarshalRemoteFile("http://"+address, &testStruct) - if err != nil { - t.Errorf("Could not unmarshal test data: %s", err) - } - - if testStruct.Field1 != field1 || testStruct.Field2 != field2 { - t.Errorf("Test data did not match! Expected {%s %d} but got: %v", field1, field2, testStruct) - } -} - -func TestUnmarshalReader(t *testing.T) { - type testStruct struct { - value string - } - value := "test-reader" - instance := testStruct{value} - data, err := json.Marshal(instance) - assert.NoError(t, err) - var reader io.Reader = bytes.NewReader(data) - err = UnmarshalReader(reader, &instance) - assert.NoError(t, err) - assert.Equal(t, value, instance.value) -} diff --git a/util/git/client.go b/util/git/client.go deleted file mode 100644 index a38aa680a..000000000 --- a/util/git/client.go +++ /dev/null @@ -1,478 +0,0 @@ -package git - -import ( - "crypto/tls" - "fmt" - "math" - "net/http" - "net/url" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "time" - - argoexec "github.com/argoproj/pkg/exec" - log "github.com/sirupsen/logrus" - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/knownhosts" - "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/config" - "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/plumbing/transport" - githttp "gopkg.in/src-d/go-git.v4/plumbing/transport/http" - ssh2 "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh" - "gopkg.in/src-d/go-git.v4/storage/memory" - - "github.com/argoproj/argo-cd/engine/common" - certutil "github.com/argoproj/argo-cd/engine/util/cert" - argoconfig "github.com/argoproj/argo-cd/engine/util/config" -) - -type RevisionMetadata struct { - Author string - Date time.Time - Tags []string - Message string -} - -// Client is a generic git client interface -type Client interface { - Root() string - Init() error - Fetch() error - Checkout(revision string) error - LsRemote(revision string) (string, error) - LsFiles(path string) ([]string, error) - LsLargeFiles() ([]string, error) - CommitSHA() (string, error) - RevisionMetadata(revision string) (*RevisionMetadata, error) -} - -// nativeGitClient implements Client interface using git CLI -type nativeGitClient struct { - // URL of the repository - repoURL string - // Root path of repository - root string - // Authenticator credentials for private repositories - creds Creds - // Whether to connect insecurely to repository, e.g. don't verify certificate - insecure bool - // Whether the repository is LFS enabled - enableLfs bool -} - -var ( - maxAttemptsCount = 1 -) - -func init() { - if countStr := os.Getenv(common.EnvGitAttemptsCount); countStr != "" { - if cnt, err := strconv.Atoi(countStr); err != nil { - panic(fmt.Sprintf("Invalid value in %s env variable: %v", common.EnvGitAttemptsCount, err)) - } else { - maxAttemptsCount = int(math.Max(float64(cnt), 1)) - } - } -} - -func NewClient(rawRepoURL string, creds Creds, insecure bool, enableLfs bool) (Client, error) { - root := filepath.Join(os.TempDir(), strings.Replace(NormalizeGitURL(rawRepoURL), "/", "_", -1)) - return NewClientExt(rawRepoURL, root, creds, insecure, enableLfs) -} - -func NewClientExt(rawRepoURL string, root string, creds Creds, insecure bool, enableLfs bool) (Client, error) { - client := nativeGitClient{ - repoURL: rawRepoURL, - root: root, - creds: creds, - insecure: insecure, - enableLfs: enableLfs, - } - return &client, nil -} - -// Returns a HTTP client object suitable for go-git to use using the following -// pattern: -// - If insecure is true, always returns a client with certificate verification -// turned off. -// - If one or more custom certificates are stored for the repository, returns -// a client with those certificates in the list of root CAs used to verify -// the server's certificate. -// - 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{ - // 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. - clientCertFunc := func(req *tls.CertificateRequestInfo) (*tls.Certificate, error) { - var err error - cert := tls.Certificate{} - - // If we aren't called with HTTPSCreds, then we just return an empty cert - httpsCreds, ok := creds.(HTTPSCreds) - if !ok { - return &cert, nil - } - - // If the creds contain client certificate data, we return a TLS.Certificate - // populated with the cert and its key. - if httpsCreds.clientCertData != "" && httpsCreds.clientCertKey != "" { - cert, err = tls.X509KeyPair([]byte(httpsCreds.clientCertData), []byte(httpsCreds.clientCertKey)) - if err != nil { - log.Errorf("Could not load Client Certificate: %v", err) - return &cert, nil - } - } - - return &cert, nil - } - - if insecure { - customHTTPClient.Transport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - GetClientCertificate: clientCertFunc, - }, - } - } else { - parsedURL, err := url.Parse(repoURL) - if err != nil { - return customHTTPClient - } - serverCertificatePem, err := certutil.GetCertificateForConnect(parsedURL.Host) - if err != nil { - return customHTTPClient - } else if len(serverCertificatePem) > 0 { - certPool := certutil.GetCertPoolFromPEMData(serverCertificatePem) - customHTTPClient.Transport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - RootCAs: certPool, - GetClientCertificate: clientCertFunc, - }, - } - } else { - // else no custom certificate stored. - customHTTPClient.Transport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - GetClientCertificate: clientCertFunc, - }, - } - } - } - - return customHTTPClient -} - -func newAuth(repoURL string, creds Creds) (transport.AuthMethod, error) { - switch creds := creds.(type) { - case SSHCreds: - var sshUser string - if isSSH, user := IsSSHURL(repoURL); isSSH { - sshUser = user - } - signer, err := ssh.ParsePrivateKey([]byte(creds.sshPrivateKey)) - if err != nil { - return nil, err - } - auth := &ssh2.PublicKeys{User: sshUser, Signer: signer} - if creds.insecure { - auth.HostKeyCallback = ssh.InsecureIgnoreHostKey() - } else { - // Set up validation of SSH known hosts for using our ssh_known_hosts - // file. - auth.HostKeyCallback, err = knownhosts.New(certutil.GetSSHKnownHostsDataPath()) - if err != nil { - log.Errorf("Could not set-up SSH known hosts callback: %v", err) - } - } - return auth, nil - case HTTPSCreds: - auth := githttp.BasicAuth{Username: creds.username, Password: creds.password} - return &auth, nil - } - return nil, nil -} - -func (m *nativeGitClient) Root() string { - return m.root -} - -// Init initializes a local git repository and sets the remote origin -func (m *nativeGitClient) Init() error { - _, err := git.PlainOpen(m.root) - if err == nil { - return nil - } - if err != git.ErrRepositoryNotExists { - return err - } - log.Infof("Initializing %s to %s", m.repoURL, m.root) - _, err = argoexec.RunCommand("rm", argoconfig.CmdOpts(), "-rf", m.root) - if err != nil { - return fmt.Errorf("unable to clean repo at %s: %v", m.root, err) - } - err = os.MkdirAll(m.root, 0755) - if err != nil { - return err - } - repo, err := git.PlainInit(m.root, false) - if err != nil { - return err - } - _, err = repo.CreateRemote(&config.RemoteConfig{ - Name: git.DefaultRemoteName, - URLs: []string{m.repoURL}, - }) - return err -} - -// Returns true if the repository is LFS enabled -func (m *nativeGitClient) IsLFSEnabled() bool { - return m.enableLfs -} - -// Fetch fetches latest updates from origin -func (m *nativeGitClient) Fetch() error { - _, err := m.runCredentialedCmd("git", "fetch", "origin", "--tags", "--force") - // When we have LFS support enabled, check for large files and fetch them too. - if err == nil && m.IsLFSEnabled() { - largeFiles, err := m.LsLargeFiles() - if err == nil && len(largeFiles) > 0 { - _, err = m.runCredentialedCmd("git", "lfs", "fetch", "--all") - if err != nil { - return err - } - } - } - return err -} - -// LsFiles lists the local working tree, including only files that are under source control -func (m *nativeGitClient) LsFiles(path string) ([]string, error) { - out, err := m.runCmd("ls-files", "--full-name", "-z", "--", path) - if err != nil { - return nil, err - } - // remove last element, which is blank regardless of whether we're using nullbyte or newline - ss := strings.Split(out, "\000") - return ss[:len(ss)-1], nil -} - -// LsLargeFiles lists all files that have references to LFS storage -func (m *nativeGitClient) LsLargeFiles() ([]string, error) { - out, err := m.runCmd("lfs", "ls-files", "-n") - if err != nil { - return nil, err - } - ss := strings.Split(out, "\n") - return ss, nil -} - -// Checkout checkout specified git sha -func (m *nativeGitClient) Checkout(revision string) error { - if revision == "" || revision == "HEAD" { - revision = "origin/HEAD" - } - if _, err := m.runCmd("checkout", "--force", revision); err != nil { - return err - } - // We must populate LFS content by using lfs checkout, if we have at least - // one LFS reference in the current revision. - if m.IsLFSEnabled() { - if largeFiles, err := m.LsLargeFiles(); err == nil { - if len(largeFiles) > 0 { - if _, err := m.runCmd("lfs", "checkout"); err != nil { - return err - } - } - } else { - return err - } - } - if _, err := m.runCmd("clean", "-fdx"); err != nil { - return err - } - return nil -} - -// LsRemote resolves the commit SHA of a specific branch, tag, or HEAD. If the supplied revision -// does not resolve, and "looks" like a 7+ hexadecimal commit SHA, it return the revision string. -// Otherwise, it returns an error indicating that the revision could not be resolved. This method -// runs with in-memory storage and is safe to run concurrently, or to be run without a git -// repository locally cloned. -func (m *nativeGitClient) LsRemote(revision string) (res string, err error) { - for attempt := 0; attempt < maxAttemptsCount; attempt++ { - if res, err = m.lsRemote(revision); err == nil { - return - } - } - return -} - -func (m *nativeGitClient) lsRemote(revision string) (string, error) { - if IsCommitSHA(revision) { - return revision, nil - } - repo, err := git.Init(memory.NewStorage(), nil) - if err != nil { - return "", err - } - remote, err := repo.CreateRemote(&config.RemoteConfig{ - Name: git.DefaultRemoteName, - URLs: []string{m.repoURL}, - }) - if err != nil { - return "", err - } - auth, err := newAuth(m.repoURL, m.creds) - if err != nil { - return "", err - } - //refs, err := remote.List(&git.ListOptions{Auth: auth}) - refs, err := listRemote(remote, &git.ListOptions{Auth: auth}, m.insecure, m.creds) - if err != nil { - return "", err - } - if revision == "" { - revision = "HEAD" - } - // refToHash keeps a maps of remote refs to their hash - // (e.g. refs/heads/master -> a67038ae2e9cb9b9b16423702f98b41e36601001) - refToHash := make(map[string]string) - // refToResolve remembers ref name of the supplied revision if we determine the revision is a - // symbolic reference (like HEAD), in which case we will resolve it from the refToHash map - refToResolve := "" - for _, ref := range refs { - refName := ref.Name().String() - if refName != "HEAD" && !strings.HasPrefix(refName, "refs/heads/") && !strings.HasPrefix(refName, "refs/tags/") { - // ignore things like 'refs/pull/' 'refs/reviewable' - continue - } - hash := ref.Hash().String() - if ref.Type() == plumbing.HashReference { - refToHash[refName] = hash - } - //log.Debugf("%s\t%s", hash, refName) - if ref.Name().Short() == revision { - if ref.Type() == plumbing.HashReference { - log.Debugf("revision '%s' resolved to '%s'", revision, hash) - return hash, nil - } - if ref.Type() == plumbing.SymbolicReference { - refToResolve = ref.Target().String() - } - } - } - if refToResolve != "" { - // If refToResolve is non-empty, we are resolving symbolic reference (e.g. HEAD). - // It should exist in our refToHash map - if hash, ok := refToHash[refToResolve]; ok { - log.Debugf("symbolic reference '%s' (%s) resolved to '%s'", revision, refToResolve, hash) - return hash, nil - } - } - // We support the ability to use a truncated commit-SHA (e.g. first 7 characters of a SHA) - if IsTruncatedCommitSHA(revision) { - log.Debugf("revision '%s' assumed to be commit sha", revision) - return revision, nil - } - // If we get here, revision string had non hexadecimal characters (indicating its a branch, tag, - // or symbolic ref) and we were unable to resolve it to a commit SHA. - return "", fmt.Errorf("Unable to resolve '%s' to a commit SHA", revision) -} - -// CommitSHA returns current commit sha from `git rev-parse HEAD` -func (m *nativeGitClient) CommitSHA() (string, error) { - out, err := m.runCmd("rev-parse", "HEAD") - if err != nil { - return "", err - } - return strings.TrimSpace(out), nil -} - -// returns the meta-data for the commit -func (m *nativeGitClient) RevisionMetadata(revision string) (*RevisionMetadata, error) { - out, err := m.runCmd("show", "-s", "--format=%an <%ae>|%at|%B", revision) - if err != nil { - return nil, err - } - segments := strings.SplitN(out, "|", 3) - if len(segments) != 3 { - return nil, fmt.Errorf("expected 3 segments, got %v", segments) - } - author := segments[0] - authorDateUnixTimestamp, _ := strconv.ParseInt(segments[1], 10, 64) - message := strings.TrimSpace(segments[2]) - - out, err = m.runCmd("tag", "--points-at", revision) - if err != nil { - return nil, err - } - tags := strings.Fields(out) - - return &RevisionMetadata{author, time.Unix(authorDateUnixTimestamp, 0), tags, message}, nil -} - -// runCmd is a convenience function to run a command in a given directory and return its output -func (m *nativeGitClient) runCmd(args ...string) (string, error) { - cmd := exec.Command("git", args...) - return m.runCmdOutput(cmd) -} - -// runCredentialedCmd is a convenience function to run a git command with username/password credentials -func (m *nativeGitClient) runCredentialedCmd(command string, args ...string) (string, error) { - cmd := exec.Command(command, args...) - closer, environ, err := m.creds.Environ() - if err != nil { - return "", err - } - defer func() { _ = closer.Close() }() - cmd.Env = append(cmd.Env, environ...) - return m.runCmdOutput(cmd) -} - -func (m *nativeGitClient) runCmdOutput(cmd *exec.Cmd) (string, error) { - cmd.Dir = m.root - cmd.Env = append(cmd.Env, os.Environ()...) - // Set $HOME to nowhere, so we can be execute Git regardless of any external - // authentication keys (e.g. in ~/.ssh) -- this is especially important for - // running tests on local machines and/or CircleCI. - cmd.Env = append(cmd.Env, "HOME=/dev/null") - // Skip LFS for most Git operations except when explicitly requested - cmd.Env = append(cmd.Env, "GIT_LFS_SKIP_SMUDGE=1") - - // For HTTPS repositories, we need to consider insecure repositories as well - // as custom CA bundles from the cert database. - if IsHTTPSURL(m.repoURL) { - if m.insecure { - cmd.Env = append(cmd.Env, "GIT_SSL_NO_VERIFY=true") - } else { - parsedURL, err := url.Parse(m.repoURL) - // We don't fail if we cannot parse the URL, but log a warning in that - // case. And we execute the command in a verbatim way. - if err != nil { - log.Warnf("runCmdOutput: Could not parse repo URL '%s'", m.repoURL) - } else { - caPath, err := certutil.GetCertBundlePathForRepository(parsedURL.Host) - if err == nil && caPath != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_SSL_CAINFO=%s", caPath)) - } - } - } - } - return argoexec.RunCommandExt(cmd, argoconfig.CmdOpts()) -} diff --git a/util/git/creds.go b/util/git/creds.go deleted file mode 100644 index 18df5ea85..000000000 --- a/util/git/creds.go +++ /dev/null @@ -1,182 +0,0 @@ -package git - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "strings" - - "github.com/argoproj/argo-cd/engine/util/misc" - - log "github.com/sirupsen/logrus" - - certutil "github.com/argoproj/argo-cd/engine/util/cert" -) - -type Creds interface { - Environ() (io.Closer, []string, error) -} - -// nop implementation -type NopCloser struct { -} - -func (c NopCloser) Close() error { - return nil -} - -type NopCreds struct { -} - -func (c NopCreds) Environ() (io.Closer, []string, error) { - return NopCloser{}, nil, nil -} - -// HTTPS creds implementation -type HTTPSCreds struct { - // Username for authentication - username string - // Password for authentication - password string - // Whether to ignore invalid server certificates - insecure bool - // Client certificate to use - clientCertData string - // Client certificate key to use - clientCertKey string -} - -func NewHTTPSCreds(username string, password string, clientCertData string, clientCertKey string, insecure bool) HTTPSCreds { - return HTTPSCreds{ - username, - password, - insecure, - clientCertData, - clientCertKey, - } -} - -// Get additional required environment variables for executing git client to -// access specific repository via HTTPS. -func (c HTTPSCreds) Environ() (io.Closer, []string, error) { - env := []string{fmt.Sprintf("GIT_ASKPASS=%s", "git-ask-pass.sh"), fmt.Sprintf("GIT_USERNAME=%s", c.username), fmt.Sprintf("GIT_PASSWORD=%s", c.password)} - httpCloser := authFilePaths(make([]string, 0)) - - // GIT_SSL_NO_VERIFY is used to tell git not to validate the server's cert at - // all. - if c.insecure { - env = append(env, "GIT_SSL_NO_VERIFY=true") - } - - // In case the repo is configured for using a TLS client cert, we need to make - // sure git client will use it. The certificate's key must not be password - // protected. - if c.clientCertData != "" && c.clientCertKey != "" { - var certFile, keyFile *os.File - - // We need to actually create two temp files, one for storing cert data and - // another for storing the key. If we fail to create second fail, the first - // must be removed. - certFile, err := ioutil.TempFile(misc.TempDir, "") - if err == nil { - defer certFile.Close() - keyFile, err = ioutil.TempFile(misc.TempDir, "") - if err != nil { - removeErr := os.Remove(certFile.Name()) - if removeErr != nil { - log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr) - } - return NopCloser{}, nil, err - } - defer keyFile.Close() - } else { - return NopCloser{}, nil, err - } - - // We should have both temp files by now - httpCloser = authFilePaths([]string{certFile.Name(), keyFile.Name()}) - - _, err = certFile.WriteString(c.clientCertData) - if err != nil { - httpCloser.Close() - return NopCloser{}, nil, err - } - // GIT_SSL_CERT is the full path to a client certificate to be used - env = append(env, fmt.Sprintf("GIT_SSL_CERT=%s", certFile.Name())) - - _, err = keyFile.WriteString(c.clientCertKey) - if err != nil { - httpCloser.Close() - return NopCloser{}, nil, err - } - // GIT_SSL_KEY is the full path to a client certificate's key to be used - env = append(env, fmt.Sprintf("GIT_SSL_KEY=%s", keyFile.Name())) - - } - return httpCloser, env, nil -} - -// SSH implementation -type SSHCreds struct { - sshPrivateKey string - caPath string - insecure bool -} - -func NewSSHCreds(sshPrivateKey string, caPath string, insecureIgnoreHostKey bool) SSHCreds { - return SSHCreds{sshPrivateKey, caPath, insecureIgnoreHostKey} -} - -type sshPrivateKeyFile string - -type authFilePaths []string - -func (f sshPrivateKeyFile) Close() error { - return os.Remove(string(f)) -} - -// Remove a list of files that have been created as temp files while creating -// HTTPCreds object above. -func (f authFilePaths) Close() error { - var retErr error = nil - for _, path := range f { - err := os.Remove(path) - if err != nil { - log.Errorf("HTTPSCreds.Close(): Could not remove temp file %s: %v", path, err) - retErr = err - } - } - return retErr -} - -func (c SSHCreds) Environ() (io.Closer, []string, error) { - // use the SHM temp dir from util, more secure - file, err := ioutil.TempFile(misc.TempDir, "") - if err != nil { - return nil, nil, err - } - defer file.Close() - - _, err = file.WriteString(c.sshPrivateKey) - if err != nil { - return nil, nil, err - } - - args := []string{"ssh", "-i", file.Name()} - var env []string - if c.caPath != "" { - env = append(env, fmt.Sprintf("GIT_SSL_CAINFO=%s", c.caPath)) - } - if c.insecure { - log.Warn("temporarily disabling strict host key checking (i.e. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'), please don't use in production") - // StrictHostKeyChecking will add the host to the knownhosts file, we don't want that - a security issue really, - // UserKnownHostsFile=/dev/null is therefore used so we write the new insecure host to /dev/null - args = append(args, "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null") - } else { - knownHostsFile := certutil.GetSSHKnownHostsDataPath() - args = append(args, "-o", "StrictHostKeyChecking=yes", "-o", fmt.Sprintf("UserKnownHostsFile=%s", knownHostsFile)) - } - env = append(env, []string{fmt.Sprintf("GIT_SSH_COMMAND=%s", strings.Join(args, " "))}...) - return sshPrivateKeyFile(file.Name()), env, nil -} diff --git a/util/git/git.go b/util/git/git.go deleted file mode 100644 index 7c2287e5b..000000000 --- a/util/git/git.go +++ /dev/null @@ -1,88 +0,0 @@ -package git - -import ( - "net/url" - "regexp" - "strings" -) - -// EnsurePrefix idempotently ensures that a base string has a given prefix. -func ensurePrefix(s, prefix string) string { - if !strings.HasPrefix(s, prefix) { - s = prefix + s - } - return s -} - -// removeSuffix idempotently removes a given suffix -func removeSuffix(s, suffix string) string { - if strings.HasSuffix(s, suffix) { - return s[0 : len(s)-len(suffix)] - } - return s -} - -var ( - commitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{40}$") - sshURLRegex = regexp.MustCompile("^(ssh://)?([^/@:]*?)@.*") - httpsURLRegex = regexp.MustCompile("^(https://).*") -) - -// IsCommitSHA returns whether or not a string is a 40 character SHA-1 -func IsCommitSHA(sha string) bool { - return commitSHARegex.MatchString(sha) -} - -var truncatedCommitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{7,}$") - -// IsTruncatedCommitSHA returns whether or not a string is a truncated SHA-1 -func IsTruncatedCommitSHA(sha string) bool { - return truncatedCommitSHARegex.MatchString(sha) -} - -// SameURL returns whether or not the two repository URLs are equivalent in location -func SameURL(leftRepo, rightRepo string) bool { - return NormalizeGitURL(leftRepo) == NormalizeGitURL(rightRepo) -} - -// NormalizeGitURL normalizes a git URL for purposes of comparison, as well as preventing redundant -// local clones (by normalizing various forms of a URL to a consistent location). -// Prefer using SameURL() over this function when possible. This algorithm may change over time -// and should not be considered stable from release to release -func NormalizeGitURL(repo string) string { - repo = strings.ToLower(strings.TrimSpace(repo)) - if yes, _ := IsSSHURL(repo); yes { - repo = ensurePrefix(repo, "ssh://") - } - repo = removeSuffix(repo, ".git") - repoURL, err := url.Parse(repo) - if err != nil { - return "" - } - normalized := repoURL.String() - return strings.TrimPrefix(normalized, "ssh://") -} - -// IsSSHURL returns true if supplied URL is SSH URL -func IsSSHURL(url string) (bool, string) { - matches := sshURLRegex.FindStringSubmatch(url) - if len(matches) > 2 { - return true, matches[2] - } - return false, "" -} - -// IsHTTPSURL returns true if supplied URL is HTTPS URL -func IsHTTPSURL(url string) bool { - return httpsURLRegex.MatchString(url) -} - -// TestRepo tests if a repo exists and is accessible with the given credentials -func TestRepo(repo string, creds Creds, insecure bool, enableLfs bool) error { - clnt, err := NewClient(repo, creds, insecure, enableLfs) - if err != nil { - return err - } - _, err = clnt.LsRemote("HEAD") - return err -} diff --git a/util/git/git_test.go b/util/git/git_test.go deleted file mode 100644 index 5b4045591..000000000 --- a/util/git/git_test.go +++ /dev/null @@ -1,312 +0,0 @@ -package git - -import ( - "fmt" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/argoproj/argo-cd/test/fixture/log" - "github.com/argoproj/argo-cd/test/fixture/path" - "github.com/argoproj/argo-cd/test/fixture/test" -) - -func TestIsCommitSHA(t *testing.T) { - assert.True(t, IsCommitSHA("9d921f65f3c5373b682e2eb4b37afba6592e8f8b")) - assert.True(t, IsCommitSHA("9D921F65F3C5373B682E2EB4B37AFBA6592E8F8B")) - assert.False(t, IsCommitSHA("gd921f65f3c5373b682e2eb4b37afba6592e8f8b")) - assert.False(t, IsCommitSHA("master")) - assert.False(t, IsCommitSHA("HEAD")) - assert.False(t, IsCommitSHA("9d921f6")) // only consider 40 characters hex strings as a commit-sha - assert.True(t, IsTruncatedCommitSHA("9d921f6")) - assert.False(t, IsTruncatedCommitSHA("9d921f")) // we only consider 7+ characters - assert.False(t, IsTruncatedCommitSHA("branch-name")) -} - -func TestEnsurePrefix(t *testing.T) { - data := [][]string{ - {"world", "hello", "helloworld"}, - {"helloworld", "hello", "helloworld"}, - {"example.com", "https://", "https://example.com"}, - {"https://example.com", "https://", "https://example.com"}, - {"cd", "argo", "argocd"}, - {"argocd", "argo", "argocd"}, - {"", "argocd", "argocd"}, - {"argocd", "", "argocd"}, - } - for _, table := range data { - result := ensurePrefix(table[0], table[1]) - assert.Equal(t, table[2], result) - } -} - -func TestRemoveSuffix(t *testing.T) { - data := [][]string{ - {"hello.git", ".git", "hello"}, - {"hello", ".git", "hello"}, - {".git", ".git", ""}, - } - for _, table := range data { - result := removeSuffix(table[0], table[1]) - assert.Equal(t, table[2], result) - } -} - -func TestIsSSHURL(t *testing.T) { - data := map[string]bool{ - "git://github.com/argoproj/test.git": false, - "git@GITHUB.com:argoproj/test.git": true, - "git@github.com:test": true, - "git@github.com:test.git": true, - "https://github.com/argoproj/test": false, - "https://github.com/argoproj/test.git": false, - "ssh://git@GITHUB.com:argoproj/test": true, - "ssh://git@GITHUB.com:argoproj/test.git": true, - "ssh://git@github.com:test.git": true, - } - for k, v := range data { - isSSH, _ := IsSSHURL(k) - assert.Equal(t, v, isSSH) - } -} - -func TestIsSSHURLUserName(t *testing.T) { - isSSH, user := IsSSHURL("ssh://john@john-server.org:29418/project") - assert.True(t, isSSH) - assert.Equal(t, "john", user) - - isSSH, user = IsSSHURL("john@john-server.org:29418/project") - assert.True(t, isSSH) - assert.Equal(t, "john", user) -} - -func TestSameURL(t *testing.T) { - data := map[string]string{ - "git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git", - "git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git", - "git@GITHUB.com:test": "git@github.com:test.git", - "git@GITHUB.com:test.git": "git@github.com:test.git", - "https://GITHUB.com/argoproj/test": "https://github.com/argoproj/test.git", - "https://GITHUB.com/argoproj/test.git": "https://github.com/argoproj/test.git", - "https://github.com/FOO": "https://github.com/foo", - "https://github.com/TEST": "https://github.com/TEST.git", - "https://github.com/TEST.git": "https://github.com/TEST.git", - "ssh://git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git", - "ssh://git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git", - "ssh://git@GITHUB.com:test.git": "git@github.com:test.git", - "ssh://git@github.com:test": "git@github.com:test.git", - " https://github.com/argoproj/test ": "https://github.com/argoproj/test.git", - "\thttps://github.com/argoproj/test\n": "https://github.com/argoproj/test.git", - "https://1234.visualstudio.com/myproj/_git/myrepo": "https://1234.visualstudio.com/myproj/_git/myrepo", - "https://dev.azure.com/1234/myproj/_git/myrepo": "https://dev.azure.com/1234/myproj/_git/myrepo", - } - for k, v := range data { - assert.True(t, SameURL(k, v)) - } -} - -func TestCustomHTTPClient(t *testing.T) { - certFile, err := filepath.Abs("./testdata/argocd-test-client.crt") - assert.NoError(t, err) - assert.NotEqual(t, "", certFile) - - keyFile, err := filepath.Abs("./testdata/argocd-test-client.key") - assert.NoError(t, err) - assert.NotEqual(t, "", keyFile) - - certData, err := ioutil.ReadFile(certFile) - assert.NoError(t, err) - assert.NotEqual(t, "", string(certData)) - - keyData, err := ioutil.ReadFile(keyFile) - assert.NoError(t, err) - assert.NotEqual(t, "", string(keyData)) - - // Get HTTPSCreds with client cert creds specified, and insecure connection - creds := NewHTTPSCreds("test", "test", string(certData), string(keyData), false) - client := GetRepoHTTPClient("https://localhost:9443/foo/bar", false, creds) - assert.NotNil(t, client) - assert.NotNil(t, client.Transport) - if client.Transport != nil { - httpClient := client.Transport.(*http.Transport) - assert.NotNil(t, httpClient.TLSClientConfig) - - assert.Equal(t, false, httpClient.TLSClientConfig.InsecureSkipVerify) - - assert.NotNil(t, httpClient.TLSClientConfig.GetClientCertificate) - if httpClient.TLSClientConfig.GetClientCertificate != nil { - cert, err := httpClient.TLSClientConfig.GetClientCertificate(nil) - assert.NoError(t, err) - if err == nil { - assert.NotNil(t, cert) - assert.NotEqual(t, 0, len(cert.Certificate)) - assert.NotNil(t, cert.PrivateKey) - } - } - } - - // Get HTTPSCreds without client cert creds, but insecure connection - creds = NewHTTPSCreds("test", "test", "", "", true) - client = GetRepoHTTPClient("https://localhost:9443/foo/bar", true, creds) - assert.NotNil(t, client) - assert.NotNil(t, client.Transport) - if client.Transport != nil { - httpClient := client.Transport.(*http.Transport) - assert.NotNil(t, httpClient.TLSClientConfig) - - assert.Equal(t, true, httpClient.TLSClientConfig.InsecureSkipVerify) - - assert.NotNil(t, httpClient.TLSClientConfig.GetClientCertificate) - if httpClient.TLSClientConfig.GetClientCertificate != nil { - cert, err := httpClient.TLSClientConfig.GetClientCertificate(nil) - assert.NoError(t, err) - if err == nil { - assert.NotNil(t, cert) - assert.Equal(t, 0, len(cert.Certificate)) - assert.Nil(t, cert.PrivateKey) - } - } - } -} - -func TestLsRemote(t *testing.T) { - clnt, err := NewClientExt("https://github.com/argoproj/argo-cd.git", "/tmp", NopCreds{}, false, false) - assert.NoError(t, err) - xpass := []string{ - "HEAD", - "master", - "release-0.8", - "v0.8.0", - "4e22a3cb21fa447ca362a05a505a69397c8a0d44", - //"4e22a3c", - } - for _, revision := range xpass { - commitSHA, err := clnt.LsRemote(revision) - assert.NoError(t, err) - assert.True(t, IsCommitSHA(commitSHA)) - } - - // We do not resolve truncated git hashes and return the commit as-is if it appears to be a commit - commitSHA, err := clnt.LsRemote("4e22a3c") - assert.NoError(t, err) - assert.False(t, IsCommitSHA(commitSHA)) - assert.True(t, IsTruncatedCommitSHA(commitSHA)) - - xfail := []string{ - "unresolvable", - "4e22a3", // too short (6 characters) - } - for _, revision := range xfail { - _, err := clnt.LsRemote(revision) - assert.Error(t, err) - } -} - -// Running this test requires git-lfs to be installed on your machine. -func TestLFSClient(t *testing.T) { - - // temporary disable LFS test - // TODO(alexmt): dockerize tests in and enabled it - t.Skip() - - tempDir, err := ioutil.TempDir("", "git-client-lfs-test-") - assert.NoError(t, err) - if err == nil { - defer func() { _ = os.RemoveAll(tempDir) }() - } - - client, err := NewClientExt("https://github.com/argoproj-labs/argocd-testrepo-lfs", tempDir, NopCreds{}, false, true) - assert.NoError(t, err) - - commitSHA, err := client.LsRemote("HEAD") - assert.NoError(t, err) - assert.NotEqual(t, "", commitSHA) - - err = client.Init() - assert.NoError(t, err) - - err = client.Fetch() - assert.NoError(t, err) - - err = client.Checkout(commitSHA) - assert.NoError(t, err) - - largeFiles, err := client.LsLargeFiles() - assert.NoError(t, err) - assert.Equal(t, 3, len(largeFiles)) - - fileHandle, err := os.Open(fmt.Sprintf("%s/test3.yaml", tempDir)) - assert.NoError(t, err) - if err == nil { - defer fileHandle.Close() - text, err := ioutil.ReadAll(fileHandle) - assert.NoError(t, err) - if err == nil { - assert.Equal(t, "This is not a YAML, sorry.\n", string(text)) - } - } -} - -func TestNewFactory(t *testing.T) { - addBinDirToPath := path.NewBinDirToPath() - defer addBinDirToPath.Close() - closer := log.Debug() - defer closer() - - type args struct { - url string - insecureIgnoreHostKey bool - } - tests := []struct { - name string - args args - }{ - {"Github", args{url: "https://github.com/argoproj/argocd-example-apps"}}, - {"Azure", args{url: "https://jsuen0437@dev.azure.com/jsuen0437/jsuen/_git/jsuen"}}, - } - for _, tt := range tests { - - if tt.name == "PrivateSSHRepo" { - test.Flaky(t) - } - - dirName, err := ioutil.TempDir("", "git-client-test-") - assert.NoError(t, err) - defer func() { _ = os.RemoveAll(dirName) }() - - client, err := NewClientExt(tt.args.url, dirName, NopCreds{}, tt.args.insecureIgnoreHostKey, false) - assert.NoError(t, err) - commitSHA, err := client.LsRemote("HEAD") - assert.NoError(t, err) - - err = client.Init() - assert.NoError(t, err) - - err = client.Fetch() - assert.NoError(t, err) - - // Do a second fetch to make sure we can treat `already up-to-date` error as not an error - err = client.Fetch() - assert.NoError(t, err) - - err = client.Checkout(commitSHA) - assert.NoError(t, err) - - revisionMetadata, err := client.RevisionMetadata(commitSHA) - assert.NoError(t, err) - assert.NotNil(t, revisionMetadata) - assert.Regexp(t, "^.*<.*>$", revisionMetadata.Author) - assert.Len(t, revisionMetadata.Tags, 0) - assert.NotEmpty(t, revisionMetadata.Date) - assert.NotEmpty(t, revisionMetadata.Message) - - commitSHA2, err := client.CommitSHA() - assert.NoError(t, err) - - assert.Equal(t, commitSHA, commitSHA2) - } -} diff --git a/util/git/mocks/Client.go b/util/git/mocks/Client.go deleted file mode 100644 index da750285a..000000000 --- a/util/git/mocks/Client.go +++ /dev/null @@ -1,180 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - git2 "github.com/argoproj/argo-cd/engine/util/git" - "github.com/stretchr/testify/mock" -) - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -// Checkout provides a mock function with given fields: revision -func (_m *Client) Checkout(revision string) error { - ret := _m.Called(revision) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(revision) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// CommitSHA provides a mock function with given fields: -func (_m *Client) CommitSHA() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Fetch provides a mock function with given fields: -func (_m *Client) Fetch() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Init provides a mock function with given fields: -func (_m *Client) Init() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// LsFiles provides a mock function with given fields: path -func (_m *Client) LsFiles(path string) ([]string, error) { - ret := _m.Called(path) - - var r0 []string - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(path) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(path) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LsLargeFiles provides a mock function with given fields: -func (_m *Client) LsLargeFiles() ([]string, error) { - ret := _m.Called() - - var r0 []string - if rf, ok := ret.Get(0).(func() []string); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LsRemote provides a mock function with given fields: revision -func (_m *Client) LsRemote(revision string) (string, error) { - ret := _m.Called(revision) - - var r0 string - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(revision) - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(revision) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RevisionMetadata provides a mock function with given fields: revision -func (_m *Client) RevisionMetadata(revision string) (*git2.RevisionMetadata, error) { - ret := _m.Called(revision) - - var r0 *git2.RevisionMetadata - if rf, ok := ret.Get(0).(func(string) *git2.RevisionMetadata); ok { - r0 = rf(revision) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*git2.RevisionMetadata) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(revision) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Root provides a mock function with given fields: -func (_m *Client) Root() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} diff --git a/util/git/testdata/argocd-test-client.crt b/util/git/testdata/argocd-test-client.crt deleted file mode 100644 index 4a1507058..000000000 --- a/util/git/testdata/argocd-test-client.crt +++ /dev/null @@ -1,85 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 33:af:0d:00:3e:e7:90:bb:8c:77:0e:24:82:e3:9d:61 - Signature Algorithm: sha256WithRSAEncryption - Issuer: CN=ArgoCD Test CA - Validity - Not Before: Jul 20 15:39:35 2019 GMT - Not After : Jun 26 15:39:35 2119 GMT - Subject: CN=argo-test-client - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public-Key: (2048 bit) - Modulus: - 00:96:1e:04:cc:35:14:87:98:83:58:87:21:89:2c: - 40:a6:40:25:60:6a:d8:85:fd:b0:c2:d7:06:8d:4a: - 0c:c3:ff:2a:98:77:60:f1:e6:74:49:b2:5d:8b:ef: - e3:80:0e:e3:6e:e0:50:7d:13:b8:fe:89:3a:ab:a5: - 05:23:6d:ba:6d:f8:3e:b3:75:90:c8:41:3d:40:c8: - 10:8d:62:a8:a9:4b:5a:6b:56:95:94:89:ca:28:f4: - 7a:a4:77:07:3a:35:15:b1:79:04:3a:43:74:70:51: - e7:9c:41:29:92:d3:f3:69:67:1a:1d:4a:be:0d:6e: - 72:bf:29:72:7d:1c:49:54:54:93:20:f3:7f:00:42: - e1:98:12:57:8e:39:a7:87:6f:f5:13:3c:25:be:9b: - 00:5f:57:07:c8:f4:f8:b8:ca:36:fd:29:35:49:70: - 31:66:0b:e7:a5:36:fb:10:ba:86:f9:18:98:17:d9: - 7d:e0:60:4f:cf:08:85:57:8d:8b:e0:19:fe:83:28: - 89:98:6f:2a:d5:85:ea:1e:59:0c:04:f5:87:b6:ff: - a2:8d:4c:62:ed:68:ba:9a:7f:2f:ac:94:c8:72:4e: - 24:f7:37:54:19:f5:14:65:3e:65:ff:7b:e4:f9:c1: - 42:80:a7:87:15:29:b9:78:26:f1:02:f2:4d:77:b8: - 04:79 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - AB:D1:69:33:0A:6A:F4:46:B1:80:D3:F7:B2:93:E8:07:FB:03:E8:BF - X509v3 Authority Key Identifier: - keyid:1E:B1:40:6A:1F:AB:D5:3D:A7:DF:07:AE:AB:5C:37:C3:CB:18:96:AC - DirName:/CN=ArgoCD Test CA - serial:06:04:D7:D4:4E:A1:2C:3F:A4:30:9E:AD:0C:A4:DF:55:68:F7:D3:C5 - - X509v3 Extended Key Usage: - TLS Web Client Authentication - X509v3 Key Usage: - Digital Signature - Signature Algorithm: sha256WithRSAEncryption - 03:a8:d4:3b:17:66:fc:93:20:b0:68:f9:79:fe:cd:e0:54:d6: - a4:20:fe:14:75:c9:63:f0:a3:ff:4a:a5:b8:d9:c8:43:fa:0b: - 9c:da:0b:fd:23:b9:cb:c0:9e:5a:db:72:21:9e:c5:56:81:32: - 14:4e:d5:ef:9b:97:ab:b8:93:1f:79:41:b0:fa:66:93:28:93: - 95:54:4a:8a:27:26:8a:fe:81:fd:a5:68:f2:9b:9c:6c:63:c3: - 96:98:9a:e9:e5:6d:34:69:f1:ea:ca:78:10:e4:2b:e1:41:bf: - dc:b6:c8:ba:76:ea:17:69:3e:cf:75:b8:28:03:17:06:0f:e5: - 9a:cb:36:27:85:d7:b8:13:92:69:1c:ce:72:fb:71:1f:38:a2: - 22:fa:86:13:20:44:79:77:9f:ab:11:e8:6e:65:94:b7:ee:c4: - 39:bd:89:45:4c:55:80:92:a6:83:83:83:75:3c:30:4e:da:6b: - 4b:74:0e:a7:86:4e:4f:79:d3:d2:a6:38:d5:ea:7d:fc:5f:a7: - 73:3b:97:ef:cb:49:08:10:96:13:64:68:48:d0:b3:eb:59:93: - 9d:22:ba:0c:83:1c:74:a1:f6:61:34:b6:8e:e5:e1:25:5a:09: - ec:7e:b0:b9:fd:21:7e:65:5d:3b:15:d7:a0:a3:e1:4f:fa:4e: - 77:90:3c:83 ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIQM68NAD7nkLuMdw4kguOdYTANBgkqhkiG9w0BAQsFADAZ -MRcwFQYDVQQDDA5BcmdvQ0QgVGVzdCBDQTAgFw0xOTA3MjAxNTM5MzVaGA8yMTE5 -MDYyNjE1MzkzNVowGzEZMBcGA1UEAwwQYXJnby10ZXN0LWNsaWVudDCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJYeBMw1FIeYg1iHIYksQKZAJWBq2IX9 -sMLXBo1KDMP/Kph3YPHmdEmyXYvv44AO427gUH0TuP6JOqulBSNtum34PrN1kMhB -PUDIEI1iqKlLWmtWlZSJyij0eqR3Bzo1FbF5BDpDdHBR55xBKZLT82lnGh1Kvg1u -cr8pcn0cSVRUkyDzfwBC4ZgSV445p4dv9RM8Jb6bAF9XB8j0+LjKNv0pNUlwMWYL -56U2+xC6hvkYmBfZfeBgT88IhVeNi+AZ/oMoiZhvKtWF6h5ZDAT1h7b/oo1MYu1o -upp/L6yUyHJOJPc3VBn1FGU+Zf975PnBQoCnhxUpuXgm8QLyTXe4BHkCAwEAAaOB -pTCBojAJBgNVHRMEAjAAMB0GA1UdDgQWBBSr0WkzCmr0RrGA0/eyk+gH+wPovzBU -BgNVHSMETTBLgBQesUBqH6vVPaffB66rXDfDyxiWrKEdpBswGTEXMBUGA1UEAwwO -QXJnb0NEIFRlc3QgQ0GCFAYE19ROoSw/pDCerQyk31Vo99PFMBMGA1UdJQQMMAoG -CCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAA6jUOxdm -/JMgsGj5ef7N4FTWpCD+FHXJY/Cj/0qluNnIQ/oLnNoL/SO5y8CeWttyIZ7FVoEy -FE7V75uXq7iTH3lBsPpmkyiTlVRKiicmiv6B/aVo8pucbGPDlpia6eVtNGnx6sp4 -EOQr4UG/3LbIunbqF2k+z3W4KAMXBg/lmss2J4XXuBOSaRzOcvtxHziiIvqGEyBE -eXefqxHobmWUt+7EOb2JRUxVgJKmg4ODdTwwTtprS3QOp4ZOT3nT0qY41ep9/F+n -czuX78tJCBCWE2RoSNCz61mTnSK6DIMcdKH2YTS2juXhJVoJ7H6wuf0hfmVdOxXX -oKPhT/pOd5A8gw== ------END CERTIFICATE----- diff --git a/util/git/testdata/argocd-test-client.key b/util/git/testdata/argocd-test-client.key deleted file mode 100644 index ce385d43e..000000000 --- a/util/git/testdata/argocd-test-client.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCWHgTMNRSHmINY -hyGJLECmQCVgatiF/bDC1waNSgzD/yqYd2Dx5nRJsl2L7+OADuNu4FB9E7j+iTqr -pQUjbbpt+D6zdZDIQT1AyBCNYqipS1prVpWUicoo9Hqkdwc6NRWxeQQ6Q3RwUeec -QSmS0/NpZxodSr4NbnK/KXJ9HElUVJMg838AQuGYEleOOaeHb/UTPCW+mwBfVwfI -9Pi4yjb9KTVJcDFmC+elNvsQuob5GJgX2X3gYE/PCIVXjYvgGf6DKImYbyrVheoe -WQwE9Ye2/6KNTGLtaLqafy+slMhyTiT3N1QZ9RRlPmX/e+T5wUKAp4cVKbl4JvEC -8k13uAR5AgMBAAECggEAQNWsOso+GKY9LDIIwOb08RjJS9A5vf0op64Y7VLrGoeN -TRZaL3/Z/65iirrL5hYIEm4dNTgccQqx5Uo7YubUWwSZiAahxmuu2djOlVHkCGI8 -JhnaNrIgNvoIMhoabABbYzAiLEvP8WbegnT+UKTr/z0BYV9ToBdwxbFP+ksKPLo1 -DZYJyKFA+h9UCDR3/woPSOp57Ta/S26BZSqCYeX7PKkzUn8OnfBG16wPfSbMQzM1 -AMwNG0VnQWpkbAhISLRcFUhyQC6kBqu8QEBHYa6SZ0qosGxZhnVo18bhz55q/6s/ -GHf5nKCkN8rBOt5G22tJ22L1s7DLjrRmeyvNogPctQKBgQDFz5ZU/bWAmGFG60lJ -5KtMoGo4Us/8j4sjwMDaoujGO/lsWKejhL4ERfqXm4/yCtDGtq+eOgXN4rOGr/b2 -SW4CCsJYdgiUdCH6A7pmUk9zKT0226Z7YcsBX14pttqni2NTcIvvWKjBDxo9r00f -OaQJbER3s0cwojvBiZs9bDE9zwKBgQDCRsyfiPyp+7NJ2u2Kx9KFIW6j3cOA5K5/ -ixpolsubL1McvTWL6JFcZQ+y7/oQbmX860CFgtKhMOsdOH2AY4UwG5A1BIvdxgwH -E6RJAwa1j/KXS8NjtTGKn7ILPwwlYyFGzCpiaDoqeGIjXD5G5bXMZ+LNMKSdXuw2 -/mOHDVSzNwKBgQCl4VTh5PhF5IL+4+RLsRTtZ0BsBxYfZ4h47PVM43xscHLTpuy9 -tV1bXAuvA2cMxIEbgqt29pVTeB6wffONyToVQEyFvkWnqFOtw16W28OAgT6yODQ+ -F14TwpPGS27FPaCHokPW7PRnIXER9WWpH78tn7sy3gZ/BC00OV8TfR02BQKBgQDB -Fz8vXSbLB/j1cdvgsKRjX4wo4DP8+s0YxTfVNfNd5RZ1HPWIfflj3KpSzcM7644A -aA1z5UfVn9o+67OJFOD+pJaaq08ceEfiDLqfOpvDfzO8/jdP9Xos7nY2SU6YJkOf -qzKBJliRd58KyBa5vnwHkkVQbYVfSEX8jrB7PVuu1wKBgQCLE6GkaJo2rwhMXGe+ -0EzjFwo9wH/zY17xfFzj0rnJ07A16Q3dAFz+BXF90BWQZeWGxOa2NhlStBEAskU4 -7PR5bV0u+G4EnD1TQbrh4jgNswrCCJylK7GjZutB+JCbA3UY3ih8QUlnlhbyoEk9 -xDNMYUwlZfcAqlI/KbmKsEm6/w== ------END PRIVATE KEY----- diff --git a/util/git/workaround.go b/util/git/workaround.go deleted file mode 100644 index 5e89acfa7..000000000 --- a/util/git/workaround.go +++ /dev/null @@ -1,75 +0,0 @@ -package git - -import ( - "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/plumbing/transport" - "gopkg.in/src-d/go-git.v4/plumbing/transport/client" - "gopkg.in/src-d/go-git.v4/plumbing/transport/http" - "gopkg.in/src-d/go-git.v4/utils/ioutil" -) - -// Below is a workaround for https://github.com/src-d/go-git/issues/1177: the `github.com/src-d/go-git` does not support disable SSL cert verification is a single repo. -// As workaround methods `newUploadPackSession`, `newClient` and `listRemote` were copied from https://github.com/src-d/go-git/blob/master/remote.go and modified to use -// transport with InsecureSkipVerify flag is verification should be disabled. - -func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, creds Creds) (transport.UploadPackSession, error) { - c, ep, err := newClient(url, insecure, creds) - if err != nil { - return nil, err - } - - return c.NewUploadPackSession(ep, auth) -} - -func newClient(url string, insecure bool, creds Creds) (transport.Transport, *transport.Endpoint, error) { - ep, err := transport.NewEndpoint(url) - if err != nil { - return nil, nil, err - } - - var c transport.Transport - // For HTTPS repositories, we get a custom Transport. Everything else will - // be default. - if IsHTTPSURL(url) { - c = http.NewClient(GetRepoHTTPClient(url, insecure, creds)) - } else { - c, err = client.NewClient(ep) - if err != nil { - return nil, nil, err - } - } - return c, ep, err -} - -func listRemote(r *git.Remote, o *git.ListOptions, insecure bool, creds Creds) (rfs []*plumbing.Reference, err error) { - s, err := newUploadPackSession(r.Config().URLs[0], o.Auth, insecure, creds) - if err != nil { - return nil, err - } - - defer ioutil.CheckClose(s, &err) - - ar, err := s.AdvertisedReferences() - if err != nil { - return nil, err - } - - allRefs, err := ar.AllReferences() - if err != nil { - return nil, err - } - - refs, err := allRefs.IterReferences() - if err != nil { - return nil, err - } - - var resultRefs []*plumbing.Reference - _ = refs.ForEach(func(ref *plumbing.Reference) error { - resultRefs = append(resultRefs, ref) - return nil - }) - - return resultRefs, nil -} diff --git a/util/health/health_test.go b/util/health/health_test.go deleted file mode 100644 index 22cc3e428..000000000 --- a/util/health/health_test.go +++ /dev/null @@ -1,229 +0,0 @@ -package health - -import ( - "io/ioutil" - "testing" - - "github.com/argoproj/argo-cd/engine/util/lua" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/argoproj/argo-cd/engine/common" - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" -) - -func assertAppHealth(t *testing.T, yamlPath string, expectedStatus appv1.HealthStatusCode) { - health := getHealthStatus(yamlPath, t) - assert.NotNil(t, health) - assert.Equal(t, expectedStatus, health.Status) -} - -func getHealthStatus(yamlPath string, t *testing.T) *appv1.HealthStatus { - yamlBytes, err := ioutil.ReadFile(yamlPath) - assert.Nil(t, err) - var obj unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &obj) - assert.Nil(t, err) - health, err := GetResourceHealth(&obj, &lua.VM{}) - assert.Nil(t, err) - return health -} - -func TestDeploymentHealth(t *testing.T) { - assertAppHealth(t, "../kube/testdata/nginx.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/deployment-progressing.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/deployment-suspended.yaml", appv1.HealthStatusSuspended) - assertAppHealth(t, "./testdata/deployment-degraded.yaml", appv1.HealthStatusDegraded) -} - -func TestStatefulSetHealth(t *testing.T) { - assertAppHealth(t, "./testdata/statefulset.yaml", appv1.HealthStatusHealthy) -} - -func TestPVCHealth(t *testing.T) { - assertAppHealth(t, "./testdata/pvc-bound.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/pvc-pending.yaml", appv1.HealthStatusProgressing) -} - -func TestServiceHealth(t *testing.T) { - assertAppHealth(t, "./testdata/svc-clusterip.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/svc-loadbalancer.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/svc-loadbalancer-unassigned.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/svc-loadbalancer-nonemptylist.yaml", appv1.HealthStatusHealthy) -} - -func TestIngressHealth(t *testing.T) { - assertAppHealth(t, "./testdata/ingress.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/ingress-unassigned.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/ingress-nonemptylist.yaml", appv1.HealthStatusHealthy) -} - -func TestCRD(t *testing.T) { - assert.Nil(t, getHealthStatus("./testdata/knative-service.yaml", t)) -} - -func TestJob(t *testing.T) { - assertAppHealth(t, "./testdata/job-running.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/job-failed.yaml", appv1.HealthStatusDegraded) - assertAppHealth(t, "./testdata/job-succeeded.yaml", appv1.HealthStatusHealthy) -} - -func TestPod(t *testing.T) { - assertAppHealth(t, "./testdata/pod-pending.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/pod-running-not-ready.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/pod-crashloop.yaml", appv1.HealthStatusDegraded) - assertAppHealth(t, "./testdata/pod-imagepullbackoff.yaml", appv1.HealthStatusDegraded) - assertAppHealth(t, "./testdata/pod-error.yaml", appv1.HealthStatusDegraded) - assertAppHealth(t, "./testdata/pod-running-restart-always.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/pod-running-restart-never.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/pod-running-restart-onfailure.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/pod-failed.yaml", appv1.HealthStatusDegraded) - assertAppHealth(t, "./testdata/pod-succeeded.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/pod-deletion.yaml", appv1.HealthStatusProgressing) -} - -func TestApplication(t *testing.T) { - assertAppHealth(t, "./testdata/application-healthy.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/application-degraded.yaml", appv1.HealthStatusDegraded) -} - -func TestAppOfAppsHealth(t *testing.T) { - newAppLiveObj := func(name string, status appv1.HealthStatusCode) (*unstructured.Unstructured, appv1.ResourceStatus) { - app := appv1.Application{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "argoproj.io/v1alpha1", - Kind: "Application", - }, - Status: appv1.ApplicationStatus{ - Health: appv1.HealthStatus{ - Status: status, - }, - }, - } - resStatus := appv1.ResourceStatus{ - Group: "argoproj.io", - Version: "v1alpha1", - Kind: "Application", - Name: name, - } - return kube.MustToUnstructured(&app), resStatus - } - - missingApp, missingStatus := newAppLiveObj("foo", appv1.HealthStatusMissing) - healthyApp, healthyStatus := newAppLiveObj("bar", appv1.HealthStatusHealthy) - degradedApp, degradedStatus := newAppLiveObj("baz", appv1.HealthStatusDegraded) - - // verify missing child app does not affect app health - { - missingAndHealthyStatuses := []appv1.ResourceStatus{missingStatus, healthyStatus} - missingAndHealthyLiveObjects := []*unstructured.Unstructured{missingApp, healthyApp} - healthStatus, err := SetApplicationHealth(missingAndHealthyStatuses, missingAndHealthyLiveObjects, &lua.VM{}, noFilter) - assert.NoError(t, err) - assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status) - } - - // verify degraded does affect - { - degradedAndHealthyStatuses := []appv1.ResourceStatus{degradedStatus, healthyStatus} - degradedAndHealthyLiveObjects := []*unstructured.Unstructured{degradedApp, healthyApp} - healthStatus, err := SetApplicationHealth(degradedAndHealthyStatuses, degradedAndHealthyLiveObjects, &lua.VM{}, noFilter) - assert.NoError(t, err) - assert.Equal(t, appv1.HealthStatusDegraded, healthStatus.Status) - } - -} - -func TestSetApplicationHealth(t *testing.T) { - yamlBytes, err := ioutil.ReadFile("./testdata/job-failed.yaml") - assert.Nil(t, err) - var failedJob unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &failedJob) - assert.Nil(t, err) - - yamlBytes, err = ioutil.ReadFile("./testdata/pod-running-restart-always.yaml") - assert.Nil(t, err) - var runningPod unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &runningPod) - assert.Nil(t, err) - - resources := []appv1.ResourceStatus{ - { - Group: "", - Version: "v1", - Kind: "Pod", - Name: runningPod.GetName(), - }, - { - Group: "batch", - Version: "v1", - Kind: "Job", - Name: failedJob.GetName(), - }, - } - liveObjs := []*unstructured.Unstructured{ - &runningPod, - &failedJob, - } - healthStatus, err := SetApplicationHealth(resources, liveObjs, &lua.VM{}, noFilter) - assert.NoError(t, err) - assert.Equal(t, appv1.HealthStatusDegraded, healthStatus.Status) - - // now mark the job as a hook and retry. it should ignore the hook and consider the app healthy - failedJob.SetAnnotations(map[string]string{common.AnnotationKeyHook: "PreSync"}) - healthStatus, err = SetApplicationHealth(resources, liveObjs, &lua.VM{}, noFilter) - assert.NoError(t, err) - assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status) -} - -func TestAPIService(t *testing.T) { - assertAppHealth(t, "./testdata/apiservice-v1-true.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/apiservice-v1-false.yaml", appv1.HealthStatusProgressing) - assertAppHealth(t, "./testdata/apiservice-v1beta1-true.yaml", appv1.HealthStatusHealthy) - assertAppHealth(t, "./testdata/apiservice-v1beta1-false.yaml", appv1.HealthStatusProgressing) -} - -func TestGetStatusFromArgoWorkflow(t *testing.T) { - sampleWorkflow := unstructured.Unstructured{Object: map[string]interface{}{ - "spec": map[string]interface{}{ - "entrypoint": "sampleEntryPoint", - "extraneousKey": "we are agnostic to extraneous keys", - }, - "status": map[string]interface{}{ - "phase": "Running", - "message": "This node is running", - }, - }, - } - - status, message := GetStatusFromArgoWorkflow(&sampleWorkflow) - assert.Equal(t, appv1.OperationRunning, status) - assert.Equal(t, "This node is running", message) - - sampleWorkflow = unstructured.Unstructured{Object: map[string]interface{}{ - "spec": map[string]interface{}{ - "entrypoint": "sampleEntryPoint", - "extraneousKey": "we are agnostic to extraneous keys", - }, - "status": map[string]interface{}{ - "phase": "Succeeded", - "message": "This node is has succeeded", - }, - }, - } - - status, message = GetStatusFromArgoWorkflow(&sampleWorkflow) - assert.Equal(t, appv1.OperationSucceeded, status) - assert.Equal(t, "This node is has succeeded", message) - -} - -func noFilter(obj *unstructured.Unstructured) bool { - return true -} diff --git a/util/healthz/healthz.go b/util/healthz/healthz.go deleted file mode 100644 index 796b3766b..000000000 --- a/util/healthz/healthz.go +++ /dev/null @@ -1,21 +0,0 @@ -package healthz - -import ( - "fmt" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// ServeHealthCheck serves the health check endpoint. -// ServeHealthCheck relies on the provided function to return an error if unhealthy and nil otherwise. -func ServeHealthCheck(mux *http.ServeMux, f func() error) { - mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { - if err := f(); err != nil { - w.WriteHeader(http.StatusServiceUnavailable) - log.Errorln(w, err) - } else { - fmt.Fprintln(w, "ok") - } - }) -} diff --git a/util/healthz/healthz_test.go b/util/healthz/healthz_test.go deleted file mode 100644 index 132806c8d..000000000 --- a/util/healthz/healthz_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package healthz - -import ( - "fmt" - "net" - "net/http" - "testing" -) - -func TestHealthCheck(t *testing.T) { - sentinel := false - - serve := func(c chan<- string) { - // listen on first available dynamic (unprivileged) port - listener, err := net.Listen("tcp", ":0") - if err != nil { - panic(err) - } - - // send back the address so that it can be used - c <- listener.Addr().String() - - mux := http.NewServeMux() - ServeHealthCheck(mux, func() error { - if sentinel { - return fmt.Errorf("This is a dummy error") - } - return nil - }) - panic(http.Serve(listener, mux)) - } - - c := make(chan string, 1) - - // run a local webserver to test data retrieval - go serve(c) - - address := <-c - t.Logf("Listening at address: %s", address) - - server := "http://" + address - - resp, err := http.Get(server + "/healthz") - if err != nil { - t.Fatal(err) - } - - if resp.StatusCode != 200 { - t.Fatalf("Was expecting status code 200 from health check, but got %d instead", resp.StatusCode) - } - - sentinel = true - - resp, _ = http.Get(server + "/healthz") - if resp.StatusCode != 503 { - t.Fatalf("Was expecting status code 503 from health check, but got %d instead", resp.StatusCode) - } - -} diff --git a/util/helm/client.go b/util/helm/client.go deleted file mode 100644 index ba971f596..000000000 --- a/util/helm/client.go +++ /dev/null @@ -1,231 +0,0 @@ -package helm - -import ( - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - "time" - - "github.com/argoproj/argo-cd/engine/util/misc" - - argoexec "github.com/argoproj/pkg/exec" - "github.com/patrickmn/go-cache" - log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" -) - -var ( - indexCache = cache.New(5*time.Minute, 5*time.Minute) - globalLock = misc.NewKeyLock() -) - -type Entry struct { - Version string - Created time.Time -} - -type Index struct { - Entries map[string][]Entry -} - -type Creds struct { - Username string - Password string - CAPath string - CertData []byte - KeyData []byte -} - -type Client interface { - CleanChartCache(chart string, version string) error - ExtractChart(chart string, version string) (string, misc.Closer, error) - GetIndex() (*Index, error) -} - -func NewClient(repoURL string, creds Creds) Client { - return NewClientWithLock(repoURL, creds, globalLock) -} - -func NewClientWithLock(repoURL string, creds Creds, repoLock *misc.KeyLock) Client { - return &nativeHelmChart{ - repoURL: repoURL, - creds: creds, - repoPath: filepath.Join(os.TempDir(), strings.Replace(repoURL, "/", "_", -1)), - repoLock: repoLock, - } -} - -type nativeHelmChart struct { - repoPath string - repoURL string - creds Creds - repoLock *misc.KeyLock -} - -func fileExist(filePath string) (bool, error) { - if _, err := os.Stat(filePath); err != nil { - if os.IsNotExist(err) { - return false, nil - } else { - return false, err - } - } - return true, nil -} - -func (c *nativeHelmChart) helmChartRepoPath() error { - c.repoLock.Lock(c.repoPath) - defer c.repoLock.Unlock(c.repoPath) - - err := os.Mkdir(c.repoPath, 0700) - if err != nil && !os.IsExist(err) { - return err - } - return nil -} - -func (c *nativeHelmChart) CleanChartCache(chart string, version string) error { - return os.RemoveAll(c.getChartPath(chart, version)) -} - -func (c *nativeHelmChart) ExtractChart(chart string, version string) (string, misc.Closer, error) { - err := c.helmChartRepoPath() - if err != nil { - return "", nil, err - } - chartPath := c.getChartPath(chart, version) - - c.repoLock.Lock(chartPath) - defer c.repoLock.Unlock(chartPath) - - exists, err := fileExist(chartPath) - if err != nil { - return "", nil, err - } - if !exists { - helmCmd, err := NewCmd(c.repoPath) - if err != nil { - return "", nil, err - } - defer helmCmd.Close() - - _, err = helmCmd.Init() - if err != nil { - return "", nil, err - } - - _, err = helmCmd.RepoUpdate() - if err != nil { - return "", nil, err - } - - // download chart tar file into persistent helm repository directory - _, err = helmCmd.Fetch(c.repoURL, chart, version, c.creds) - if err != nil { - return "", nil, err - } - } - // untar helm chart into throw away temp directory which should be deleted as soon as no longer needed - tempDir, err := ioutil.TempDir("", "") - if err != nil { - return "", nil, err - } - cmd := exec.Command("tar", "-zxvf", chartPath) - cmd.Dir = tempDir - _, err = argoexec.RunCommandExt(cmd, argoexec.CmdOpts{}) - if err != nil { - _ = os.RemoveAll(tempDir) - } - return path.Join(tempDir, chart), misc.NewCloser(func() error { - return os.RemoveAll(tempDir) - }), nil -} - -func (c *nativeHelmChart) GetIndex() (*Index, error) { - cachedIndex, found := indexCache.Get(c.repoURL) - if found { - log.WithFields(log.Fields{"url": c.repoURL}).Debug("Index cache hit") - i := cachedIndex.(Index) - return &i, nil - } - - start := time.Now() - repoURL, err := url.Parse(c.repoURL) - if err != nil { - return nil, err - } - repoURL.Path = path.Join(repoURL.Path, "index.yaml") - - req, err := http.NewRequest("GET", repoURL.String(), nil) - if err != nil { - return nil, err - } - if c.creds.Username != "" || c.creds.Password != "" { - // only basic supported - req.SetBasicAuth(c.creds.Username, c.creds.Password) - } - - tlsConf, err := newTLSConfig(c.creds) - if err != nil { - return nil, err - } - tr := &http.Transport{TLSClientConfig: tlsConf} - client := http.Client{Transport: tr} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer func() { _ = resp.Body.Close() }() - - if resp.StatusCode != 200 { - return nil, errors.New("failed to get Index: " + resp.Status) - } - - index := &Index{} - err = yaml.NewDecoder(resp.Body).Decode(index) - - log.WithFields(log.Fields{"seconds": time.Since(start).Seconds()}).Info("took to get Index") - - indexCache.Set(c.repoURL, *index, cache.DefaultExpiration) - - return index, err -} - -func newTLSConfig(creds Creds) (*tls.Config, error) { - tlsConfig := &tls.Config{InsecureSkipVerify: false} - - if creds.CAPath != "" { - caData, err := ioutil.ReadFile(creds.CAPath) - if err != nil { - return nil, err - } - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caData) - tlsConfig.RootCAs = caCertPool - } - - // If a client cert & key is provided then configure TLS config accordingly. - if len(creds.CertData) > 0 && len(creds.KeyData) > 0 { - cert, err := tls.X509KeyPair(creds.CertData, creds.KeyData) - if err != nil { - return nil, err - } - tlsConfig.Certificates = []tls.Certificate{cert} - } - tlsConfig.BuildNameToCertificate() - - return tlsConfig, nil -} - -func (c *nativeHelmChart) getChartPath(chart string, version string) string { - return path.Join(c.repoPath, fmt.Sprintf("%s-%s.tgz", chart, version)) -} diff --git a/util/helm/client_test.go b/util/helm/client_test.go deleted file mode 100644 index 877d7050c..000000000 --- a/util/helm/client_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package helm - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestIndex(t *testing.T) { - t.Run("Invalid", func(t *testing.T) { - _, err := NewClient("", Creds{}).GetIndex() - assert.Error(t, err) - }) - t.Run("Stable", func(t *testing.T) { - index, err := NewClient("https://kubernetes-charts.storage.googleapis.com", Creds{}).GetIndex() - assert.NoError(t, err) - assert.NotNil(t, index) - }) - t.Run("BasicAuth", func(t *testing.T) { - index, err := NewClient("https://kubernetes-charts.storage.googleapis.com", Creds{ - Username: "my-password", - Password: "my-username", - }).GetIndex() - assert.NoError(t, err) - assert.NotNil(t, index) - }) -} diff --git a/util/helm/cmd.go b/util/helm/cmd.go deleted file mode 100644 index 2734a446d..000000000 --- a/util/helm/cmd.go +++ /dev/null @@ -1,203 +0,0 @@ -package helm - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "regexp" - - "github.com/argoproj/argo-cd/engine/util/misc" - - argoexec "github.com/argoproj/pkg/exec" -) - -// A thin wrapper around the "helm" command, adding logging and error translation. -type Cmd struct { - helmHome string - WorkDir string -} - -func NewCmd(workDir string) (*Cmd, error) { - tmpDir, err := ioutil.TempDir("", "helm") - if err != nil { - return nil, err - } - return &Cmd{WorkDir: workDir, helmHome: tmpDir}, err -} - -var redactor = func(text string) string { - return regexp.MustCompile("(--username|--password) [^ ]*").ReplaceAllString(text, "$1 ******") -} - -func (c Cmd) run(args ...string) (string, error) { - cmd := exec.Command("helm", args...) - cmd.Dir = c.WorkDir - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, fmt.Sprintf("HELM_HOME=%s", c.helmHome)) - return argoexec.RunCommandExt(cmd, argoexec.CmdOpts{ - Redactor: redactor, - }) -} - -func (c *Cmd) Init() (string, error) { - return c.run("init", "--client-only", "--skip-refresh") -} - -func (c *Cmd) RepoAdd(name, url string, opts Creds) (string, error) { - - tmp, err := ioutil.TempDir("", "helm") - if err != nil { - return "", err - } - defer func() { _ = os.RemoveAll(tmp) }() - - args := []string{"repo", "add"} - - if opts.Username != "" { - args = append(args, "--username", opts.Username) - } - - if opts.Password != "" { - args = append(args, "--password", opts.Password) - } - - if opts.CAPath != "" { - args = append(args, "--ca-file", opts.CAPath) - } - - if len(opts.CertData) > 0 { - certFile, err := ioutil.TempFile("", "helm") - if err != nil { - return "", err - } - _, err = certFile.Write(opts.CertData) - if err != nil { - return "", err - } - args = append(args, "--cert-file", certFile.Name()) - } - - if len(opts.KeyData) > 0 { - keyFile, err := ioutil.TempFile("", "helm") - if err != nil { - return "", err - } - _, err = keyFile.Write(opts.KeyData) - if err != nil { - return "", err - } - args = append(args, "--key-file", keyFile.Name()) - } - - args = append(args, name, url) - - return c.run(args...) -} - -func (c *Cmd) RepoUpdate() (string, error) { - return c.run("repo", "update") -} - -func writeToTmp(data []byte) (string, io.Closer, error) { - file, err := ioutil.TempFile("", "") - if err != nil { - return "", nil, err - } - err = ioutil.WriteFile(file.Name(), data, 0644) - if err != nil { - _ = os.RemoveAll(file.Name()) - return "", nil, err - } - return file.Name(), misc.NewCloser(func() error { - return os.RemoveAll(file.Name()) - }), nil -} - -func (c *Cmd) Fetch(repo, chartName string, version string, opts Creds) (string, error) { - args := []string{"fetch"} - - if version != "" { - args = append(args, "--version", version) - } - if opts.Username != "" { - args = append(args, "--username", opts.Username) - } - if opts.Password != "" { - args = append(args, "--password", opts.Password) - } - if opts.CAPath != "" { - args = append(args, "--ca-file", opts.CAPath) - } - if len(opts.CertData) > 0 { - filePath, closer, err := writeToTmp(opts.CertData) - if err != nil { - return "", err - } - defer misc.Close(closer) - args = append(args, "--cert-file", filePath) - } - if len(opts.KeyData) > 0 { - filePath, closer, err := writeToTmp(opts.KeyData) - if err != nil { - return "", err - } - defer misc.Close(closer) - args = append(args, "--key-file", filePath) - } - - args = append(args, "--repo", repo, chartName) - return c.run(args...) -} - -func (c *Cmd) dependencyBuild() (string, error) { - return c.run("dependency", "build") -} - -func (c *Cmd) inspectValues(values string) (string, error) { - return c.run("inspect", "values", values) -} - -type TemplateOpts struct { - Name string - Namespace string - KubeVersion string - Set map[string]string - SetString map[string]string - Values []string -} - -var ( - re = regexp.MustCompile(`([^\\]),`) -) - -func cleanSetParameters(val string) string { - return re.ReplaceAllString(val, `$1\,`) -} - -func (c *Cmd) template(chart string, opts *TemplateOpts) (string, error) { - args := []string{"template", chart, "--name", opts.Name} - - if opts.Namespace != "" { - args = append(args, "--namespace", opts.Namespace) - } - if opts.KubeVersion != "" { - args = append(args, "--kube-version", opts.KubeVersion) - } - for key, val := range opts.Set { - args = append(args, "--set", key+"="+cleanSetParameters(val)) - } - for key, val := range opts.SetString { - args = append(args, "--set-string", key+"="+cleanSetParameters(val)) - } - for _, val := range opts.Values { - args = append(args, "--values", val) - } - - return c.run(args...) -} - -func (c *Cmd) Close() { - _ = os.RemoveAll(c.helmHome) -} diff --git a/util/helm/cmd_test.go b/util/helm/cmd_test.go deleted file mode 100644 index 331b6c305..000000000 --- a/util/helm/cmd_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package helm - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_cmd_redactor(t *testing.T) { - assert.Equal(t, "--foo bar", redactor("--foo bar")) - assert.Equal(t, "--username ******", redactor("--username bar")) - assert.Equal(t, "--password ******", redactor("--password bar")) -} - -func TestCmd_template_kubeVersion(t *testing.T) { - cmd, err := NewCmd(".") - assert.NoError(t, err) - s, err := cmd.template("testdata/redis", &TemplateOpts{ - KubeVersion: "1.14", - }) - assert.NoError(t, err) - assert.NotEmpty(t, s) -} diff --git a/util/helm/helm.go b/util/helm/helm.go deleted file mode 100644 index c0d50d457..000000000 --- a/util/helm/helm.go +++ /dev/null @@ -1,149 +0,0 @@ -package helm - -import ( - "errors" - "fmt" - "io/ioutil" - "net/url" - "os/exec" - "path" - "regexp" - "strings" - - "github.com/ghodss/yaml" - - argoexec "github.com/argoproj/pkg/exec" - - "github.com/argoproj/argo-cd/engine/util/config" -) - -type HelmRepository struct { - Creds - Name string - Repo string -} - -// Helm provides wrapper functionality around the `helm` command. -type Helm interface { - // Template returns a list of unstructured objects from a `helm template` command - Template(opts *TemplateOpts) (string, error) - // GetParameters returns a list of chart parameters taking into account values in provided YAML files. - GetParameters(valuesFiles []string) (map[string]string, error) - // DependencyBuild runs `helm dependency build` to download a chart's dependencies - DependencyBuild() error - // Init runs `helm init --client-only` - Init() error - // Dispose deletes temp resources - Dispose() -} - -// NewHelmApp create a new wrapper to run commands on the `helm` command-line tool. -func NewHelmApp(workDir string, repos []HelmRepository) (Helm, error) { - cmd, err := NewCmd(workDir) - if err != nil { - return nil, err - } - return &helm{repos: repos, cmd: *cmd}, nil -} - -type helm struct { - cmd Cmd - repos []HelmRepository -} - -// IsMissingDependencyErr tests if the error is related to a missing chart dependency -func IsMissingDependencyErr(err error) bool { - return strings.Contains(err.Error(), "found in requirements.yaml, but missing in charts") -} - -func (h *helm) Template(templateOpts *TemplateOpts) (string, error) { - out, err := h.cmd.template(".", templateOpts) - if err != nil { - return "", err - } - return out, nil -} - -func (h *helm) DependencyBuild() error { - for _, repo := range h.repos { - _, err := h.cmd.RepoAdd(repo.Name, repo.Repo, repo.Creds) - - if err != nil { - return err - } - } - h.repos = nil - _, err := h.cmd.dependencyBuild() - return err -} - -func (h *helm) Init() error { - _, err := h.cmd.Init() - return err -} - -func (h *helm) Dispose() { - h.cmd.Close() -} - -func Version() (string, error) { - cmd := exec.Command("helm", "version", "--client") - out, err := argoexec.RunCommandExt(cmd, argoexec.CmdOpts{ - Redactor: redactor, - }) - if err != nil { - return "", fmt.Errorf("could not get helm version: %s", err) - } - re := regexp.MustCompile(`SemVer:"([a-zA-Z0-9\.]+)"`) - matches := re.FindStringSubmatch(out) - if len(matches) != 2 { - return "", errors.New("could not get helm version") - } - version := matches[1] - if version[0] != 'v' { - version = "v" + version - } - return strings.TrimSpace(version), nil -} - -func (h *helm) GetParameters(valuesFiles []string) (map[string]string, error) { - out, err := h.cmd.inspectValues(".") - if err != nil { - return nil, err - } - values := append([]string{out}) - for _, file := range valuesFiles { - var fileValues []byte - parsedURL, err := url.ParseRequestURI(file) - if err == nil && (parsedURL.Scheme == "http" || parsedURL.Scheme == "https") { - fileValues, err = config.ReadRemoteFile(file) - } else { - fileValues, err = ioutil.ReadFile(path.Join(h.cmd.WorkDir, file)) - } - if err != nil { - return nil, fmt.Errorf("failed to read value file %s: %s", file, err) - } - values = append(values, string(fileValues)) - } - - output := map[string]string{} - for _, file := range values { - values := map[string]interface{}{} - if err = yaml.Unmarshal([]byte(file), &values); err != nil { - return nil, fmt.Errorf("failed to parse values: %s", err) - } - flatVals(values, output) - } - - return output, nil -} - -func flatVals(input map[string]interface{}, output map[string]string, prefixes ...string) { - for key, val := range input { - if subMap, ok := val.(map[string]interface{}); ok { - flatVals(subMap, output, append(prefixes, fmt.Sprintf("%v", key))...) - } else { - output[strings.Join(append(prefixes, fmt.Sprintf("%v", key)), ".")] = fmt.Sprintf("%v", val) - } - } -} diff --git a/util/helm/helm_test.go b/util/helm/helm_test.go deleted file mode 100644 index 3262fa30a..000000000 --- a/util/helm/helm_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package helm - -import ( - "os" - "regexp" - "testing" - - "github.com/argoproj/argo-cd/engine/util/kube" - - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - apiv1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" -) - -func template(h Helm, opts *TemplateOpts) ([]*unstructured.Unstructured, error) { - out, err := h.Template(opts) - if err != nil { - return nil, err - } - return kube.SplitYAML(out) -} - -func TestHelmTemplateParams(t *testing.T) { - h, err := NewHelmApp("./testdata/minio", []HelmRepository{}) - assert.NoError(t, err) - opts := TemplateOpts{ - Name: "test", - Set: map[string]string{ - "service.type": "LoadBalancer", - "service.port": "1234", - }, - SetString: map[string]string{ - "service.annotations.prometheus\\.io/scrape": "true", - }, - } - objs, err := template(h, &opts) - assert.Nil(t, err) - assert.Equal(t, 5, len(objs)) - - for _, obj := range objs { - if obj.GetKind() == "Service" && obj.GetName() == "test-minio" { - var svc apiv1.Service - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &svc) - assert.Nil(t, err) - assert.Equal(t, apiv1.ServiceTypeLoadBalancer, svc.Spec.Type) - assert.Equal(t, int32(1234), svc.Spec.Ports[0].TargetPort.IntVal) - assert.Equal(t, "true", svc.ObjectMeta.Annotations["prometheus.io/scrape"]) - } - } -} - -func TestHelmTemplateValues(t *testing.T) { - h, err := NewHelmApp("./testdata/redis", []HelmRepository{}) - assert.NoError(t, err) - opts := TemplateOpts{ - Name: "test", - Values: []string{"values-production.yaml"}, - } - objs, err := template(h, &opts) - assert.Nil(t, err) - assert.Equal(t, 8, len(objs)) - - for _, obj := range objs { - if obj.GetKind() == "Deployment" && obj.GetName() == "test-redis-slave" { - var dep appsv1.Deployment - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) - assert.Nil(t, err) - assert.Equal(t, int32(3), *dep.Spec.Replicas) - } - } -} - -func TestHelmGetParams(t *testing.T) { - h, err := NewHelmApp("./testdata/redis", nil) - assert.NoError(t, err) - params, err := h.GetParameters([]string{}) - assert.Nil(t, err) - - slaveCountParam := params["cluster.slaveCount"] - assert.Equal(t, slaveCountParam, "1") -} - -func TestHelmGetParamsValueFiles(t *testing.T) { - h, err := NewHelmApp("./testdata/redis", nil) - assert.NoError(t, err) - params, err := h.GetParameters([]string{"values-production.yaml"}) - assert.Nil(t, err) - - slaveCountParam := params["cluster.slaveCount"] - assert.Equal(t, slaveCountParam, "3") -} - -func TestHelmDependencyBuild(t *testing.T) { - clean := func() { - _ = os.RemoveAll("./testdata/wordpress/charts") - } - clean() - defer clean() - h, err := NewHelmApp("./testdata/wordpress", nil) - assert.NoError(t, err) - err = h.Init() - assert.NoError(t, err) - _, err = h.Template(&TemplateOpts{Name: "wordpress"}) - assert.Error(t, err) - err = h.DependencyBuild() - assert.NoError(t, err) - _, err = h.Template(&TemplateOpts{Name: "wordpress"}) - assert.NoError(t, err) -} - -func TestHelmTemplateReleaseNameOverwrite(t *testing.T) { - h, err := NewHelmApp("./testdata/redis", nil) - assert.NoError(t, err) - - objs, err := template(h, &TemplateOpts{Name: "my-release"}) - assert.Nil(t, err) - assert.Equal(t, 5, len(objs)) - - for _, obj := range objs { - if obj.GetKind() == "StatefulSet" { - var stateful appsv1.StatefulSet - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) - assert.Nil(t, err) - assert.Equal(t, "my-release-redis-master", stateful.ObjectMeta.Name) - } - } -} - -func TestHelmTemplateReleaseName(t *testing.T) { - h, err := NewHelmApp("./testdata/redis", nil) - assert.NoError(t, err) - objs, err := template(h, &TemplateOpts{Name: "test"}) - assert.Nil(t, err) - assert.Equal(t, 5, len(objs)) - - for _, obj := range objs { - if obj.GetKind() == "StatefulSet" { - var stateful appsv1.StatefulSet - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) - assert.Nil(t, err) - assert.Equal(t, "test-redis-master", stateful.ObjectMeta.Name) - } - } -} - -func TestHelmArgCleaner(t *testing.T) { - for input, expected := range map[string]string{ - `val`: `val`, - `bar`: `bar`, - `not, clean`: `not\, clean`, - `a\,b,c`: `a\,b\,c`, - } { - cleaned := cleanSetParameters(input) - assert.Equal(t, expected, cleaned) - } -} - -func TestVersion(t *testing.T) { - ver, err := Version() - assert.NoError(t, err) - SemverRegexValidation := `^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$` - re := regexp.MustCompile(SemverRegexValidation) - assert.True(t, re.MatchString(ver)) -} diff --git a/util/helm/mocks/Client.go b/util/helm/mocks/Client.go deleted file mode 100644 index 17fe0a527..000000000 --- a/util/helm/mocks/Client.go +++ /dev/null @@ -1,81 +0,0 @@ -// Code generated by mockery v1.0.0. DO NOT EDIT. - -package mocks - -import ( - helm2 "github.com/argoproj/argo-cd/engine/util/helm" - "github.com/argoproj/argo-cd/engine/util/misc" - "github.com/stretchr/testify/mock" -) - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -// CleanChartCache provides a mock function with given fields: chart, version -func (_m *Client) CleanChartCache(chart string, version string) error { - ret := _m.Called(chart, version) - - var r0 error - if rf, ok := ret.Get(0).(func(string, string) error); ok { - r0 = rf(chart, version) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ExtractChart provides a mock function with given fields: chart, version -func (_m *Client) ExtractChart(chart string, version string) (string, misc.Closer, error) { - ret := _m.Called(chart, version) - - var r0 string - if rf, ok := ret.Get(0).(func(string, string) string); ok { - r0 = rf(chart, version) - } else { - r0 = ret.Get(0).(string) - } - - var r1 misc.Closer - if rf, ok := ret.Get(1).(func(string, string) misc.Closer); ok { - r1 = rf(chart, version) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(misc.Closer) - } - } - - var r2 error - if rf, ok := ret.Get(2).(func(string, string) error); ok { - r2 = rf(chart, version) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -// GetIndex provides a mock function with given fields: -func (_m *Client) GetIndex() (*helm2.Index, error) { - ret := _m.Called() - - var r0 *helm2.Index - if rf, ok := ret.Get(0).(func() *helm2.Index); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*helm2.Index) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} diff --git a/util/helm/testdata/minio/.helmignore b/util/helm/testdata/minio/.helmignore deleted file mode 100644 index f0c131944..000000000 --- a/util/helm/testdata/minio/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj diff --git a/util/helm/testdata/minio/Chart.yaml b/util/helm/testdata/minio/Chart.yaml deleted file mode 100755 index ed1cc4c69..000000000 --- a/util/helm/testdata/minio/Chart.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -description: Minio is a high performance distributed object storage server, designed for large-scale private cloud infrastructure. -name: minio -version: 1.6.0 -appVersion: RELEASE.2018-07-10T01-42-11Z -keywords: -- storage -- object-storage -- S3 -home: https://minio.io -icon: https://www.minio.io/img/logo_160x160.png -sources: -- https://github.com/minio/minio -maintainers: -- name: Acaleph - email: hello@acale.ph -- name: Minio - email: dev@minio.io diff --git a/util/helm/testdata/minio/README.md b/util/helm/testdata/minio/README.md deleted file mode 100644 index 427613f7b..000000000 --- a/util/helm/testdata/minio/README.md +++ /dev/null @@ -1,226 +0,0 @@ -Minio -===== - -[Minio](https://minio.io) is a lightweight, AWS S3 compatible object storage server. It is best suited for storing unstructured data such as photos, videos, log files, backups, VM and container images. Size of an object can range from a few KBs to a maximum of 5TB. Minio server is light enough to be bundled with the application stack, similar to NodeJS, Redis and MySQL. - -Minio supports [distributed mode](https://docs.minio.io/docs/distributed-minio-quickstart-guide). In distributed mode, you can pool multiple drives (even on different machines) into a single object storage server. - -Introduction ------------- - -This chart bootstraps Minio deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -Prerequisites -------------- - -- Kubernetes 1.4+ with Beta APIs enabled for default standalone mode. -- Kubernetes 1.5+ with Beta APIs enabled to run Minio in [distributed mode](#distributed-minio). -- PV provisioner support in the underlying infrastructure. - -Installing the Chart --------------------- - -Install this chart using: - -```bash -$ helm install stable/minio -``` - -The command deploys Minio on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -### Release name - -An instance of a chart running in a Kubernetes cluster is called a release. Each release is identified by a unique name within the cluster. Helm automatically assigns a unique release name after installing the chart. You can also set your preferred name by: - -```bash -$ helm install --name my-release stable/minio -``` - -### Access and Secret keys - -By default a pre-generated access and secret key will be used. To override the default keys, pass the access and secret keys as arguments to helm install. - -```bash -$ helm install --set accessKey=myaccesskey,secretKey=mysecretkey \ - stable/minio -``` - -### Updating Minio configuration via Helm - -[ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) allows injecting containers with configuration data even while a Helm release is deployed. - -To update your Minio server configuration while it is deployed in a release, you need to - -1. Check all the configurable values in the Minio chart using `helm inspect values stable/minio`. -2. Override the `minio_server_config` settings in a YAML formatted file, and then pass that file like this `helm upgrade -f config.yaml stable/minio`. -3. Restart the Minio server(s) for the changes to take effect. - -You can also check the history of upgrades to a release using `helm history my-release`. Replace `my-release` with the actual release name. - -Uninstalling the Chart ----------------------- - -Assuming your release is named as `my-release`, delete it using the command: - -```bash -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -Configuration -------------- - -The following table lists the configurable parameters of the Minio chart and their default values. - -| Parameter | Description | Default | -|----------------------------|-------------------------------------|---------------------------------------------------------| -| `image.repository` | Image repository | `minio/minio` | -| `image.tag` | Minio image tag. Possible values listed [here](https://hub.docker.com/r/minio/minio/tags/).| `RELEASE.2018-07-10T01-42-11Z`| -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `mcImage.repository` | Client image repository | `minio/mc` | -| `mcImage.tag` | mc image tag. Possible values listed [here](https://hub.docker.com/r/minio/mc/tags/).| `RELEASE.2018-06-09T02-18-09Z`| -| `mcImage.pullPolicy` | mc Image pull policy | `IfNotPresent` | -| `ingress.enabled` | Enables Ingress | `false` | -| `ingress.annotations` | Ingress annotations | `{}` | -| `ingress.hosts` | Ingress accepted hostnames | `[]` | -| `ingress.tls` | Ingress TLS configuration | `[]` | -| `mode` | Minio server mode (`standalone` or `distributed`)| `standalone` | -| `replicas` | Number of nodes (applicable only for Minio distributed mode). Should be 4 <= x <= 32 | `4` | -| `accessKey` | Default access key (5 to 20 characters) | `AKIAIOSFODNN7EXAMPLE` | -| `secretKey` | Default secret key (8 to 40 characters) | `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` | -| `configPath` | Default config file location | `~/.minio` | -| `mountPath` | Default mount location for persistent drive| `/export` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.port` | Kubernetes port where service is exposed| `9000` | -| `service.annotations` | Service annotations | `{}` | -| `persistence.enabled` | Use persistent volume to store data | `true` | -| `persistence.size` | Size of persistent volume claim | `10Gi` | -| `persistence.existingClaim`| Use an existing PVC to persist data | `nil` | -| `persistence.storageClass` | Type of persistent volume claim | `generic` | -| `persistence.accessMode` | ReadWriteOnce or ReadOnly | `ReadWriteOnce` | -| `persistence.subPath` | Mount a sub directory of the persistent volume if set | `""` | -| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | -| `priorityClassName` | Pod priority settings | `""` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `affinity` | Affinity settings for pod assignment | `{}` | -| `tolerations` | Toleration labels for pod assignment | `[]` | -| `defaultBucket.enabled` | If set to true, a bucket will be created after minio install | `false` | -| `defaultBucket.name` | Bucket name | `bucket` | -| `defaultBucket.policy` | Bucket policy | `none` | -| `defaultBucket.purge` | Purge the bucket if already exists | `false` | -| `azuregateway.enabled` | Use minio as an [azure gateway](https://docs.minio.io/docs/minio-gateway-for-azure)| `false` | -| `gcsgateway.enabled` | Use minio as a [Google Cloud Storage gateway](https://docs.minio.io/docs/minio-gateway-for-gcs)| `false` | -| `gcsgateway.gcsKeyJson` | credential json file of service account key | `""` | -| `gcsgateway.projectId` | Google cloud project id | `""` | -| `nasgateway.enabled` | Use minio as a [NAS gateway](https://docs.minio.io/docs/minio-gateway-for-nas) | `false` | -| `nasgateway.replicas` | Number of NAS gateway instances to be run in parallel on a PV | `4` | - -Some of the parameters above map to the env variables defined in the [Minio DockerHub image](https://hub.docker.com/r/minio/minio/). - -You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```bash -$ helm install --name my-release \ - --set persistence.size=100Gi \ - stable/minio -``` - -The above command deploys Minio server with a 100Gi backing persistent volume. - -Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, - -```bash -$ helm install --name my-release -f values.yaml stable/minio -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -Distributed Minio ------------ - -This chart provisions a Minio server in standalone mode, by default. To provision Minio server in [distributed mode](https://docs.minio.io/docs/distributed-minio-quickstart-guide), set the `mode` field to `distributed`, - -```bash -$ helm install --set mode=distributed stable/minio -``` - -This provisions Minio server in distributed mode with 4 nodes. To change the number of nodes in your distributed Minio server, set the `replicas` field, - -```bash -$ helm install --set mode=distributed,replicas=8 stable/minio -``` - -This provisions Minio server in distributed mode with 8 nodes. Note that the `replicas` value should be an integer between 4 and 16 (inclusive). - -### StatefulSet [limitations](http://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/#limitations) applicable to distributed Minio - -1. StatefulSets need persistent storage, so the `persistence.enabled` flag is ignored when `mode` is set to `distributed`. -2. When uninstalling a distributed Minio release, you'll need to manually delete volumes associated with the StatefulSet. - -NAS Gateway ------------ - -### Prerequisites - -Minio in [NAS gateway mode](https://docs.minio.io/docs/minio-gateway-for-nas) can be used to create multiple Minio instances backed by single PV in `ReadWriteMany` mode. Currently few [Kubernetes volume plugins](https://kubernetes.io/docs/user-guide/persistent-volumes/#access-modes) support `ReadWriteMany` mode. To deploy Minio NAS gateway with Helm chart you'll need to have a Persistent Volume running with one of the supported volume plugins. [This document](https://kubernetes.io/docs/user-guide/volumes/#nfs) -outlines steps to create a NFS PV in Kubernetes cluster. - -### Provision NAS Gateway Minio instances - -To provision Minio servers in [NAS gateway mode](https://docs.minio.io/docs/minio-gateway-for-nas), set the `nasgateway.enabled` field to `true`, - -```bash -$ helm install --set nasgateway.enabled=true stable/minio -``` - -This provisions 4 Minio NAS gateway instances backed by single storage. To change the number of instances in your Minio deployment, set the `replicas` field, - -```bash -$ helm install --set nasgateway.enabled=true,nasgateway.replicas=8 stable/minio -``` - -This provisions Minio NAS gateway with 8 instances. - -Persistence ------------ - -This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by: - -```bash -$ helm install --set persistence.enabled=false stable/minio -``` - -> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* - -Existing PersistentVolumeClaim ------------------------------- - -If a Persistent Volume Claim already exists, specify it during installation. - -1. Create the PersistentVolume -1. Create the PersistentVolumeClaim -1. Install the chart - -```bash -$ helm install --set persistence.existingClaim=PVC_NAME stable/minio -``` - -NetworkPolicy -------------- - -To enable network policy for Minio, -install [a networking plugin that implements the Kubernetes -NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), -and set `networkPolicy.enabled` to `true`. - -For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting -the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: - - kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" - -With NetworkPolicy enabled, traffic will be limited to just port 9000. - -For more precise policy, set `networkPolicy.allowExternal=true`. This will -only allow pods with the generated client label to connect to Minio. -This label will be displayed in the output of a successful install. diff --git a/util/helm/testdata/minio/templates/NOTES.txt b/util/helm/testdata/minio/templates/NOTES.txt deleted file mode 100644 index 07d264eab..000000000 --- a/util/helm/testdata/minio/templates/NOTES.txt +++ /dev/null @@ -1,44 +0,0 @@ -{{- if eq .Values.service.type "ClusterIP" "NodePort" }} -Minio can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: -{{ template "minio.fullname" . }}-svc.{{ .Release.Namespace }}.svc.cluster.local - -To access Minio from localhost, run the below commands: - - 1. export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ template "minio.fullname" . }}" -o jsonpath="{.items[0].metadata.name}") - - 2. kubectl port-forward $POD_NAME 9000 --namespace {{ .Release.Namespace }} - -Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ - -You can now access Minio server on http://localhost:9000. Follow the below steps to connect to Minio server with mc client: - - 1. Download the Minio mc client - https://docs.minio.io/docs/minio-client-quickstart-guide - - 2. mc config host add {{ template "minio.fullname" . }}-local http://localhost:9000 {{ .Values.accessKey }} {{ .Values.secretKey }} S3v4 - - 3. mc ls {{ template "minio.fullname" . }}-local - -Alternately, you can use your browser or the Minio SDK to access the server - https://docs.minio.io/categories/17 -{{- end }} -{{- if eq .Values.service.type "LoadBalancer" }} -Minio can be accessed via port {{ .Values.service.port }} on an external IP address. Get the service external IP address by: -kubectl get svc --namespace {{ .Release.Namespace }} -l app={{ template "minio.fullname" . }} - -Note that the public IP may take a couple of minutes to be available. - -You can now access Minio server on http://:9000. Follow the below steps to connect to Minio server with mc client: - - 1. Download the Minio mc client - https://docs.minio.io/docs/minio-client-quickstart-guide - - 2. mc config host add {{ template "minio.fullname" . }}-local http://:{{ .Values.service.port }} {{ .Values.accessKey }} {{ .Values.secretKey }} S3v4 - - 3. mc ls {{ template "minio.fullname" . }}-local - -Alternately, you can use your browser or the Minio SDK to access the server - https://docs.minio.io/categories/17 -{{- end }} - -{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} -Note: Since NetworkPolicy is enabled, only pods with label -{{ template "minio.fullname" . }}-client=true" -will be able to connect to this minio cluster. -{{- end }} diff --git a/util/helm/testdata/minio/templates/_helper_create_bucket.txt b/util/helm/testdata/minio/templates/_helper_create_bucket.txt deleted file mode 100644 index 582c7cd4b..000000000 --- a/util/helm/testdata/minio/templates/_helper_create_bucket.txt +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -set -e ; # Have script exit in the event of a failed command. - -# connectToMinio -# Use a check-sleep-check loop to wait for Minio service to be available -connectToMinio() { - ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts - set -e ; # fail if we can't read the keys. - ACCESS=$(cat /config/accesskey) ; SECRET=$(cat /config/secretkey) ; - set +e ; # The connections to minio are allowed to fail. - echo "Connecting to Minio server: http://$MINIO_ENDPOINT:$MINIO_PORT" ; - MC_COMMAND="mc config host add myminio http://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; - $MC_COMMAND ; - STATUS=$? ; - until [ $STATUS = 0 ] - do - ATTEMPTS=`expr $ATTEMPTS + 1` ; - echo \"Failed attempts: $ATTEMPTS\" ; - if [ $ATTEMPTS -gt $LIMIT ]; then - exit 1 ; - fi ; - sleep 2 ; # 1 second intervals between attempts - $MC_COMMAND ; - STATUS=$? ; - done ; - set -e ; # reset `e` as active - return 0 -} - -# checkBucketExists ($bucket) -# Check if the bucket exists, by using the exit code of `mc ls` -checkBucketExists() { - BUCKET=$1 - CMD=$(/usr/bin/mc ls myminio/$BUCKET > /dev/null 2>&1) - return $? -} - -# createBucket ($bucket, $policy, $purge) -# Ensure bucket exists, purging if asked to -createBucket() { - BUCKET=$1 - POLICY=$2 - PURGE=$3 - - # Purge the bucket, if set & exists - # Since PURGE is user input, check explicitly for `true` - if [ $PURGE = true ]; then - if checkBucketExists $BUCKET ; then - echo "Purging bucket '$BUCKET'." - set +e ; # don't exit if this fails - /usr/bin/mc rm -r --force myminio/$BUCKET - set -e ; # reset `e` as active - else - echo "Bucket '$BUCKET' does not exist, skipping purge." - fi - fi - - # Create the bucket if it does not exist - if ! checkBucketExists $BUCKET ; then - echo "Creating bucket '$BUCKET'" - /usr/bin/mc mb myminio/$BUCKET - else - echo "Bucket '$BUCKET' already exists." - fi - - # At this point, the bucket should exist, skip checking for existence - # Set policy on the bucket - echo "Setting policy of bucket '$BUCKET' to '$POLICY'." - /usr/bin/mc policy $POLICY myminio/$BUCKET -} - -# Try connecting to Minio instance -connectToMinio -# Create the bucket -createBucket {{ .Values.defaultBucket.name }} {{ .Values.defaultBucket.policy }} {{ .Values.defaultBucket.purge }} diff --git a/util/helm/testdata/minio/templates/_helpers.tpl b/util/helm/testdata/minio/templates/_helpers.tpl deleted file mode 100644 index c8fe9ba7a..000000000 --- a/util/helm/testdata/minio/templates/_helpers.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "minio.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "minio.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "minio.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Return the appropriate apiVersion for networkpolicy. -*/}} -{{- define "minio.networkPolicy.apiVersion" -}} -{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "networking.k8s.io/v1" -}} -{{- end -}} -{{- end -}} diff --git a/util/helm/testdata/minio/templates/configmap.yaml b/util/helm/testdata/minio/templates/configmap.yaml deleted file mode 100644 index 5cef4c373..000000000 --- a/util/helm/testdata/minio/templates/configmap.yaml +++ /dev/null @@ -1,140 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -data: - initialize: |- -{{ include (print $.Template.BasePath "/_helper_create_bucket.txt") . | indent 4 }} - config.json: |- - { - "version": "26", - "credential": { - "accessKey": {{ .Values.accessKey | quote }}, - "secretKey": {{ .Values.secretKey | quote }} - }, - "region": {{ .Values.minioConfig.region | quote }}, - "browser": {{ .Values.minioConfig.browser | quote }}, - "worm": {{ .Values.minioConfig.worm | quote }}, - "domain": {{ .Values.minioConfig.domain | quote }}, - "storageclass": { - "standard": {{ .Values.minioConfig.storageClass.standardStorageClass | quote }}, - "rrs": {{ .Values.minioConfig.storageClass.reducedRedundancyStorageClass | quote }} - }, - "cache": { - "drives": {{ .Values.minioConfig.cache.drives }}, - "expiry": {{ .Values.minioConfig.cache.expiry | int }}, - "maxuse": {{ .Values.minioConfig.cache.maxuse | int }}, - "exclude": {{ .Values.minioConfig.cache.exclude }} - }, - "notify": { - "amqp": { - "1": { - "enable": {{ .Values.minioConfig.aqmp.enable }}, - "url": {{ .Values.minioConfig.aqmp.url | quote }}, - "exchange": {{ .Values.minioConfig.aqmp.exchange | quote }}, - "routingKey": {{ .Values.minioConfig.aqmp.routingKey | quote }}, - "exchangeType": {{ .Values.minioConfig.aqmp.exchangeType | quote }}, - "deliveryMode": {{ .Values.minioConfig.aqmp.deliveryMode }}, - "mandatory": {{ .Values.minioConfig.aqmp.mandatory }}, - "immediate": {{ .Values.minioConfig.aqmp.immediate }}, - "durable": {{ .Values.minioConfig.aqmp.durable }}, - "internal": {{ .Values.minioConfig.aqmp.internal }}, - "noWait": {{ .Values.minioConfig.aqmp.noWait }}, - "autoDeleted": {{ .Values.minioConfig.aqmp.autoDeleted }} - } - }, - "nats": { - "1": { - "enable": {{ .Values.minioConfig.nats.enable }}, - "address": {{ .Values.minioConfig.nats.address | quote }}, - "subject": {{ .Values.minioConfig.nats.subject | quote }}, - "username": {{ .Values.minioConfig.nats.username | quote }}, - "password": {{ .Values.minioConfig.nats.password | quote }}, - "token": {{ .Values.minioConfig.nats.token | quote }}, - "secure": {{ .Values.minioConfig.nats.secure }}, - "pingInterval": {{ .Values.minioConfig.nats.pingInterval | int64 }}, - "streaming": { - "enable": {{ .Values.minioConfig.nats.enableStreaming }}, - "clusterID": {{ .Values.minioConfig.nats.clusterID | quote }}, - "clientID": {{ .Values.minioConfig.nats.clientID | quote }}, - "async": {{ .Values.minioConfig.nats.async }}, - "maxPubAcksInflight": {{ .Values.minioConfig.nats.maxPubAcksInflight | int }} - } - } - }, - "elasticsearch": { - "1": { - "enable": {{ .Values.minioConfig.elasticsearch.enable }}, - "format": {{ .Values.minioConfig.elasticsearch.format | quote }}, - "url": {{ .Values.minioConfig.elasticsearch.url | quote }}, - "index": {{ .Values.minioConfig.elasticsearch.index | quote }} - } - }, - "redis": { - "1": { - "enable": {{ .Values.minioConfig.redis.enable }}, - "format": {{ .Values.minioConfig.redis.format | quote }}, - "address": {{ .Values.minioConfig.redis.address | quote }}, - "password": {{ .Values.minioConfig.redis.password | quote }}, - "key": {{ .Values.minioConfig.redis.key | quote }} - } - }, - "postgresql": { - "1": { - "enable": {{ .Values.minioConfig.postgresql.enable }}, - "format": {{ .Values.minioConfig.postgresql.format | quote }}, - "connectionString": {{ .Values.minioConfig.postgresql.connectionString | quote }}, - "table": {{ .Values.minioConfig.postgresql.table | quote }}, - "host": {{ .Values.minioConfig.postgresql.host | quote }}, - "port": {{ .Values.minioConfig.postgresql.port | quote }}, - "user": {{ .Values.minioConfig.postgresql.user | quote }}, - "password": {{ .Values.minioConfig.postgresql.password | quote }}, - "database": {{ .Values.minioConfig.postgresql.database | quote }} - } - }, - "kafka": { - "1": { - "enable": {{ .Values.minioConfig.kafka.enable }}, - "brokers": {{ .Values.minioConfig.kafka.brokers }}, - "topic": {{ .Values.minioConfig.kafka.topic | quote }} - } - }, - "webhook": { - "1": { - "enable": {{ .Values.minioConfig.webhook.enable }}, - "endpoint": {{ .Values.minioConfig.webhook.endpoint | quote }} - } - }, - "mysql": { - "1": { - "enable": {{ .Values.minioConfig.mysql.enable }}, - "format": {{ .Values.minioConfig.mysql.format | quote }}, - "dsnString": {{ .Values.minioConfig.mysql.dsnString | quote }}, - "table": {{ .Values.minioConfig.mysql.table | quote }}, - "host": {{ .Values.minioConfig.mysql.host | quote }}, - "port": {{ .Values.minioConfig.mysql.port | quote }}, - "user": {{ .Values.minioConfig.mysql.user | quote }}, - "password": {{ .Values.minioConfig.mysql.password | quote }}, - "database": {{ .Values.minioConfig.mysql.database | quote }} - } - }, - "mqtt": { - "1": { - "enable": {{ .Values.minioConfig.mqtt.enable }}, - "broker": {{ .Values.minioConfig.mqtt.broker | quote }}, - "topic": {{ .Values.minioConfig.mqtt.topic | quote }}, - "qos": {{ .Values.minioConfig.mqtt.qos | int }}, - "clientId": {{ .Values.minioConfig.mqtt.clientId | quote }}, - "username": {{ .Values.minioConfig.mqtt.username | quote }}, - "password": {{ .Values.minioConfig.mqtt.password | quote }}, - "reconnectInterval": {{ .Values.minioConfig.mqtt.reconnectInterval | int }}, - "keepAliveInterval": {{ .Values.minioConfig.mqtt.keepAliveInterval | int }} - } - } - } - } \ No newline at end of file diff --git a/util/helm/testdata/minio/templates/deployment.yaml b/util/helm/testdata/minio/templates/deployment.yaml deleted file mode 100644 index a18ed706c..000000000 --- a/util/helm/testdata/minio/templates/deployment.yaml +++ /dev/null @@ -1,126 +0,0 @@ -{{- if eq .Values.mode "standalone" }} -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - {{- if .Values.nasgateway.enabled }} - replicas: {{ .Values.nasgateway.replicas }} - {{- end }} - selector: - matchLabels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - template: - metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - spec: - {{- if .Values.priorityClassName }} - priorityClassName: "{{ .Values.priorityClassName }}" - {{- end }} - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- if .Values.azuregateway.enabled }} - command: [ "/bin/sh", - "-ce", - "cp /tmp/config.json {{ .Values.configPath }} && - /usr/bin/docker-entrypoint.sh minio -C {{ .Values.configPath }} gateway azure"] - {{- else }} - {{- if .Values.gcsgateway.enabled }} - command: [ "/bin/sh", - "-ce", - "cp /tmp/config.json {{ .Values.configPath }} && - /usr/bin/docker-entrypoint.sh minio -C {{ .Values.configPath }} gateway gcs {{ .Values.gcsgateway.projectId }}"] - {{- else }} - {{- if .Values.nasgateway.enabled }} - command: [ "/bin/sh", - "-ce", - "cp /tmp/config.json {{ .Values.configPath }} && - /usr/bin/docker-entrypoint.sh minio -C {{ .Values.configPath }} gateway nas {{ .Values.mountPath }}"] - {{- else }} - command: [ "/bin/sh", - "-ce", - "cp /tmp/config.json {{ .Values.configPath }} && - /usr/bin/docker-entrypoint.sh minio -C {{ .Values.configPath }} server {{ .Values.mountPath }}" ] - {{- end }} - {{- end }} - {{- end }} - volumeMounts: - - name: export - mountPath: {{ .Values.mountPath }} - {{- if and .Values.persistence.enabled .Values.persistence.subPath }} - subPath: "{{ .Values.persistence.subPath }}" - {{- end }} - {{- if .Values.gcsgateway.enabled }} - - name: minio-user - mountPath: "/etc/credentials" - readOnly: true - {{- end }} - - name: minio-server-config - mountPath: "/tmp/config.json" - subPath: config.json - - name: minio-config-dir - mountPath: {{ .Values.configPath }} - ports: - - name: service - containerPort: 9000 - env: - - name: MINIO_ACCESS_KEY - valueFrom: - secretKeyRef: - name: {{ template "minio.fullname" . }} - key: accesskey - - name: MINIO_SECRET_KEY - valueFrom: - secretKeyRef: - name: {{ template "minio.fullname" . }} - key: secretkey - {{- if .Values.gcsgateway.enabled }} - - name: GOOGLE_APPLICATION_CREDENTIALS - value: "/etc/credentials/gcs_key.json" - {{- end }} - livenessProbe: - tcpSocket: - port: 9000 - timeoutSeconds: 1 - resources: -{{ toYaml .Values.resources | indent 12 }} -{{- with .Values.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.affinity }} - affinity: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} - volumes: - - name: export - {{- if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ .Values.persistence.existingClaim | default (include "minio.fullname" .) }} - {{- else }} - emptyDir: {} - {{- end }} - - name: minio-server-config - configMap: - name: {{ template "minio.fullname" . }} - - name: minio-user - secret: - secretName: {{ template "minio.fullname" . }} - - name: minio-config-dir - emptyDir: {} -{{- end }} diff --git a/util/helm/testdata/minio/templates/ingress.yaml b/util/helm/testdata/minio/templates/ingress.yaml deleted file mode 100644 index dddad9618..000000000 --- a/util/helm/testdata/minio/templates/ingress.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "minio.fullname" . -}} -{{- $servicePort := .Values.service.port -}} -{{- $ingressPath := .Values.ingress.path -}} -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -{{- with .Values.ingress.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: -{{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} -{{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ . }} - http: - paths: - - path: {{ $ingressPath }} - backend: - serviceName: {{ $fullName }} - servicePort: {{ $servicePort }} - {{- end }} -{{- end }} diff --git a/util/helm/testdata/minio/templates/networkpolicy.yaml b/util/helm/testdata/minio/templates/networkpolicy.yaml deleted file mode 100644 index de57f485f..000000000 --- a/util/helm/testdata/minio/templates/networkpolicy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -kind: NetworkPolicy -apiVersion: {{ template "minio.networkPolicy.apiVersion" . }} -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - podSelector: - matchLabels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - ingress: - - ports: - - port: {{ .Values.service.port }} - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ template "minio.name" . }}-client: "true" - {{- end }} -{{- end }} diff --git a/util/helm/testdata/minio/templates/post-install-create-bucket-job.yaml b/util/helm/testdata/minio/templates/post-install-create-bucket-job.yaml deleted file mode 100644 index b0b9cd378..000000000 --- a/util/helm/testdata/minio/templates/post-install-create-bucket-job.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if .Values.defaultBucket.enabled }} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "minio.fullname" . }}-make-bucket-job - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - annotations: - "helm.sh/hook": post-install,post-upgrade - "helm.sh/hook-delete-policy": hook-succeeded -spec: - template: - metadata: - labels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - spec: - restartPolicy: OnFailure -{{- if .Values.nodeSelector }} - nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} -{{- end }} - volumes: - - name: minio-configuration - projected: - sources: - - configMap: - name: {{ template "minio.fullname" . }} - - secret: - name: {{ template "minio.fullname" . }} - containers: - - name: minio-mc - image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" - imagePullPolicy: {{ .Values.mcImage.pullPolicy }} - command: ["/bin/sh", "/config/initialize"] - env: - - name: MINIO_ENDPOINT - value: {{ template "minio.fullname" . }} - - name: MINIO_PORT - value: {{ .Values.service.port | quote }} - volumeMounts: - - name: minio-configuration - mountPath: /config -{{- end }} diff --git a/util/helm/testdata/minio/templates/pvc.yaml b/util/helm/testdata/minio/templates/pvc.yaml deleted file mode 100644 index 5bffaf758..000000000 --- a/util/helm/testdata/minio/templates/pvc.yaml +++ /dev/null @@ -1,27 +0,0 @@ -{{- if eq .Values.mode "standalone" }} -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: -{{- if .Values.nasgateway.enabled }} - selector: - matchLabels: - pv: {{ .Values.nasgateway.pv | quote }} -{{- end }} - accessModes: - - {{ .Values.persistence.accessMode | quote }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} -{{- if .Values.persistence.storageClass }} - storageClassName: {{ .Values.persistence.storageClass | quote }} -{{- end }} -{{- end }} -{{- end }} diff --git a/util/helm/testdata/minio/templates/secrets.yaml b/util/helm/testdata/minio/templates/secrets.yaml deleted file mode 100644 index f130bf9a0..000000000 --- a/util/helm/testdata/minio/templates/secrets.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -type: Opaque -data: - accesskey: {{ .Values.accessKey | b64enc }} - secretkey: {{ .Values.secretKey | b64enc }} -{{- if .Values.gcsgateway.enabled }} - gcs_key.json: {{ .Values.gcsgateway.gcsKeyJson | b64enc }} -{{- end }} \ No newline at end of file diff --git a/util/helm/testdata/minio/templates/service.yaml b/util/helm/testdata/minio/templates/service.yaml deleted file mode 100644 index 7c6af5681..000000000 --- a/util/helm/testdata/minio/templates/service.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -{{- if .Values.service.annotations }} - annotations: -{{ toYaml .Values.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if (or (eq .Values.service.type "ClusterIP" "") (empty .Values.service.type)) }} - type: ClusterIP - {{- if .Values.service.clusterIP }} - clusterIP: {{ .Values.service.clusterIP }} - {{end}} -{{- else if eq .Values.service.type "LoadBalancer" }} - type: {{ .Values.service.type }} - loadBalancerIP: {{ default "" .Values.service.loadBalancerIP }} -{{- else }} - type: {{ .Values.service.type }} -{{- end }} - ports: - - name: service - port: 9000 - targetPort: {{ .Values.service.port }} - protocol: TCP -{{- if (and (eq .Values.service.type "NodePort") ( .Values.service.nodePort)) }} - nodePort: {{ .Values.service.nodePort }} -{{- end}} -{{- if .Values.service.externalIPs }} - externalIPs: -{{- range $i , $ip := .Values.service.externalIPs }} - - {{ $ip }} -{{- end }} -{{- end }} - selector: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} diff --git a/util/helm/testdata/minio/templates/statefulset.yaml b/util/helm/testdata/minio/templates/statefulset.yaml deleted file mode 100644 index b4fdf801e..000000000 --- a/util/helm/testdata/minio/templates/statefulset.yaml +++ /dev/null @@ -1,99 +0,0 @@ -{{- if eq .Values.mode "distributed" }} -{{ $nodeCount := .Values.replicas | int }} -apiVersion: apps/v1beta1 -kind: StatefulSet -metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - chart: {{ template "minio.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - serviceName: {{ template "minio.fullname" . }} - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - template: - metadata: - name: {{ template "minio.fullname" . }} - labels: - app: {{ template "minio.name" . }} - release: {{ .Release.Name }} - spec: - {{- if .Values.priorityClassName }} - priorityClassName: "{{ .Values.priorityClassName }}" - {{- end }} - containers: - - name: {{ .Chart.Name }} - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: [ "/bin/sh", - "-ce", - "cp /tmp/config.json {{ .Values.configPath }} && - /usr/bin/docker-entrypoint.sh minio -C {{ .Values.configPath }} server - {{- range $i := until $nodeCount }} - http://{{ template `minio.fullname` $ }}-{{ $i }}.{{ template `minio.fullname` $ }}.{{ $.Release.Namespace }}.svc.cluster.local{{ $.Values.mountPath }} - {{- end }}" ] - volumeMounts: - - name: export - mountPath: {{ .Values.mountPath }} - {{- if and .Values.persistence.enabled .Values.persistence.subPath }} - subPath: "{{ .Values.persistence.subPath }}" - {{- end }} - - name: minio-server-config - mountPath: "/tmp/config.json" - subPath: config.json - - name: minio-config-dir - mountPath: {{ .Values.configPath }} - ports: - - name: service - containerPort: 9000 - env: - - name: MINIO_ACCESS_KEY - valueFrom: - secretKeyRef: - name: {{ template "minio.fullname" . }} - key: accesskey - - name: MINIO_SECRET_KEY - valueFrom: - secretKeyRef: - name: {{ template "minio.fullname" . }} - key: secretkey - resources: -{{ toYaml .Values.resources | indent 12 }} - {{- with .Values.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} - volumes: - - name: minio-user - secret: - secretName: {{ template "minio.fullname" . }} - - name: minio-server-config - configMap: - name: {{ template "minio.fullname" . }} - - name: minio-config-dir - emptyDir: {} - volumeClaimTemplates: - - metadata: - name: export - spec: - accessModes: [ {{ .Values.persistence.accessMode | quote }} ] - {{- if .Values.persistence.storageClass }} - storageClassName: {{ .Values.persistence.storageClass }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size }} -{{- end }} diff --git a/util/helm/testdata/minio/values.yaml b/util/helm/testdata/minio/values.yaml deleted file mode 100644 index 9c93550e9..000000000 --- a/util/helm/testdata/minio/values.yaml +++ /dev/null @@ -1,237 +0,0 @@ -## Set default image, imageTag, and imagePullPolicy. mode is used to indicate the -## -image: - repository: minio/minio - tag: RELEASE.2018-07-10T01-42-11Z - pullPolicy: IfNotPresent - -## Set default image, imageTag, and imagePullPolicy for the `mc` (the minio -## client used to create a default bucket). -## -mcImage: - repository: minio/mc - tag: RELEASE.2018-06-09T02-18-09Z - pullPolicy: IfNotPresent - -## minio server mode, i.e. standalone or distributed. -## Distributed Minio ref: https://docs.minio.io/docs/distributed-minio-quickstart-guide -## -mode: standalone - -## Pod priority settings -## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ -## -priorityClassName: "" - -## Set default accesskey, secretkey, Minio config file path, volume mount path and -## number of nodes (only used for Minio distributed mode) -## Distributed Minio ref: https://docs.minio.io/docs/distributed-minio-quickstart-guide -## -accessKey: "AKIAIOSFODNN7EXAMPLE" -secretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" -configPath: "/root/.minio/" -mountPath: "/export" -replicas: 4 - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - - ## minio data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - ## Storage class of PV to bind. By default it looks for standard storage class. - ## If the PV uses a different storage class, specify that here. - storageClass: standard - accessMode: ReadWriteOnce - size: 10Gi - -## If subPath is set mount a sub folder of a volume instead of the root of the volume. -## This is especially handy for volume plugins that don't natively support sub mounting (like glusterfs). -## -subPath: "" - -## Expose the Minio service to be accessed from outside the cluster (LoadBalancer service). -## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. -## ref: http://kubernetes.io/docs/user-guide/services/ -## - -service: - type: ClusterIP - clusterIP: None - port: 9000 - # nodePort: 31311 - annotations: {} - # prometheus.io/scrape: 'true' - # prometheus.io/path: '/minio/prometheus/metrics' - # prometheus.io/port: '9000' - -ingress: - enabled: false - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - path: / - hosts: - - chart-example.local - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -## -nodeSelector: {} -tolerations: [] -affinity: {} - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 256Mi - cpu: 250m - -## Create a bucket after minio install -## -defaultBucket: - enabled: false - ## If enabled, must be a string with length > 0 - name: bucket - ## Can be one of none|download|upload|public - policy: none - ## Purge if bucket exists already - purge: false - -## Use minio as an azure blob gateway, you should disable data persistence so no volume claim are created. -## https://docs.minio.io/docs/minio-gateway-for-azure -azuregateway: - enabled: false - -## Use minio as GCS (Google Cloud Storage) gateway, you should disable data persistence so no volume claim are created. -## https://docs.minio.io/docs/minio-gateway-for-gcs - -gcsgateway: - enabled: false - # credential json file of service account key - gcsKeyJson: "" - # Google cloud project-id - projectId: "" - -## Use minio on NAS backend -## https://docs.minio.io/docs/minio-gateway-for-nas - -nasgateway: - enabled: false - # Number of parallel instances - replicas: 4 - # Generally for NAS Gateway, you'd like to bind the PVC to a specific PV. To ensure that happens, PV to bind to should have - # a label like "pv: ", use value here. - pv: "" - -## https://docs.minio.io/docs/minio-bucket-notification-guide -## https://github.com/minio/minio/blob/master/docs/config -minioConfig: - region: "us-east-1" - browser: "on" - domain: "" - worm: "off" - storageClass: - standardStorageClass: "" - reducedRedundancyStorageClass: "" - cache: - drives: [] - expiry: 90 - maxuse: 80 - exclude: [] - aqmp: - enable: false - url: "" - exchange: "" - routingKey: "" - exchangeType: "" - deliveryMode: 0 - mandatory: false - immediate: false - durable: false - internal: false - noWait: false - autoDeleted: false - nats: - enable: false - address: "" - subject: "" - username: "" - password: "" - token: "" - secure: false - pingInterval: 0 - enableStreaming: false - clusterID: "" - clientID: "" - async: false - maxPubAcksInflight: 0 - elasticsearch: - enable: false - format: "namespace" - url: "" - index: "" - redis: - enable: false - format: "namespace" - address: "" - password: "" - key: "" - postgresql: - enable: false - format: "namespace" - connectionString: "" - table: "" - host: "" - port: "" - user: "" - password: "" - database: "" - kafka: - enable: false - brokers: "null" - topic: "" - webhook: - enable: false - endpoint: "" - mysql: - enable: false - format: "namespace" - dsnString: "" - table: "" - host: "" - port: "" - user: "" - password: "" - database: "" - mqtt: - enable: false - broker: "" - topic: "" - qos: 0 - clientId: "" - username: "" - password: "" - reconnectInterval: 0 - keepAliveInterval: 0 -networkPolicy: - enabled: false - allowExternal: true diff --git a/util/helm/testdata/redis/.helmignore b/util/helm/testdata/redis/.helmignore deleted file mode 100644 index b2767ae17..000000000 --- a/util/helm/testdata/redis/.helmignore +++ /dev/null @@ -1,3 +0,0 @@ -.git -# OWNERS file for Kubernetes -OWNERS diff --git a/util/helm/testdata/redis/Chart.yaml b/util/helm/testdata/redis/Chart.yaml deleted file mode 100644 index e7469f005..000000000 --- a/util/helm/testdata/redis/Chart.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: redis -version: 3.6.5 -appVersion: 4.0.10 -description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. -keywords: -- redis -- keyvalue -- database -home: http://redis.io/ -icon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png -sources: -- https://github.com/bitnami/bitnami-docker-redis -maintainers: -- name: bitnami-bot - email: containers@bitnami.com -engine: gotpl diff --git a/util/helm/testdata/redis/OWNERS b/util/helm/testdata/redis/OWNERS deleted file mode 100644 index e74df3ff3..000000000 --- a/util/helm/testdata/redis/OWNERS +++ /dev/null @@ -1,12 +0,0 @@ -approvers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- juan131 -reviewers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- juan131 \ No newline at end of file diff --git a/util/helm/testdata/redis/README.md b/util/helm/testdata/redis/README.md deleted file mode 100644 index e15f59e13..000000000 --- a/util/helm/testdata/redis/README.md +++ /dev/null @@ -1,205 +0,0 @@ -# Redis - -[Redis](http://redis.io/) is an advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs. - -## TL;DR - -```bash -# Testing configuration -$ helm install stable/redis -``` - -```bash -# Production configuration -$ helm install stable/redis --values values-production.yaml -``` - -## Introduction - -This chart bootstraps a [Redis](https://github.com/bitnami/bitnami-docker-redis) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -## Prerequisites - -- Kubernetes 1.8+ -- PV provisioner support in the underlying infrastructure - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```bash -$ helm install --name my-release stable/redis -``` - -The command deploys Redis on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## Uninstalling the Chart - -To uninstall/delete the `my-release` deployment: - -```bash -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Configuration - -The following table lists the configurable parameters of the Redis chart and their default values. - -| Parameter | Description | Default | -|--------------------------------------------|----------------------------------------------------------------------------------------------------------------|--------------------------------------| -| `image.registry` | Redis Image registry | `docker.io` | -| `image.repository` | Redis Image name | `bitnami/redis` | -| `image.tag` | Redis Image tag | `{VERSION}` | -| `image.pullPolicy` | Image pull policy | `Always` | -| `image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | -| `cluster.enabled` | Use master-slave topology | `true` | -| `cluster.slaveCount` | Number of slaves | 1 | -| `existingSecret` | Name of existing secret object (for password authentication) | `nil` | -| `usePassword` | Use password | `true` | -| `password` | Redis password (ignored if existingSecret set) | Randomly generated | -| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | -| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | -| `serviceAccount.create` | Specifies whether a ServiceAccount should be created | `false` | -| `serviceAccount.name` | The name of the ServiceAccount to create | Generated using the fullname template | -| `rbac.create` | Specifies whether RBAC resources should be created | `false` | -| `rbac.role.rules` | Rules to create | `[]` | -| `metrics.enabled` | Start a side-car prometheus exporter | `false` | -| `metrics.image.registry` | Redis exporter image registry | `docker.io` | -| `metrics.image.repository` | Redis exporter image name | `bitnami/redis` | -| `metrics.image.tag` | Redis exporter image tag | `v0.20.2` | -| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` | -| `metrics.podLabels` | Additional labels for Metrics exporter pod | {} | -| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | {} | -| `master.service.type` | Kubernetes Service type (redis metrics) | `LoadBalancer` | -| `metrics.service.annotations` | Annotations for the services to monitor (redis master and redis slave service) | {} | -| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `nil` | -| `metrics.resources` | Exporter resource requests/limit | Memory: `256Mi`, CPU: `100m` | -| `persistence.existingClaim` | Provide an existing PersistentVolumeClaim | `nil` | -| `master.persistence.enabled` | Use a PVC to persist data (master node) | `true` | -| `master.persistence.path` | Path to mount the volume at, to use other images | `/bitnami` | -| `master.persistence.subPath` | Subdirectory of the volume to mount at | `""` | -| `master.persistence.storageClass` | Storage class of backing PVC | `generic` | -| `master.persistence.accessModes` | Persistent Volume Access Modes | `[ReadWriteOnce]` | -| `master.persistence.size` | Size of data volume | `8Gi` | -| `master.statefulset.updateStrategy` | Update strategy for StatefulSet | onDelete | -| `master.statefulset.rollingUpdatePartition`| Partition update strategy | `nil` | -| `master.podLabels` | Additional labels for Redis master pod | {} | -| `master.podAnnotations` | Additional annotations for Redis master pod | {} | -| `master.port` | Redis master port | 6379 | -| `master.args` | Redis master command-line args | [] | -| `master.disableCommands` | Comma-separated list of Redis commands to disable (master) | `FLUSHDB,FLUSHALL` | -| `master.extraFlags` | Redis master additional command line flags | [] | -| `master.nodeSelector` | Redis master Node labels for pod assignment | {"beta.kubernetes.io/arch": "amd64"} | -| `master.tolerations` | Toleration labels for Redis master pod assignment | [] | -| `master.affinity ` | Affinity settings for Redis master pod assignment | [] | -| `master.schedulerName` | Name of an alternate scheduler | `nil` | -| `master.service.type` | Kubernetes Service type (redis master) | `ClusterIP` | -| `master.service.annotations` | annotations for redis master service | {} | -| `master.service.loadBalancerIP` | loadBalancerIP if redis master service type is `LoadBalancer` | `nil` | -| `master.securityContext.enabled` | Enable security context (redis master pod) | `true` | -| `master.securityContext.fsGroup` | Group ID for the container (redis master pod) | `1001` | -| `master.securityContext.runAsUser` | User ID for the container (redis master pod) | `1001` | -| `master.resources` | Redis master CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | -| `master.livenessProbe.enabled` | Turn on and off liveness probe (redis master pod) | `true` | -| `master.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis master pod) | `30` | -| `master.livenessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `30` | -| `master.livenessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `5` | -| `master.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | -| `master.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `master.readinessProbe.enabled` | Turn on and off readiness probe (redis master pod) | `true` | -| `master.readinessProbe.initialDelaySeconds`| Delay before readiness probe is initiated (redis master pod) | `5` | -| `master.readinessProbe.periodSeconds` | How often to perform the probe (redis master pod) | `10` | -| `master.readinessProbe.timeoutSeconds` | When the probe times out (redis master pod) | `1` | -| `master.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis master pod) | `1` | -| `master.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `5` | -| `slave.serviceType` | Kubernetes Service type (redis slave) | `LoadBalancer` | -| `slave.service.annotations` | annotations for redis slave service | {} | -| `slave.service.loadBalancerIP` | LoadBalancerIP if Redis slave service type is `LoadBalancer` | `nil` | -| `slave.port` | Redis slave port | `master.port` | -| `slave.args` | Redis slave command-line args | `master.args` | -| `slave.disableCommands` | Comma-separated list of Redis commands to disable (slave) | `master.disableCommands` | -| `slave.extraFlags` | Redis slave additional command line flags | `master.extraFlags` | -| `slave.livenessProbe.enabled` | Turn on and off liveness probe (redis slave pod) | `master.livenessProbe.enabled` | -| `slave.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (redis slave pod) | `master.livenessProbe.initialDelaySeconds` | -| `slave.livenessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `master.livenessProbe.periodSeconds` | -| `slave.livenessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `master.livenessProbe.timeoutSeconds` | -| `slave.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `master.livenessProbe.successThreshold` | -| `slave.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `master.livenessProbe.failureThreshold` | -| `slave.readinessProbe.enabled` | Turn on and off slave.readiness probe (redis slave pod) | `master.readinessProbe.enabled` | -| `slave.readinessProbe.initialDelaySeconds` | Delay before slave.readiness probe is initiated (redis slave pod) | `master.readinessProbe.initialDelaySeconds` | -| `slave.readinessProbe.periodSeconds` | How often to perform the probe (redis slave pod) | `master.readinessProbe.periodSeconds` | -| `slave.readinessProbe.timeoutSeconds` | When the probe times out (redis slave pod) | `master.readinessProbe.timeoutSeconds` | -| `slave.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (redis slave pod) | `master.readinessProbe.successThreshold` | -| `slave.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. (redis slave pod) | `master.readinessProbe.failureThreshold` | -| `slave.podLabels` | Additional labels for Redis slave pod | `master.podLabels` | -| `slave.podAnnotations` | Additional annotations for Redis slave pod | `master.podAnnotations` | -| `slave.schedulerName` | Name of an alternate scheduler | `nil` | -| `slave.securityContext.enabled` | Enable security context (redis slave pod) | `master.securityContext.enabled` | -| `slave.securityContext.fsGroup` | Group ID for the container (redis slave pod) | `master.securityContext.fsGroup` | -| `slave.securityContext.runAsUser` | User ID for the container (redis slave pod) | `master.securityContext.runAsUser` | -| `slave.resources` | Redis slave CPU/Memory resource requests/limits | `master.resources` | -| `slave.affinity` | Enable node/pod affinity for slaves | {} | - -The above parameters map to the env variables defined in [bitnami/redis](http://github.com/bitnami/bitnami-docker-redis). For more information please refer to the [bitnami/redis](http://github.com/bitnami/bitnami-docker-redis) image documentation. - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```bash -$ helm install --name my-release \ - --set password=secretpassword \ - stable/redis -``` - -The above command sets the Redis server password to `secretpassword`. - -Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, - -```bash -$ helm install --name my-release -f values.yaml stable/redis -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -> **Note for minikube users**: Current versions of minikube (v0.24.1 at the time of writing) provision `hostPath` persistent volumes that are only writable by root. Using chart defaults cause pod failure for the Redis pod as it attempts to write to the `/bitnami` directory. Consider installing Redis with `--set persistence.enabled=false`. See minikube issue [1990](https://github.com/kubernetes/minikube/issues/1990) for more information. - -## NetworkPolicy - -To enable network policy for Redis, install -[a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), -and set `networkPolicy.enabled` to `true`. - -For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting -the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: - - kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" - -With NetworkPolicy enabled, only pods with the generated client label will be -able to connect to Redis. This label will be displayed in the output -after a successful install. - -## Persistence - -The [Bitnami Redis](https://github.com/bitnami/bitnami-docker-redis) image stores the Redis data and configurations at the `/bitnami` path of the container. - -By default, the chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) at this location. The volume is created using dynamic volume provisioning. If a Persistent Volume Claim already exists, specify it during installation. - -By default, the chart persists both data and configuration. If you wish to persist only the data directory set `persistence.path` to `/bitnami/redis/data` and `persistence.subPath` to `redis/data`. - -### Existing PersistentVolumeClaim - -1. Create the PersistentVolume -1. Create the PersistentVolumeClaim -1. Install the chart - -```bash -$ helm install --set persistence.existingClaim=PVC_NAME stable/redis -``` - -## Metrics - -The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9121) is exposed in the service. Metrics can be scraped from within the cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). If metrics are to be scraped from outside the cluster, the Kubernetes API proxy can be utilized to access the endpoint. diff --git a/util/helm/testdata/redis/templates/NOTES.txt b/util/helm/testdata/redis/templates/NOTES.txt deleted file mode 100644 index 47a72bdde..000000000 --- a/util/helm/testdata/redis/templates/NOTES.txt +++ /dev/null @@ -1,89 +0,0 @@ -** Please be patient while the chart is being deployed ** - -{{- if contains .Values.master.service.type "LoadBalancer" }} -{{- if not .Values.usePassword }} -{{ if and (not .Values.networkPolicy.enabled) (.Values.networkPolicy.allowExternal) }} - -------------------------------------------------------------------------------- - WARNING - - By specifying "master.service.type=LoadBalancer" and "usePassword=false" you have - most likely exposed the Redis service externally without any authentication - mechanism. - - For security reasons, we strongly suggest that you switch to "ClusterIP" or - "NodePort". As alternative, you can also switch to "usePassword=true" - providing a valid password on "password" parameter. - -------------------------------------------------------------------------------- -{{- end }} -{{- end }} -{{- end }} - -{{- if .Values.cluster.enabled }} -Redis can be accessed via port {{ .Values.master.port }} on the following DNS names from within your cluster: - -{{ template "redis.fullname" . }}-master.{{ .Release.Namespace }}.svc.cluster.local for read/write operations -{{ template "redis.fullname" . }}-slave.{{ .Release.Namespace }}.svc.cluster.local for read-only operations - -{{- else }} -Redis can be accessed via port {{ .Values.master.port }} on the following DNS name from within your cluster: - -{{ template "redis.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - -{{- end }} - -{{ if .Values.usePassword }} -To get your password run: - - export REDIS_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }} -o jsonpath="{.data.redis-password}" | base64 --decode) -{{- end }} - -To connect to your Redis server: - -1. Run a Redis pod that you can use as a client: - - kubectl run --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }}-client --rm --tty -i \ - {{ if .Values.usePassword }} --env REDIS_PASSWORD=$REDIS_PASSWORD \{{ end }} - {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis.name" . }}-client=true" \{{- end }} - --image {{ template "redis.image" . }} -- bash - -2. Connect using the Redis CLI: - -{{- if .Values.cluster.enabled }} - redis-cli -h {{ template "redis.fullname" . }}-master{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - redis-cli -h {{ template "redis.fullname" . }}-slave{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} -{{- else }} - redis-cli -h {{ template "redis.fullname" . }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} -{{- end }} - -{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} -Note: Since NetworkPolicy is enabled, only pods with label -{{ template "redis.fullname" . }}-client=true" -will be able to connect to redis. -{{- else -}} - -To connect to your database from outside the cluster execute the following commands: - -{{- if contains "NodePort" .Values.master.service.type }} - - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "redis.fullname" . }}-master) - redis-cli -h $NODE_IP -p $NODE_PORT {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- else if contains "LoadBalancer" .Values.master.service.type }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "redis.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "redis.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - redis-cli -h $SERVICE_IP -p {{ .Values.master.service.nodePort }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- else if contains "ClusterIP" .Values.master.service.type }} - - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "redis.name" . }}" -o jsonpath="{.items[0].metadata.name}") - kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME {{ .Values.master.port }}:{{ .Values.master.port }} - redis-cli -h 127.0.0.1 -p {{ .Values.master.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} - -{{- end }} -{{- end }} diff --git a/util/helm/testdata/redis/templates/_helpers.tpl b/util/helm/testdata/redis/templates/_helpers.tpl deleted file mode 100644 index af5aada51..000000000 --- a/util/helm/testdata/redis/templates/_helpers.tpl +++ /dev/null @@ -1,130 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "redis.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Expand the chart plus release name (used by the chart label) -*/}} -{{- define "redis.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "redis.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Return the appropriate apiVersion for networkpolicy. -*/}} -{{- define "networkPolicy.apiVersion" -}} -{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} -{{- print "extensions/v1beta1" -}} -{{- else -}} -{{- print "networking.k8s.io/v1" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the proper image name -*/}} -{{- define "redis.image" -}} -{{- $registryName := .Values.image.registry -}} -{{- $repositoryName := .Values.image.repository -}} -{{- $tag := .Values.image.tag | toString -}} -{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} - -{{/* -Return the proper image name (for the metrics image) -*/}} -{{- define "metrics.image" -}} -{{- $registryName := .Values.metrics.image.registry -}} -{{- $repositoryName := .Values.metrics.image.repository -}} -{{- $tag := .Values.metrics.image.tag | toString -}} -{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- end -}} - -{{/* -Return slave readiness probe -*/}} -{{- define "redis.slave.readinessProbe" -}} -{{- $readinessProbe := .Values.slave.readinessProbe | default .Values.master.readinessProbe -}} -{{- if $readinessProbe }} -{{- if $readinessProbe.enabled }} -readinessProbe: - initialDelaySeconds: {{ $readinessProbe.initialDelaySeconds | default .Values.master.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ $readinessProbe.periodSeconds | default .Values.master.readinessProbe.periodSeconds }} - timeoutSeconds: {{ $readinessProbe.timeoutSeconds | default .Values.master.readinessProbe.timeoutSeconds }} - successThreshold: {{ $readinessProbe.successThreshold | default .Values.master.readinessProbe.successThreshold }} - failureThreshold: {{ $readinessProbe.failureThreshold | default .Values.master.readinessProbe.failureThreshold }} - exec: - command: - - redis-cli - - ping -{{- end }} -{{- end -}} -{{- end -}} - -{{/* -Return slave liveness probe -*/}} -{{- define "redis.slave.livenessProbe" -}} -{{- $livenessProbe := .Values.slave.livenessProbe | default .Values.master.livenessProbe -}} -{{- if $livenessProbe }} -{{- if $livenessProbe.enabled }} -livenessProbe: - initialDelaySeconds: {{ $livenessProbe.initialDelaySeconds | default .Values.master.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ $livenessProbe.periodSeconds | default .Values.master.livenessProbe.periodSeconds }} - timeoutSeconds: {{ $livenessProbe.timeoutSeconds | default .Values.master.livenessProbe.timeoutSeconds }} - successThreshold: {{ $livenessProbe.successThreshold | default .Values.master.livenessProbe.successThreshold }} - failureThreshold: {{ $livenessProbe.failureThreshold | default .Values.master.livenessProbe.failureThreshold}} - exec: - command: - - redis-cli - - ping -{{- end }} -{{- end -}} -{{- end -}} - -{{/* -Return slave security context -*/}} -{{- define "redis.slave.securityContext" -}} -{{- $securityContext := .Values.slave.securityContext | default .Values.master.securityContext -}} -{{- if $securityContext }} -{{- if $securityContext.enabled }} -securityContext: - fsGroup: {{ $securityContext.fsGroup | default .Values.master.securityContext.fsGroup }} - runAsUser: {{ $securityContext.runAsUser | default .Values.master.securityContext.runAsUser }} -{{- end }} -{{- end }} -{{- end -}} - -{{/* -Create the name of the service account to use -*/}} -{{- define "redis.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include "redis.fullname" .) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} diff --git a/util/helm/testdata/redis/templates/metrics-deployment.yaml b/util/helm/testdata/redis/templates/metrics-deployment.yaml deleted file mode 100644 index 2f6e1cc84..000000000 --- a/util/helm/testdata/redis/templates/metrics-deployment.yaml +++ /dev/null @@ -1,70 +0,0 @@ -{{- if .Values.metrics.enabled }} -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ template "redis.fullname" . }}-metrics - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - template: - metadata: - labels: - release: "{{ .Release.Name }}" - role: metrics - app: {{ template "redis.name" . }} - {{- if .Values.metrics.podLabels }} -{{ toYaml .Values.metrics.podLabels | indent 8 }} - {{- end }} - {{- if .Values.metrics.podAnnotations }} - annotations: -{{ toYaml .Values.metrics.podAnnotations | indent 8 }} - {{- end }} - spec: - {{- if .Values.metrics.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.metrics.image.pullSecrets }} - - name: {{ . }} - {{- end}} - {{- end}} - {{- if .Values.metrics.nodeSelector }} - serviceAccountName: "{{ template "redis.serviceAccountName" . }}" - nodeSelector: -{{ toYaml .Values.metrics.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.metrics.tolerations }} - tolerations: -{{ toYaml .Values.metrics.tolerations | indent 8 }} - {{- end }} - containers: - - name: metrics - image: {{ template "metrics.image" . }} - imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} - env: - - name: REDIS_ADDR - {{- if .Values.cluster.enabled }} - value: {{ printf "%s-master:%d,%s-slave:%d" ( include "redis.fullname" . ) ( int .Values.master.port ) ( include "redis.fullname" . ) ( .Values.slave.port | default .Values.master.port | int ) | quote }} - {{- else }} - value: {{ printf "%s-master:%d" (include "redis.fullname" . ) (int .Values.master.port) | quote }} - {{- end }} - - name: REDIS_ALIAS - value: {{ template "redis.fullname" . }} - {{- if .Values.usePassword }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - {{- if .Values.existingSecret }} - name: {{ .Values.existingSecret }} - {{- else }} - name: {{ template "redis.fullname" . }} - {{- end }} - key: redis-password - {{- end }} - ports: - - name: metrics - containerPort: 9121 - resources: -{{ toYaml .Values.metrics.resources | indent 10 }} -{{- end }} diff --git a/util/helm/testdata/redis/templates/metrics-svc.yaml b/util/helm/testdata/redis/templates/metrics-svc.yaml deleted file mode 100644 index 269f1fc60..000000000 --- a/util/helm/testdata/redis/templates/metrics-svc.yaml +++ /dev/null @@ -1,27 +0,0 @@ -{{- if .Values.metrics.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-metrics - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" - annotations: -{{ toYaml .Values.metrics.service.annotations | indent 4 }} -spec: - type: {{ .Values.metrics.service.type }} - {{ if eq .Values.metrics.service.type "LoadBalancer" -}} {{ if .Values.metrics.service.loadBalancerIP -}} - loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} - {{ end -}} - {{- end -}} - ports: - - name: metrics - port: 9121 - targetPort: metrics - selector: - app: {{ template "redis.name" . }} - release: {{ .Release.Name }} - role: metrics -{{- end }} diff --git a/util/helm/testdata/redis/templates/networkpolicy.yaml b/util/helm/testdata/redis/templates/networkpolicy.yaml deleted file mode 100644 index d6e721be2..000000000 --- a/util/helm/testdata/redis/templates/networkpolicy.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -kind: NetworkPolicy -apiVersion: {{ template "networkPolicy.apiVersion" . }} -metadata: - name: "{{ template "redis.fullname" . }}" - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - podSelector: - matchLabels: - app: {{ template "redis.name" . }} - ingress: - # Allow inbound connections - - ports: - - port: 6379 - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ template "redis.fullname" . }}-client: "true" - {{- end }} - {{- if .Values.metrics.enabled }} - # Allow prometheus scrapes for metrics - - ports: - - port: 9121 - {{- end }} -{{- end }} diff --git a/util/helm/testdata/redis/templates/redis-master-statefulset.yaml b/util/helm/testdata/redis/templates/redis-master-statefulset.yaml deleted file mode 100644 index 76482705f..000000000 --- a/util/helm/testdata/redis/templates/redis-master-statefulset.yaml +++ /dev/null @@ -1,166 +0,0 @@ -apiVersion: apps/v1beta2 -kind: StatefulSet -metadata: - name: {{ template "redis.fullname" . }}-master - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - selector: - matchLabels: - release: "{{ .Release.Name }}" - role: master - app: {{ template "redis.name" . }} - serviceName: "redis-master" - template: - metadata: - labels: - release: "{{ .Release.Name }}" - role: master - app: {{ template "redis.name" . }} -{{- if .Values.master.podLabels }} -{{ toYaml .Values.master.podLabels | indent 8 }} -{{- end }} - {{- if .Values.master.podAnnotations }} - annotations: -{{ toYaml .Values.master.podAnnotations | indent 8 }} - {{- end }} - spec: - {{- if .Values.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.image.pullSecrets }} - - name: {{ . }} - {{- end}} - {{- end}} - {{- if .Values.master.securityContext.enabled }} - securityContext: - fsGroup: {{ .Values.master.securityContext.fsGroup }} - runAsUser: {{ .Values.master.securityContext.runAsUser }} - {{- end }} - serviceAccountName: "{{ template "redis.serviceAccountName" . }}" - {{- with .Values.master.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- if .Values.master.nodeSelector }} - nodeSelector: -{{ toYaml .Values.master.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.master.tolerations }} - tolerations: -{{ toYaml .Values.master.tolerations | indent 8 }} - {{- end }} - {{- if .Values.master.schedulerName }} - schedulerName: "{{ .Values.master.schedulerName }}" - {{- end }} - containers: - - name: {{ template "redis.fullname" . }} - image: "{{ template "redis.image" . }}" - imagePullPolicy: {{ default "" .Values.image.pullPolicy | quote }} - {{- if .Values.master.args }} - args: -{{ toYaml .Values.master.args | indent 10 }} - {{- end }} - env: - - name: REDIS_REPLICATION_MODE - value: master - {{- if .Values.usePassword }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - {{- if .Values.existingSecret }} - name: {{ .Values.existingSecret }} - {{- else }} - name: {{ template "redis.fullname" . }} - {{- end }} - key: redis-password - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - - name: REDIS_PORT - value: {{ .Values.master.port | quote }} - {{- end }} - - name: REDIS_DISABLE_COMMANDS - value: {{ .Values.master.disableCommands }} - {{- if .Values.master.extraFlags }} - - name: REDIS_EXTRA_FLAGS - value: {{ .Values.master.extraFlags | join " " }} - {{- end }} - ports: - - name: redis - containerPort: {{ .Values.master.port }} - {{- if .Values.master.livenessProbe.enabled }} - livenessProbe: - initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.master.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.master.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.master.livenessProbe.failureThreshold }} - exec: - command: - - redis-cli - - ping - {{- end }} - {{- if .Values.master.readinessProbe.enabled}} - readinessProbe: - initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.master.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.master.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.master.readinessProbe.failureThreshold }} - exec: - command: - - redis-cli - - ping - {{- end }} - resources: -{{ toYaml .Values.master.resources | indent 10 }} - volumeMounts: - - name: redis-data - mountPath: {{ .Values.master.persistence.path }} - subPath: {{ .Values.master.persistence.subPath }} - {{- if not .Values.master.persistence.enabled }} - volumes: - - name: "redis-data" - emptyDir: {} - {{- else }} - {{- if .Values.persistence.existingClaim }} - volumes: - - name: "redis-data" - persistentVolumeClaim: - claimName: {{ .Values.persistence.existingClaim }} - {{- else }} - volumeClaimTemplates: - - metadata: - name: redis-data - labels: - app: "{{ template "redis.name" . }}" - chart: {{ template "redis.chart" . }} - component: "master" - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - spec: - accessModes: - {{- range .Values.master.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.master.persistence.size | quote }} - {{- if .Values.master.persistence.storageClass }} - {{- if (eq "-" .Values.master.persistence.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: {{ .Values.master.persistence.storageClass | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - updateStrategy: - type: {{ .Values.master.statefulset.updateStrategy }} - {{- if .Values.master.statefulset.rollingUpdatePartition }} - rollingUpdate: - partition: {{ .Values.master.statefulset.rollingUpdatePartition }} - {{- end }} diff --git a/util/helm/testdata/redis/templates/redis-master-svc.yaml b/util/helm/testdata/redis/templates/redis-master-svc.yaml deleted file mode 100644 index bd569b9ae..000000000 --- a/util/helm/testdata/redis/templates/redis-master-svc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-master - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" - annotations: -{{- if .Values.master.service.annotations }} -{{ toYaml .Values.master.service.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.master.service.type }} - {{ if eq .Values.master.service.type "LoadBalancer" -}} {{ if .Values.master.service.loadBalancerIP -}} - loadBalancerIP: {{ .Values.master.service.loadBalancerIP }} - {{ end -}} - {{- end -}} - ports: - - name: redis - port: 6379 - targetPort: redis - selector: - app: {{ template "redis.name" . }} - release: "{{ .Release.Name }}" - {{- if .Values.cluster.enabled }} - role: master - {{- end }} diff --git a/util/helm/testdata/redis/templates/redis-role.yaml b/util/helm/testdata/redis/templates/redis-role.yaml deleted file mode 100644 index 26e04b727..000000000 --- a/util/helm/testdata/redis/templates/redis-role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.role.rules -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -rules: -{{ toYaml .Values.rbac.role.rules }} -{{- end -}} diff --git a/util/helm/testdata/redis/templates/redis-rolebinding.yaml b/util/helm/testdata/redis/templates/redis-rolebinding.yaml deleted file mode 100644 index 3a641097e..000000000 --- a/util/helm/testdata/redis/templates/redis-rolebinding.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "redis.fullname" . }} -subjects: -- kind: ServiceAccount - name: {{ template "redis.serviceAccountName" . }} -{{- end -}} diff --git a/util/helm/testdata/redis/templates/redis-serviceaccount.yaml b/util/helm/testdata/redis/templates/redis-serviceaccount.yaml deleted file mode 100644 index 392fb3f01..000000000 --- a/util/helm/testdata/redis/templates/redis-serviceaccount.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "redis.serviceAccountName" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -{{- end -}} diff --git a/util/helm/testdata/redis/templates/redis-slave-deployment.yaml b/util/helm/testdata/redis/templates/redis-slave-deployment.yaml deleted file mode 100644 index 7aca36a7b..000000000 --- a/util/helm/testdata/redis/templates/redis-slave-deployment.yaml +++ /dev/null @@ -1,108 +0,0 @@ -{{- if .Values.cluster.enabled }} -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ template "redis.fullname" . }}-slave - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: -{{- if .Values.cluster.slaveCount }} - replicas: {{ .Values.cluster.slaveCount }} -{{- end }} - template: - metadata: - labels: - release: "{{ .Release.Name }}" - role: slave - app: {{ template "redis.name" . }} - {{- if (.Values.slave.podLabels | default .Values.master.podLabels) }} -{{ toYaml (.Values.slave.podLabels | default .Values.master.podLabels) | indent 8 }} - {{- end }} - {{- if (.Values.slave.podAnnotations | default .Values.master.podAnnotations) }} - annotations: -{{ toYaml (.Values.slave.podAnnotations | default .Values.master.podAnnotations) | indent 8 }} - {{- end }} - spec: - {{- if .Values.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.image.pullSecrets }} - - name: {{ . }} - {{- end}} - {{- end}} - {{- /* Include master securityContext if slave securityContext not defined */ -}} - {{ include "redis.slave.securityContext" . | indent 6 }} - serviceAccountName: "{{ template "redis.serviceAccountName" . }}" - {{- if (.Values.slave.nodeSelector | default .Values.master.nodeSelector) }} - nodeSelector: -{{ toYaml (.Values.slave.nodeSelector | default .Values.master.nodeSelector) | indent 8 }} - {{- end }} - {{- if (.Values.slave.tolerations | default .Values.master.tolerations) }} - tolerations: -{{ toYaml (.Values.slave.tolerations | default .Values.master.tolerations) | indent 8 }} - {{- end }} - {{- if .Values.slave.schedulerName }} - schedulerName: "{{ .Values.slave.schedulerName }}" - {{- end }} - {{- with .Values.slave.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - containers: - - name: {{ template "redis.fullname" . }} - image: {{ template "redis.image" . }} - imagePullPolicy: {{ .Values.image.pullPolicy | default "" | quote }} - {{- if (.Values.slave.args | default .Values.master.args) }} - args: -{{ toYaml (.Values.slave.args | default .Values.master.args) | indent 10 }} - {{- end }} - env: - - name: REDIS_REPLICATION_MODE - value: slave - - name: REDIS_MASTER_HOST - value: {{ template "redis.fullname" . }}-master - - name: REDIS_PORT - value: {{ .Values.slave.port | default .Values.master.port | quote }} - - name: REDIS_MASTER_PORT_NUMBER - value: {{ .Values.master.port | quote }} - {{- if .Values.usePassword }} - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - {{- if .Values.existingSecret }} - name: {{ .Values.existingSecret }} - {{- else }} - name: {{ template "redis.fullname" . }} - {{- end }} - key: redis-password - - name: REDIS_MASTER_PASSWORD - valueFrom: - secretKeyRef: - {{- if .Values.existingSecret }} - name: {{ .Values.existingSecret }} - {{- else }} - name: {{ template "redis.fullname" . }} - {{- end }} - key: redis-password - {{- else }} - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - {{- end }} - - name: REDIS_DISABLE_COMMANDS - value: {{ .Values.slave.disableCommands | default .Values.master.disableCommands }} - {{- if (.Values.slave.extraFlags | default .Values.master.extraFlags) }} - - name: REDIS_EXTRA_FLAGS - value: {{ .Values.slave.extraFlags | default .Values.master.extraFlags | join " " }} - {{- end }} - ports: - - name: redis - containerPort: {{ .Values.slave.port | default .Values.master.port }} - {{- /* Include master livenessProbe if slave livenessProbe not defined */ -}} - {{ include "redis.slave.livenessProbe" . | indent 8 }} - {{- /* Include master readinessProbe if slave readinessProbe not defined */ -}} - {{ include "redis.slave.readinessProbe" . | indent 8 }} - resources: -{{ toYaml (.Values.slave.resources | default .Values.master.resources) | indent 10 }} -{{- end }} diff --git a/util/helm/testdata/redis/templates/redis-slave-svc.yaml b/util/helm/testdata/redis/templates/redis-slave-svc.yaml deleted file mode 100644 index 4fd79bfb6..000000000 --- a/util/helm/testdata/redis/templates/redis-slave-svc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if .Values.cluster.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "redis.fullname" . }}-slave - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" - annotations: -{{- if .Values.slave.service.annotations }} -{{ toYaml .Values.slave.service.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.slave.service.type }} - {{ if eq .Values.slave.service.type "LoadBalancer" -}} {{ if .Values.slave.service.loadBalancerIP -}} - loadBalancerIP: {{ .Values.slave.service.loadBalancerIP }} - {{ end -}} - {{- end -}} - ports: - - name: redis - port: 6379 - targetPort: redis - selector: - app: {{ template "redis.name" . }} - release: "{{ .Release.Name }}" - role: slave -{{- end}} diff --git a/util/helm/testdata/redis/templates/secrets.yaml b/util/helm/testdata/redis/templates/secrets.yaml deleted file mode 100644 index 36c9ebf69..000000000 --- a/util/helm/testdata/redis/templates/secrets.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.usePassword (not .Values.existingSecret) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "redis.fullname" . }} - labels: - app: {{ template "redis.name" . }} - chart: {{ template "redis.chart" . }} - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - {{- if .Values.password }} - redis-password: {{ .Values.password | b64enc | quote }} - {{- else }} - redis-password: {{ randAlphaNum 10 | b64enc | quote }} - {{- end }} -{{- end -}} diff --git a/util/helm/testdata/redis/values-production.yaml b/util/helm/testdata/redis/values-production.yaml deleted file mode 100644 index 49a09b81d..000000000 --- a/util/helm/testdata/redis/values-production.yaml +++ /dev/null @@ -1,258 +0,0 @@ -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - tag: 4.0.10-debian-9 - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - - -## Cluster settings -cluster: - enabled: true - slaveCount: 3 - -metrics: - enabled: true - # resources: {} - # podAnnotations: {} - service: - type: ClusterIP - annotations: {} - # prometheus.io/scrape: "true" - # prometheus.io/port: "9121" - loadBalancerIP: - image: - registry: docker.io - repository: oliver006/redis_exporter - tag: v0.20.2 - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - ## Metrics exporter labels and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Metrics exporter pod Annotation and Labels - # podLabels: {} - -networkPolicy: - ## Enable creation of NetworkPolicy resources. - ## - enabled: true - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -usePassword: true -password: -## Use existing secret (ignores previous password) -# existingSecret: - -## -## Redis Master parameters -## -master: - ## Use password authentication - port: 6379 - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - ## args: - ## - "redis-server" - ## - "--maxmemory-policy volatile-ttl" - args: [] - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## redisExtraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## ref: https://github.com/bitnami/bitnami-docker-redis#disabling-redis-commands - ## - disableCommands: "FLUSHDB,FLUSHALL" - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - ## Redis Master additional pod labels - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Redis Master Liveness Probe - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Readiness Probe - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Master Node labels and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod annotations - podAnnotations: {} - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - ## Redis Master Pod Security Context - securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - persistence: - enabled: true - - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /bitnami/redis/data - - ## The subdirectory of the volume to mount to, useful in dev environments and one PV for multiple services. - subPath: "" - - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: OnDelete - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - -## -## Redis Slave properties -## Note: serviceType and service are mandatory parameters -## The rest of the parameters, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Redis slave optional overrides - - ## Redis port - # port: 6379 - ## Redis command arguments - # args: [] - ## Redis extra flags - # extraFlags: [] - ## Comma-separated list of Redis commands to disable - # disableCommands: "" - - affinity: {} - - ## Redis slave Liveness Probe - # livenessProbe: - # enabled: true - # initialDelaySeconds: 30 - # periodSeconds: 10 - # timeoutSeconds: 5 - # successThreshold: 1 - # failureThreshold: 5 - - ## Redis slave Readiness Probe - # readinessProbe: - # enabled: true - # initialDelaySeconds: 5 - # periodSeconds: 10 - # timeoutSeconds: 10 - # successThreshold: 1 - # failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Redis slave labels and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Redis slave pod Annotation and Labels - # podLabels: {} - ## annotations for redis pods - # podAnnotations: {} - - ## Redis slave pod Security Context - # securityContext: - # enabled: true - # fsGroup: 1001 - # runAsUser: 1001 diff --git a/util/helm/testdata/redis/values.yaml b/util/helm/testdata/redis/values.yaml deleted file mode 100644 index 7e0b44c83..000000000 --- a/util/helm/testdata/redis/values.yaml +++ /dev/null @@ -1,306 +0,0 @@ -## Bitnami Redis image version -## ref: https://hub.docker.com/r/bitnami/redis/tags/ -## -image: - registry: docker.io - repository: bitnami/redis - tag: 4.0.10-debian-9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: Always - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - - -## Cluster settings -cluster: - enabled: true - slaveCount: 1 - -metrics: - enabled: false - # resources: {} - # podAnnotations: {} - service: - type: ClusterIP - annotations: {} - # prometheus.io/scrape: "true" - # prometheus.io/port: "9121" - loadBalancerIP: - image: - registry: docker.io - repository: oliver006/redis_exporter - tag: v0.20.2 - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - - ## Metrics exporter labels and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Metrics exporter pod Annotation and Labels - # podLabels: {} - -networkPolicy: - ## Enable creation of NetworkPolicy resources. - ## - enabled: false - - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to the port Redis is listening - ## on. When true, Redis will accept connections from any source - ## (with the correct destination port). - ## - # allowExternal: true - -serviceAccount: - # Specifies whether a ServiceAccount should be created - create: false - # The name of the ServiceAccount to use. - # If not set and create is true, a name is generated using the fullname template - name: - -rbac: - # Specifies whether RBAC resources should be created - create: false - - role: - ## Rules to create. It follows the role specification - # rules: - # - apiGroups: - # - extensions - # resources: - # - podsecuritypolicies - # verbs: - # - use - # resourceNames: - # - gce.unprivileged - rules: [] - -## Redis password (both master and slave) -## Defaults to a random 10-character alphanumeric string if not set and usePassword is true -## ref: https://github.com/bitnami/bitnami-docker-redis#setting-the-server-password-on-first-run -## -usePassword: true -password: -## Use existing secret (ignores previous password) -# existingSecret: - -## Persist data to a persistent volume -persistence: {} - ## A manually managed Persistent Volume and Claim - ## Requires persistence.enabled: true - ## If defined, PVC must be created manually before volume will be bound - # existingClaim: - -## -## Redis Master parameters -## -master: - ## Use password authentication - port: 6379 - ## Redis command arguments - ## - ## Can be used to specify command line arguments, for example: - ## - ## args: - ## - "redis-server" - ## - "--maxmemory-policy volatile-ttl" - args: [] - ## Redis additional command line flags - ## - ## Can be used to specify command line flags, for example: - ## - ## redisExtraFlags: - ## - "--maxmemory-policy volatile-ttl" - ## - "--repl-backlog-size 1024mb" - extraFlags: [] - ## Comma-separated list of Redis commands to disable - ## - ## Can be used to disable Redis commands for security reasons. - ## ref: https://github.com/bitnami/bitnami-docker-redis#disabling-redis-commands - ## - disableCommands: "FLUSHDB,FLUSHALL" - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - ## Redis Master additional pod labels - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - podLabels: {} - ## Redis Master resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - - ## Redis Master Liveness Probe - livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 5 - - ## Redis Master Readiness Probe - readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 5 - ## Redis Master Node labels and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - ## Redis Master pod/node affinity/anti-affinity - affinity: {} - ## Redis Master pod annotations - podAnnotations: {} - ## Redis Master Service properties - service: - ## Redis Master Service type - type: ClusterIP - - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - ## Redis Master Pod Security Context - securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - persistence: - enabled: true - - ## The path the volume will be mounted at, useful when using different - ## Redis images. - path: /bitnami/redis/data - - ## The subdirectory of the volume to mount to, useful in dev environments and one PV for multiple services. - subPath: "" - - ## redis data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessModes: - - ReadWriteOnce - size: 8Gi - - ## Update strategy, can be set to RollingUpdate or onDelete by default. - ## https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets - statefulset: - updateStrategy: OnDelete - ## Partition update strategy - ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions - # rollingUpdatePartition: - - -## -## Redis Slave properties -## Note: serviceType and service are mandatory parameters -## The rest of the parameters, if undefined, will inherit those declared in Redis Master -## -slave: - ## Slave Service properties - service: - ## Redis Slave Service type - type: ClusterIP - ## Specify the nodePort value for the LoadBalancer and NodePort service types. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport - ## - # nodePort: - - ## Provide any additional annotations which may be required. This can be used to - ## set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - annotations: {} - loadBalancerIP: - - ## Redis port - # port: 6379 - ## Redis command arguments - # args: [] - ## Redis extra flags - # extraFlags: [] - ## Comma-separated list of Redis commands to disable - # disableCommands: "" - - affinity: {} - - ## Redis slave Liveness Probe - # livenessProbe: - # enabled: true - # initialDelaySeconds: 30 - # periodSeconds: 10 - # timeoutSeconds: 5 - # successThreshold: 1 - # failureThreshold: 5 - - ## Redis slave Readiness Probe - # readinessProbe: - # enabled: true - # initialDelaySeconds: 5 - # periodSeconds: 10 - # timeoutSeconds: 10 - # successThreshold: 1 - # failureThreshold: 5 - - ## Redis slave Resource - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - - ## Redis slave labels and tolerations for pod assignment - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - # tolerations: [] - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: - - ## Redis slave pod Annotation and Labels - # podLabels: {} - ## annotations for redis pods - # podAnnotations: {} - - ## Redis slave pod Security Context - # securityContext: - # enabled: true - # fsGroup: 1001 - # runAsUser: 1001 diff --git a/util/helm/testdata/wordpress/.helmignore b/util/helm/testdata/wordpress/.helmignore deleted file mode 100644 index e2cf7941f..000000000 --- a/util/helm/testdata/wordpress/.helmignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -# OWNERS file for Kubernetes -OWNERS -# example production yaml -values-production.yaml \ No newline at end of file diff --git a/util/helm/testdata/wordpress/Chart.yaml b/util/helm/testdata/wordpress/Chart.yaml deleted file mode 100644 index 58b6f7449..000000000 --- a/util/helm/testdata/wordpress/Chart.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: wordpress -version: 2.1.10 -appVersion: 4.9.8 -description: Web publishing platform for building blogs and websites. -icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png -keywords: -- wordpress -- cms -- blog -- http -- web -- application -- php -home: http://www.wordpress.com/ -sources: -- https://github.com/bitnami/bitnami-docker-wordpress -maintainers: -- name: bitnami-bot - email: containers@bitnami.com -engine: gotpl diff --git a/util/helm/testdata/wordpress/OWNERS b/util/helm/testdata/wordpress/OWNERS deleted file mode 100644 index e74df3ff3..000000000 --- a/util/helm/testdata/wordpress/OWNERS +++ /dev/null @@ -1,12 +0,0 @@ -approvers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- juan131 -reviewers: -- prydonius -- tompizmor -- sameersbn -- carrodher -- juan131 \ No newline at end of file diff --git a/util/helm/testdata/wordpress/README.md b/util/helm/testdata/wordpress/README.md deleted file mode 100644 index 8a5dd9b6c..000000000 --- a/util/helm/testdata/wordpress/README.md +++ /dev/null @@ -1,232 +0,0 @@ -# WordPress - -[WordPress](https://wordpress.org/) is one of the most versatile open source content management systems on the market. A publishing platform for building blogs and websites. - -## TL;DR; - -```console -$ helm install stable/wordpress -``` - -## Introduction - -This chart bootstraps a [WordPress](https://github.com/bitnami/bitnami-docker-wordpress) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -It also packages the [Bitnami MariaDB chart](https://github.com/kubernetes/charts/tree/master/stable/mariadb) which is required for bootstrapping a MariaDB deployment for the database requirements of the WordPress application. - -## Prerequisites - -- Kubernetes 1.4+ with Beta APIs enabled -- PV provisioner support in the underlying infrastructure - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```console -$ helm install --name my-release stable/wordpress -``` - -The command deploys WordPress on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## Uninstalling the Chart - -To uninstall/delete the `my-release` deployment: - -```console -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Configuration - -The following table lists the configurable parameters of the WordPress chart and their default values. - -| Parameter | Description | Default | -|----------------------------------|--------------------------------------------|---------------------------------------------------------| -| `image.registry` | WordPress image registry | `docker.io` | -| `image.repository` | WordPress image name | `bitnami/wordpress` | -| `image.tag` | WordPress image tag | `{VERSION}` | -| `image.pullPolicy` | Image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent` | -| `image.pullSecrets` | Specify image pull secrets | `nil` | -| `wordpressUsername` | User of the application | `user` | -| `wordpressPassword` | Application password | _random 10 character long alphanumeric string_ | -| `wordpressEmail` | Admin email | `user@example.com` | -| `wordpressFirstName` | First name | `FirstName` | -| `wordpressLastName` | Last name | `LastName` | -| `wordpressBlogName` | Blog name | `User's Blog!` | -| `wordpressTablePrefix` | Table prefix | `wp_` | -| `allowEmptyPassword` | Allow DB blank passwords | `true` | -| `smtpHost` | SMTP host | `nil` | -| `smtpPort` | SMTP port | `nil` | -| `smtpUser` | SMTP user | `nil` | -| `smtpPassword` | SMTP password | `nil` | -| `smtpUsername` | User name for SMTP emails | `nil` | -| `smtpProtocol` | SMTP protocol [`tls`, `ssl`] | `nil` | -| `replicaCount` | Number of WordPress Pods to run | `1` | -| `mariadb.enabled` | Deploy MariaDB container(s) | `true` | -| `mariadb.rootUser.password` | MariaDB admin password | `nil` | -| `mariadb.db.name` | Database name to create | `bitnami_wordpress` | -| `mariadb.db.user` | Database user to create | `bn_wordpress` | -| `mariadb.db.password` | Password for the database | _random 10 character long alphanumeric string_ | -| `externalDatabase.host` | Host of the external database | `localhost` | -| `externalDatabase.user` | Existing username in the external db | `bn_wordpress` | -| `externalDatabase.password` | Password for the above username | `nil` | -| `externalDatabase.database` | Name of the existing database | `bitnami_wordpress` | -| `externalDatabase.port` | Database port number | `3306` | -| `serviceType` | Kubernetes Service type | `LoadBalancer` | -| `serviceExternalTrafficPolicy` | Enable client source IP preservation | `Cluster` | -| `nodePorts.http` | Kubernetes http node port | `""` | -| `nodePorts.https` | Kubernetes https node port | `""` | -| `healthcheckHttps` | Use https for liveliness and readiness | `false` | -| `ingress.enabled` | Enable ingress controller resource | `false` | -| `ingress.hosts[0].name` | Hostname to your WordPress installation | `wordpress.local` | -| `ingress.hosts[0].path` | Path within the url structure | `/` | -| `ingress.hosts[0].tls` | Utilize TLS backend in ingress | `false` | -| `ingress.hosts[0].tlsSecret` | TLS Secret (certificates) | `wordpress.local-tls-secret` | -| `ingress.hosts[0].annotations` | Annotations for this host's ingress record | `[]` | -| `ingress.secrets[0].name` | TLS Secret Name | `nil` | -| `ingress.secrets[0].certificate` | TLS Secret Certificate | `nil` | -| `ingress.secrets[0].key` | TLS Secret Key | `nil` | -| `persistence.enabled` | Enable persistence using PVC | `true` | -| `persistence.existingClaim` | Enable persistence using an existing PVC | `nil` | -| `persistence.storageClass` | PVC Storage Class | `nil` (uses alpha storage class annotation) | -| `persistence.accessMode` | PVC Access Mode | `ReadWriteOnce` | -| `persistence.size` | PVC Storage Request | `10Gi` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `tolerations` | List of node taints to tolerate | `[]` | -| `affinity` | Map of node/pod affinities | `{}` | - -The above parameters map to the env variables defined in [bitnami/wordpress](http://github.com/bitnami/bitnami-docker-wordpress). For more information please refer to the [bitnami/wordpress](http://github.com/bitnami/bitnami-docker-wordpress) image documentation. - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```console -$ helm install --name my-release \ - --set wordpressUsername=admin,wordpressPassword=password,mariadb.mariadbRootPassword=secretpassword \ - stable/wordpress -``` - -The above command sets the WordPress administrator account username and password to `admin` and `password` respectively. Additionally, it sets the MariaDB `root` user password to `secretpassword`. - -Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, - -```console -$ helm install --name my-release -f values.yaml stable/wordpress -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -## Production and horizontal scaling - -The following repo contains the recommended production settings for wordpress capture in an alternative [values file](values-production.yaml). Please read carefully the comments in the values-production.yaml file to set up your environment appropriately. - -To horizontally scale this chart, first download the [values-production.yaml](values-production.yaml) file to your local folder, then: - -```console -$ helm install --name my-release -f ./values-production.yaml stable/wordpress -``` - -Note that [values-production.yaml](values-production.yaml) includes a replicaCount of 3, so there will be 3 WordPress pods. As a result, to use the /admin portal and to ensure you can scale wordpress you need to provide a ReadWriteMany PVC, if you don't have a provisioner for this type of storage, we recommend that you install the nfs provisioner and map it to a RWO volume. - -```console -$ helm install stable/nfs-server-provisioner --set persistence.enabled=true,persistence.size=10Gi -$ helm install --name my-release -f values-production.yaml --set persistence.storageClass=nfs stable/wordpress -``` - -## Persistence - -The [Bitnami WordPress](https://github.com/bitnami/bitnami-docker-wordpress) image stores the WordPress data and configurations at the `/bitnami` path of the container. - -Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. -See the [Configuration](#configuration) section to configure the PVC or to disable persistence. - -## Using an external database - -Sometimes you may want to have Wordpress connect to an external database rather than installing one inside your cluster, e.g. to use a managed database service, or use run a single database server for all your applications. To do this, the chart allows you to specify credentials for an external database under the [`externalDatabase` parameter](#configuration). You should also disable the MariaDB installation with the `mariadb.enabled` option. For example: - -```console -$ helm install stable/wordpress \ - --set mariadb.enabled=false,externalDatabase.host=myexternalhost,externalDatabase.user=myuser,externalDatabase.password=mypassword,externalDatabase.database=mydatabase,externalDatabase.port=3306 -``` - -Note also if you disable MariaDB per above you MUST supply values for the `externalDatabase` connection. - -## Ingress - -This chart provides support for ingress resources. If you have an -ingress controller installed on your cluster, such as [nginx-ingress](https://kubeapps.com/charts/stable/nginx-ingress) -or [traefik](https://kubeapps.com/charts/stable/traefik) you can utilize -the ingress controller to serve your WordPress application. - -To enable ingress integration, please set `ingress.enabled` to `true` - -### Hosts - -Most likely you will only want to have one hostname that maps to this -WordPress installation, however, it is possible to have more than one -host. To facilitate this, the `ingress.hosts` object is an array. - -For each item, please indicate a `name`, `tls`, `tlsSecret`, and any -`annotations` that you may want the ingress controller to know about. - -Indicating TLS will cause WordPress to generate HTTPS URLs, and -WordPress will be connected to at port 443. The actual secret that -`tlsSecret` references do not have to be generated by this chart. -However, please note that if TLS is enabled, the ingress record will not -work until this secret exists. - -For annotations, please see [this document](https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md). -Not all annotations are supported by all ingress controllers, but this -document does a good job of indicating which annotation is supported by -many popular ingress controllers. - -### TLS Secrets - -This chart will facilitate the creation of TLS secrets for use with the -ingress controller, however, this is not required. There are three -common use cases: - -* helm generates/manages certificate secrets -* user generates/manages certificates separately -* an additional tool (like [kube-lego](https://kubeapps.com/charts/stable/kube-lego)) -manages the secrets for the application - -In the first two cases, one will need a certificate and a key. We would -expect them to look like this: - -* certificate files should look like (and there can be more than one -certificate if there is a certificate chain) - -``` ------BEGIN CERTIFICATE----- -MIID6TCCAtGgAwIBAgIJAIaCwivkeB5EMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -... -jScrvkiBO65F46KioCL9h5tDvomdU1aqpI/CBzhvZn1c0ZTf87tGQR8NK7v7 ------END CERTIFICATE----- -``` -* keys should look like: -``` ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAvLYcyu8f3skuRyUgeeNpeDvYBCDcgq+LsWap6zbX5f8oLqp4 -... -wrj2wDbCDCFmfqnSJ+dKI3vFLlEz44sAV8jX/kd4Y6ZTQhlLbYc= ------END RSA PRIVATE KEY----- -```` - -If you are going to use Helm to manage the certificates, please copy -these values into the `certificate` and `key` values for a given -`ingress.secrets` entry. - -If you are going are going to manage TLS secrets outside of Helm, please -know that you can create a TLS secret by doing the following: - -``` -kubectl create secret tls wordpress.local-tls --key /path/to/key.key --cert /path/to/cert.crt -``` - -Please see [this example](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls) -for more information. diff --git a/util/helm/testdata/wordpress/charts/mariadb-4.3.1.tgz b/util/helm/testdata/wordpress/charts/mariadb-4.3.1.tgz deleted file mode 100644 index 9fd9453ff..000000000 Binary files a/util/helm/testdata/wordpress/charts/mariadb-4.3.1.tgz and /dev/null differ diff --git a/util/helm/testdata/wordpress/requirements.lock b/util/helm/testdata/wordpress/requirements.lock deleted file mode 100644 index cb3439862..000000000 --- a/util/helm/testdata/wordpress/requirements.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: mariadb - repository: https://kubernetes-charts.storage.googleapis.com/ - version: 4.3.1 -digest: sha256:82a0e5374376169d2ecf7d452c18a2ed93507f5d17c3393a1457f9ffad7e9b26 -generated: 2018-08-02T22:07:51.905271776Z diff --git a/util/helm/testdata/wordpress/requirements.yaml b/util/helm/testdata/wordpress/requirements.yaml deleted file mode 100644 index a894b8b3b..000000000 --- a/util/helm/testdata/wordpress/requirements.yaml +++ /dev/null @@ -1,7 +0,0 @@ -dependencies: -- name: mariadb - version: 4.x.x - repository: https://kubernetes-charts.storage.googleapis.com/ - condition: mariadb.enabled - tags: - - wordpress-database diff --git a/util/helm/testdata/wordpress/templates/NOTES.txt b/util/helm/testdata/wordpress/templates/NOTES.txt deleted file mode 100644 index 55626e4d1..000000000 --- a/util/helm/testdata/wordpress/templates/NOTES.txt +++ /dev/null @@ -1,38 +0,0 @@ -1. Get the WordPress URL: - -{{- if .Values.ingress.enabled }} - - You should be able to access your new WordPress installation through - - {{- range .Values.ingress.hosts }} - {{ if .tls }}https{{ else }}http{{ end }}://{{ .name }}/admin - {{- end }} - -{{- else if contains "LoadBalancer" .Values.serviceType }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo "WordPress URL: http://$SERVICE_IP/" - echo "WordPress Admin URL: http://$SERVICE_IP/admin" - -{{- else if contains "ClusterIP" .Values.serviceType }} - - echo "WordPress URL: http://127.0.0.1:8080/" - echo "WordPress Admin URL: http://127.0.0.1:8080/admin" - kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "fullname" . }} 8080:80 - -{{- else if contains "NodePort" .Values.serviceType }} - - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo "WordPress URL: http://$NODE_IP:$NODE_PORT/" - echo "WordPress Admin URL: http://$NODE_IP:$NODE_PORT/admin" - -{{- end }} - -2. Login with the following credentials to see your blog - - echo Username: {{ .Values.wordpressUsername }} - echo Password: $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.data.wordpress-password}" | base64 --decode) diff --git a/util/helm/testdata/wordpress/templates/_helpers.tpl b/util/helm/testdata/wordpress/templates/_helpers.tpl deleted file mode 100644 index 1e52d321c..000000000 --- a/util/helm/testdata/wordpress/templates/_helpers.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "mariadb.fullname" -}} -{{- printf "%s-%s" .Release.Name "mariadb" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/util/helm/testdata/wordpress/templates/deployment.yaml b/util/helm/testdata/wordpress/templates/deployment.yaml deleted file mode 100644 index f22927b6e..000000000 --- a/util/helm/testdata/wordpress/templates/deployment.yaml +++ /dev/null @@ -1,159 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ template "fullname" . }} - labels: - app: {{ template "fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - replicas: {{ .Values.replicaCount }} - template: - metadata: - labels: - app: {{ template "fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - spec: - {{- if .Values.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.image.pullSecrets }} - - name: {{ . }} - {{- end}} - {{- end }} - containers: - - name: {{ template "fullname" . }} - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - env: - - name: ALLOW_EMPTY_PASSWORD - {{- if .Values.allowEmptyPassword }} - value: "yes" - {{- else }} - value: "no" - {{- end }} - - name: MARIADB_HOST - {{- if .Values.mariadb.enabled }} - value: {{ template "mariadb.fullname" . }} - {{- else }} - value: {{ .Values.externalDatabase.host | quote }} - {{- end }} - - name: MARIADB_PORT_NUMBER - {{- if .Values.mariadb.enabled }} - value: "3306" - {{- else }} - value: {{ .Values.externalDatabase.port | quote }} - {{- end }} - - name: WORDPRESS_DATABASE_NAME - {{- if .Values.mariadb.enabled }} - value: {{ .Values.mariadb.db.name | quote }} - {{- else }} - value: {{ .Values.externalDatabase.database | quote }} - {{- end }} - - name: WORDPRESS_DATABASE_USER - {{- if .Values.mariadb.enabled }} - value: {{ .Values.mariadb.db.user | quote }} - {{- else }} - value: {{ .Values.externalDatabase.user | quote }} - {{- end }} - - name: WORDPRESS_DATABASE_PASSWORD - valueFrom: - secretKeyRef: - {{- if .Values.mariadb.enabled }} - name: {{ template "mariadb.fullname" . }} - key: mariadb-password - {{- else }} - name: {{ printf "%s-%s" .Release.Name "externaldb" }} - key: db-password - {{- end }} - - name: WORDPRESS_USERNAME - value: {{ .Values.wordpressUsername | quote }} - - name: WORDPRESS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "fullname" . }} - key: wordpress-password - - name: WORDPRESS_EMAIL - value: {{ .Values.wordpressEmail | quote }} - - name: WORDPRESS_FIRST_NAME - value: {{ .Values.wordpressFirstName | quote }} - - name: WORDPRESS_LAST_NAME - value: {{ .Values.wordpressLastName | quote }} - - name: WORDPRESS_BLOG_NAME - value: {{ .Values.wordpressBlogName | quote }} - - name: WORDPRESS_TABLE_PREFIX - value: {{ .Values.wordpressTablePrefix | quote }} - - name: SMTP_HOST - value: {{ .Values.smtpHost | quote }} - - name: SMTP_PORT - value: {{ .Values.smtpPort | quote }} - - name: SMTP_USER - value: {{ .Values.smtpUser | quote }} - - name: SMTP_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "fullname" . }} - key: smtp-password - - name: SMTP_USERNAME - value: {{ .Values.smtpUsername | quote }} - - name: SMTP_PROTOCOL - value: {{ .Values.smtpProtocol | quote }} - ports: - - name: http - containerPort: 80 - - name: https - containerPort: 443 - livenessProbe: - httpGet: - path: /wp-login.php - {{- if not .Values.healthcheckHttps }} - port: http - {{- else }} - port: https - scheme: HTTPS - {{- end }} -{{ toYaml .Values.livenessProbe | indent 10 }} - readinessProbe: - httpGet: - path: /wp-login.php - {{- if not .Values.healthcheckHttps }} - port: http - {{- else }} - port: https - scheme: HTTPS - {{- end }} -{{ toYaml .Values.readinessProbe | indent 10 }} - volumeMounts: - - mountPath: /bitnami/apache - name: wordpress-data - subPath: apache - - mountPath: /bitnami/wordpress - name: wordpress-data - subPath: wordpress - - mountPath: /bitnami/php - name: wordpress-data - subPath: php - resources: -{{ toYaml .Values.resources | indent 10 }} - volumes: - - name: wordpress-data - {{- if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ .Values.persistence.existingClaim | default (include "fullname" .) }} - {{- else }} - emptyDir: {} - {{ end }} - {{- if .Values.nodeSelector }} - nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} - {{- end -}} - {{- with .Values.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} - diff --git a/util/helm/testdata/wordpress/templates/externaldb-secrets.yaml b/util/helm/testdata/wordpress/templates/externaldb-secrets.yaml deleted file mode 100644 index 39399ae54..000000000 --- a/util/helm/testdata/wordpress/templates/externaldb-secrets.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if not .Values.mariadb.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ printf "%s-%s" .Release.Name "externaldb" }} - labels: - app: {{ printf "%s-%s" .Release.Name "externaldb" }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - db-password: {{ .Values.externalDatabase.password | b64enc | quote }} -{{- end }} diff --git a/util/helm/testdata/wordpress/templates/ingress.yaml b/util/helm/testdata/wordpress/templates/ingress.yaml deleted file mode 100644 index 7870146ff..000000000 --- a/util/helm/testdata/wordpress/templates/ingress.yaml +++ /dev/null @@ -1,36 +0,0 @@ -{{- if .Values.ingress.enabled }} -{{- range .Values.ingress.hosts }} -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: "{{- printf "%s-%s" .name $.Release.Name | trunc 63 | trimSuffix "-" -}}" - labels: - app: {{ template "fullname" $ }} - chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" - release: "{{ $.Release.Name }}" - heritage: "{{ $.Release.Service }}" - annotations: - {{- if .tls }} - ingress.kubernetes.io/secure-backends: "true" - {{- end }} - {{- range $key, $value := .annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - rules: - - host: {{ .name }} - http: - paths: - - path: {{ default "/" .path }} - backend: - serviceName: {{ template "fullname" $ }} - servicePort: 80 -{{- if .tls }} - tls: - - hosts: - - {{ .name }} - secretName: {{ .tlsSecret }} -{{- end }} ---- -{{- end }} -{{- end }} diff --git a/util/helm/testdata/wordpress/templates/pvc.yaml b/util/helm/testdata/wordpress/templates/pvc.yaml deleted file mode 100644 index b3f912480..000000000 --- a/util/helm/testdata/wordpress/templates/pvc.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ template "fullname" . }} - labels: - app: {{ template "fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - accessModes: - - {{ .Values.persistence.accessMode | quote }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} -{{- if .Values.persistence.storageClass }} -{{- if (eq "-" .Values.persistence.storageClass) }} - storageClassName: "" -{{- else }} - storageClassName: "{{ .Values.persistence.storageClass }}" -{{- end }} -{{- end }} -{{- end -}} diff --git a/util/helm/testdata/wordpress/templates/secrets.yaml b/util/helm/testdata/wordpress/templates/secrets.yaml deleted file mode 100644 index 80a28d724..000000000 --- a/util/helm/testdata/wordpress/templates/secrets.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "fullname" . }} - labels: - app: {{ template "fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - {{ if .Values.wordpressPassword }} - wordpress-password: {{ default "" .Values.wordpressPassword | b64enc | quote }} - {{ else }} - wordpress-password: {{ randAlphaNum 10 | b64enc | quote }} - {{ end }} - smtp-password: {{ default "" .Values.smtpPassword | b64enc | quote }} diff --git a/util/helm/testdata/wordpress/templates/svc.yaml b/util/helm/testdata/wordpress/templates/svc.yaml deleted file mode 100644 index f6c399313..000000000 --- a/util/helm/testdata/wordpress/templates/svc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "fullname" . }} - labels: - app: {{ template "fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - type: {{ .Values.serviceType }} - {{- if (or (eq .Values.serviceType "LoadBalancer") (eq .Values.serviceType "NodePort")) }} - externalTrafficPolicy: {{ .Values.serviceExternalTrafficPolicy | quote }} - {{- end }} - ports: - - name: http - port: 80 - targetPort: http - {{- if (and (eq .Values.serviceType "NodePort") (not (empty .Values.nodePorts.http)))}} - nodePort: {{ .Values.nodePorts.http }} - {{- end }} - - name: https - port: 443 - targetPort: https - {{- if (and (eq .Values.serviceType "NodePort") (not (empty .Values.nodePorts.https)))}} - nodePort: {{ .Values.nodePorts.https }} - {{- end }} - selector: - app: {{ template "fullname" . }} diff --git a/util/helm/testdata/wordpress/templates/tests/test-mariadb-connection.yaml b/util/helm/testdata/wordpress/templates/tests/test-mariadb-connection.yaml deleted file mode 100644 index 95ccb38ad..000000000 --- a/util/helm/testdata/wordpress/templates/tests/test-mariadb-connection.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if .Values.mariadb.enabled }} -apiVersion: v1 -kind: Pod -metadata: - name: "{{ .Release.Name }}-credentials-test" - annotations: - "helm.sh/hook": test-success -spec: - containers: - - name: {{ .Release.Name }}-credentials-test - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - env: - - name: MARIADB_HOST - value: {{ template "mariadb.fullname" . }} - - name: MARIADB_PORT - value: "3306" - - name: WORDPRESS_DATABASE_NAME - value: {{ default "" .Values.mariadb.db.name | quote }} - - name: WORDPRESS_DATABASE_USER - value: {{ default "" .Values.mariadb.db.user | quote }} - - name: WORDPRESS_DATABASE_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template "mariadb.fullname" . }} - key: mariadb-password - command: ["sh", "-c", "mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD"] - restartPolicy: Never -{{- end }} diff --git a/util/helm/testdata/wordpress/templates/tls-secrets.yaml b/util/helm/testdata/wordpress/templates/tls-secrets.yaml deleted file mode 100644 index ca75d33ef..000000000 --- a/util/helm/testdata/wordpress/templates/tls-secrets.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.ingress.enabled }} -{{- range .Values.ingress.secrets }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ .name }} - labels: - app: {{ template "fullname" $ }} - chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" - release: "{{ $.Release.Name }}" - heritage: "{{ $.Release.Service }}" -type: kubernetes.io/tls -data: - tls.crt: {{ .certificate | b64enc }} - tls.key: {{ .key | b64enc }} ---- -{{- end }} -{{- end }} \ No newline at end of file diff --git a/util/helm/testdata/wordpress/values-production.yaml b/util/helm/testdata/wordpress/values-production.yaml deleted file mode 100644 index e3b1d49bc..000000000 --- a/util/helm/testdata/wordpress/values-production.yaml +++ /dev/null @@ -1,256 +0,0 @@ -## Bitnami WordPress image version -## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ -## -image: - registry: docker.io - repository: bitnami/wordpress - tag: 4.9.8-debian-9 - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - -## User of the application -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressUsername: user - -## Application password -## Defaults to a random 10-character alphanumeric string if not set -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -# wordpressPassword: - -## Admin email -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressEmail: user@example.com - -## First name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressFirstName: FirstName - -## Last name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressLastName: LastName - -## Blog name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressBlogName: User's Blog! - -## Table prefix -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressTablePrefix: wp_ - -## Set to `yes` to allow the container to be started with blank passwords -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -allowEmptyPassword: "yes" - -## SMTP mail delivery configuration -## ref: https://github.com/bitnami/bitnami-docker-wordpress/#smtp-configuration -## -# smtpHost: -# smtpPort: -# smtpUser: -# smtpPassword: -# smtpUsername: -# smtpProtocol: - -replicaCount: 3 - -externalDatabase: -## All of these values are only used when mariadb.enabled is set to false - ## Database host - host: localhost - - ## non-root Username for Wordpress Database - user: bn_wordpress - - ## Database password - password: "" - - ## Database name - database: bitnami_wordpress - - ## Database port number - port: 3306 - -## -## MariaDB chart configuration -## -mariadb: - ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters - enabled: true - ## Disable MariaDB replication - replication: - enabled: false - - ## Create a database and a database user - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run - ## - db: - name: bitnami_wordpress - user: bn_wordpress - ## If the password is not specified, mariadb will generates a random password - ## - # password: - - ## MariaDB admin password - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run - ## - # rootUser: - # password: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - master: - persistence: - enabled: true - ## mariadb data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessMode: ReadWriteOnce - size: 8Gi - -## Kubernetes configuration -## For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP -## -serviceType: ClusterIP -## -## serviceType: NodePort -## nodePorts: -## http: -## https: -nodePorts: - http: "" - https: "" -## Enable client source IP preservation -## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip -## -serviceExternalTrafficPolicy: Local - -## Allow health checks to be pointed at the https port -healthcheckHttps: false - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - initialDelaySeconds: 120 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 -readinessProbe: - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure the ingress resource that allows you to access the -## Wordpress installation. Set up the URL -## ref: http://kubernetes.io/docs/user-guide/ingress/ -## -ingress: - ## Set to true to enable ingress record generation - enabled: true - - ## The list of hostnames to be covered with this ingress record. - ## Most likely this will be just one host, but in the event more hosts are needed, this is an array - ## Please make sure to change the name and tlsSecret to your own settings - hosts: - - name: wordpress.local - - ## Set this to true in order to enable TLS on the ingress record - ## A side effect of this will be that the backend wordpress service will be connected at port 443 - tls: true - - ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS - tlsSecret: wordpress.local-tls - - ## Ingress annotations done as key:value pairs - ## If you're using kube-lego, you will want to add: - ## kubernetes.io/tls-acme: true - ## - ## For a full list of possible ingress annotations, please see - ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md - ## - ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set - annotations: - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: true - - secrets: - ## If you're providing your own certificates, please use this to add the certificates as secrets - ## key and certificate should start with -----BEGIN CERTIFICATE----- or - ## -----BEGIN RSA PRIVATE KEY----- - ## - ## name should line up with a tlsSecret set further up - ## If you're using kube-lego, this is unneeded, as it will create the secret for you if it is not set - ## - ## It is also possible to create and manage the certificates outside of this helm chart - ## Please see README.md for more information - # - name: wordpress.local-tls - # key: - # certificate: - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - ## wordpress data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - ## - ## If you want to reuse an existing claim, you can pass the name of the PVC using - ## the existingClaim variable - # existingClaim: your-claim - ## - ## To use the /admin portal and to ensure you can scale wordpress you need to provide a - ## ReadWriteMany PVC, if you dont have a provisioner for this type of storage - ## We recommend that you install the nfs provisioner and map it to a RWO volume - ## helm install stable/nfs-server-provisioner --set persistence.enabled=true,persistence.size=10Gi - accessMode: ReadWriteMany - size: 10Gi - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 512Mi - cpu: 300m - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -## -nodeSelector: {} - -## Tolerations for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -## -tolerations: [] - -## Affinity for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} diff --git a/util/helm/testdata/wordpress/values.yaml b/util/helm/testdata/wordpress/values.yaml deleted file mode 100644 index 97c1b2f04..000000000 --- a/util/helm/testdata/wordpress/values.yaml +++ /dev/null @@ -1,254 +0,0 @@ -## Bitnami WordPress image version -## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ -## -image: - registry: docker.io - repository: bitnami/wordpress - tag: 4.9.8-debian-9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - -## User of the application -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressUsername: user - -## Application password -## Defaults to a random 10-character alphanumeric string if not set -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -# wordpressPassword: - -## Admin email -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressEmail: user@example.com - -## First name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressFirstName: FirstName - -## Last name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressLastName: LastName - -## Blog name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressBlogName: User's Blog! - -## Table prefix -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressTablePrefix: wp_ - -## Set to `false` to allow the container to be started with blank passwords -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -allowEmptyPassword: true - -## SMTP mail delivery configuration -## ref: https://github.com/bitnami/bitnami-docker-wordpress/#smtp-configuration -## -# smtpHost: -# smtpPort: -# smtpUser: -# smtpPassword: -# smtpUsername: -# smtpProtocol: - -replicaCount: 1 - -externalDatabase: -## All of these values are only used when mariadb.enabled is set to false - ## Database host - host: localhost - - ## non-root Username for Wordpress Database - user: bn_wordpress - - ## Database password - password: "" - - ## Database name - database: bitnami_wordpress - - ## Database port number - port: 3306 - -## -## MariaDB chart configuration -## -mariadb: - ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters - enabled: true - ## Disable MariaDB replication - replication: - enabled: false - - ## Create a database and a database user - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run - ## - db: - name: bitnami_wordpress - user: bn_wordpress - ## If the password is not specified, mariadb will generates a random password - ## - # password: - - ## MariaDB admin password - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run - ## - # rootUser: - # password: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - master: - persistence: - enabled: true - ## mariadb data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessMode: ReadWriteOnce - size: 8Gi - -## Kubernetes configuration -## For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP -## -serviceType: LoadBalancer -## -## serviceType: NodePort -## nodePorts: -## http: -## https: -nodePorts: - http: "" - https: "" -## Enable client source IP preservation -## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip -## -serviceExternalTrafficPolicy: Cluster - -## Allow health checks to be pointed at the https port -healthcheckHttps: false - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - initialDelaySeconds: 120 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 -readinessProbe: - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure the ingress resource that allows you to access the -## Wordpress installation. Set up the URL -## ref: http://kubernetes.io/docs/user-guide/ingress/ -## -ingress: - ## Set to true to enable ingress record generation - enabled: false - - ## The list of hostnames to be covered with this ingress record. - ## Most likely this will be just one host, but in the event more hosts are needed, this is an array - hosts: - - name: wordpress.local - - ## Set this to true in order to enable TLS on the ingress record - ## A side effect of this will be that the backend wordpress service will be connected at port 443 - tls: false - - ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS - tlsSecret: wordpress.local-tls - - ## Ingress annotations done as key:value pairs - ## If you're using kube-lego, you will want to add: - ## kubernetes.io/tls-acme: true - ## - ## For a full list of possible ingress annotations, please see - ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md - ## - ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set - annotations: - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: true - - secrets: - ## If you're providing your own certificates, please use this to add the certificates as secrets - ## key and certificate should start with -----BEGIN CERTIFICATE----- or - ## -----BEGIN RSA PRIVATE KEY----- - ## - ## name should line up with a tlsSecret set further up - ## If you're using kube-lego, this is unneeded, as it will create the secret for you if it is not set - ## - ## It is also possible to create and manage the certificates outside of this helm chart - ## Please see README.md for more information - # - name: wordpress.local-tls - # key: - # certificate: - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - ## wordpress data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - ## - ## If you want to reuse an existing claim, you can pass the name of the PVC using - ## the existingClaim variable - # existingClaim: your-claim - accessMode: ReadWriteOnce - size: 10Gi - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 512Mi - cpu: 300m - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -## -nodeSelector: {} - -## Tolerations for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -## -tolerations: [] - -## Affinity for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} diff --git a/util/kube/ctl.go b/util/kube/ctl.go deleted file mode 100644 index be89d5fe1..000000000 --- a/util/kube/ctl.go +++ /dev/null @@ -1,393 +0,0 @@ -package kube - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "os/exec" - "regexp" - "strings" - - "github.com/argoproj/argo-cd/engine/util/misc" - - argoexec "github.com/argoproj/pkg/exec" - log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/discovery" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - - "github.com/argoproj/argo-cd/engine/util/config" - "github.com/argoproj/argo-cd/engine/util/diff" -) - -type Kubectl interface { - ApplyResource(config *rest.Config, obj *unstructured.Unstructured, namespace string, dryRun, force, validate bool) (string, error) - ConvertToVersion(obj *unstructured.Unstructured, group, version string) (*unstructured.Unstructured, error) - DeleteResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, forceDelete bool) error - GetResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error) - PatchResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, patchType types.PatchType, patchBytes []byte) (*unstructured.Unstructured, error) - GetAPIResources(config *rest.Config, resourceFilter ResourceFilter) ([]APIResourceInfo, error) - GetServerVersion(config *rest.Config) (string, error) - SetOnKubectlRun(onKubectlRun func(command string) (misc.Closer, error)) -} - -type KubectlCmd struct { - OnKubectlRun func(command string) (misc.Closer, error) -} - -type APIResourceInfo struct { - GroupKind schema.GroupKind - Meta metav1.APIResource - Interface dynamic.ResourceInterface -} - -type filterFunc func(apiResource *metav1.APIResource) bool - -func filterAPIResources(config *rest.Config, resourceFilter ResourceFilter, filter filterFunc, namespace string) ([]APIResourceInfo, error) { - dynamicIf, err := dynamic.NewForConfig(config) - if err != nil { - return nil, err - } - - disco, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - - serverResources, err := disco.ServerPreferredResources() - if err != nil { - if len(serverResources) == 0 { - return nil, err - } - log.Warnf("Partial success when performing preferred resource discovery: %v", err) - } - apiResIfs := make([]APIResourceInfo, 0) - for _, apiResourcesList := range serverResources { - gv, err := schema.ParseGroupVersion(apiResourcesList.GroupVersion) - if err != nil { - gv = schema.GroupVersion{} - } - for _, apiResource := range apiResourcesList.APIResources { - - if resourceFilter.IsExcludedResource(gv.Group, apiResource.Kind, config.Host) { - continue - } - - if filter(&apiResource) { - resource := ToGroupVersionResource(apiResourcesList.GroupVersion, &apiResource) - resourceIf := ToResourceInterface(dynamicIf, &apiResource, resource, namespace) - gv, err := schema.ParseGroupVersion(apiResourcesList.GroupVersion) - if err != nil { - return nil, err - } - apiResIf := APIResourceInfo{ - GroupKind: schema.GroupKind{Group: gv.Group, Kind: apiResource.Kind}, - Meta: apiResource, - Interface: resourceIf, - } - apiResIfs = append(apiResIfs, apiResIf) - } - } - } - return apiResIfs, nil -} - -// isSupportedVerb returns whether or not a APIResource supports a specific verb -func isSupportedVerb(apiResource *metav1.APIResource, verb string) bool { - for _, v := range apiResource.Verbs { - if v == verb { - return true - } - } - return false -} - -func (k KubectlCmd) GetAPIResources(config *rest.Config, resourceFilter ResourceFilter) ([]APIResourceInfo, error) { - apiResIfs, err := filterAPIResources(config, resourceFilter, func(apiResource *metav1.APIResource) bool { - return isSupportedVerb(apiResource, listVerb) && isSupportedVerb(apiResource, watchVerb) - }, "") - if err != nil { - return nil, err - } - return apiResIfs, err -} - -// GetResource returns resource -func (k KubectlCmd) GetResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error) { - dynamicIf, err := dynamic.NewForConfig(config) - if err != nil { - return nil, err - } - disco, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) - if err != nil { - return nil, err - } - resource := gvk.GroupVersion().WithResource(apiResource.Name) - resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) - return resourceIf.Get(name, metav1.GetOptions{}) -} - -// PatchResource patches resource -func (k KubectlCmd) PatchResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, patchType types.PatchType, patchBytes []byte) (*unstructured.Unstructured, error) { - dynamicIf, err := dynamic.NewForConfig(config) - if err != nil { - return nil, err - } - disco, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) - if err != nil { - return nil, err - } - resource := gvk.GroupVersion().WithResource(apiResource.Name) - resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) - return resourceIf.Patch(name, patchType, patchBytes, metav1.PatchOptions{}) -} - -// DeleteResource deletes resource -func (k KubectlCmd) DeleteResource(config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, forceDelete bool) error { - dynamicIf, err := dynamic.NewForConfig(config) - if err != nil { - return err - } - disco, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return err - } - apiResource, err := ServerResourceForGroupVersionKind(disco, gvk) - if err != nil { - return err - } - resource := gvk.GroupVersion().WithResource(apiResource.Name) - resourceIf := ToResourceInterface(dynamicIf, apiResource, resource, namespace) - propagationPolicy := metav1.DeletePropagationForeground - deleteOptions := &metav1.DeleteOptions{PropagationPolicy: &propagationPolicy} - if forceDelete { - propagationPolicy = metav1.DeletePropagationBackground - zeroGracePeriod := int64(0) - deleteOptions.GracePeriodSeconds = &zeroGracePeriod - } - - return resourceIf.Delete(name, deleteOptions) -} - -// ApplyResource performs an apply of a unstructured resource -func (k KubectlCmd) ApplyResource(config *rest.Config, obj *unstructured.Unstructured, namespace string, dryRun, force, validate bool) (string, error) { - log.Infof("Applying resource %s/%s in cluster: %s, namespace: %s", obj.GetKind(), obj.GetName(), config.Host, namespace) - f, err := ioutil.TempFile(misc.TempDir, "") - if err != nil { - return "", fmt.Errorf("Failed to generate temp file for kubeconfig: %v", err) - } - _ = f.Close() - err = WriteKubeConfig(config, namespace, f.Name()) - if err != nil { - return "", fmt.Errorf("Failed to write kubeconfig: %v", err) - } - defer misc.DeleteFile(f.Name()) - manifestBytes, err := json.Marshal(obj) - if err != nil { - return "", err - } - var out []string - // If it is an RBAC resource, run `kubectl auth reconcile`. This is preferred over - // `kubectl apply`, which cannot tolerate changes in roleRef, which is an immutable field. - // See: https://github.com/kubernetes/kubernetes/issues/66353 - // `auth reconcile` will delete and recreate the resource if necessary - if obj.GetAPIVersion() == "rbac.authorization.k8s.io/v1" { - // `kubectl auth reconcile` has a side effect of auto-creating namespaces if it doesn't exist. - // See: https://github.com/kubernetes/kubernetes/issues/71185. This is behavior which we do - // not want. We need to check if the namespace exists, before know if it is safe to run this - // command. Skip this for dryRuns. - if !dryRun && namespace != "" { - kubeClient, err := kubernetes.NewForConfig(config) - if err != nil { - return "", err - } - _, err = kubeClient.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) - if err != nil { - return "", err - } - } - outReconcile, err := k.runKubectl(f.Name(), namespace, []string{"auth", "reconcile"}, manifestBytes, dryRun) - if err != nil { - return "", err - } - out = append(out, outReconcile) - // We still want to fallthrough and run `kubectl apply` in order set the - // last-applied-configuration annotation in the object. - } - - // Run kubectl apply - applyArgs := []string{"apply"} - if force { - applyArgs = append(applyArgs, "--force") - } - if !validate { - applyArgs = append(applyArgs, "--validate=false") - } - outApply, err := k.runKubectl(f.Name(), namespace, applyArgs, manifestBytes, dryRun) - if err != nil { - return "", err - } - out = append(out, outApply) - return strings.Join(out, ". "), nil -} - -func convertKubectlError(err error) error { - errorStr := err.Error() - if cmdErr, ok := err.(*argoexec.CmdError); ok { - parts := []string{fmt.Sprintf("kubectl failed %s", cmdErr.Cause.Error())} - if cmdErr.Stderr != "" { - parts = append(parts, cleanKubectlOutput(cmdErr.Stderr)) - } - errorStr = strings.Join(parts, ": ") - } - return fmt.Errorf(errorStr) -} - -func (k *KubectlCmd) processKubectlRun(args []string) (misc.Closer, error) { - if k.OnKubectlRun != nil { - cmd := "unknown" - if len(args) > 0 { - cmd = args[0] - } - return k.OnKubectlRun(cmd) - } - return misc.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 misc.Close(closer) - - cmdArgs := append([]string{"--kubeconfig", kubeconfigPath, "-f", "-"}, args...) - if namespace != "" { - cmdArgs = append(cmdArgs, "-n", namespace) - } - if dryRun { - cmdArgs = append(cmdArgs, "--dry-run") - } - cmd := exec.Command("kubectl", cmdArgs...) - if log.IsLevelEnabled(log.DebugLevel) { - var obj unstructured.Unstructured - err := json.Unmarshal(manifestBytes, &obj) - if err != nil { - return "", err - } - redacted, _, err := diff.HideSecretData(&obj, nil) - if err != nil { - return "", err - } - redactedBytes, err := json.Marshal(redacted) - if err != nil { - return "", err - } - log.Debug(string(redactedBytes)) - } - cmd.Stdin = bytes.NewReader(manifestBytes) - out, err := argoexec.RunCommandExt(cmd, config.CmdOpts()) - if err != nil { - return "", convertKubectlError(err) - } - return out, nil -} - -func Version() (string, error) { - cmd := exec.Command("kubectl", "version", "--client") - out, err := argoexec.RunCommandExt(cmd, config.CmdOpts()) - if err != nil { - return "", fmt.Errorf("could not get kubectl version: %s", err) - } - re := regexp.MustCompile(`GitVersion:"([a-zA-Z0-9\.]+)"`) - matches := re.FindStringSubmatch(out) - if len(matches) != 2 { - return "", errors.New("could not get kubectl version") - } - version := matches[1] - if version[0] != 'v' { - version = "v" + version - } - return strings.TrimSpace(version), nil -} - -// ConvertToVersion converts an unstructured object into the specified group/version -func (k KubectlCmd) ConvertToVersion(obj *unstructured.Unstructured, group string, version string) (*unstructured.Unstructured, error) { - gvk := obj.GroupVersionKind() - if gvk.Group == group && gvk.Version == version { - return obj.DeepCopy(), nil - } - - manifestBytes, err := json.Marshal(obj) - if err != nil { - return nil, err - } - f, err := ioutil.TempFile(misc.TempDir, "") - if err != nil { - return nil, fmt.Errorf("Failed to generate temp file for kubectl: %v", err) - } - _ = f.Close() - if err := ioutil.WriteFile(f.Name(), manifestBytes, 0600); err != nil { - return nil, err - } - defer misc.DeleteFile(f.Name()) - - closer, err := k.processKubectlRun([]string{"convert"}) - if err != nil { - return nil, err - } - defer misc.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) - out, err := argoexec.RunCommandExt(cmd, config.CmdOpts()) - if err != nil { - return nil, convertKubectlError(err) - } - // NOTE: when kubectl convert runs against stdin (i.e. kubectl convert -f -), the output is - // a unstructured list instead of an unstructured object - var convertedObj unstructured.Unstructured - err = json.Unmarshal([]byte(out), &convertedObj) - if err != nil { - return nil, err - } - if convertedObj.GetNamespace() == "" { - convertedObj.SetNamespace(obj.GetNamespace()) - } - return &convertedObj, nil -} - -func (k KubectlCmd) GetServerVersion(config *rest.Config) (string, error) { - client, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return "", err - } - v, err := client.ServerVersion() - if err != nil { - return "", err - } - return fmt.Sprintf("%s.%s", v.Major, v.Minor), nil -} - -func (k KubectlCmd) SetOnKubectlRun(onKubectlRun func(command string) (misc.Closer, error)) { - k.OnKubectlRun = onKubectlRun -} diff --git a/util/kube/ctl_test.go b/util/kube/ctl_test.go deleted file mode 100644 index c1fc905c7..000000000 --- a/util/kube/ctl_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package kube - -import ( - "io/ioutil" - "regexp" - "testing" - - "github.com/argoproj/argo-cd/engine/util/misc" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -func TestConvertToVersion(t *testing.T) { - callbackExecuted := false - closerExecuted := false - kubectl := KubectlCmd{ - func(command string) (misc.Closer, error) { - callbackExecuted = true - return misc.NewCloser(func() error { - closerExecuted = true - return nil - }), nil - }, - } - - yamlBytes, err := ioutil.ReadFile("testdata/nginx.yaml") - assert.Nil(t, err) - var obj unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &obj) - assert.Nil(t, err) - - // convert an extensions/v1beta1 object into an apps/v1 - newObj, err := kubectl.ConvertToVersion(&obj, "apps", "v1") - assert.Nil(t, err) - 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") - assert.Nil(t, err) - gvk = newObj.GroupVersionKind() - 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) (misc.Closer, error) { - callbackExecuted = true - return misc.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) -} - -func TestVersion(t *testing.T) { - ver, err := Version() - assert.NoError(t, err) - SemverRegexValidation := `^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$` - re := regexp.MustCompile(SemverRegexValidation) - assert.True(t, re.MatchString(ver)) -} diff --git a/util/kube/kube_test.go b/util/kube/kube_test.go deleted file mode 100644 index 1ff2e17cc..000000000 --- a/util/kube/kube_test.go +++ /dev/null @@ -1,271 +0,0 @@ -package kube - -import ( - "encoding/json" - "io/ioutil" - "log" - "testing" - - "github.com/argoproj/argo-cd/engine/common" - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - apiv1 "k8s.io/api/core/v1" - extv1beta1 "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -const depWithLabel = ` -apiVersion: extensions/v1beta2 -kind: Deployment -metadata: - name: nginx-deployment - labels: - foo: bar -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: nginx:1.7.9 - name: nginx - ports: - - containerPort: 80 -` - -func TestUnsetLabels(t *testing.T) { - for _, yamlStr := range []string{depWithLabel} { - var obj unstructured.Unstructured - err := yaml.Unmarshal([]byte(yamlStr), &obj) - assert.Nil(t, err) - - UnsetLabel(&obj, "foo") - - manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") - assert.Nil(t, err) - log.Println(string(manifestBytes)) - - var dep extv1beta1.Deployment - err = json.Unmarshal(manifestBytes, &dep) - assert.Nil(t, err) - assert.Equal(t, 0, len(dep.ObjectMeta.Labels)) - } - -} - -const depWithoutSelector = ` -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: nginx:1.7.9 - name: nginx - ports: - - containerPort: 80 -` - -const depWithSelector = ` -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: nginx:1.7.9 - name: nginx - ports: - - containerPort: 80 -` - -func TestSetLabels(t *testing.T) { - for _, yamlStr := range []string{depWithoutSelector, depWithSelector} { - var obj unstructured.Unstructured - err := yaml.Unmarshal([]byte(yamlStr), &obj) - assert.Nil(t, err) - - err = SetAppInstanceLabel(&obj, common.LabelKeyAppInstance, "my-app") - assert.Nil(t, err) - - manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") - assert.Nil(t, err) - log.Println(string(manifestBytes)) - - var depV1Beta1 extv1beta1.Deployment - err = json.Unmarshal(manifestBytes, &depV1Beta1) - assert.Nil(t, err) - - // the following makes sure we are not falling into legacy code which injects labels - if yamlStr == depWithoutSelector { - assert.Nil(t, depV1Beta1.Spec.Selector) - } else if yamlStr == depWithSelector { - assert.Equal(t, 1, len(depV1Beta1.Spec.Selector.MatchLabels)) - assert.Equal(t, "nginx", depV1Beta1.Spec.Selector.MatchLabels["app"]) - } - assert.Equal(t, 1, len(depV1Beta1.Spec.Template.Labels)) - assert.Equal(t, "nginx", depV1Beta1.Spec.Template.Labels["app"]) - } -} - -func TestSetLegacyLabels(t *testing.T) { - for _, yamlStr := range []string{depWithoutSelector, depWithSelector} { - var obj unstructured.Unstructured - err := yaml.Unmarshal([]byte(yamlStr), &obj) - assert.Nil(t, err) - - err = SetAppInstanceLabel(&obj, common.LabelKeyLegacyApplicationName, "my-app") - assert.Nil(t, err) - - manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") - assert.Nil(t, err) - log.Println(string(manifestBytes)) - - var depV1Beta1 extv1beta1.Deployment - err = json.Unmarshal(manifestBytes, &depV1Beta1) - assert.Nil(t, err) - assert.Equal(t, 1, len(depV1Beta1.Spec.Selector.MatchLabels)) - assert.Equal(t, "nginx", depV1Beta1.Spec.Selector.MatchLabels["app"]) - assert.Equal(t, 2, len(depV1Beta1.Spec.Template.Labels)) - assert.Equal(t, "nginx", depV1Beta1.Spec.Template.Labels["app"]) - assert.Equal(t, "my-app", depV1Beta1.Spec.Template.Labels[common.LabelKeyLegacyApplicationName]) - } -} - -func TestSetLegacyJobLabel(t *testing.T) { - yamlBytes, err := ioutil.ReadFile("testdata/job.yaml") - assert.Nil(t, err) - var obj unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &obj) - assert.Nil(t, err) - err = SetAppInstanceLabel(&obj, common.LabelKeyLegacyApplicationName, "my-app") - assert.Nil(t, err) - - manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") - assert.Nil(t, err) - log.Println(string(manifestBytes)) - - job := unstructured.Unstructured{} - err = json.Unmarshal(manifestBytes, &job) - assert.Nil(t, err) - - labels := job.GetLabels() - assert.Equal(t, "my-app", labels[common.LabelKeyLegacyApplicationName]) - - templateLabels, ok, err := unstructured.NestedMap(job.UnstructuredContent(), "spec", "template", "metadata", "labels") - assert.True(t, ok) - assert.Nil(t, err) - assert.Equal(t, "my-app", templateLabels[common.LabelKeyLegacyApplicationName]) -} - -func TestSetSvcLabel(t *testing.T) { - yamlBytes, err := ioutil.ReadFile("testdata/svc.yaml") - assert.Nil(t, err) - var obj unstructured.Unstructured - err = yaml.Unmarshal(yamlBytes, &obj) - assert.Nil(t, err) - err = SetAppInstanceLabel(&obj, common.LabelKeyAppInstance, "my-app") - assert.Nil(t, err) - - manifestBytes, err := json.MarshalIndent(obj.Object, "", " ") - assert.Nil(t, err) - log.Println(string(manifestBytes)) - - var s apiv1.Service - err = json.Unmarshal(manifestBytes, &s) - assert.Nil(t, err) - - log.Println(s.Name) - log.Println(s.ObjectMeta) - assert.Equal(t, "my-app", s.ObjectMeta.Labels[common.LabelKeyAppInstance]) -} - -func TestCleanKubectlOutput(t *testing.T) { - testString := `error: error validating "STDIN": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1beta2.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false` - assert.Equal(t, cleanKubectlOutput(testString), `error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1beta2.DeploymentSpec`) -} - -func TestInClusterKubeConfig(t *testing.T) { - restConfig := &rest.Config{} - kubeConfig := NewKubeConfig(restConfig, "") - assert.NotEmpty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) - - restConfig = &rest.Config{ - Password: "foo", - } - kubeConfig = NewKubeConfig(restConfig, "") - assert.Empty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) - - restConfig = &rest.Config{ - ExecProvider: &clientcmdapi.ExecConfig{ - APIVersion: "client.authentication.k8s.io/v1alpha1", - Command: "aws-iam-authenticator", - }, - } - kubeConfig = NewKubeConfig(restConfig, "") - assert.Empty(t, kubeConfig.AuthInfos[kubeConfig.CurrentContext].TokenFile) -} - -func TestGetDeploymentReplicas(t *testing.T) { - manifest := []byte(` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 2 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.7.9 - ports: - - containerPort: 80 -`) - deployment := unstructured.Unstructured{} - err := yaml.Unmarshal(manifest, &deployment) - assert.NoError(t, err) - assert.Equal(t, int64(2), *GetDeploymentReplicas(&deployment)) -} - -func TestGetNilDeploymentReplicas(t *testing.T) { - manifest := []byte(` -apiVersion: v1 -kind: Pod -metadata: - name: my-pod -spec: - containers: - - image: nginx:1.7.9 - name: nginx - resources: - requests: - cpu: 0.2 -`) - noDeployment := unstructured.Unstructured{} - err := yaml.Unmarshal(manifest, &noDeployment) - assert.NoError(t, err) - assert.Nil(t, GetDeploymentReplicas(&noDeployment)) -} diff --git a/util/kube/testdata/job.yaml b/util/kube/testdata/job.yaml deleted file mode 100644 index ee1d89fdd..000000000 --- a/util/kube/testdata/job.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: pi -spec: - template: - spec: - containers: - - name: pi - image: perl - command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] - restartPolicy: Never - backoffLimit: 4 diff --git a/util/kube/testdata/svc.yaml b/util/kube/testdata/svc.yaml deleted file mode 100644 index 11aeb957d..000000000 --- a/util/kube/testdata/svc.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: my-service -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 diff --git a/util/lua/lua.go b/util/lua/lua.go deleted file mode 100644 index 3974bce47..000000000 --- a/util/lua/lua.go +++ /dev/null @@ -1,366 +0,0 @@ -package lua - -import ( - "context" - "encoding/json" - "fmt" - "time" - - lua "github.com/yuin/gopher-lua" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - luajson "layeh.com/gopher-json" - - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -const ( - incorrectReturnType = "expect %s output from Lua script, not %s" - invalidHealthStatus = "Lua returned an invalid health status" -) - -type ScriptType = string - -const ( - ScriptTypeHealth = "health" - ScriptTypeActionDiscovery = "action-discovery" - ScriptTypeAction = "action" -) - -// VM Defines a struct that implements the luaVM -type VM struct { - ResourceOverrides map[string]appv1.ResourceOverride - PredefinedScriptsSource func(objKey string, scriptType ScriptType) (string, error) - // UseOpenLibs flag to enable open libraries. Libraries are always disabled while running, but enabled during testing to allow the use of print statements - UseOpenLibs bool -} - -func (vm VM) runLua(obj *unstructured.Unstructured, script string) (*lua.LState, error) { - l := lua.NewState(lua.Options{ - SkipOpenLibs: !vm.UseOpenLibs, - }) - defer l.Close() - // Opens table library to allow access to functions to manipulate tables - for _, pair := range []struct { - n string - f lua.LGFunction - }{ - {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), - NRet: 0, - Protect: true, - }, lua.LString(pair.n)); err != nil { - 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() - l.SetContext(ctx) - objectValue := decodeValue(l, obj.Object) - l.SetGlobal("obj", objectValue) - err := l.DoString(script) - return l, err -} - -// ExecuteHealthLua runs the lua script to generate the health status of a resource -func (vm VM) ExecuteHealthLua(obj *unstructured.Unstructured, script string) (*appv1.HealthStatus, error) { - l, err := vm.runLua(obj, script) - if err != nil { - return nil, err - } - returnValue := l.Get(-1) - if returnValue.Type() == lua.LTTable { - jsonBytes, err := luajson.Encode(returnValue) - if err != nil { - return nil, err - } - healthStatus := &appv1.HealthStatus{} - err = json.Unmarshal(jsonBytes, healthStatus) - if err != nil { - return nil, err - } - if !isValidHealthStatusCode(healthStatus.Status) { - return &appv1.HealthStatus{ - Status: appv1.HealthStatusUnknown, - Message: invalidHealthStatus, - }, nil - } - - return healthStatus, nil - } - return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) -} - -// GetHealthScript attempts to read lua script from config and then filesystem for that resource -func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (string, error) { - key := getConfigMapKey(obj) - if script, ok := vm.ResourceOverrides[key]; ok && script.HealthLua != "" { - return script.HealthLua, nil - } - return vm.getPredefinedLuaScripts(key, ScriptTypeHealth) -} - -func (vm VM) ExecuteResourceAction(obj *unstructured.Unstructured, script string) (*unstructured.Unstructured, error) { - l, err := vm.runLua(obj, script) - if err != nil { - return nil, err - } - returnValue := l.Get(-1) - if returnValue.Type() == lua.LTTable { - jsonBytes, err := luajson.Encode(returnValue) - if err != nil { - return nil, err - } - newObj, err := appv1.UnmarshalToUnstructured(string(jsonBytes)) - if err != nil { - return nil, err - } - cleanedNewObj := cleanReturnedObj(newObj.Object, obj.Object) - newObj.Object = cleanedNewObj - return newObj, nil - } - return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) -} - -// cleanReturnedObj Lua cannot distinguish an empty table as an array or map, and the library we are using choose to -// decoded an empty table into an empty array. This function prevents the lua scripts from unintentionally changing an -// empty struct into empty arrays -func cleanReturnedObj(newObj, obj map[string]interface{}) map[string]interface{} { - mapToReturn := newObj - for key := range obj { - if newValueInterface, ok := newObj[key]; ok { - oldValueInterface, ok := obj[key] - if !ok { - continue - } - switch newValue := newValueInterface.(type) { - case map[string]interface{}: - if oldValue, ok := oldValueInterface.(map[string]interface{}); ok { - convertedMap := cleanReturnedObj(newValue, oldValue) - mapToReturn[key] = convertedMap - } - - case []interface{}: - switch oldValue := oldValueInterface.(type) { - case map[string]interface{}: - if len(newValue) == 0 { - mapToReturn[key] = oldValue - } - case []interface{}: - newArray := cleanReturnedArray(newValue, oldValue) - mapToReturn[key] = newArray - } - } - } - } - return mapToReturn -} - -// cleanReturnedArray allows Argo CD to recurse into nested arrays when checking for unintentional empty struct to -// empty array conversions. -func cleanReturnedArray(newObj, obj []interface{}) []interface{} { - arrayToReturn := newObj - for i := range newObj { - switch newValue := newObj[i].(type) { - case map[string]interface{}: - if oldValue, ok := obj[i].(map[string]interface{}); ok { - convertedMap := cleanReturnedObj(newValue, oldValue) - arrayToReturn[i] = convertedMap - } - case []interface{}: - if oldValue, ok := obj[i].([]interface{}); ok { - convertedMap := cleanReturnedArray(newValue, oldValue) - arrayToReturn[i] = convertedMap - } - } - } - return arrayToReturn -} - -func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, script string) ([]appv1.ResourceAction, error) { - l, err := vm.runLua(obj, script) - if err != nil { - return nil, err - } - returnValue := l.Get(-1) - if returnValue.Type() == lua.LTTable { - - jsonBytes, err := luajson.Encode(returnValue) - if err != nil { - return nil, err - } - availableActions := make([]appv1.ResourceAction, 0) - if noAvailableActions(jsonBytes) { - return availableActions, nil - } - availableActionsMap := make(map[string]interface{}) - err = json.Unmarshal(jsonBytes, &availableActionsMap) - if err != nil { - return nil, err - } - for key := range availableActionsMap { - value := availableActionsMap[key] - resourceAction := appv1.ResourceAction{Name: key, Disabled: isActionDisabled(value)} - if emptyResourceActionFromLua(value) { - availableActions = append(availableActions, resourceAction) - continue - } - resourceActionBytes, err := json.Marshal(value) - if err != nil { - return nil, err - } - - err = json.Unmarshal(resourceActionBytes, &resourceAction) - if err != nil { - return nil, err - } - availableActions = append(availableActions, resourceAction) - } - return availableActions, err - } - - return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) -} - -// Actions are enabled by default -func isActionDisabled(actionsMap interface{}) bool { - actions, ok := actionsMap.(map[string]interface{}) - if !ok { - return false - } - for key, val := range actions { - switch vv := val.(type) { - case bool: - if key == "disabled" { - return vv - } - } - } - return false -} - -func emptyResourceActionFromLua(i interface{}) bool { - _, ok := i.([]interface{}) - return ok -} - -func noAvailableActions(jsonBytes []byte) bool { - // When the Lua script returns an empty table, it is decoded as a empty array. - return string(jsonBytes) == "[]" -} - -func (vm VM) GetResourceActionDiscovery(obj *unstructured.Unstructured) (string, error) { - key := getConfigMapKey(obj) - override, ok := vm.ResourceOverrides[key] - if ok && override.Actions != "" { - actions, err := override.GetActions() - if err != nil { - return "", err - } - return actions.ActionDiscoveryLua, nil - } - discoveryKey := fmt.Sprintf("%s/actions/", key) - discoveryScript, err := vm.getPredefinedLuaScripts(discoveryKey, ScriptTypeActionDiscovery) - if err != nil { - return "", err - } - return discoveryScript, nil -} - -// GetResourceAction attempts to read lua script from config and then filesystem for that resource -func (vm VM) GetResourceAction(obj *unstructured.Unstructured, actionName string) (appv1.ResourceActionDefinition, error) { - key := getConfigMapKey(obj) - override, ok := vm.ResourceOverrides[key] - if ok && override.Actions != "" { - actions, err := override.GetActions() - if err != nil { - return appv1.ResourceActionDefinition{}, err - } - for _, action := range actions.Definitions { - if action.Name == actionName { - return action, nil - } - } - } - - actionKey := fmt.Sprintf("%s/actions/%s", key, actionName) - actionScript, err := vm.getPredefinedLuaScripts(actionKey, ScriptTypeAction) - if err != nil { - return appv1.ResourceActionDefinition{}, err - } - - return appv1.ResourceActionDefinition{ - Name: actionName, - ActionLua: actionScript, - }, nil -} - -func getConfigMapKey(obj *unstructured.Unstructured) string { - gvk := obj.GroupVersionKind() - if gvk.Group == "" { - return gvk.Kind - } - return fmt.Sprintf("%s/%s", gvk.Group, gvk.Kind) - -} - -func (vm VM) getPredefinedLuaScripts(objKey string, scriptType ScriptType) (string, error) { - if vm.PredefinedScriptsSource != nil { - return vm.PredefinedScriptsSource(objKey, scriptType) - } - return "", nil -} - -func isValidHealthStatusCode(statusCode string) bool { - switch statusCode { - case appv1.HealthStatusUnknown, appv1.HealthStatusProgressing, appv1.HealthStatusSuspended, appv1.HealthStatusHealthy, appv1.HealthStatusDegraded, appv1.HealthStatusMissing: - return true - } - return false -} - -// Took logic from the link below and added the int, int32, and int64 types since the value would have type int64 -// while actually running in the controller and it was not reproducible through testing. -// https://github.com/layeh/gopher-json/blob/97fed8db84274c421dbfffbb28ec859901556b97/json.go#L154 -func decodeValue(L *lua.LState, value interface{}) lua.LValue { - switch converted := value.(type) { - case bool: - return lua.LBool(converted) - case float64: - return lua.LNumber(converted) - case string: - return lua.LString(converted) - case json.Number: - return lua.LString(converted) - case int: - return lua.LNumber(converted) - case int32: - return lua.LNumber(converted) - case int64: - return lua.LNumber(converted) - case []interface{}: - arr := L.CreateTable(len(converted), 0) - for _, item := range converted { - arr.Append(decodeValue(L, item)) - } - return arr - case map[string]interface{}: - tbl := L.CreateTable(0, len(converted)) - for key, item := range converted { - tbl.RawSetH(lua.LString(key), decodeValue(L, item)) - } - return tbl - case nil: - return lua.LNil - } - - return lua.LNil -} diff --git a/util/lua/lua_test.go b/util/lua/lua_test.go deleted file mode 100644 index 610f12d01..000000000 --- a/util/lua/lua_test.go +++ /dev/null @@ -1,361 +0,0 @@ -package lua - -import ( - "fmt" - "testing" - - "github.com/argoproj/argo-cd/engine/util/json" - - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - lua "github.com/yuin/gopher-lua" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - appv1 "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -const objJSON = ` -apiVersion: argoproj.io/v1alpha1 -kind: Rollout -metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - name: helm-guestbook - namespace: default - resourceVersion: "123" -` -const objWithNoScriptJSON = ` -apiVersion: not-an-endpoint.io/v1alpha1 -kind: Test -metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - name: helm-guestbook - namespace: default - resourceVersion: "123" -` - -const newHealthStatusFunction = `a = {} -a.status = "Healthy" -a.message ="NeedsToBeChanged" -if obj.metadata.name == "helm-guestbook" then - a.message = "testMessage" -end -return a` - -func StrToUnstructured(jsonStr string) *unstructured.Unstructured { - obj := make(map[string]interface{}) - err := yaml.Unmarshal([]byte(jsonStr), &obj) - if err != nil { - panic(err) - } - return &unstructured.Unstructured{Object: obj} -} - -func TestExecuteNewHealthStatusFunction(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - status, err := vm.ExecuteHealthLua(testObj, newHealthStatusFunction) - assert.Nil(t, err) - expectedHealthStatus := &appv1.HealthStatus{ - Status: "Healthy", - Message: "testMessage", - } - assert.Equal(t, expectedHealthStatus, status) - -} - -const osLuaScript = `os.getenv("HOME")` - -func TestFailExternalLibCall(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - _, err := vm.ExecuteHealthLua(testObj, osLuaScript) - assert.Error(t, err, "") - assert.IsType(t, &lua.ApiError{}, err) -} - -const returnInt = `return 1` - -func TestFailLuaReturnNonTable(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - _, err := vm.ExecuteHealthLua(testObj, returnInt) - assert.Equal(t, fmt.Errorf(incorrectReturnType, "table", "number"), err) -} - -const invalidHealthStatusStatus = `local healthStatus = {} -healthStatus.status = "test" -return healthStatus -` - -func TestInvalidHealthStatusStatus(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - status, err := vm.ExecuteHealthLua(testObj, invalidHealthStatusStatus) - assert.Nil(t, err) - expectedStatus := &appv1.HealthStatus{ - Status: appv1.HealthStatusUnknown, - Message: invalidHealthStatus, - } - assert.Equal(t, expectedStatus, status) -} - -const infiniteLoop = `while true do ; end` - -func TestHandleInfiniteLoop(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - _, err := vm.ExecuteHealthLua(testObj, infiniteLoop) - assert.IsType(t, &lua.ApiError{}, err) -} - -func TestGetHealthScriptWithOverride(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{ - ResourceOverrides: map[string]appv1.ResourceOverride{ - "argoproj.io/Rollout": { - HealthLua: newHealthStatusFunction, - }, - }, - } - script, err := vm.GetHealthScript(testObj) - assert.Nil(t, err) - assert.Equal(t, newHealthStatusFunction, script) -} - -func TestGetHealthScriptNoPredefined(t *testing.T) { - testObj := StrToUnstructured(objWithNoScriptJSON) - vm := VM{} - script, err := vm.GetHealthScript(testObj) - assert.Nil(t, err) - assert.Equal(t, "", script) -} - -func TestGetResourceActionPredefined(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - - action, err := vm.GetResourceAction(testObj, "resume") - assert.Nil(t, err) - assert.NotEmpty(t, action) -} - -func TestGetResourceActionNoPredefined(t *testing.T) { - testObj := StrToUnstructured(objWithNoScriptJSON) - vm := VM{} - action, err := vm.GetResourceAction(testObj, "test") - assert.Nil(t, err) - assert.Empty(t, action.ActionLua) -} - -func TestGetResourceActionWithOverride(t *testing.T) { - testObj := StrToUnstructured(objJSON) - test := appv1.ResourceActionDefinition{ - Name: "test", - ActionLua: "return obj", - } - - vm := VM{ - ResourceOverrides: map[string]appv1.ResourceOverride{ - "argoproj.io/Rollout": { - Actions: string(json.MustMarshal(appv1.ResourceActions{ - Definitions: []appv1.ResourceActionDefinition{ - test, - }, - })), - }, - }, - } - action, err := vm.GetResourceAction(testObj, "test") - assert.Nil(t, err) - assert.Equal(t, test, action) -} - -func TestGetResourceActionDiscoveryNoPredefined(t *testing.T) { - testObj := StrToUnstructured(objWithNoScriptJSON) - vm := VM{} - discoveryLua, err := vm.GetResourceActionDiscovery(testObj) - assert.Nil(t, err) - assert.Empty(t, discoveryLua) -} - -func TestGetResourceActionDiscoveryWithOverride(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{ - ResourceOverrides: map[string]appv1.ResourceOverride{ - "argoproj.io/Rollout": { - Actions: string(json.MustMarshal(appv1.ResourceActions{ - ActionDiscoveryLua: validDiscoveryLua, - })), - }, - }, - } - discoveryLua, err := vm.GetResourceActionDiscovery(testObj) - assert.Nil(t, err) - assert.Equal(t, validDiscoveryLua, discoveryLua) -} - -const validDiscoveryLua = ` -scaleParams = { {name = "replicas", type = "number"} } -scale = {name = 'scale', params = scaleParams} - -resume = {name = 'resume'} - -test = {} -a = {scale = scale, resume = resume, test = test} - -return a -` - -func TestExecuteResourceActionDiscovery(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - actions, err := vm.ExecuteResourceActionDiscovery(testObj, validDiscoveryLua) - assert.Nil(t, err) - expectedActions := []appv1.ResourceAction{ - { - Name: "resume", - }, { - Name: "scale", - Params: []appv1.ResourceActionParam{{ - Name: "replicas", - Type: "number", - }}, - }, { - Name: "test", - }, - } - for _, expectedAction := range expectedActions { - assert.Contains(t, actions, expectedAction) - } -} - -const discoveryLuaWithInvalidResourceAction = ` -resume = {name = 'resume', invalidField: "test""} -a = {resume = resume} -return a` - -func TestExecuteResourceActionDiscoveryInvalidResourceAction(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - actions, err := vm.ExecuteResourceActionDiscovery(testObj, discoveryLuaWithInvalidResourceAction) - assert.Error(t, err) - assert.Nil(t, actions) -} - -const invalidDiscoveryLua = ` -a = 1 -return a -` - -func TestExecuteResourceActionDiscoveryInvalidReturn(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - actions, err := vm.ExecuteResourceActionDiscovery(testObj, invalidDiscoveryLua) - assert.Nil(t, actions) - assert.Error(t, err) - -} - -const validActionLua = ` -obj.metadata.labels["test"] = "test" -return obj -` - -const expectedUpdatedObj = ` -apiVersion: argoproj.io/v1alpha1 -kind: Rollout -metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - test: test - name: helm-guestbook - namespace: default - resourceVersion: "123" -` - -func TestExecuteResourceAction(t *testing.T) { - testObj := StrToUnstructured(objJSON) - expectedObj := StrToUnstructured(expectedUpdatedObj) - vm := VM{} - newObj, err := vm.ExecuteResourceAction(testObj, validActionLua) - assert.Nil(t, err) - assert.Equal(t, expectedObj, newObj) -} - -func TestExecuteResourceActionNonTableReturn(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - _, err := vm.ExecuteResourceAction(testObj, returnInt) - assert.Errorf(t, err, incorrectReturnType, "table", "number") -} - -const invalidTableReturn = `newObj = {} -newObj["test"] = "test" -return newObj -` - -func TestExecuteResourceActionInvalidUnstructured(t *testing.T) { - testObj := StrToUnstructured(objJSON) - vm := VM{} - _, err := vm.ExecuteResourceAction(testObj, invalidTableReturn) - assert.Error(t, err) -} - -const objWithEmptyStruct = ` -apiVersion: argoproj.io/v1alpha1 -kind: Test -metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - test: test - name: helm-guestbook - namespace: default - resourceVersion: "123" -spec: - resources: {} - paused: true - containers: - - name: name1 - test: {} - anotherList: - - name: name2 - test2: {} -` - -const expectedUpdatedObjWithEmptyStruct = ` -apiVersion: argoproj.io/v1alpha1 -kind: Test -metadata: - labels: - app.kubernetes.io/instance: helm-guestbook - test: test - name: helm-guestbook - namespace: default - resourceVersion: "123" -spec: - resources: {} - paused: false - containers: - - name: name1 - test: {} - anotherList: - - name: name2 - test2: {} -` - -const pausedToFalseLua = ` -obj.spec.paused = false -return obj -` - -func TestCleanPatch(t *testing.T) { - testObj := StrToUnstructured(objWithEmptyStruct) - expectedObj := StrToUnstructured(expectedUpdatedObjWithEmptyStruct) - vm := VM{} - newObj, err := vm.ExecuteResourceAction(testObj, pausedToFalseLua) - assert.Nil(t, err) - assert.Equal(t, expectedObj, newObj) - -} diff --git a/util/lua/oslib_safe.go b/util/lua/oslib_safe.go deleted file mode 100644 index e871ecc0c..000000000 --- a/util/lua/oslib_safe.go +++ /dev/null @@ -1,184 +0,0 @@ -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 -} diff --git a/util/lua/testdata/example.lua b/util/lua/testdata/example.lua deleted file mode 100644 index edc7a2a8b..000000000 --- a/util/lua/testdata/example.lua +++ /dev/null @@ -1 +0,0 @@ -return 'Hello World' \ No newline at end of file diff --git a/util/misc/keylock.go b/util/misc/keylock.go deleted file mode 100644 index 85cb2b486..000000000 --- a/util/misc/keylock.go +++ /dev/null @@ -1,48 +0,0 @@ -package misc - -import "sync" - -// Allows to lock by string key -type KeyLock struct { - giantLock sync.RWMutex - locks map[string]*sync.Mutex -} - -// NewKeyLock creates new instance of KeyLock -func NewKeyLock() *KeyLock { - return &KeyLock{ - giantLock: sync.RWMutex{}, - locks: map[string]*sync.Mutex{}, - } -} - -func (keyLock *KeyLock) getLock(key string) *sync.Mutex { - keyLock.giantLock.RLock() - if lock, ok := keyLock.locks[key]; ok { - keyLock.giantLock.RUnlock() - return lock - } - - keyLock.giantLock.RUnlock() - keyLock.giantLock.Lock() - - if lock, ok := keyLock.locks[key]; ok { - keyLock.giantLock.Unlock() - return lock - } - - lock := &sync.Mutex{} - keyLock.locks[key] = lock - keyLock.giantLock.Unlock() - return lock -} - -// Lock blocks goroutine using key specific mutex -func (keyLock *KeyLock) Lock(key string) { - keyLock.getLock(key).Lock() -} - -// Unlock releases key specific mutex -func (keyLock *KeyLock) Unlock(key string) { - keyLock.getLock(key).Unlock() -} diff --git a/util/misc/util.go b/util/misc/util.go deleted file mode 100644 index d2f9ccce3..000000000 --- a/util/misc/util.go +++ /dev/null @@ -1,159 +0,0 @@ -package misc - -import ( - "context" - "crypto/rand" - "encoding/base64" - "errors" - "fmt" - "os" - "runtime/debug" - "sync" - "time" - - log "github.com/sirupsen/logrus" -) - -var ( - // location to use for generating temporary files, such as the kubeconfig needed by kubectl - TempDir string -) - -func init() { - fileInfo, err := os.Stat("/dev/shm") - if err == nil && fileInfo.IsDir() { - TempDir = "/dev/shm" - } -} - -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) { - if err := c.Close(); err != nil { - log.Warnf("failed to close %v: %v", c, err) - } -} - -// DeleteFile is best effort deletion of a file -func DeleteFile(path string) { - if _, err := os.Stat(path); os.IsNotExist(err) { - return - } - _ = os.Remove(path) -} - -// Wait takes a check interval and timeout and waits for a function to return `true`. -// Wait will return `true` on success and `false` on timeout. -// The passed function, in turn, should pass `true` (or anything, really) to the channel when it's done. -// Pass `0` as the timeout to run infinitely until completion. -func Wait(timeout uint, f func(chan<- bool)) bool { - done := make(chan bool) - go f(done) - - // infinite - if timeout == 0 { - return <-done - } - - timedOut := time.After(time.Duration(timeout) * time.Second) - for { - select { - case <-done: - return true - case <-timedOut: - return false - } - } -} - -// MakeSignature generates a cryptographically-secure pseudo-random token, based on a given number of random bytes, for signing purposes. -func MakeSignature(size int) ([]byte, error) { - b := make([]byte, size) - _, err := rand.Read(b) - if err != nil { - b = nil - } - // base64 encode it so signing key can be typed into validation utilities - b = []byte(base64.StdEncoding.EncodeToString(b)) - return b, err -} - -// RetryUntilSucceed keep retrying given action with specified timeout until action succeed or specified context is done. -func RetryUntilSucceed(action func() error, desc string, ctx context.Context, timeout time.Duration) { - ctxCompleted := false - stop := make(chan bool) - defer close(stop) - go func() { - select { - case <-ctx.Done(): - ctxCompleted = true - case <-stop: - } - }() - for { - log.Debugf("Start %s", desc) - err := action() - if err == nil { - log.Debugf("Completed %s", desc) - return - } - if ctxCompleted { - log.Debugf("Stop retrying %s", desc) - return - } - log.Debugf("Failed to %s: %+v, retrying in %v", desc, err, timeout) - time.Sleep(timeout) - - } -} - -func FirstNonEmpty(args ...string) string { - for _, value := range args { - if len(value) > 0 { - return value - } - } - return "" -} - -func RunAllAsync(count int, action func(i int) error) (err error) { - defer func() { - if r := recover(); r != nil { - message := fmt.Sprintf("Recovered from panic: %+v\n%s", r, debug.Stack()) - log.Error(message) - err = errors.New(message) - } - }() - var wg sync.WaitGroup - for i := 0; i < count; i++ { - wg.Add(1) - go func(index int) { - defer wg.Done() - actionErr := action(index) - if actionErr != nil { - err = actionErr - } - }(i) - if err != nil { - break - } - } - wg.Wait() - return err -} diff --git a/util/misc/util_test.go b/util/misc/util_test.go deleted file mode 100644 index bfa605ea8..000000000 --- a/util/misc/util_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package misc - -import ( - "testing" -) - -func TestMakeSignature(t *testing.T) { - for size := 1; size <= 64; size++ { - s, err := MakeSignature(size) - if err != nil { - t.Errorf("Could not generate signature of size %d: %v", size, err) - } - t.Logf("Generated token: %v", s) - } -} diff --git a/util/rand/rand.go b/util/rand/rand.go deleted file mode 100644 index 8a942c812..000000000 --- a/util/rand/rand.go +++ /dev/null @@ -1,37 +0,0 @@ -package rand - -import ( - "math/rand" - "time" -) - -const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const ( - letterIdxBits = 6 // 6 bits to represent a letter index - letterIdxMask = 1<= 0; { - if remain == 0 { - cache, remain = src.Int63(), letterIdxMax - } - if idx := int(cache & letterIdxMask); idx < len(charset) { - b[i] = charset[idx] - i-- - } - cache >>= letterIdxBits - remain-- - } - return string(b) -} diff --git a/util/rand/rand_test.go b/util/rand/rand_test.go deleted file mode 100644 index 62002c409..000000000 --- a/util/rand/rand_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package rand - -import ( - "testing" -) - -func TestRandString(t *testing.T) { - ss := RandStringCharset(10, "A") - if ss != "AAAAAAAAAA" { - t.Errorf("Expected 10 As, but got %q", ss) - } - ss = RandStringCharset(5, "ABC123") - if len(ss) != 5 { - t.Errorf("Expected random string of length 10, but got %q", ss) - } -} diff --git a/util/rbac/rbac.go b/util/rbac/rbac.go deleted file mode 100644 index 8ba74bc13..000000000 --- a/util/rbac/rbac.go +++ /dev/null @@ -1,295 +0,0 @@ -package rbac - -import ( - "context" - "errors" - "fmt" - "strings" - "time" - - "github.com/argoproj/argo-cd/util/assets" - - "github.com/casbin/casbin" - "github.com/casbin/casbin/model" - "github.com/casbin/casbin/persist" - jwt "github.com/dgrijalva/jwt-go" - log "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - apiv1 "k8s.io/api/core/v1" - apierr "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - v1 "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" -) - -const ( - ConfigMapPolicyCSVKey = "policy.csv" - ConfigMapPolicyDefaultKey = "policy.default" - ConfigMapScopesKey = "scopes" - - defaultRBACSyncPeriod = 10 * time.Minute -) - -// Enforcer is a wrapper around an Casbin enforcer that: -// * is backed by a kubernetes config map -// * has a predefined RBAC model -// * supports a built-in policy -// * supports a user-defined bolicy -// * supports a custom JWT claims enforce function -type Enforcer struct { - *casbin.Enforcer - adapter *argocdAdapter - clientset kubernetes.Interface - namespace string - configmap string - claimsEnforcerFunc ClaimsEnforcerFunc - model model.Model - defaultRole string -} - -// ClaimsEnforcerFunc is func template to enforce a JWT claims. The subject is replaced -type ClaimsEnforcerFunc func(claims jwt.Claims, rvals ...interface{}) bool - -func NewEnforcer(clientset kubernetes.Interface, namespace, configmap string, claimsEnforcer ClaimsEnforcerFunc) *Enforcer { - adapter := newAdapter("", "", "") - builtInModel := newBuiltInModel() - enf := casbin.NewEnforcer(builtInModel, adapter) - enf.EnableLog(false) - return &Enforcer{ - Enforcer: enf, - adapter: adapter, - clientset: clientset, - namespace: namespace, - configmap: configmap, - model: builtInModel, - claimsEnforcerFunc: claimsEnforcer, - } -} - -// SetDefaultRole sets a default role to use during enforcement. Will fall back to this role if -// normal enforcement fails -func (e *Enforcer) SetDefaultRole(roleName string) { - e.defaultRole = roleName -} - -// SetClaimsEnforcerFunc sets a claims enforce function during enforcement. The claims enforce function -// can extract claims from JWT token and do the proper enforcement based on user, group or any information -// available in the input parameter list -func (e *Enforcer) SetClaimsEnforcerFunc(claimsEnforcer ClaimsEnforcerFunc) { - e.claimsEnforcerFunc = claimsEnforcer -} - -// Enforce is a wrapper around casbin.Enforce to additionally enforce a default role and a custom -// claims function -func (e *Enforcer) Enforce(rvals ...interface{}) bool { - return enforce(e.Enforcer, e.defaultRole, e.claimsEnforcerFunc, rvals...) -} - -// EnforceErr is a convenience helper to wrap a failed enforcement with a detailed error about the request -func (e *Enforcer) EnforceErr(rvals ...interface{}) error { - if !e.Enforce(rvals...) { - errMsg := "permission denied" - if len(rvals) > 0 { - rvalsStrs := make([]string, len(rvals)-1) - for i, rval := range rvals[1:] { - rvalsStrs[i] = fmt.Sprintf("%s", rval) - } - errMsg = fmt.Sprintf("%s: %s", errMsg, strings.Join(rvalsStrs, ", ")) - } - return status.Error(codes.PermissionDenied, errMsg) - } - return nil -} - -// EnforceRuntimePolicy enforces a policy defined at run-time which augments the built-in and -// user-defined policy. This allows any explicit denies of the built-in, and user-defined policies -// to override the run-time policy. Runs normal enforcement if run-time policy is empty. -func (e *Enforcer) EnforceRuntimePolicy(policy string, rvals ...interface{}) bool { - var enf *casbin.Enforcer - var err error - if policy == "" { - enf = e.Enforcer - } else { - enf, err = casbin.NewEnforcerSafe(newBuiltInModel(), newAdapter(e.adapter.builtinPolicy, e.adapter.userDefinedPolicy, policy)) - if err != nil { - log.Warnf("invalid runtime policy: %s", policy) - enf = e.Enforcer - } - } - return enforce(enf, e.defaultRole, e.claimsEnforcerFunc, rvals...) -} - -// enforce is a helper to additionally check a default role and invoke a custom claims enforcement function -func enforce(enf *casbin.Enforcer, defaultRole string, claimsEnforcerFunc ClaimsEnforcerFunc, rvals ...interface{}) bool { - // check the default role - if defaultRole != "" && len(rvals) >= 2 { - if enf.Enforce(append([]interface{}{defaultRole}, rvals[1:]...)...) { - return true - } - } - if len(rvals) == 0 { - return false - } - // check if subject is jwt.Claims vs. a normal subject string and run custom claims - // enforcement func (if set) - sub := rvals[0] - switch s := sub.(type) { - case string: - // noop - case jwt.Claims: - if claimsEnforcerFunc != nil && claimsEnforcerFunc(s, rvals...) { - return true - } - rvals = append([]interface{}{""}, rvals[1:]...) - default: - rvals = append([]interface{}{""}, rvals[1:]...) - } - return enf.Enforce(rvals...) -} - -// SetBuiltinPolicy sets a built-in policy, which augments any user defined policies -func (e *Enforcer) SetBuiltinPolicy(policy string) error { - e.adapter.builtinPolicy = policy - return e.LoadPolicy() -} - -// SetUserPolicy sets a user policy, augmenting the built-in policy -func (e *Enforcer) SetUserPolicy(policy string) error { - e.adapter.userDefinedPolicy = policy - return e.LoadPolicy() -} - -// newInformers returns an informer which watches updates on the rbac configmap -func (e *Enforcer) newInformer() cache.SharedIndexInformer { - tweakConfigMap := func(options *metav1.ListOptions) { - cmFieldSelector := fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", e.configmap)) - options.FieldSelector = cmFieldSelector.String() - } - return v1.NewFilteredConfigMapInformer(e.clientset, e.namespace, defaultRBACSyncPeriod, cache.Indexers{}, tweakConfigMap) -} - -// RunPolicyLoader runs the policy loader which watches policy updates from the configmap and reloads them -func (e *Enforcer) RunPolicyLoader(ctx context.Context, onUpdated func(cm *apiv1.ConfigMap) error) error { - cm, err := e.clientset.CoreV1().ConfigMaps(e.namespace).Get(e.configmap, metav1.GetOptions{}) - if err != nil { - if !apierr.IsNotFound(err) { - return err - } - } else { - err = e.syncUpdate(cm, onUpdated) - if err != nil { - return err - } - } - e.runInformer(ctx, onUpdated) - return nil -} - -func (e *Enforcer) runInformer(ctx context.Context, onUpdated func(cm *apiv1.ConfigMap) error) { - cmInformer := e.newInformer() - cmInformer.AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - if cm, ok := obj.(*apiv1.ConfigMap); ok { - err := e.syncUpdate(cm, onUpdated) - if err != nil { - log.Error(err) - } else { - log.Infof("RBAC ConfigMap '%s' added", e.configmap) - } - } - }, - UpdateFunc: func(old, new interface{}) { - oldCM := old.(*apiv1.ConfigMap) - newCM := new.(*apiv1.ConfigMap) - if oldCM.ResourceVersion == newCM.ResourceVersion { - return - } - err := e.syncUpdate(newCM, onUpdated) - if err != nil { - log.Error(err) - } else { - log.Infof("RBAC ConfigMap '%s' updated", e.configmap) - } - }, - }, - ) - log.Info("Starting rbac config informer") - cmInformer.Run(ctx.Done()) - log.Info("rbac configmap informer cancelled") -} - -// syncUpdate updates the enforcer -func (e *Enforcer) syncUpdate(cm *apiv1.ConfigMap, onUpdated func(cm *apiv1.ConfigMap) error) error { - e.SetDefaultRole(cm.Data[ConfigMapPolicyDefaultKey]) - policyCSV, ok := cm.Data[ConfigMapPolicyCSVKey] - if !ok { - policyCSV = "" - } - if err := onUpdated(cm); err != nil { - return err - } - return e.SetUserPolicy(policyCSV) -} - -// ValidatePolicy verifies a policy string is acceptable to casbin -func ValidatePolicy(policy string) error { - _, err := casbin.NewEnforcerSafe(newBuiltInModel(), newAdapter("", "", policy)) - if err != nil { - return fmt.Errorf("policy syntax error: %s", policy) - } - return nil -} - -// newBuiltInModel is a helper to return a brand new casbin model from the built-in model string. -// This is needed because it is not safe to re-use the same casbin Model when instantiating new -// casbin enforcers. -func newBuiltInModel() model.Model { - return casbin.NewModel(assets.ModelConf) -} - -// Casbin adapter which satisfies persist.Adapter interface -type argocdAdapter struct { - builtinPolicy string - userDefinedPolicy string - runtimePolicy string -} - -func newAdapter(builtinPolicy, userDefinedPolicy, runtimePolicy string) *argocdAdapter { - return &argocdAdapter{ - builtinPolicy: builtinPolicy, - userDefinedPolicy: userDefinedPolicy, - runtimePolicy: runtimePolicy, - } -} - -func (a *argocdAdapter) LoadPolicy(model model.Model) error { - for _, policyStr := range []string{a.builtinPolicy, a.userDefinedPolicy, a.runtimePolicy} { - for _, line := range strings.Split(policyStr, "\n") { - if line == "" { - continue - } - persist.LoadPolicyLine(line, model) - } - } - return nil -} - -func (a *argocdAdapter) SavePolicy(model model.Model) error { - return errors.New("not implemented") -} - -func (a *argocdAdapter) AddPolicy(sec string, ptype string, rule []string) error { - return errors.New("not implemented") -} - -func (a *argocdAdapter) RemovePolicy(sec string, ptype string, rule []string) error { - return errors.New("not implemented") -} - -func (a *argocdAdapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error { - return errors.New("not implemented") -} diff --git a/util/rbac/rbac_test.go b/util/rbac/rbac_test.go deleted file mode 100644 index cd2b83948..000000000 --- a/util/rbac/rbac_test.go +++ /dev/null @@ -1,401 +0,0 @@ -package rbac - -import ( - "context" - "testing" - "time" - - "github.com/dgrijalva/jwt-go" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - apiv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/fake" - - "github.com/argoproj/argo-cd/util/assets" -) - -const ( - fakeConfgMapName = "fake-cm" - fakeNamespace = "fake-ns" -) - -var ( - noOpUpdate = func(cm *apiv1.ConfigMap) error { - return nil - } -) - -func fakeConfigMap() *apiv1.ConfigMap { - cm := apiv1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fakeConfgMapName, - Namespace: fakeNamespace, - }, - Data: make(map[string]string), - } - return &cm -} - -// TestBuiltinPolicyEnforcer tests the builtin policy rules -func TestBuiltinPolicyEnforcer(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - - // Without setting builtin policy, this should fail - assert.False(t, enf.Enforce("admin", "applications", "get", "foo/bar")) - - // now set builtin policy - _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) - - allowed := [][]interface{}{ - {"admin", "applications", "get", "foo/bar"}, - {"admin", "applications", "delete", "foo/bar"}, - {"role:readonly", "applications", "get", "foo/bar"}, - {"role:admin", "applications", "get", "foo/bar"}, - {"role:admin", "applications", "delete", "foo/bar"}, - } - for _, a := range allowed { - if !assert.True(t, enf.Enforce(a...)) { - log.Errorf("%s: expected true, got false", a) - } - } - - disallowed := [][]interface{}{ - {"role:readonly", "applications", "create", "foo/bar"}, - {"role:readonly", "applications", "delete", "foo/bar"}, - } - for _, a := range disallowed { - if !assert.False(t, enf.Enforce(a...)) { - log.Errorf("%s: expected false, got true", a) - } - } -} - -// TestPolicyInformer verifies the informer will get updated with a new configmap -func TestPolicyInformer(t *testing.T) { - cm := fakeConfigMap() - cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow" - kubeclientset := fake.NewSimpleClientset(cm) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - go enf.runInformer(ctx, func(cm *apiv1.ConfigMap) error { - return nil - }) - - loaded := false - for i := 1; i <= 20; i++ { - if enf.Enforce("admin", "applications", "delete", "foo/bar") { - loaded = true - break - } - time.Sleep(50 * time.Millisecond) - } - assert.True(t, loaded, "Policy update failed to load") - - // update the configmap and update policy - delete(cm.Data, ConfigMapPolicyCSVKey) - err := enf.syncUpdate(cm, noOpUpdate) - assert.Nil(t, err) - assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar")) -} - -// TestResourceActionWildcards verifies the ability to use wildcards in resources and actions -func TestResourceActionWildcards(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - policy := ` -p, alice, *, get, foo/obj, allow -p, bob, repositories, *, foo/obj, allow -p, cathy, *, *, foo/obj, allow -p, dave, applications, get, foo/obj, allow -p, dave, applications/*, get, foo/obj, allow -p, eve, *, get, foo/obj, deny -p, mallory, repositories, *, foo/obj, deny -p, mallory, repositories, *, foo/obj, allow -p, mike, *, *, foo/obj, allow -p, mike, *, *, foo/obj, deny -p, trudy, applications, get, foo/obj, allow -p, trudy, applications/*, get, foo/obj, allow -p, trudy, applications/secrets, get, foo/obj, deny -` - _ = enf.SetUserPolicy(policy) - - // Verify the resource wildcard - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("alice", "applications/resources", "get", "foo/obj")) - assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj")) - - // Verify action wildcards work - assert.True(t, enf.Enforce("bob", "repositories", "get", "foo/obj")) - assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - // Verify resource and action wildcards work in conjunction - assert.True(t, enf.Enforce("cathy", "repositories", "get", "foo/obj")) - assert.True(t, enf.Enforce("cathy", "repositories", "delete", "foo/obj")) - assert.True(t, enf.Enforce("cathy", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("cathy", "applications/resources", "delete", "foo/obj")) - - // Verify wildcards with sub-resources - assert.True(t, enf.Enforce("dave", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("dave", "applications/logs", "get", "foo/obj")) - - // Verify the resource wildcard - assert.False(t, enf.Enforce("eve", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("eve", "applications/resources", "get", "foo/obj")) - assert.False(t, enf.Enforce("eve", "applications/resources", "delete", "foo/obj")) - - // Verify action wildcards work - assert.False(t, enf.Enforce("mallory", "repositories", "get", "foo/obj")) - assert.False(t, enf.Enforce("mallory", "repositories", "delete", "foo/obj")) - assert.False(t, enf.Enforce("mallory", "applications", "get", "foo/obj")) - - // Verify resource and action wildcards work in conjunction - assert.False(t, enf.Enforce("mike", "repositories", "get", "foo/obj")) - assert.False(t, enf.Enforce("mike", "repositories", "delete", "foo/obj")) - assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj")) - - // Verify wildcards with sub-resources - assert.True(t, enf.Enforce("trudy", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("trudy", "applications/logs", "get", "foo/obj")) - assert.False(t, enf.Enforce("trudy", "applications/secrets", "get", "foo/obj")) -} - -// TestProjectIsolationEnforcement verifies the ability to create Project specific policies -func TestProjectIsolationEnforcement(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - policy := ` -p, role:foo-admin, *, *, foo/*, allow -p, role:bar-admin, *, *, bar/*, allow -g, alice, role:foo-admin -g, bob, role:bar-admin -` - _ = enf.SetBuiltinPolicy(policy) - - // verify alice can only affect objects in foo and not bar, - // and that bob can only affect objects in bar and not foo - assert.True(t, enf.Enforce("bob", "applications", "delete", "bar/obj")) - assert.False(t, enf.Enforce("bob", "applications", "delete", "foo/obj")) - assert.True(t, enf.Enforce("alice", "applications", "delete", "foo/obj")) - assert.False(t, enf.Enforce("alice", "applications", "delete", "bar/obj")) -} - -// TestProjectReadOnly verifies the ability to have a read only role in a Project -func TestProjectReadOnly(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - policy := ` -p, role:foo-readonly, *, get, foo/*, allow -g, alice, role:foo-readonly -` - _ = enf.SetBuiltinPolicy(policy) - - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("alice", "applications", "delete", "bar/obj")) - assert.False(t, enf.Enforce("alice", "applications", "get", "bar/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) -} - -// TestDefaultRole tests the ability to set a default role -func TestDefaultRole(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) - - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/bar")) - // after setting the default role to be the read-only role, this should now pass - enf.SetDefaultRole("role:readonly") - assert.True(t, enf.Enforce("bob", "applications", "get", "foo/bar")) -} - -// TestURLAsObjectName tests the ability to have a URL as an object name -func TestURLAsObjectName(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - policy := ` -p, alice, repositories, *, foo/*, allow -p, bob, repositories, *, foo/https://github.com/argoproj/argo-cd.git, allow -p, cathy, repositories, *, foo/*, allow -` - _ = enf.SetUserPolicy(policy) - - assert.True(t, enf.Enforce("alice", "repositories", "delete", "foo/https://github.com/argoproj/argo-cd.git")) - assert.True(t, enf.Enforce("alice", "repositories", "delete", "foo/https://github.com/golang/go.git")) - - assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/https://github.com/argoproj/argo-cd.git")) - assert.False(t, enf.Enforce("bob", "repositories", "delete", "foo/https://github.com/golang/go.git")) - -} - -func TestEnableDisableEnforce(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - policy := ` -p, alice, *, get, foo/obj, allow -p, mike, *, get, foo/obj, deny -` - _ = enf.SetUserPolicy(policy) - enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { - return false - }) - - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj")) - assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj")) - assert.False(t, enf.Enforce(nil, "applications/resources", "delete", "foo/obj")) - assert.False(t, enf.Enforce(&jwt.StandardClaims{}, "applications/resources", "delete", "foo/obj")) - - enf.EnableEnforce(false) - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj")) - assert.True(t, enf.Enforce("mike", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj")) - assert.True(t, enf.Enforce(nil, "applications/resources", "delete", "foo/obj")) - assert.True(t, enf.Enforce(&jwt.StandardClaims{}, "applications/resources", "delete", "foo/obj")) -} - -func TestUpdatePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - - _ = enf.SetUserPolicy("p, alice, *, get, foo/obj, allow") - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - _ = enf.SetUserPolicy("p, bob, *, get, foo/obj, allow") - assert.False(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - _ = enf.SetUserPolicy("") - assert.False(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - _ = enf.SetBuiltinPolicy("p, alice, *, get, foo/obj, allow") - assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - _ = enf.SetBuiltinPolicy("p, bob, *, get, foo/obj, allow") - assert.False(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.True(t, enf.Enforce("bob", "applications", "get", "foo/obj")) - - _ = enf.SetBuiltinPolicy("") - assert.False(t, enf.Enforce("alice", "applications", "get", "foo/obj")) - assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) -} - -func TestNoPolicy(t *testing.T) { - cm := fakeConfigMap() - kubeclientset := fake.NewSimpleClientset(cm) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar")) -} - -// TestClaimsEnforcerFunc tests -func TestClaimsEnforcerFunc(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - claims := jwt.StandardClaims{ - Subject: "foo", - } - assert.False(t, enf.Enforce(&claims, "applications", "get", "foo/bar")) - enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { - return true - }) - assert.True(t, enf.Enforce(&claims, "applications", "get", "foo/bar")) -} - -// TestDefaultRoleWithRuntimePolicy tests the ability for a default role to still take affect when -// enforcing a runtime policy -func TestDefaultRoleWithRuntimePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - runtimePolicy := assets.BuiltinPolicyCSV - assert.False(t, enf.EnforceRuntimePolicy(runtimePolicy, "bob", "applications", "get", "foo/bar")) - enf.SetDefaultRole("role:readonly") - assert.True(t, enf.EnforceRuntimePolicy(runtimePolicy, "bob", "applications", "get", "foo/bar")) -} - -// TestClaimsEnforcerFuncWithRuntimePolicy tests the ability for claims enforcer function to still -// take effect when enforcing a runtime policy -func TestClaimsEnforcerFuncWithRuntimePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - runtimePolicy := assets.BuiltinPolicyCSV - claims := jwt.StandardClaims{ - Subject: "foo", - } - assert.False(t, enf.EnforceRuntimePolicy(runtimePolicy, claims, "applications", "get", "foo/bar")) - enf.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { - return true - }) - assert.True(t, enf.EnforceRuntimePolicy(runtimePolicy, claims, "applications", "get", "foo/bar")) -} - -// TestInvalidRuntimePolicy tests when an invalid policy is supplied, it falls back to normal enforcement -func TestInvalidRuntimePolicy(t *testing.T) { - cm := fakeConfigMap() - kubeclientset := fake.NewSimpleClientset(cm) - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) - assert.True(t, enf.EnforceRuntimePolicy("", "admin", "applications", "update", "foo/bar")) - assert.False(t, enf.EnforceRuntimePolicy("", "role:readonly", "applications", "update", "foo/bar")) - badPolicy := "this, is, not, a, good, policy" - assert.True(t, enf.EnforceRuntimePolicy(badPolicy, "admin", "applications", "update", "foo/bar")) - assert.False(t, enf.EnforceRuntimePolicy(badPolicy, "role:readonly", "applications", "update", "foo/bar")) -} - -func TestValidatePolicy(t *testing.T) { - goodPolicies := []string{ - "p, role:admin, projects, delete, *, allow", - "", - } - for _, good := range goodPolicies { - assert.Nil(t, ValidatePolicy(good)) - } - badPolicies := []string{ - "this, is, not, a, good, policy", - "this\ttoo", - } - for _, bad := range badPolicies { - assert.Error(t, ValidatePolicy(bad)) - } -} - -// TestEnforceErrorMessage ensures we give descriptive error message -func TestEnforceErrorMessage(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() - enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfgMapName, nil) - err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) - assert.Nil(t, err) - - err = enf.EnforceErr("admin", "applications", "get", "foo/bar") - assert.Error(t, err) - assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied: applications, get, foo/bar", err.Error()) - - err = enf.EnforceErr() - assert.Error(t, err) - assert.Equal(t, "rpc error: code = PermissionDenied desc = permission denied", err.Error()) -} diff --git a/util/settings/appclientset.go b/util/settings/appclientset.go deleted file mode 100644 index cfb752ec7..000000000 --- a/util/settings/appclientset.go +++ /dev/null @@ -1,146 +0,0 @@ -package settings - -import ( - "encoding/json" - "fmt" - "sync" - - "github.com/go-openapi/errors" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/strategicpatch" - "k8s.io/apimachinery/pkg/watch" - - "k8s.io/client-go/rest" - - "k8s.io/client-go/discovery/fake" - - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned" - appsfake "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/fake" - alpha1 "github.com/argoproj/argo-cd/engine/pkg/client/clientset/versioned/typed/application/v1alpha1" - "k8s.io/client-go/discovery" -) - -type staticAppClientSet struct { - apps map[string]*v1alpha1.Application - projects alpha1.AppProjectInterface - watch *watch.RaceFreeFakeWatcher - lock *sync.Mutex -} - -func (s staticAppClientSet) Create(app *v1alpha1.Application) (*v1alpha1.Application, error) { - s.lock.Lock() - defer s.lock.Unlock() - s.apps[app.Name] = app - s.watch.Add(app) - return app.DeepCopy(), nil -} - -func (s staticAppClientSet) Update(app *v1alpha1.Application) (*v1alpha1.Application, error) { - s.lock.Lock() - defer s.lock.Unlock() - s.apps[app.Name] = app - s.watch.Modify(app) - return app.DeepCopy(), nil -} - -func (s staticAppClientSet) Delete(name string, options *v1.DeleteOptions) error { - s.lock.Lock() - defer s.lock.Unlock() - if app, ok := s.apps[name]; ok { - delete(s.apps, name) - s.watch.Delete(app) - } - return nil -} - -func (s staticAppClientSet) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - return fmt.Errorf("not implemented") -} - -func (s staticAppClientSet) Get(name string, options v1.GetOptions) (*v1alpha1.Application, error) { - s.lock.Lock() - defer s.lock.Unlock() - if app, ok := s.apps[name]; ok { - return app, nil - } - return nil, errors.NotFound(fmt.Sprintf("applicaition %s not found", name)) -} - -func (s staticAppClientSet) List(opts v1.ListOptions) (*v1alpha1.ApplicationList, error) { - s.lock.Lock() - defer s.lock.Unlock() - res := v1alpha1.ApplicationList{} - for _, app := range s.apps { - res.Items = append(res.Items, *app) - } - return &res, nil -} - -func (s staticAppClientSet) Watch(opts v1.ListOptions) (watch.Interface, error) { - return s.watch, nil -} - -func (s staticAppClientSet) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Application, err error) { - s.lock.Lock() - defer s.lock.Unlock() - - app, ok := s.apps[name] - if !ok { - return app, errors.NotFound(fmt.Sprintf("applicaition %s not found", name)) - } - - origBytes, err := json.Marshal(app) - if err != nil { - return nil, err - } - - newAppData, err := strategicpatch.StrategicMergePatch(origBytes, data, app) - if err != nil { - return nil, err - } - updatedApp := &v1alpha1.Application{} - err = json.Unmarshal(newAppData, updatedApp) - if err != nil { - return nil, err - } - s.apps[app.Name] = updatedApp - s.watch.Modify(updatedApp) - return updatedApp, nil -} - -func (s staticAppClientSet) RESTClient() rest.Interface { - return nil -} - -func (s staticAppClientSet) AppProjects(namespace string) alpha1.AppProjectInterface { - return s.projects -} - -func (s staticAppClientSet) Applications(namespace string) alpha1.ApplicationInterface { - return s -} - -func (s staticAppClientSet) Discovery() discovery.DiscoveryInterface { - return &fake.FakeDiscovery{} -} - -func (s staticAppClientSet) ArgoprojV1alpha1() alpha1.ArgoprojV1alpha1Interface { - return s -} - -func NewStaticAppClientSet(project v1alpha1.AppProject, applications ...v1alpha1.Application) versioned.Interface { - apps := make(map[string]*v1alpha1.Application) - for i := range applications { - app := applications[i] - apps[app.Name] = &app - } - return &staticAppClientSet{ - apps: apps, - projects: appsfake.NewSimpleClientset(&project).ArgoprojV1alpha1().AppProjects(project.Namespace), - lock: &sync.Mutex{}, - watch: watch.NewRaceFreeFake(), - } -} diff --git a/util/settings/creds_store.go b/util/settings/creds_store.go deleted file mode 100644 index f82c6c512..000000000 --- a/util/settings/creds_store.go +++ /dev/null @@ -1,42 +0,0 @@ -package settings - -import ( - "context" - "fmt" - - "github.com/argoproj/argo-cd/engine/pkg" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" -) - -type StaticCredsStore struct { - Clusters map[string]v1alpha1.Cluster - Repos map[string]v1alpha1.Repository -} - -func (s *StaticCredsStore) GetCluster(ctx context.Context, url string) (*v1alpha1.Cluster, error) { - if cluster, ok := s.Clusters[url]; ok { - return &cluster, nil - } - return nil, fmt.Errorf("cluster %s not found", url) -} - -func (s *StaticCredsStore) GetRepository(ctx context.Context, url string) (*v1alpha1.Repository, error) { - if repo, ok := s.Repos[url]; ok { - return &repo, nil - } - return &v1alpha1.Repository{Repo: url}, nil -} - -func (s *StaticCredsStore) WatchClusters(ctx context.Context, callback func(event *pkg.ClusterEvent)) error { - return nil -} -func (s *StaticCredsStore) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { - res := make([]*v1alpha1.Repository, 0) - for url := range s.Repos { - repo := s.Repos[url] - if repo.Type == "helm" { - res = append(res, &repo) - } - } - return res, nil -} diff --git a/util/settings/noop_callbacks.go b/util/settings/noop_callbacks.go deleted file mode 100644 index aa60a03f6..000000000 --- a/util/settings/noop_callbacks.go +++ /dev/null @@ -1,33 +0,0 @@ -package settings - -import ( - "github.com/argoproj/argo-cd/engine/pkg" - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/util/kube" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -type noop_callbacks struct { -} - -func (n noop_callbacks) OnClusterInitialized(server string) { -} - -func (n noop_callbacks) OnResourceUpdated(un *unstructured.Unstructured) { -} - -func (n noop_callbacks) OnResourceRemoved(key kube.ResourceKey) { - -} - -func (n noop_callbacks) OnBeforeSync(appName string, tasks []pkg.SyncTaskInfo) ([]pkg.SyncTaskInfo, error) { - return tasks, nil -} - -func (n noop_callbacks) OnSyncCompleted(appName string, state v1alpha1.OperationState) error { - return nil -} - -func NewNoOpCallbacks() pkg.Callbacks { - return &noop_callbacks{} -} diff --git a/util/settings/reconciliation_settings.go b/util/settings/reconciliation_settings.go deleted file mode 100644 index 4cd7d7070..000000000 --- a/util/settings/reconciliation_settings.go +++ /dev/null @@ -1,44 +0,0 @@ -package settings - -import ( - "github.com/argoproj/argo-cd/engine/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/engine/resource" -) - -type StaticReconciliationSettings struct { - AppInstanceLabelKey string - ResourcesFilter resource.ResourcesFilter - ResourceOverrides map[string]v1alpha1.ResourceOverride - ConfigManagementPlugins []v1alpha1.ConfigManagementPlugin - KustomizeBuildOptions string -} - -func (s *StaticReconciliationSettings) GetAppInstanceLabelKey() (string, error) { - return s.AppInstanceLabelKey, nil -} - -func (s *StaticReconciliationSettings) GetResourcesFilter() (*resource.ResourcesFilter, error) { - return &s.ResourcesFilter, nil -} - -func (s *StaticReconciliationSettings) GetResourceOverrides() (map[string]v1alpha1.ResourceOverride, error) { - if s.ResourceOverrides == nil { - return make(map[string]v1alpha1.ResourceOverride), nil - } - return s.ResourceOverrides, nil -} - -func (s *StaticReconciliationSettings) GetConfigManagementPlugins() ([]v1alpha1.ConfigManagementPlugin, error) { - return s.ConfigManagementPlugins, nil -} -func (s *StaticReconciliationSettings) GetKustomizeBuildOptions() (string, error) { - return s.KustomizeBuildOptions, nil -} - -func (s *StaticReconciliationSettings) Subscribe(subCh chan<- bool) { - -} - -func (s *StaticReconciliationSettings) Unsubscribe(subCh chan<- bool) { - -}