diff --git a/go.mod b/go.mod index 4e8956f83..d051fc16a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.6 require ( code.gitea.io/sdk/gitea v0.22.0 github.com/Masterminds/semver/v3 v3.4.0 - github.com/argoproj-labs/argocd-operator v0.15.0-rc1 + github.com/argoproj-labs/argocd-operator v0.15.0 github.com/go-errors/errors v1.5.1 github.com/go-git/go-git/v5 v5.16.2 github.com/go-logr/logr v1.4.3 @@ -27,7 +27,7 @@ require ( sigs.k8s.io/controller-runtime v0.21.0 ) -require github.com/argoproj/argo-cd/v3 v3.0.14 +require github.com/argoproj/argo-cd/v3 v3.0.16 require ( cloud.google.com/go/compute/metadata v0.7.0 // indirect @@ -44,7 +44,7 @@ require ( github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect - github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1 // indirect + github.com/argoproj/gitops-engine v0.7.1-0.20250905153922-d96c3d51e4c4 // indirect github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -65,7 +65,6 @@ require ( github.com/dlclark/regexp2 v1.11.5 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch v5.9.11+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/camelcase v1.0.0 // indirect diff --git a/go.sum b/go.sum index fadb0b434..fec29e6e2 100644 --- a/go.sum +++ b/go.sum @@ -43,12 +43,12 @@ github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQg github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/argoproj-labs/argocd-operator v0.15.0-rc1 h1:/9AQac/svD+NlJoddaR0Qpv6IZNEIuCT9T+qSMg6Mcg= -github.com/argoproj-labs/argocd-operator v0.15.0-rc1/go.mod h1:6rbhhiij9sAuSkUjNrSIcn83lgEc7w0huuImaARS7uA= -github.com/argoproj/argo-cd/v3 v3.0.14 h1:sM+h75i1QtTQS+wKoJOKeS9g7cqysE97eUTrwZC30j0= -github.com/argoproj/argo-cd/v3 v3.0.14/go.mod h1:bVeSUtER7VMb2qLqmjZag9X35UldkiolYOdEyNbnZ2A= -github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1 h1:Ze4U6kV49vSzlUBhH10HkO52bYKAIXS4tHr/MlNDfdU= -github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1/go.mod h1:WsnykM8idYRUnneeT31cM/Fq/ZsjkefCbjiD8ioCJkU= +github.com/argoproj-labs/argocd-operator v0.15.0 h1:7zSjRchKUBCGBpz4v1pJ/Igmgn5blXorTxW0Ch9hWZ0= +github.com/argoproj-labs/argocd-operator v0.15.0/go.mod h1:5jApqvt/B2NpI2fFEa7g/8TGUvnesspv86yu1E4hVUI= +github.com/argoproj/argo-cd/v3 v3.0.16 h1:V67eJxuPTS20kjcA1K/uLnbapEVUfIJ9eIO62ns4ECU= +github.com/argoproj/argo-cd/v3 v3.0.16/go.mod h1:oTCI5r+Hacij94yJto2/mVXAHB8r3375h9SInqbS8EM= +github.com/argoproj/gitops-engine v0.7.1-0.20250905153922-d96c3d51e4c4 h1:OsQxWX8UHdwXuy72Y1Js8gQY3xmOzFEieCSpMoXKFb8= +github.com/argoproj/gitops-engine v0.7.1-0.20250905153922-d96c3d51e4c4/go.mod h1:duVhxDW7M7M7+19IBCVth2REOS11gmqzTWwj4u8N7aQ= github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5 h1:YBoLSjpoaJXaXAldVvBRKJuOPvIXz9UOv6S96gMJM/Q= github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5/go.mod h1:ebVOzFJphdN1p6EG2mIMECv/3Rk/almSaxIYuFAmsSw= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= diff --git a/vendor/github.com/argoproj-labs/argocd-operator/common/defaults.go b/vendor/github.com/argoproj-labs/argocd-operator/common/defaults.go index db18884fa..66eb7d424 100644 --- a/vendor/github.com/argoproj-labs/argocd-operator/common/defaults.go +++ b/vendor/github.com/argoproj-labs/argocd-operator/common/defaults.go @@ -70,7 +70,7 @@ const ( ArgoCDDefaultArgoImage = "quay.io/argoproj/argocd" // ArgoCDDefaultArgoVersion is the Argo CD container image digest to use when version not specified. - ArgoCDDefaultArgoVersion = "sha256:1cb4ede2fc4a6332c128d9ba29d19e8cb5b76f9260dc47550a4b3b154269ff86" // v3.0.11 + ArgoCDDefaultArgoVersion = "sha256:bbdb994007855fed9adfbef31cd58c49f867e652c0e16654bf6579ff037e13e2" // v3.0.16 // ArgoCDDefaultBackupKeyLength is the length of the generated default backup key. ArgoCDDefaultBackupKeyLength = 32 @@ -300,6 +300,9 @@ vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOf // ArgoCDCmdParamsConfigMapName is the upstream hard-coded ArgoCD command params ConfigMap name. ArgoCDCmdParamsConfigMapName = "argocd-cmd-params-cm" + + // ArgoCDAgentPrincipalDefaultImageName is the default image name for the ArgoCD agent principal. + ArgoCDAgentPrincipalDefaultImageName = "quay.io/argoprojlabs/argocd-agent:v0.3.2" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/diff/diff.go b/vendor/github.com/argoproj/gitops-engine/pkg/diff/diff.go index c8e2aa3dc..efe15f227 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/diff/diff.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/diff/diff.go @@ -13,7 +13,7 @@ import ( "fmt" "reflect" - jsonpatch "github.com/evanphx/json-patch" + jsonpatch "github.com/evanphx/json-patch/v5" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -55,10 +55,9 @@ type DiffResultList struct { Modified bool } -type noopNormalizer struct { -} +type noopNormalizer struct{} -func (n *noopNormalizer) Normalize(un *unstructured.Unstructured) error { +func (n *noopNormalizer) Normalize(_ *unstructured.Unstructured) error { return nil } @@ -117,15 +116,13 @@ func Diff(config, live *unstructured.Unstructured, opts ...Option) (*DiffResult, orig, err := GetLastAppliedConfigAnnotation(live) if err != nil { o.log.V(1).Info(fmt.Sprintf("Failed to get last applied configuration: %v", err)) - } else { - if orig != nil && config != nil { - Normalize(orig, opts...) - dr, err := ThreeWayDiff(orig, config, live) - if err == nil { - return dr, nil - } - o.log.V(1).Info(fmt.Sprintf("three-way diff calculation failed: %v. Falling back to two-way diff", err)) + } else if orig != nil && config != nil { + Normalize(orig, opts...) + dr, err := ThreeWayDiff(orig, config, live) + if err == nil { + return dr, nil } + o.log.V(1).Info(fmt.Sprintf("three-way diff calculation failed: %v. Falling back to two-way diff", err)) } return TwoWayDiff(config, live) } @@ -162,7 +159,7 @@ func ServerSideDiff(config, live *unstructured.Unstructured, opts ...Option) (*D func serverSideDiff(config, live *unstructured.Unstructured, opts ...Option) (*DiffResult, error) { o := applyOptions(opts) if o.serverSideDryRunner == nil { - return nil, fmt.Errorf("serverSideDryRunner is null") + return nil, errors.New("serverSideDryRunner is null") } predictedLiveStr, err := o.serverSideDryRunner.Run(context.Background(), config, o.manager) if err != nil { @@ -231,7 +228,7 @@ func removeWebhookMutation(predictedLive, live *unstructured.Unstructured, gvkPa managedFieldsSet := &fieldpath.Set{} err := managedFieldsSet.FromJSON(bytes.NewReader(mfEntry.FieldsV1.Raw)) if err != nil { - return nil, fmt.Errorf("error building managedFields set: %s", err) + return nil, fmt.Errorf("error building managedFields set: %w", err) } if mfEntry.Manager == manager { // Union the fields with the aggregated set @@ -278,7 +275,7 @@ func removeWebhookMutation(predictedLive, live *unstructured.Unstructured, gvkPa } plu := typedPredictedLive.AsValue().Unstructured() - pl, ok := plu.(map[string]interface{}) + pl, ok := plu.(map[string]any) if !ok { return nil, fmt.Errorf("error converting live typedValue: expected map got %T", plu) } @@ -311,10 +308,10 @@ func safelyRemoveFieldsSet(predictedLive *typed.TypedValue, fieldsToRemove *fiel } func jsonStrToUnstructured(jsonString string) (*unstructured.Unstructured, error) { - res := make(map[string]interface{}) + res := make(map[string]any) err := json.Unmarshal([]byte(jsonString), &res) if err != nil { - return nil, fmt.Errorf("unmarshal error: %s", err) + return nil, fmt.Errorf("unmarshal error: %w", err) } return &unstructured.Unstructured{Object: res}, nil } @@ -344,7 +341,6 @@ type SMDParams struct { } func structuredMergeDiff(p *SMDParams) (*DiffResult, error) { - gvk := p.config.GetObjectKind().GroupVersionKind() pt := gescheme.ResolveParseableType(gvk, p.gvkParser) if pt == nil { @@ -398,7 +394,6 @@ func structuredMergeDiff(p *SMDParams) (*DiffResult, error) { // to correctly calculate the diff with the same logic used in k8s with server-side // apply. func apply(tvConfig, tvLive *typed.TypedValue, p *SMDParams) (*typed.TypedValue, error) { - // Build the structured-merge-diff Updater updater := merge.Updater{ Converter: fieldmanager.NewVersionConverter(p.gvkParser, scheme.Scheme, p.config.GroupVersionKind().GroupVersion()), @@ -442,7 +437,7 @@ func buildManagerInfoForApply(manager string) (string, error) { // - applying default values func normalizeTypedValue(tv *typed.TypedValue) ([]byte, error) { ru := tv.AsValue().Unstructured() - r, ok := ru.(map[string]interface{}) + r, ok := ru.(map[string]any) if !ok { return nil, fmt.Errorf("error converting result typedValue: expected map got %T", ru) } @@ -503,15 +498,13 @@ func handleResourceCreateOrDeleteDiff(config, live *unstructured.Unstructured) ( return nil, err } return &DiffResult{Modified: true, NormalizedLive: []byte("null"), PredictedLive: predictedLiveData}, nil - } else { - return nil, errors.New("both live and config are null objects") } + return nil, errors.New("both live and config are null objects") } // generateSchemeDefaultPatch runs the scheme default functions on the given parameter, and // return a patch representing the delta vs the origin parameter object. func generateSchemeDefaultPatch(kubeObj runtime.Object) ([]byte, error) { - // 1) Call scheme defaulter functions on a clone of our k8s resource object patched := kubeObj.DeepCopyObject() gescheme.Scheme.Default(patched) @@ -537,7 +530,6 @@ func generateSchemeDefaultPatch(kubeObj runtime.Object) ([]byte, error) { // applyPatch executes kubernetes server side patch: // uses corresponding data structure, applies appropriate defaults and executes strategic merge patch func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() (runtime.Object, error)) ([]byte, []byte, error) { - // Construct an empty instance of the object we are applying a patch against predictedLive, err := newVersionedObject() if err != nil { @@ -553,7 +545,6 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() ( // Unmarshal predictedLiveBytes into predictedLive; note that this will discard JSON fields in predictedLiveBytes // which are not in the predictedLive struct. predictedLive is thus "tainted" and we should not use it directly. if err = json.Unmarshal(predictedLiveBytes, &predictedLive); err == nil { - // 1) Calls 'kubescheme.Scheme.Default(predictedLive)' and generates a patch containing the delta of that // call, which can then be applied to predictedLiveBytes. // @@ -574,10 +565,10 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() ( return nil, nil, err } - // 3) Unmarshall into a map[string]interface{}, then back into byte[], to ensure the fields + // 3) Unmarshall into a map[string]any, then back into byte[], to ensure the fields // are sorted in a consistent order (we do the same below, so that they can be // lexicographically compared with one another) - var result map[string]interface{} + var result map[string]any err = json.Unmarshal([]byte(predictedLiveBytes), &result) if err != nil { return nil, nil, err @@ -597,7 +588,6 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() ( // However, this is much less likely since liveBytes is coming from a live k8s instance which // has already accepted those resources. Regardless, we still treat 'live' as tainted. if err = json.Unmarshal(liveBytes, live); err == nil { - // As above, indirectly apply the schema defaults against liveBytes patch, err := generateSchemeDefaultPatch(live) if err != nil { @@ -609,7 +599,7 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() ( } // Ensure the fields are sorted in a consistent order (as above) - var result map[string]interface{} + var result map[string]any err = json.Unmarshal([]byte(liveBytes), &result) if err != nil { return nil, nil, err @@ -618,7 +608,6 @@ func applyPatch(liveBytes []byte, patchBytes []byte, newVersionedObject func() ( if err != nil { return nil, nil, err } - } return liveBytes, predictedLiveBytes, nil @@ -641,10 +630,10 @@ func patchDefaultValues(objBytes []byte, obj runtime.Object) ([]byte, error) { return nil, fmt.Errorf("error applying patch for default values: %w", err) } - // 3) Unmarshall into a map[string]interface{}, then back into byte[], to + // 3) Unmarshall into a map[string]any, then back into byte[], to // ensure the fields are sorted in a consistent order (we do the same below, // so that they can be lexicographically compared with one another). - var result map[string]interface{} + var result map[string]any err = json.Unmarshal([]byte(patchedBytes), &result) if err != nil { return nil, fmt.Errorf("error unmarshaling patched bytes: %w", err) @@ -702,14 +691,14 @@ func ThreeWayDiff(orig, config, live *unstructured.Unstructured) (*DiffResult, e func removeNamespaceAnnotation(orig *unstructured.Unstructured) *unstructured.Unstructured { orig = orig.DeepCopy() if metadataIf, ok := orig.Object["metadata"]; ok { - metadata := metadataIf.(map[string]interface{}) + metadata := metadataIf.(map[string]any) delete(metadata, "namespace") if annotationsIf, ok := metadata["annotations"]; ok { shouldDelete := false if annotationsIf == nil { shouldDelete = true } else { - annotation, ok := annotationsIf.(map[string]interface{}) + annotation, ok := annotationsIf.(map[string]any) if ok && len(annotation) == 0 { shouldDelete = true } @@ -774,22 +763,21 @@ func threeWayMergePatch(orig, config, live *unstructured.Unstructured) ([]byte, return scheme.Scheme.New(orig.GroupVersionKind()) } return patch, newVersionedObject, nil - } else { - // Remove defaulted fields from the live object. - // This subtracts any extra fields in the live object which are not present in last-applied-configuration. - live = &unstructured.Unstructured{Object: jsonutil.RemoveMapFields(orig.Object, live.Object)} + } + // Remove defaulted fields from the live object. + // This subtracts any extra fields in the live object which are not present in last-applied-configuration. + live = &unstructured.Unstructured{Object: jsonutil.RemoveMapFields(orig.Object, live.Object)} - liveBytes, err := json.Marshal(live.Object) - if err != nil { - return nil, nil, err - } + liveBytes, err := json.Marshal(live.Object) + if err != nil { + return nil, nil, err + } - patch, err := jsonmergepatch.CreateThreeWayJSONMergePatch(origBytes, configBytes, liveBytes) - if err != nil { - return nil, nil, err - } - return patch, nil, nil + patch, err := jsonmergepatch.CreateThreeWayJSONMergePatch(origBytes, configBytes, liveBytes) + if err != nil { + return nil, nil, err } + return patch, nil, nil } func GetLastAppliedConfigAnnotation(live *unstructured.Unstructured) (*unstructured.Unstructured, error) { @@ -804,7 +792,7 @@ func GetLastAppliedConfigAnnotation(live *unstructured.Unstructured) (*unstructu var obj unstructured.Unstructured err := json.Unmarshal([]byte(lastAppliedStr), &obj) if err != nil { - return nil, fmt.Errorf("failed to unmarshal %s in %s: %v", corev1.LastAppliedConfigAnnotation, live.GetName(), err) + return nil, fmt.Errorf("failed to unmarshal %s in %s: %w", corev1.LastAppliedConfigAnnotation, live.GetName(), err) } return &obj, nil } @@ -846,11 +834,12 @@ func Normalize(un *unstructured.Unstructured, opts ...Option) { unstructured.RemoveNestedField(un.Object, "metadata", "creationTimestamp") gvk := un.GroupVersionKind() - if gvk.Group == "" && gvk.Kind == "Secret" { + switch { + case gvk.Group == "" && gvk.Kind == "Secret": NormalizeSecret(un, opts...) - } else if gvk.Group == "rbac.authorization.k8s.io" && (gvk.Kind == "ClusterRole" || gvk.Kind == "Role") { + case gvk.Group == "rbac.authorization.k8s.io" && (gvk.Kind == "ClusterRole" || gvk.Kind == "Role"): normalizeRole(un, o) - } else if gvk.Group == "" && gvk.Kind == "Endpoints" { + case gvk.Group == "" && gvk.Kind == "Endpoints": normalizeEndpoint(un, o) } @@ -873,10 +862,10 @@ func NormalizeSecret(un *unstructured.Unstructured, opts ...Option) { // move stringData to data section if stringData, found, err := unstructured.NestedMap(un.Object, "stringData"); found && err == nil { - var data map[string]interface{} + var data map[string]any data, found, _ = unstructured.NestedMap(un.Object, "data") if !found { - data = make(map[string]interface{}) + data = make(map[string]any) } // base64 encode string values and add non-string values as is. @@ -974,7 +963,7 @@ func normalizeRole(un *unstructured.Unstructured, o options) { if o.ignoreAggregatedRoles { aggrIf, ok := un.Object["aggregationRule"] if ok { - _, ok = aggrIf.(map[string]interface{}) + _, ok = aggrIf.(map[string]any) if !ok { o.log.Info(fmt.Sprintf("Malformed aggregationRule in resource '%s', won't modify.", un.GetName())) } else { @@ -987,18 +976,17 @@ func normalizeRole(un *unstructured.Unstructured, o options) { if !ok { return } - rules, ok := rulesIf.([]interface{}) + rules, ok := rulesIf.([]any) if !ok { return } if rules != nil && len(rules) == 0 { un.Object["rules"] = nil } - } // CreateTwoWayMergePatch is a helper to construct a two-way merge patch from objects (instead of bytes) -func CreateTwoWayMergePatch(orig, new, dataStruct interface{}) ([]byte, bool, error) { +func CreateTwoWayMergePatch(orig, new, dataStruct any) ([]byte, bool, error) { origBytes, err := json.Marshal(orig) if err != nil { return nil, false, err @@ -1062,7 +1050,7 @@ func HideSecretData(target *unstructured.Unstructured, live *unstructured.Unstru } else { lastAppliedData, err := json.Marshal(liveLastAppliedAnnotation) if err != nil { - return nil, nil, fmt.Errorf("error marshaling json: %s", err) + return nil, nil, fmt.Errorf("error marshaling json: %w", err) } annotations[corev1.LastAppliedConfigAnnotation] = string(lastAppliedData) } @@ -1077,7 +1065,7 @@ func hide(target, live, liveLastAppliedAnnotation *unstructured.Unstructured, ke nextReplacement := replacement valToReplacement := make(map[string]string) for _, obj := range []*unstructured.Unstructured{target, live, liveLastAppliedAnnotation} { - var data map[string]interface{} + var data map[string]any if obj != nil { // handles an edge case when secret data has nil value // https://github.com/argoproj/argo-cd/issues/5584 @@ -1090,11 +1078,11 @@ func hide(target, live, liveLastAppliedAnnotation *unstructured.Unstructured, ke var err error data, _, err = unstructured.NestedMap(obj.Object, fields...) if err != nil { - return nil, nil, nil, fmt.Errorf("unstructured.NestedMap error: %s", err) + return nil, nil, nil, fmt.Errorf("unstructured.NestedMap error: %w", err) } } if data == nil { - data = make(map[string]interface{}) + data = make(map[string]any) } valData, ok := data[k] if !ok { @@ -1110,14 +1098,14 @@ func hide(target, live, liveLastAppliedAnnotation *unstructured.Unstructured, ke data[k] = replacement err := unstructured.SetNestedField(obj.Object, data, fields...) if err != nil { - return nil, nil, nil, fmt.Errorf("unstructured.SetNestedField error: %s", err) + return nil, nil, nil, fmt.Errorf("unstructured.SetNestedField error: %w", err) } } } return target, live, liveLastAppliedAnnotation, nil } -func toString(val interface{}) string { +func toString(val any) string { if val == nil { return "" } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/diff/internal/fieldmanager/borrowed_typeconverter.go b/vendor/github.com/argoproj/gitops-engine/pkg/diff/internal/fieldmanager/borrowed_typeconverter.go index fc40546f1..11ca37433 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/diff/internal/fieldmanager/borrowed_typeconverter.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/diff/internal/fieldmanager/borrowed_typeconverter.go @@ -102,7 +102,7 @@ func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, func valueToObject(val value.Value) (runtime.Object, error) { vu := val.Unstructured() switch o := vu.(type) { - case map[string]interface{}: + case map[string]any: return &unstructured.Unstructured{Object: o}, nil default: return nil, fmt.Errorf("failed to convert value to unstructured for type %T", vu) diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health.go index b93d8c967..c615deea9 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health.go @@ -1,9 +1,11 @@ package health import ( - "github.com/argoproj/gitops-engine/pkg/utils/kube" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/argoproj/gitops-engine/pkg/sync/hook" + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) // Represents resource health status @@ -64,7 +66,7 @@ func IsWorse(current, new HealthStatusCode) bool { // GetResourceHealth returns the health of a k8s resource func GetResourceHealth(obj *unstructured.Unstructured, healthOverride HealthOverride) (health *HealthStatus, err error) { - if obj.GetDeletionTimestamp() != nil { + if obj.GetDeletionTimestamp() != nil && !hook.HasHookFinalizer(obj) { return &HealthStatus{ Status: HealthStatusProgressing, Message: "Pending deletion", @@ -94,7 +96,6 @@ func GetResourceHealth(obj *unstructured.Unstructured, healthOverride HealthOver } } return health, err - } // GetHealthCheckFunc returns built-in health check function or nil if health check is not supported @@ -112,23 +113,19 @@ func GetHealthCheckFunc(gvk schema.GroupVersionKind) func(obj *unstructured.Unst return getDaemonSetHealth } case "extensions": - switch gvk.Kind { - case kube.IngressKind: + if gvk.Kind == kube.IngressKind { return getIngressHealth } case "argoproj.io": - switch gvk.Kind { - case "Workflow": + if gvk.Kind == "Workflow" { return getArgoWorkflowHealth } case "apiregistration.k8s.io": - switch gvk.Kind { - case kube.APIServiceKind: + if gvk.Kind == kube.APIServiceKind { return getAPIServiceHealth } case "networking.k8s.io": - switch gvk.Kind { - case kube.IngressKind: + if gvk.Kind == kube.IngressKind { return getIngressHealth } case "": @@ -141,13 +138,11 @@ func GetHealthCheckFunc(gvk schema.GroupVersionKind) func(obj *unstructured.Unst return getPodHealth } case "batch": - switch gvk.Kind { - case kube.JobKind: + if gvk.Kind == kube.JobKind { return getJobHealth } case "autoscaling": - switch gvk.Kind { - case kube.HorizontalPodAutoscalerKind: + if gvk.Kind == kube.HorizontalPodAutoscalerKind { return getHPAHealth } } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_apiservice.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_apiservice.go index 6b9fb44a5..8def46256 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_apiservice.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_apiservice.go @@ -3,11 +3,12 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getAPIServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -17,14 +18,14 @@ func getAPIServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) var apiService apiregistrationv1.APIService err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &apiService) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured APIService to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured APIService to typed: %w", err) } return getApiregistrationv1APIServiceHealth(&apiService) case apiregistrationv1beta1.SchemeGroupVersion.WithKind(kube.APIServiceKind): var apiService apiregistrationv1beta1.APIService err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &apiService) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured APIService to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured APIService to typed: %w", err) } return getApiregistrationv1beta1APIServiceHealth(&apiService) default: @@ -34,19 +35,17 @@ func getAPIServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) func getApiregistrationv1APIServiceHealth(apiservice *apiregistrationv1.APIService) (*HealthStatus, error) { for _, c := range apiservice.Status.Conditions { - switch c.Type { - case apiregistrationv1.Available: + if c.Type == apiregistrationv1.Available { if c.Status == apiregistrationv1.ConditionTrue { return &HealthStatus{ Status: HealthStatusHealthy, Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), }, nil - } else { - return &HealthStatus{ - Status: HealthStatusProgressing, - Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), - }, nil } + return &HealthStatus{ + Status: HealthStatusProgressing, + Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), + }, nil } } return &HealthStatus{ @@ -57,19 +56,17 @@ func getApiregistrationv1APIServiceHealth(apiservice *apiregistrationv1.APIServi func getApiregistrationv1beta1APIServiceHealth(apiservice *apiregistrationv1beta1.APIService) (*HealthStatus, error) { for _, c := range apiservice.Status.Conditions { - switch c.Type { - case apiregistrationv1beta1.Available: + if c.Type == apiregistrationv1beta1.Available { if c.Status == apiregistrationv1beta1.ConditionTrue { return &HealthStatus{ Status: HealthStatusHealthy, Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), }, nil - } else { - return &HealthStatus{ - Status: HealthStatusProgressing, - Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), - }, nil } + return &HealthStatus{ + Status: HealthStatusProgressing, + Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), + }, nil } } return &HealthStatus{ diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_daemonset.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_daemonset.go index 76131daf3..9cb9eff8e 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_daemonset.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_daemonset.go @@ -3,10 +3,11 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getDaemonSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -16,7 +17,7 @@ func getDaemonSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var daemon appsv1.DaemonSet err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &daemon) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured DaemonSet to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured DaemonSet to typed: %w", err) } return getAppsv1DaemonSetHealth(&daemon) default: @@ -26,31 +27,30 @@ func getDaemonSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { func getAppsv1DaemonSetHealth(daemon *appsv1.DaemonSet) (*HealthStatus, error) { // 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.Spec.UpdateStrategy.Type == appsv1.OnDeleteDaemonSetStrategyType { - return &HealthStatus{ - Status: HealthStatusHealthy, - Message: fmt.Sprintf("daemon set %d out of %d new pods have been updated", daemon.Status.UpdatedNumberScheduled, daemon.Status.DesiredNumberScheduled), - }, nil - } - if daemon.Status.UpdatedNumberScheduled < daemon.Status.DesiredNumberScheduled { - 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 &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 { + if daemon.Generation > daemon.Status.ObservedGeneration { return &HealthStatus{ Status: HealthStatusProgressing, Message: "Waiting for rollout to finish: observed daemon set generation less than desired generation", }, nil } + if daemon.Spec.UpdateStrategy.Type == appsv1.OnDeleteDaemonSetStrategyType { + return &HealthStatus{ + Status: HealthStatusHealthy, + Message: fmt.Sprintf("daemon set %d out of %d new pods have been updated", daemon.Status.UpdatedNumberScheduled, daemon.Status.DesiredNumberScheduled), + }, nil + } + if daemon.Status.UpdatedNumberScheduled < daemon.Status.DesiredNumberScheduled { + 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 &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 + } return &HealthStatus{ Status: HealthStatusHealthy, }, nil diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_deployment.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_deployment.go index 605d5e77f..4f7984a2f 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_deployment.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_deployment.go @@ -3,10 +3,11 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getDeploymentHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -16,7 +17,7 @@ func getDeploymentHealth(obj *unstructured.Unstructured) (*HealthStatus, error) var deployment appsv1.Deployment err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deployment) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured Deployment to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured Deployment to typed: %w", err) } return getAppsv1DeploymentHealth(&deployment) default: @@ -34,22 +35,23 @@ func getAppsv1DeploymentHealth(deployment *appsv1.Deployment) (*HealthStatus, er // Borrowed at kubernetes/kubectl/rollout_status.go https://github.com/kubernetes/kubernetes/blob/5232ad4a00ec93942d0b2c6359ee6cd1201b46bc/pkg/kubectl/rollout_status.go#L80 if deployment.Generation <= deployment.Status.ObservedGeneration { cond := getAppsv1DeploymentCondition(deployment.Status, appsv1.DeploymentProgressing) - if cond != nil && cond.Reason == "ProgressDeadlineExceeded" { + switch { + case cond != nil && cond.Reason == "ProgressDeadlineExceeded": return &HealthStatus{ Status: HealthStatusDegraded, Message: fmt.Sprintf("Deployment %q exceeded its progress deadline", deployment.Name), }, nil - } else if deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas { + case deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas: 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 { + case deployment.Status.Replicas > deployment.Status.UpdatedReplicas: 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 { + case deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas: 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), diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_hpa.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_hpa.go index 95580ebb0..67d178767 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_hpa.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_hpa.go @@ -14,12 +14,10 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" ) -var ( - progressingStatus = &HealthStatus{ - Status: HealthStatusProgressing, - Message: "Waiting to Autoscale", - } -) +var progressingStatus = &HealthStatus{ + Status: HealthStatusProgressing, + Message: "Waiting to Autoscale", +} type hpaCondition struct { Type string diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_job.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_job.go index 4e0d7be66..b79b4d902 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_job.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_job.go @@ -2,12 +2,14 @@ package health import ( "fmt" + corev1 "k8s.io/api/core/v1" - "github.com/argoproj/gitops-engine/pkg/utils/kube" batchv1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getJobHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -17,7 +19,7 @@ func getJobHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var job batchv1.Job err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &job) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured Job to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured Job to typed: %w", err) } return getBatchv1JobHealth(&job) default: @@ -48,22 +50,23 @@ func getBatchv1JobHealth(job *batchv1.Job) (*HealthStatus, error) { } } } - if !complete { + switch { + case !complete: return &HealthStatus{ Status: HealthStatusProgressing, Message: message, }, nil - } else if failed { + case failed: return &HealthStatus{ Status: HealthStatusDegraded, Message: failMsg, }, nil - } else if isSuspended { + case isSuspended: return &HealthStatus{ Status: HealthStatusSuspended, Message: failMsg, }, nil - } else { + default: return &HealthStatus{ Status: HealthStatusHealthy, Message: message, diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pod.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pod.go index 25db283ef..9ebcef558 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pod.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pod.go @@ -4,11 +4,12 @@ import ( "fmt" "strings" - "github.com/argoproj/gitops-engine/pkg/utils/kube" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubectl/pkg/util/podutils" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getPodHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -18,7 +19,7 @@ func getPodHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var pod corev1.Pod err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &pod) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured Pod to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured Pod to typed: %w", err) } return getCorev1PodHealth(&pod) default: diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pvc.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pvc.go index 817e31510..7d41120a0 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pvc.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_pvc.go @@ -3,10 +3,11 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getPVCHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -16,7 +17,7 @@ func getPVCHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var pvc corev1.PersistentVolumeClaim err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &pvc) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured PersistentVolumeClaim to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured PersistentVolumeClaim to typed: %w", err) } return getCorev1PVCHealth(&pvc) default: diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_replicaset.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_replicaset.go index 95b56793b..7d59eaccc 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_replicaset.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_replicaset.go @@ -3,11 +3,12 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getReplicaSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -17,7 +18,7 @@ func getReplicaSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) var replicaSet appsv1.ReplicaSet err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &replicaSet) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured ReplicaSet to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured ReplicaSet to typed: %w", err) } return getAppsv1ReplicaSetHealth(&replicaSet) default: diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_service.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_service.go index 17d5f3e4c..ea8cda2bb 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_service.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_service.go @@ -3,10 +3,11 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -16,7 +17,7 @@ func getServiceHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { var service corev1.Service err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &service) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured Service to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured Service to typed: %w", err) } return getCorev1ServiceHealth(&service) default: diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_statefulset.go b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_statefulset.go index 52d156712..920e5ed2d 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/health/health_statefulset.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/health/health_statefulset.go @@ -3,10 +3,11 @@ package health import ( "fmt" - "github.com/argoproj/gitops-engine/pkg/utils/kube" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" ) func getStatefulSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { @@ -16,7 +17,7 @@ func getStatefulSetHealth(obj *unstructured.Unstructured) (*HealthStatus, error) var sts appsv1.StatefulSet err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &sts) if err != nil { - return nil, fmt.Errorf("failed to convert unstructured StatefulSet to typed: %v", err) + return nil, fmt.Errorf("failed to convert unstructured StatefulSet to typed: %w", err) } return getAppsv1StatefulSetHealth(&sts) default: diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/sync/common/types.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/common/types.go index b02ad8c20..060f79369 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/sync/common/types.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/common/types.go @@ -20,6 +20,8 @@ const ( // Sync option that disables dry run in resource is missing in the cluster SyncOptionSkipDryRunOnMissingResource = "SkipDryRunOnMissingResource=true" + // Sync option that disables dry run for applying resources + SyncOptionSkipDryRun = "SkipDryRun=true" // Sync option that disables resource pruning SyncOptionDisablePrune = "Prune=false" // Sync option that disables resource validation @@ -116,7 +118,6 @@ func NewHookType(t string) (HookType, bool) { t == string(HookTypePostSync) || t == string(HookTypeSyncFail) || t == string(HookTypeSkip) - } type HookDeletePolicy string @@ -137,6 +138,10 @@ func NewHookDeletePolicy(p string) (HookDeletePolicy, bool) { type ResourceSyncResult struct { // holds associated resource key ResourceKey kube.ResourceKey + // Images holds the images associated with the resource. These images are collected on a best-effort basis + // from fields used by known workload resources. This does not necessarily reflect the exact list of images + // used by workloads in the application. + Images []string // holds resource version Version string // holds the execution order diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/delete_policy.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/delete_policy.go new file mode 100644 index 000000000..56a9e15c8 --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/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/sync/common" + helmhook "github.com/argoproj/gitops-engine/pkg/sync/hook/helm" + resourceutil "github.com/argoproj/gitops-engine/pkg/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/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/delete_policy.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/delete_policy.go new file mode 100644 index 000000000..f174eda7d --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/delete_policy.go @@ -0,0 +1,42 @@ +package helm + +import ( + "github.com/argoproj/gitops-engine/pkg/sync/common" + resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +type DeletePolicy string + +const ( + BeforeHookCreation DeletePolicy = "before-hook-creation" + HookSucceeded DeletePolicy = "hook-succeeded" + HookFailed DeletePolicy = "hook-failed" +) + +// note that we do not take into account if this is or is not a hook, caller should check +func NewDeletePolicy(p string) (DeletePolicy, bool) { + return DeletePolicy(p), p == string(BeforeHookCreation) || p == string(HookSucceeded) || p == string(HookFailed) +} + +var hookDeletePolicies = map[DeletePolicy]common.HookDeletePolicy{ + BeforeHookCreation: common.HookDeletePolicyBeforeHookCreation, + HookSucceeded: common.HookDeletePolicyHookSucceeded, + HookFailed: common.HookDeletePolicyHookFailed, +} + +func (p DeletePolicy) DeletePolicy() common.HookDeletePolicy { + return hookDeletePolicies[p] +} + +func DeletePolicies(obj *unstructured.Unstructured) []DeletePolicy { + var policies []DeletePolicy + for _, text := range resourceutil.GetAnnotationCSVs(obj, "helm.sh/hook-delete-policy") { + p, ok := NewDeletePolicy(text) + if ok { + policies = append(policies, p) + } + } + return policies +} diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/hook.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/hook.go new file mode 100644 index 000000000..9b3339919 --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/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/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/type.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/type.go new file mode 100644 index 000000000..f94f3bc47 --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/type.go @@ -0,0 +1,47 @@ +package helm + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/sync/common" + resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource" +) + +type Type string + +const ( + PreInstall Type = "pre-install" + PreUpgrade Type = "pre-upgrade" + PostUpgrade Type = "post-upgrade" + PostInstall Type = "post-install" +) + +func NewType(t string) (Type, bool) { + return Type(t), + t == string(PreInstall) || + t == string(PreUpgrade) || + t == string(PostUpgrade) || + t == string(PostInstall) +} + +var hookTypes = map[Type]common.HookType{ + PreInstall: common.HookTypePreSync, + PreUpgrade: common.HookTypePreSync, + PostUpgrade: common.HookTypePostSync, + PostInstall: common.HookTypePostSync, +} + +func (t Type) HookType() common.HookType { + return hookTypes[t] +} + +func Types(obj *unstructured.Unstructured) []Type { + var types []Type + for _, text := range resourceutil.GetAnnotationCSVs(obj, "helm.sh/hook") { + t, ok := NewType(text) + if ok { + types = append(types, t) + } + } + return types +} diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/weight.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/weight.go new file mode 100644 index 000000000..15ecfdf20 --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/helm/weight.go @@ -0,0 +1,19 @@ +package helm + +import ( + "strconv" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// note that we do not take into account if this is or is not a hook, caller should check +func Weight(obj *unstructured.Unstructured) int { + text, ok := obj.GetAnnotations()["helm.sh/hook-weight"] + if ok { + value, err := strconv.Atoi(text) + if err == nil { + return value + } + } + return 0 +} diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/hook.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/hook.go new file mode 100644 index 000000000..66dfc26e5 --- /dev/null +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/hook/hook.go @@ -0,0 +1,58 @@ +package hook + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/gitops-engine/pkg/sync/common" + helmhook "github.com/argoproj/gitops-engine/pkg/sync/hook/helm" + resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource" +) + +const ( + // HookFinalizer is the finalizer added to hooks to ensure they are deleted only after the sync phase is completed. + HookFinalizer = "argocd.argoproj.io/hook-finalizer" +) + +func HasHookFinalizer(obj *unstructured.Unstructured) bool { + finalizers := obj.GetFinalizers() + for _, finalizer := range finalizers { + if finalizer == HookFinalizer { + return true + } + } + return false +} + +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/vendor/github.com/argoproj/gitops-engine/pkg/sync/resource/annotations.go b/vendor/github.com/argoproj/gitops-engine/pkg/sync/resource/annotations.go index 73a879ce7..aa9c27cdc 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/sync/resource/annotations.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/sync/resource/annotations.go @@ -30,7 +30,7 @@ func GetAnnotationCSVs(obj AnnotationGetter, key string) []string { } // HasAnnotationOption will return if the given obj has an annotation defined -// as the given key and has in its values, the ocurrence of val. +// as the given key and has in its values, the occurrence of val. func HasAnnotationOption(obj AnnotationGetter, key, val string) bool { for _, item := range GetAnnotationCSVs(obj, key) { if item == val { diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/io/io.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/io/io.go index e21441f78..6f07bb192 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/io/io.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/io/io.go @@ -4,10 +4,8 @@ import ( "os" ) -var ( - // TempDir is set to '/dev/shm' if exists, otherwise is "", which defaults to os.TempDir() when passed to os.CreateTemp() - TempDir string -) +// TempDir is set to '/dev/shm' if exists, otherwise is "", which defaults to os.TempDir() when passed to os.CreateTemp() +var TempDir string func init() { fileInfo, err := os.Stat("/dev/shm") diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/json/json.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/json/json.go index 7f2999e71..4cb2f8ed0 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/json/json.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/json/json.go @@ -1,31 +1,28 @@ package json // https://github.com/ksonnet/ksonnet/blob/master/pkg/kubecfg/diff.go -func removeFields(config, live interface{}) interface{} { +func removeFields(config, live any) any { switch c := config.(type) { - case map[string]interface{}: - l, ok := live.(map[string]interface{}) + case map[string]any: + l, ok := live.(map[string]any) if ok { return RemoveMapFields(c, l) - } else { - return live } - case []interface{}: - l, ok := live.([]interface{}) + return live + case []any: + l, ok := live.([]any) if ok { return RemoveListFields(c, l) - } else { - return live } + return live default: return live } - } // RemoveMapFields remove all non-existent fields in the live that don't exist in the config -func RemoveMapFields(config, live map[string]interface{}) map[string]interface{} { - result := map[string]interface{}{} +func RemoveMapFields(config, live map[string]any) map[string]any { + result := map[string]any{} for k, v1 := range config { v2, ok := live[k] if !ok { @@ -39,10 +36,10 @@ func RemoveMapFields(config, live map[string]interface{}) map[string]interface{} return result } -func RemoveListFields(config, live []interface{}) []interface{} { +func RemoveListFields(config, live []any) []any { // If live is longer than config, then the extra elements at the end of the // list will be returned as-is so they appear in the diff. - result := make([]interface{}, 0, len(live)) + result := make([]any, 0, len(live)) for i, v2 := range live { if len(config) > i { if v2 != nil { diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/ctl.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/ctl.go index a80c63ea5..8af205ad4 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/ctl.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/ctl.go @@ -82,7 +82,6 @@ func (k *KubectlCmd) filterAPIResources(config *rest.Config, preferred bool, res gv = schema.GroupVersion{} } for _, apiResource := range apiResourcesList.APIResources { - if resourceFilter.IsExcludedResource(gv.Group, apiResource.Kind, config.Host) { continue } @@ -133,11 +132,11 @@ func (k *KubectlCmd) LoadOpenAPISchema(config *rest.Config) (openapi.Resources, oapiGetter := openapi.NewOpenAPIGetter(disco) oapiResources, err := openapi.NewOpenAPIParser(oapiGetter).Parse() if err != nil { - return nil, nil, fmt.Errorf("error getting openapi resources: %s", err) + return nil, nil, fmt.Errorf("error getting openapi resources: %w", err) } gvkParser, err := k.newGVKParser(oapiGetter) if err != nil { - return oapiResources, nil, fmt.Errorf("error getting gvk parser: %s", err) + return oapiResources, nil, fmt.Errorf("error getting gvk parser: %w", err) } return oapiResources, gvkParser, nil } @@ -145,11 +144,11 @@ func (k *KubectlCmd) LoadOpenAPISchema(config *rest.Config) (openapi.Resources, func (k *KubectlCmd) newGVKParser(oapiGetter discovery.OpenAPISchemaInterface) (*managedfields.GvkParser, error) { doc, err := oapiGetter.OpenAPISchema() if err != nil { - return nil, fmt.Errorf("error getting openapi schema: %s", err) + return nil, fmt.Errorf("error getting openapi schema: %w", err) } models, err := proto.NewOpenAPIData(doc) if err != nil { - return nil, fmt.Errorf("error getting openapi data: %s", err) + return nil, fmt.Errorf("error getting openapi data: %w", err) } var taintedGVKs []schema.GroupVersionKind models, taintedGVKs = newUniqueModels(models) @@ -275,13 +274,13 @@ func (k *KubectlCmd) DeleteResource(ctx context.Context, config *rest.Config, gv func (k *KubectlCmd) ManageResources(config *rest.Config, openAPISchema openapi.Resources) (ResourceOperations, func(), error) { f, err := os.CreateTemp(utils.TempDir, "") if err != nil { - return nil, nil, fmt.Errorf("failed to generate temp file for kubeconfig: %v", err) + return nil, nil, fmt.Errorf("failed to generate temp file for kubeconfig: %w", err) } _ = f.Close() err = WriteKubeConfig(config, "", f.Name()) if err != nil { utils.DeleteFile(f.Name()) - return nil, nil, fmt.Errorf("failed to write kubeconfig: %v", err) + return nil, nil, fmt.Errorf("failed to write kubeconfig: %w", err) } fact := kubeCmdFactory(f.Name(), "", config) cleanup := func() { @@ -300,13 +299,13 @@ func (k *KubectlCmd) ManageResources(config *rest.Config, openAPISchema openapi. func ManageServerSideDiffDryRuns(config *rest.Config, openAPISchema openapi.Resources, tracer tracing.Tracer, log logr.Logger, onKubectlRun OnKubectlRunFunc) (diff.KubeApplier, func(), error) { f, err := os.CreateTemp(utils.TempDir, "") if err != nil { - return nil, nil, fmt.Errorf("failed to generate temp file for kubeconfig: %v", err) + return nil, nil, fmt.Errorf("failed to generate temp file for kubeconfig: %w", err) } _ = f.Close() err = WriteKubeConfig(config, "", f.Name()) if err != nil { utils.DeleteFile(f.Name()) - return nil, nil, fmt.Errorf("failed to write kubeconfig: %v", err) + return nil, nil, fmt.Errorf("failed to write kubeconfig: %w", err) } fact := kubeCmdFactory(f.Name(), "", config) cleanup := func() { diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/kube.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/kube.go index 9db109062..0c144a699 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/kube.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/kube.go @@ -4,6 +4,7 @@ package kube import ( "bytes" "context" + "errors" "fmt" "io" "regexp" @@ -12,9 +13,9 @@ import ( "github.com/go-logr/logr" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" - apierr "k8s.io/apimachinery/pkg/api/errors" + apierrors "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" @@ -88,8 +89,8 @@ func GetResourceKey(obj *unstructured.Unstructured) ResourceKey { return NewResourceKey(gvk.Group, gvk.Kind, obj.GetNamespace(), obj.GetName()) } -func GetObjectRef(obj *unstructured.Unstructured) v1.ObjectReference { - return v1.ObjectReference{ +func GetObjectRef(obj *unstructured.Unstructured) corev1.ObjectReference { + return corev1.ObjectReference{ UID: obj.GetUID(), APIVersion: obj.GetAPIVersion(), Kind: obj.GetKind(), @@ -102,17 +103,17 @@ func GetObjectRef(obj *unstructured.Unstructured) v1.ObjectReference { func TestConfig(config *rest.Config) error { kubeclientset, err := kubernetes.NewForConfig(config) if err != nil { - return fmt.Errorf("REST config invalid: %s", err) + return fmt.Errorf("REST config invalid: %w", err) } _, err = kubeclientset.ServerVersion() if err != nil { - return fmt.Errorf("REST config invalid: %s", err) + return fmt.Errorf("REST config invalid: %w", err) } return nil } // ToUnstructured converts a concrete K8s API type to a un unstructured object -func ToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { +func ToUnstructured(obj any) (*unstructured.Unstructured, error) { uObj, err := runtime.NewTestUnstructuredConverter(equality.Semantic).ToUnstructured(obj) if err != nil { return nil, err @@ -121,7 +122,7 @@ func ToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { } // MustToUnstructured converts a concrete K8s API type to a un unstructured object and panics if not successful -func MustToUnstructured(obj interface{}) *unstructured.Unstructured { +func MustToUnstructured(obj any) *unstructured.Unstructured { uObj, err := ToUnstructured(obj) if err != nil { panic(err) @@ -180,7 +181,7 @@ func IsCRD(obj *unstructured.Unstructured) bool { // See: https://github.com/ksonnet/ksonnet/blob/master/utils/client.go func ServerResourceForGroupVersionKind(disco discovery.DiscoveryInterface, gvk schema.GroupVersionKind, verb string) (*metav1.APIResource, error) { // default is to return a not found for the requested resource - retErr := apierr.NewNotFound(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, "") + retErr := apierrors.NewNotFound(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, "") resources, err := disco.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) if err != nil { return nil, err @@ -189,11 +190,10 @@ func ServerResourceForGroupVersionKind(disco discovery.DiscoveryInterface, gvk s if r.Kind == gvk.Kind { if isSupportedVerb(&r, verb) { return &r, nil - } else { - // We have a match, but the API does not support the action - // that was requested. Memorize this. - retErr = apierr.NewMethodNotSupported(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, verb) } + // We have a match, but the API does not support the action + // that was requested. Memorize this. + retErr = apierrors.NewMethodNotSupported(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, verb) } } return nil, retErr @@ -215,7 +215,7 @@ func cleanKubectlOutput(s string) string { s = kubectlErrOutRegexp.ReplaceAllString(s, "") s = kubectlErrOutMapRegexp.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.ReplaceAll(s, "; if you choose to ignore these errors, turn validation off with --validate=false", "") return s } @@ -245,10 +245,10 @@ func NewKubeConfig(restConfig *rest.Config, namespace string) *clientcmdapi.Conf Clusters: map[string]*clientcmdapi.Cluster{ restConfig.Host: { Server: restConfig.Host, - TLSServerName: restConfig.TLSClientConfig.ServerName, - InsecureSkipTLSVerify: restConfig.TLSClientConfig.Insecure, - CertificateAuthority: restConfig.TLSClientConfig.CAFile, - CertificateAuthorityData: restConfig.TLSClientConfig.CAData, + TLSServerName: restConfig.ServerName, + InsecureSkipTLSVerify: restConfig.Insecure, + CertificateAuthority: restConfig.CAFile, + CertificateAuthorityData: restConfig.CAData, ProxyURL: proxyUrl, }, }, @@ -263,20 +263,20 @@ func NewKubeConfig(restConfig *rest.Config, namespace string) *clientcmdapi.Conf func newAuthInfo(restConfig *rest.Config) *clientcmdapi.AuthInfo { authInfo := clientcmdapi.AuthInfo{} haveCredentials := false - if restConfig.TLSClientConfig.CertFile != "" { - authInfo.ClientCertificate = restConfig.TLSClientConfig.CertFile + if restConfig.CertFile != "" { + authInfo.ClientCertificate = restConfig.CertFile haveCredentials = true } - if len(restConfig.TLSClientConfig.CertData) > 0 { - authInfo.ClientCertificateData = restConfig.TLSClientConfig.CertData + if len(restConfig.CertData) > 0 { + authInfo.ClientCertificateData = restConfig.CertData haveCredentials = true } - if restConfig.TLSClientConfig.KeyFile != "" { - authInfo.ClientKey = restConfig.TLSClientConfig.KeyFile + if restConfig.KeyFile != "" { + authInfo.ClientKey = restConfig.KeyFile haveCredentials = true } - if len(restConfig.TLSClientConfig.KeyData) > 0 { - authInfo.ClientKeyData = restConfig.TLSClientConfig.KeyData + if len(restConfig.KeyData) > 0 { + authInfo.ClientKeyData = restConfig.KeyData haveCredentials = true } if restConfig.Username != "" { @@ -315,7 +315,7 @@ func SplitYAML(yamlData []byte) ([]*unstructured.Unstructured, error) { for _, yml := range ymls { u := &unstructured.Unstructured{} if err := yaml.Unmarshal([]byte(yml), u); err != nil { - return objs, fmt.Errorf("failed to unmarshal manifest: %v", err) + return objs, fmt.Errorf("failed to unmarshal manifest: %w", err) } objs = append(objs, u) } @@ -334,10 +334,10 @@ func SplitYAMLToString(yamlData []byte) ([]string, error) { for { ext := runtime.RawExtension{} if err := d.Decode(&ext); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } - return objs, fmt.Errorf("failed to unmarshal manifest: %v", err) + return objs, fmt.Errorf("failed to unmarshal manifest: %w", err) } ext.Raw = bytes.TrimSpace(ext.Raw) if len(ext.Raw) == 0 || bytes.Equal(ext.Raw, []byte("null")) { @@ -407,13 +407,56 @@ func GetDeploymentReplicas(u *unstructured.Unstructured) *int64 { return &val } +func GetResourceImages(u *unstructured.Unstructured) []string { + var containers []any + var found bool + var err error + var images []string + + containerPaths := [][]string{ + // Resources without template, like pods + {"spec", "containers"}, + // Resources with template, like deployments + {"spec", "template", "spec", "containers"}, + // Cronjobs + {"spec", "jobTemplate", "spec", "template", "spec", "containers"}, + } + + for _, path := range containerPaths { + containers, found, err = unstructured.NestedSlice(u.Object, path...) + if found && err == nil { + break + } + } + + if !found || err != nil { + return nil + } + + for _, container := range containers { + containerMap, ok := container.(map[string]any) + if !ok { + continue + } + + image, found, err := unstructured.NestedString(containerMap, "image") + if !found || err != nil { + continue + } + + images = append(images, image) + } + + return images +} + // RetryUntilSucceed keep retrying given action with specified interval until action succeed or specified context is done. func RetryUntilSucceed(ctx context.Context, interval time.Duration, desc string, log logr.Logger, action func() error) { - pollErr := wait.PollUntilContextCancel(ctx, interval, true, func(ctx context.Context) (bool /*done*/, error) { - log.V(1).Info(fmt.Sprintf("Start %s", desc)) + pollErr := wait.PollUntilContextCancel(ctx, interval, true, func(_ context.Context) (bool /*done*/, error) { + log.V(1).Info("Start " + desc) err := action() if err == nil { - log.V(1).Info(fmt.Sprintf("Completed %s", desc)) + log.V(1).Info("Completed " + desc) return true, nil } log.V(1).Info(fmt.Sprintf("Failed to %s: %+v, retrying in %v", desc, err, interval)) @@ -421,6 +464,6 @@ func RetryUntilSucceed(ctx context.Context, interval time.Duration, desc string, }) if pollErr != nil { // The only error that can happen here is wait.ErrWaitTimeout if ctx is done. - log.V(1).Info(fmt.Sprintf("Stop retrying %s", desc)) + log.V(1).Info("Stop retrying " + desc) } } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/resource_ops.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/resource_ops.go index 8f5f29665..b110153f0 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/resource_ops.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/resource_ops.go @@ -39,7 +39,7 @@ import ( // ResourceOperations provides methods to manage k8s resources type ResourceOperations interface { - ApplyResource(ctx context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, force, validate, serverSideApply bool, manager string) (string, error) + ApplyResource(ctx context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, force bool, validate bool, serverSideApply bool, manager string) (string, error) ReplaceResource(ctx context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, force bool) (string, error) CreateResource(ctx context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, validate bool) (string, error) UpdateResource(ctx context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy) (*unstructured.Unstructured, error) @@ -95,13 +95,13 @@ func createManifestFile(obj *unstructured.Unstructured, log logr.Logger) (*os.Fi } manifestFile, err := os.CreateTemp(io.TempDir, "") if err != nil { - return nil, fmt.Errorf("Failed to generate temp file for manifest: %v", err) + return nil, fmt.Errorf("failed to generate temp file for manifest: %w", err) } if _, err = manifestFile.Write(manifestBytes); err != nil { - return nil, fmt.Errorf("Failed to write manifest: %v", err) + return nil, fmt.Errorf("failed to write manifest: %w", err) } if err = manifestFile.Close(); err != nil { - return nil, fmt.Errorf("Failed to close manifest: %v", err) + return nil, fmt.Errorf("failed to close manifest: %w", err) } err = maybeLogManifest(manifestBytes, log) @@ -123,7 +123,7 @@ func (k *kubectlResourceOperations) runResourceCommand(ctx context.Context, obj if obj.GetAPIVersion() == "rbac.authorization.k8s.io/v1" { outReconcile, err := k.rbacReconcile(ctx, obj, manifestFile.Name(), dryRunStrategy) if err != nil { - return "", fmt.Errorf("error running rbacReconcile: %s", err) + return "", fmt.Errorf("error running rbacReconcile: %w", err) } out = append(out, outReconcile) // We still want to fallthrough and run `kubectl apply` in order set the @@ -173,7 +173,7 @@ func (k *kubectlServerSideDiffDryRunApplier) runResourceCommand(obj *unstructure stderr := stderrBuf.String() if stderr != "" && stdout == "" { - err := fmt.Errorf("Server-side dry run apply had non-empty stderr: %s", stderr) + err := fmt.Errorf("server-side dry run apply had non-empty stderr: %s", stderr) k.log.Error(err, "server-side diff") return "", err } @@ -301,7 +301,7 @@ func (k *kubectlResourceOperations) UpdateResource(ctx context.Context, obj *uns } // ApplyResource performs an apply of a unstructured resource -func (k *kubectlServerSideDiffDryRunApplier) ApplyResource(_ context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, force, validate, serverSideApply bool, manager string) (string, error) { +func (k *kubectlServerSideDiffDryRunApplier) ApplyResource(_ context.Context, obj *unstructured.Unstructured, dryRunStrategy cmdutil.DryRunStrategy, force bool, validate bool, serverSideApply bool, manager string) (string, error) { span := k.tracer.StartSpan("ApplyResource") span.SetBaggageItem("kind", obj.GetKind()) span.SetBaggageItem("name", obj.GetName()) @@ -357,7 +357,7 @@ func (k *kubectlResourceOperations) ApplyResource(ctx context.Context, obj *unst }) } -func newApplyOptionsCommon(config *rest.Config, fact cmdutil.Factory, ioStreams genericclioptions.IOStreams, obj *unstructured.Unstructured, fileName string, validate bool, force, serverSideApply bool, dryRunStrategy cmdutil.DryRunStrategy, manager string) (*apply.ApplyOptions, error) { +func newApplyOptionsCommon(config *rest.Config, fact cmdutil.Factory, ioStreams genericclioptions.IOStreams, obj *unstructured.Unstructured, fileName string, validate bool, force bool, serverSideApply bool, dryRunStrategy cmdutil.DryRunStrategy, manager string) (*apply.ApplyOptions, error) { flags := apply.NewApplyFlags(ioStreams) o := &apply.ApplyOptions{ IOStreams: ioStreams, @@ -395,7 +395,7 @@ func newApplyOptionsCommon(config *rest.Config, fact cmdutil.Factory, ioStreams return nil, err } - o.DeleteOptions.FilenameOptions.Filenames = []string{fileName} + o.DeleteOptions.Filenames = []string{fileName} o.Namespace = obj.GetNamespace() o.DeleteOptions.ForceDeletion = force o.DryRunStrategy = dryRunStrategy @@ -427,6 +427,10 @@ func (k *kubectlServerSideDiffDryRunApplier) newApplyOptions(ioStreams genericcl } o.ForceConflicts = true + + if err := o.Validate(); err != nil { + return nil, fmt.Errorf("error validating options: %w", err) + } return o, nil } @@ -456,6 +460,10 @@ func (k *kubectlResourceOperations) newApplyOptions(ioStreams genericclioptions. if serverSideApply { o.ForceConflicts = true } + + if err := o.Validate(); err != nil { + return nil, fmt.Errorf("error validating options: %w", err) + } return o, nil } @@ -490,6 +498,10 @@ func (k *kubectlResourceOperations) newCreateOptions(ioStreams genericclioptions return printer.PrintObj(obj, o.Out) } o.FilenameOptions.Filenames = []string{fileName} + + if err := o.Validate(); err != nil { + return nil, fmt.Errorf("error validating options: %w", err) + } return o, nil } @@ -538,9 +550,16 @@ func (k *kubectlResourceOperations) newReplaceOptions(config *rest.Config, f cmd return printer.PrintObj(obj, o.Out) } - o.DeleteOptions.FilenameOptions.Filenames = []string{fileName} + o.DeleteOptions.Filenames = []string{fileName} o.Namespace = namespace - o.DeleteOptions.ForceDeletion = force + + if dryRunStrategy == cmdutil.DryRunNone { + o.DeleteOptions.ForceDeletion = force + } + + if err := o.Validate(); err != nil { + return nil, fmt.Errorf("error validating options: %w", err) + } return o, nil } @@ -570,6 +589,10 @@ func newReconcileOptions(f cmdutil.Factory, kubeClient *kubernetes.Clientset, fi return nil, err } o.PrintObject = printer.PrintObj + + if err := o.Validate(); err != nil { + return nil, fmt.Errorf("error validating options: %w", err) + } return o, nil } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/parser.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/parser.go index afab64d74..441e28e9d 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/parser.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/parser.go @@ -22,8 +22,8 @@ limitations under the License. package scheme import ( - "fmt" - "sync" + fmt "fmt" + sync "sync" typed "sigs.k8s.io/structured-merge-diff/v4/typed" ) @@ -515,6 +515,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: url type: scalar: string +- name: io.k8s.api.admissionregistration.v1alpha1.ApplyConfiguration + map: + fields: + - name: expression + type: + scalar: string - name: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation map: fields: @@ -537,6 +543,12 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.JSONPatch + map: + fields: + - name: expression + type: + scalar: string - name: io.k8s.api.admissionregistration.v1alpha1.MatchCondition map: fields: @@ -573,6 +585,100 @@ var schemaYAML = typed.YAMLObject(`types: namedType: io.k8s.api.admissionregistration.v1alpha1.NamedRuleWithOperations elementRelationship: atomic elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicy + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicySpec + default: {} +- name: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicyBinding + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicyBindingSpec + default: {} +- name: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicyBindingSpec + map: + fields: + - name: matchResources + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources + - name: paramRef + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ParamRef + - name: policyName + type: + scalar: string +- name: io.k8s.api.admissionregistration.v1alpha1.MutatingAdmissionPolicySpec + map: + fields: + - name: failurePolicy + type: + scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + elementRelationship: associative + keys: + - name + - name: matchConstraints + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources + - name: mutations + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.Mutation + elementRelationship: atomic + - name: paramKind + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ParamKind + - name: reinvocationPolicy + type: + scalar: string + - name: variables + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.Variable + elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.Mutation + map: + fields: + - name: applyConfiguration + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ApplyConfiguration + - name: jsonPatch + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.JSONPatch + - name: patchType + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1alpha1.NamedRuleWithOperations map: fields: @@ -4368,7 +4474,7 @@ var schemaYAML = typed.YAMLObject(`types: - name: strategy type: scalar: string -- name: io.k8s.api.coordination.v1alpha1.LeaseCandidate +- name: io.k8s.api.coordination.v1alpha2.LeaseCandidate map: fields: - name: apiVersion @@ -4383,14 +4489,15 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.coordination.v1alpha1.LeaseCandidateSpec + namedType: io.k8s.api.coordination.v1alpha2.LeaseCandidateSpec default: {} -- name: io.k8s.api.coordination.v1alpha1.LeaseCandidateSpec +- name: io.k8s.api.coordination.v1alpha2.LeaseCandidateSpec map: fields: - name: binaryVersion type: scalar: string + default: "" - name: emulationVersion type: scalar: string @@ -4401,15 +4508,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: pingTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime - - name: preferredStrategies - type: - list: - elementType: - scalar: string - elementRelationship: atomic - name: renewTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime + - name: strategy + type: + scalar: string - name: io.k8s.api.coordination.v1beta1.Lease map: fields: @@ -6923,6 +7027,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: runAsUser type: scalar: numeric + - name: seLinuxChangePolicy + type: + scalar: string - name: seLinuxOptions type: namedType: io.k8s.api.core.v1.SELinuxOptions @@ -7063,6 +7170,9 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name + - name: resources + type: + namedType: io.k8s.api.core.v1.ResourceRequirements - name: restartPolicy type: scalar: string @@ -12247,12 +12357,38 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string -- name: io.k8s.api.resource.v1alpha3.AllocationResult +- name: io.k8s.api.resource.v1alpha3.AllocatedDeviceStatus map: fields: - - name: controller + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: data + type: + namedType: __untyped_atomic_ + - name: device + type: + scalar: string + default: "" + - name: driver + type: + scalar: string + default: "" + - name: networkData + type: + namedType: io.k8s.api.resource.v1alpha3.NetworkDeviceData + - name: pool type: scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha3.AllocationResult + map: + fields: - name: devices type: namedType: io.k8s.api.resource.v1alpha3.DeviceAllocationResult @@ -12407,9 +12543,6 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.resource.v1alpha3.DeviceSelector elementRelationship: atomic - - name: suitableNodes - type: - namedType: io.k8s.api.core.v1.NodeSelector - name: io.k8s.api.resource.v1alpha3.DeviceConstraint map: fields: @@ -12428,7 +12561,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: adminAccess type: scalar: boolean - default: false - name: allocationMode type: scalar: string @@ -12452,6 +12584,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.resource.v1alpha3.DeviceRequestAllocationResult map: fields: + - name: adminAccess + type: + scalar: boolean - name: device type: scalar: string @@ -12474,60 +12609,31 @@ var schemaYAML = typed.YAMLObject(`types: - name: cel type: namedType: io.k8s.api.resource.v1alpha3.CELDeviceSelector -- name: io.k8s.api.resource.v1alpha3.OpaqueDeviceConfiguration - map: - fields: - - name: driver - type: - scalar: string - default: "" - - name: parameters - type: - namedType: __untyped_atomic_ -- name: io.k8s.api.resource.v1alpha3.PodSchedulingContext +- name: io.k8s.api.resource.v1alpha3.NetworkDeviceData map: fields: - - name: apiVersion + - name: hardwareAddress type: scalar: string - - name: kind + - name: interfaceName type: scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.resource.v1alpha3.PodSchedulingContextSpec - default: {} - - name: status - type: - namedType: io.k8s.api.resource.v1alpha3.PodSchedulingContextStatus - default: {} -- name: io.k8s.api.resource.v1alpha3.PodSchedulingContextSpec - map: - fields: - - name: potentialNodes + - name: ips type: list: elementType: scalar: string elementRelationship: atomic - - name: selectedNode - type: - scalar: string -- name: io.k8s.api.resource.v1alpha3.PodSchedulingContextStatus +- name: io.k8s.api.resource.v1alpha3.OpaqueDeviceConfiguration map: fields: - - name: resourceClaims + - name: driver type: - list: - elementType: - namedType: io.k8s.api.resource.v1alpha3.ResourceClaimSchedulingStatus - elementRelationship: associative - keys: - - name + scalar: string + default: "" + - name: parameters + type: + namedType: __untyped_atomic_ - name: io.k8s.api.resource.v1alpha3.ResourceClaim map: fields: @@ -12567,25 +12673,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha3.ResourceClaimSchedulingStatus - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: unsuitableNodes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - name: io.k8s.api.resource.v1alpha3.ResourceClaimSpec map: fields: - - name: controller - type: - scalar: string - name: devices type: namedType: io.k8s.api.resource.v1alpha3.DeviceClaim @@ -12596,9 +12686,16 @@ var schemaYAML = typed.YAMLObject(`types: - name: allocation type: namedType: io.k8s.api.resource.v1alpha3.AllocationResult - - name: deallocationRequested + - name: devices type: - scalar: boolean + list: + elementType: + namedType: io.k8s.api.resource.v1alpha3.AllocatedDeviceStatus + elementRelationship: associative + keys: + - driver + - device + - pool - name: reservedFor type: list: @@ -12693,49 +12790,488 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.api.resource.v1alpha3.ResourcePool default: {} -- name: io.k8s.api.scheduling.v1.PriorityClass +- name: io.k8s.api.resource.v1beta1.AllocatedDeviceStatus map: fields: - - name: apiVersion + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: data + type: + namedType: __untyped_atomic_ + - name: device type: scalar: string - - name: description + default: "" + - name: driver type: scalar: string - - name: globalDefault + default: "" + - name: networkData type: - scalar: boolean - - name: kind + namedType: io.k8s.api.resource.v1beta1.NetworkDeviceData + - name: pool type: scalar: string - - name: metadata + default: "" +- name: io.k8s.api.resource.v1beta1.AllocationResult + map: + fields: + - name: devices type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + namedType: io.k8s.api.resource.v1beta1.DeviceAllocationResult default: {} - - name: preemptionPolicy - type: - scalar: string - - name: value + - name: nodeSelector type: - scalar: numeric - default: 0 -- name: io.k8s.api.scheduling.v1alpha1.PriorityClass + namedType: io.k8s.api.core.v1.NodeSelector +- name: io.k8s.api.resource.v1beta1.BasicDevice map: fields: - - name: apiVersion + - name: attributes type: - scalar: string - - name: description + map: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceAttribute + - name: capacity + type: + map: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceCapacity +- name: io.k8s.api.resource.v1beta1.CELDeviceSelector + map: + fields: + - name: expression type: scalar: string - - name: globalDefault + default: "" +- name: io.k8s.api.resource.v1beta1.Device + map: + fields: + - name: basic type: - scalar: boolean - - name: kind + namedType: io.k8s.api.resource.v1beta1.BasicDevice + - name: name type: scalar: string - - name: metadata - type: + default: "" +- name: io.k8s.api.resource.v1beta1.DeviceAllocationConfiguration + map: + fields: + - name: opaque + type: + namedType: io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration + - name: requests + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: source + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1beta1.DeviceAllocationResult + map: + fields: + - name: config + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceAllocationConfiguration + elementRelationship: atomic + - name: results + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceRequestAllocationResult + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceAttribute + map: + fields: + - name: bool + type: + scalar: boolean + - name: int + type: + scalar: numeric + - name: string + type: + scalar: string + - name: version + type: + scalar: string +- name: io.k8s.api.resource.v1beta1.DeviceCapacity + map: + fields: + - name: value + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity +- name: io.k8s.api.resource.v1beta1.DeviceClaim + map: + fields: + - name: config + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceClaimConfiguration + elementRelationship: atomic + - name: constraints + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceConstraint + elementRelationship: atomic + - name: requests + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceRequest + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceClaimConfiguration + map: + fields: + - name: opaque + type: + namedType: io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration + - name: requests + type: + list: + elementType: + scalar: string + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceClass + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta1.DeviceClassSpec + default: {} +- name: io.k8s.api.resource.v1beta1.DeviceClassConfiguration + map: + fields: + - name: opaque + type: + namedType: io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration +- name: io.k8s.api.resource.v1beta1.DeviceClassSpec + map: + fields: + - name: config + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceClassConfiguration + elementRelationship: atomic + - name: selectors + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceSelector + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceConstraint + map: + fields: + - name: matchAttribute + type: + scalar: string + - name: requests + type: + list: + elementType: + scalar: string + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceRequest + map: + fields: + - name: adminAccess + type: + scalar: boolean + - name: allocationMode + type: + scalar: string + - name: count + type: + scalar: numeric + - name: deviceClassName + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" + - name: selectors + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.DeviceSelector + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.DeviceRequestAllocationResult + map: + fields: + - name: adminAccess + type: + scalar: boolean + - name: device + type: + scalar: string + default: "" + - name: driver + type: + scalar: string + default: "" + - name: pool + type: + scalar: string + default: "" + - name: request + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1beta1.DeviceSelector + map: + fields: + - name: cel + type: + namedType: io.k8s.api.resource.v1beta1.CELDeviceSelector +- name: io.k8s.api.resource.v1beta1.NetworkDeviceData + map: + fields: + - name: hardwareAddress + type: + scalar: string + - name: interfaceName + type: + scalar: string + - name: ips + type: + list: + elementType: + scalar: string + elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration + map: + fields: + - name: driver + type: + scalar: string + default: "" + - name: parameters + type: + namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1beta1.ResourceClaim + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta1.ResourceClaimSpec + default: {} + - name: status + type: + namedType: io.k8s.api.resource.v1beta1.ResourceClaimStatus + default: {} +- name: io.k8s.api.resource.v1beta1.ResourceClaimConsumerReference + map: + fields: + - name: apiGroup + type: + scalar: string + - name: name + type: + scalar: string + default: "" + - name: resource + type: + scalar: string + default: "" + - name: uid + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1beta1.ResourceClaimSpec + map: + fields: + - name: devices + type: + namedType: io.k8s.api.resource.v1beta1.DeviceClaim + default: {} +- name: io.k8s.api.resource.v1beta1.ResourceClaimStatus + map: + fields: + - name: allocation + type: + namedType: io.k8s.api.resource.v1beta1.AllocationResult + - name: devices + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.AllocatedDeviceStatus + elementRelationship: associative + keys: + - driver + - device + - pool + - name: reservedFor + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.ResourceClaimConsumerReference + elementRelationship: associative + keys: + - uid +- name: io.k8s.api.resource.v1beta1.ResourceClaimTemplate + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta1.ResourceClaimTemplateSpec + default: {} +- name: io.k8s.api.resource.v1beta1.ResourceClaimTemplateSpec + map: + fields: + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta1.ResourceClaimSpec + default: {} +- name: io.k8s.api.resource.v1beta1.ResourcePool + map: + fields: + - name: generation + type: + scalar: numeric + default: 0 + - name: name + type: + scalar: string + default: "" + - name: resourceSliceCount + type: + scalar: numeric + default: 0 +- name: io.k8s.api.resource.v1beta1.ResourceSlice + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta1.ResourceSliceSpec + default: {} +- name: io.k8s.api.resource.v1beta1.ResourceSliceSpec + map: + fields: + - name: allNodes + type: + scalar: boolean + - name: devices + type: + list: + elementType: + namedType: io.k8s.api.resource.v1beta1.Device + elementRelationship: atomic + - name: driver + type: + scalar: string + default: "" + - name: nodeName + type: + scalar: string + - name: nodeSelector + type: + namedType: io.k8s.api.core.v1.NodeSelector + - name: pool + type: + namedType: io.k8s.api.resource.v1beta1.ResourcePool + default: {} +- name: io.k8s.api.scheduling.v1.PriorityClass + map: + fields: + - name: apiVersion + type: + scalar: string + - name: description + type: + scalar: string + - name: globalDefault + type: + scalar: boolean + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: preemptionPolicy + type: + scalar: string + - name: value + type: + scalar: numeric + default: 0 +- name: io.k8s.api.scheduling.v1alpha1.PriorityClass + map: + fields: + - name: apiVersion + type: + scalar: string + - name: description + type: + scalar: string + - name: globalDefault + type: + scalar: boolean + - name: kind + type: + scalar: string + - name: metadata + type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta default: {} - name: preemptionPolicy @@ -13542,6 +14078,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: gracePeriodSeconds type: scalar: numeric + - name: ignoreStoreReadErrorWithClusterBreakingPotential + type: + scalar: boolean - name: kind type: scalar: string diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/typed.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/typed.go index 0d7612e87..c9645d211 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/typed.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/scheme/typed.go @@ -43,8 +43,10 @@ func resolveFromStaticParser(gvk schema.GroupVersionKind, parser *managedfields. return nil } -var gvkMap map[schema.GroupVersionKind]string -var extractOnce sync.Once +var ( + gvkMap map[schema.GroupVersionKind]string + extractOnce sync.Once +) func getGvkMap(parser *managedfields.GvkParser) map[schema.GroupVersionKind]string { extractOnce.Do(func() { diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/uniqueprotomodels.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/uniqueprotomodels.go index 31d2e98e9..ba8b2a3ea 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/uniqueprotomodels.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/kube/uniqueprotomodels.go @@ -2,9 +2,10 @@ package kube import ( "fmt" + "sort" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kube-openapi/pkg/util/proto" - "sort" ) /** @@ -154,7 +155,7 @@ func parseGroupVersionKind(s proto.Schema) []schema.GroupVersionKind { } // gvk extension must be a list of at least 1 element. - gvkList, ok := gvkExtension.([]interface{}) + gvkList, ok := gvkExtension.([]any) if !ok { return []schema.GroupVersionKind{} } @@ -162,7 +163,7 @@ func parseGroupVersionKind(s proto.Schema) []schema.GroupVersionKind { for _, gvk := range gvkList { // gvk extension list must be a map with group, version, and // kind fields - gvkMap, ok := gvk.(map[interface{}]interface{}) + gvkMap, ok := gvk.(map[any]any) if !ok { continue } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/api.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/api.go index 1d28daa94..89670a67b 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/api.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/api.go @@ -11,6 +11,6 @@ type Tracer interface { } type Span interface { - SetBaggageItem(key string, value interface{}) + SetBaggageItem(key string, value any) Finish() } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/logging.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/logging.go index 166e09c13..fd0619f99 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/logging.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/logging.go @@ -25,7 +25,7 @@ func (l LoggingTracer) StartSpan(operationName string) Span { return loggingSpan{ logger: l.logger, operationName: operationName, - baggage: make(map[string]interface{}), + baggage: make(map[string]any), start: time.Now(), } } @@ -33,7 +33,7 @@ func (l LoggingTracer) StartSpan(operationName string) Span { type loggingSpan struct { logger logr.Logger operationName string - baggage map[string]interface{} + baggage map[string]any start time.Time } @@ -43,12 +43,12 @@ func (s loggingSpan) Finish() { Info("Trace") } -func (s loggingSpan) SetBaggageItem(key string, value interface{}) { +func (s loggingSpan) SetBaggageItem(key string, value any) { s.baggage[key] = value } -func baggageToVals(baggage map[string]interface{}) []interface{} { - result := make([]interface{}, 0, len(baggage)*2) +func baggageToVals(baggage map[string]any) []any { + result := make([]any, 0, len(baggage)*2) for k, v := range baggage { result = append(result, k, v) } diff --git a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/nop.go b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/nop.go index 94984d611..e39b67b99 100644 --- a/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/nop.go +++ b/vendor/github.com/argoproj/gitops-engine/pkg/utils/tracing/nop.go @@ -5,17 +5,15 @@ var ( _ Span = nopSpan{} ) -type NopTracer struct { -} +type NopTracer struct{} -func (n NopTracer) StartSpan(operationName string) Span { +func (n NopTracer) StartSpan(_ string) Span { return nopSpan{} } -type nopSpan struct { -} +type nopSpan struct{} -func (n nopSpan) SetBaggageItem(key string, value interface{}) { +func (n nopSpan) SetBaggageItem(_ string, _ any) { } func (n nopSpan) Finish() { diff --git a/vendor/github.com/evanphx/json-patch/.gitignore b/vendor/github.com/evanphx/json-patch/.gitignore deleted file mode 100644 index b7ed7f956..000000000 --- a/vendor/github.com/evanphx/json-patch/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# editor and IDE paraphernalia -.idea -.vscode - -# macOS paraphernalia -.DS_Store diff --git a/vendor/github.com/evanphx/json-patch/LICENSE b/vendor/github.com/evanphx/json-patch/LICENSE deleted file mode 100644 index df76d7d77..000000000 --- a/vendor/github.com/evanphx/json-patch/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2014, Evan Phoenix -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of the Evan Phoenix nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/evanphx/json-patch/README.md b/vendor/github.com/evanphx/json-patch/README.md deleted file mode 100644 index 86fefd5bf..000000000 --- a/vendor/github.com/evanphx/json-patch/README.md +++ /dev/null @@ -1,315 +0,0 @@ -# JSON-Patch -`jsonpatch` is a library which provides functionality for both applying -[RFC6902 JSON patches](http://tools.ietf.org/html/rfc6902) against documents, as -well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396). - -[![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch) -[![Build Status](https://github.com/evanphx/json-patch/actions/workflows/go.yml/badge.svg)](https://github.com/evanphx/json-patch/actions/workflows/go.yml) -[![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch) - -# Get It! - -**Latest and greatest**: -```bash -go get -u github.com/evanphx/json-patch/v5 -``` - -If you need version 4, use `go get -u gopkg.in/evanphx/json-patch.v4` - -(previous versions below `v3` are unavailable) - -# Use It! -* [Create and apply a merge patch](#create-and-apply-a-merge-patch) -* [Create and apply a JSON Patch](#create-and-apply-a-json-patch) -* [Comparing JSON documents](#comparing-json-documents) -* [Combine merge patches](#combine-merge-patches) - - -# Configuration - -* There is a global configuration variable `jsonpatch.SupportNegativeIndices`. - This defaults to `true` and enables the non-standard practice of allowing - negative indices to mean indices starting at the end of an array. This - functionality can be disabled by setting `jsonpatch.SupportNegativeIndices = - false`. - -* There is a global configuration variable `jsonpatch.AccumulatedCopySizeLimit`, - which limits the total size increase in bytes caused by "copy" operations in a - patch. It defaults to 0, which means there is no limit. - -These global variables control the behavior of `jsonpatch.Apply`. - -An alternative to `jsonpatch.Apply` is `jsonpatch.ApplyWithOptions` whose behavior -is controlled by an `options` parameter of type `*jsonpatch.ApplyOptions`. - -Structure `jsonpatch.ApplyOptions` includes the configuration options above -and adds two new options: `AllowMissingPathOnRemove` and `EnsurePathExistsOnAdd`. - -When `AllowMissingPathOnRemove` is set to `true`, `jsonpatch.ApplyWithOptions` will ignore -`remove` operations whose `path` points to a non-existent location in the JSON document. -`AllowMissingPathOnRemove` defaults to `false` which will lead to `jsonpatch.ApplyWithOptions` -returning an error when hitting a missing `path` on `remove`. - -When `EnsurePathExistsOnAdd` is set to `true`, `jsonpatch.ApplyWithOptions` will make sure -that `add` operations produce all the `path` elements that are missing from the target object. - -Use `jsonpatch.NewApplyOptions` to create an instance of `jsonpatch.ApplyOptions` -whose values are populated from the global configuration variables. - -## Create and apply a merge patch -Given both an original JSON document and a modified JSON document, you can create -a [Merge Patch](https://tools.ietf.org/html/rfc7396) document. - -It can describe the changes needed to convert from the original to the -modified JSON document. - -Once you have a merge patch, you can apply it to other JSON documents using the -`jsonpatch.MergePatch(document, patch)` function. - -```go -package main - -import ( - "fmt" - - jsonpatch "github.com/evanphx/json-patch" -) - -func main() { - // Let's create a merge patch from these two documents... - original := []byte(`{"name": "John", "age": 24, "height": 3.21}`) - target := []byte(`{"name": "Jane", "age": 24}`) - - patch, err := jsonpatch.CreateMergePatch(original, target) - if err != nil { - panic(err) - } - - // Now lets apply the patch against a different JSON document... - - alternative := []byte(`{"name": "Tina", "age": 28, "height": 3.75}`) - modifiedAlternative, err := jsonpatch.MergePatch(alternative, patch) - - fmt.Printf("patch document: %s\n", patch) - fmt.Printf("updated alternative doc: %s\n", modifiedAlternative) -} -``` - -When ran, you get the following output: - -```bash -$ go run main.go -patch document: {"height":null,"name":"Jane"} -updated alternative doc: {"age":28,"name":"Jane"} -``` - -## Create and apply a JSON Patch -You can create patch objects using `DecodePatch([]byte)`, which can then -be applied against JSON documents. - -The following is an example of creating a patch from two operations, and -applying it against a JSON document. - -```go -package main - -import ( - "fmt" - - jsonpatch "github.com/evanphx/json-patch" -) - -func main() { - original := []byte(`{"name": "John", "age": 24, "height": 3.21}`) - patchJSON := []byte(`[ - {"op": "replace", "path": "/name", "value": "Jane"}, - {"op": "remove", "path": "/height"} - ]`) - - patch, err := jsonpatch.DecodePatch(patchJSON) - if err != nil { - panic(err) - } - - modified, err := patch.Apply(original) - if err != nil { - panic(err) - } - - fmt.Printf("Original document: %s\n", original) - fmt.Printf("Modified document: %s\n", modified) -} -``` - -When ran, you get the following output: - -```bash -$ go run main.go -Original document: {"name": "John", "age": 24, "height": 3.21} -Modified document: {"age":24,"name":"Jane"} -``` - -## Comparing JSON documents -Due to potential whitespace and ordering differences, one cannot simply compare -JSON strings or byte-arrays directly. - -As such, you can instead use `jsonpatch.Equal(document1, document2)` to -determine if two JSON documents are _structurally_ equal. This ignores -whitespace differences, and key-value ordering. - -```go -package main - -import ( - "fmt" - - jsonpatch "github.com/evanphx/json-patch" -) - -func main() { - original := []byte(`{"name": "John", "age": 24, "height": 3.21}`) - similar := []byte(` - { - "age": 24, - "height": 3.21, - "name": "John" - } - `) - different := []byte(`{"name": "Jane", "age": 20, "height": 3.37}`) - - if jsonpatch.Equal(original, similar) { - fmt.Println(`"original" is structurally equal to "similar"`) - } - - if !jsonpatch.Equal(original, different) { - fmt.Println(`"original" is _not_ structurally equal to "different"`) - } -} -``` - -When ran, you get the following output: -```bash -$ go run main.go -"original" is structurally equal to "similar" -"original" is _not_ structurally equal to "different" -``` - -## Combine merge patches -Given two JSON merge patch documents, it is possible to combine them into a -single merge patch which can describe both set of changes. - -The resulting merge patch can be used such that applying it results in a -document structurally similar as merging each merge patch to the document -in succession. - -```go -package main - -import ( - "fmt" - - jsonpatch "github.com/evanphx/json-patch" -) - -func main() { - original := []byte(`{"name": "John", "age": 24, "height": 3.21}`) - - nameAndHeight := []byte(`{"height":null,"name":"Jane"}`) - ageAndEyes := []byte(`{"age":4.23,"eyes":"blue"}`) - - // Let's combine these merge patch documents... - combinedPatch, err := jsonpatch.MergeMergePatches(nameAndHeight, ageAndEyes) - if err != nil { - panic(err) - } - - // Apply each patch individual against the original document - withoutCombinedPatch, err := jsonpatch.MergePatch(original, nameAndHeight) - if err != nil { - panic(err) - } - - withoutCombinedPatch, err = jsonpatch.MergePatch(withoutCombinedPatch, ageAndEyes) - if err != nil { - panic(err) - } - - // Apply the combined patch against the original document - - withCombinedPatch, err := jsonpatch.MergePatch(original, combinedPatch) - if err != nil { - panic(err) - } - - // Do both result in the same thing? They should! - if jsonpatch.Equal(withCombinedPatch, withoutCombinedPatch) { - fmt.Println("Both JSON documents are structurally the same!") - } - - fmt.Printf("combined merge patch: %s", combinedPatch) -} -``` - -When ran, you get the following output: -```bash -$ go run main.go -Both JSON documents are structurally the same! -combined merge patch: {"age":4.23,"eyes":"blue","height":null,"name":"Jane"} -``` - -# CLI for comparing JSON documents -You can install the commandline program `json-patch`. - -This program can take multiple JSON patch documents as arguments, -and fed a JSON document from `stdin`. It will apply the patch(es) against -the document and output the modified doc. - -**patch.1.json** -```json -[ - {"op": "replace", "path": "/name", "value": "Jane"}, - {"op": "remove", "path": "/height"} -] -``` - -**patch.2.json** -```json -[ - {"op": "add", "path": "/address", "value": "123 Main St"}, - {"op": "replace", "path": "/age", "value": "21"} -] -``` - -**document.json** -```json -{ - "name": "John", - "age": 24, - "height": 3.21 -} -``` - -You can then run: - -```bash -$ go install github.com/evanphx/json-patch/cmd/json-patch -$ cat document.json | json-patch -p patch.1.json -p patch.2.json -{"address":"123 Main St","age":"21","name":"Jane"} -``` - -# Help It! -Contributions are welcomed! Leave [an issue](https://github.com/evanphx/json-patch/issues) -or [create a PR](https://github.com/evanphx/json-patch/compare). - - -Before creating a pull request, we'd ask that you make sure tests are passing -and that you have added new tests when applicable. - -Contributors can run tests using: - -```bash -go test -cover ./... -``` - -Builds for pull requests are tested automatically -using [GitHub Actions](https://github.com/evanphx/json-patch/actions/workflows/go.yml). diff --git a/vendor/github.com/evanphx/json-patch/errors.go b/vendor/github.com/evanphx/json-patch/errors.go deleted file mode 100644 index 75304b443..000000000 --- a/vendor/github.com/evanphx/json-patch/errors.go +++ /dev/null @@ -1,38 +0,0 @@ -package jsonpatch - -import "fmt" - -// AccumulatedCopySizeError is an error type returned when the accumulated size -// increase caused by copy operations in a patch operation has exceeded the -// limit. -type AccumulatedCopySizeError struct { - limit int64 - accumulated int64 -} - -// NewAccumulatedCopySizeError returns an AccumulatedCopySizeError. -func NewAccumulatedCopySizeError(l, a int64) *AccumulatedCopySizeError { - return &AccumulatedCopySizeError{limit: l, accumulated: a} -} - -// Error implements the error interface. -func (a *AccumulatedCopySizeError) Error() string { - return fmt.Sprintf("Unable to complete the copy, the accumulated size increase of copy is %d, exceeding the limit %d", a.accumulated, a.limit) -} - -// ArraySizeError is an error type returned when the array size has exceeded -// the limit. -type ArraySizeError struct { - limit int - size int -} - -// NewArraySizeError returns an ArraySizeError. -func NewArraySizeError(l, s int) *ArraySizeError { - return &ArraySizeError{limit: l, size: s} -} - -// Error implements the error interface. -func (a *ArraySizeError) Error() string { - return fmt.Sprintf("Unable to create array of size %d, limit is %d", a.size, a.limit) -} diff --git a/vendor/github.com/evanphx/json-patch/merge.go b/vendor/github.com/evanphx/json-patch/merge.go deleted file mode 100644 index ad88d4018..000000000 --- a/vendor/github.com/evanphx/json-patch/merge.go +++ /dev/null @@ -1,389 +0,0 @@ -package jsonpatch - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" -) - -func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode { - curDoc, err := cur.intoDoc() - - if err != nil { - pruneNulls(patch) - return patch - } - - patchDoc, err := patch.intoDoc() - - if err != nil { - return patch - } - - mergeDocs(curDoc, patchDoc, mergeMerge) - - return cur -} - -func mergeDocs(doc, patch *partialDoc, mergeMerge bool) { - for k, v := range *patch { - if v == nil { - if mergeMerge { - (*doc)[k] = nil - } else { - delete(*doc, k) - } - } else { - cur, ok := (*doc)[k] - - if !ok || cur == nil { - if !mergeMerge { - pruneNulls(v) - } - - (*doc)[k] = v - } else { - (*doc)[k] = merge(cur, v, mergeMerge) - } - } - } -} - -func pruneNulls(n *lazyNode) { - sub, err := n.intoDoc() - - if err == nil { - pruneDocNulls(sub) - } else { - ary, err := n.intoAry() - - if err == nil { - pruneAryNulls(ary) - } - } -} - -func pruneDocNulls(doc *partialDoc) *partialDoc { - for k, v := range *doc { - if v == nil { - delete(*doc, k) - } else { - pruneNulls(v) - } - } - - return doc -} - -func pruneAryNulls(ary *partialArray) *partialArray { - newAry := []*lazyNode{} - - for _, v := range *ary { - if v != nil { - pruneNulls(v) - } - newAry = append(newAry, v) - } - - *ary = newAry - - return ary -} - -var ErrBadJSONDoc = fmt.Errorf("Invalid JSON Document") -var ErrBadJSONPatch = fmt.Errorf("Invalid JSON Patch") -var errBadMergeTypes = fmt.Errorf("Mismatched JSON Documents") - -// MergeMergePatches merges two merge patches together, such that -// applying this resulting merged merge patch to a document yields the same -// as merging each merge patch to the document in succession. -func MergeMergePatches(patch1Data, patch2Data []byte) ([]byte, error) { - return doMergePatch(patch1Data, patch2Data, true) -} - -// MergePatch merges the patchData into the docData. -func MergePatch(docData, patchData []byte) ([]byte, error) { - return doMergePatch(docData, patchData, false) -} - -func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) { - doc := &partialDoc{} - - docErr := json.Unmarshal(docData, doc) - - patch := &partialDoc{} - - patchErr := json.Unmarshal(patchData, patch) - - if _, ok := docErr.(*json.SyntaxError); ok { - return nil, ErrBadJSONDoc - } - - if _, ok := patchErr.(*json.SyntaxError); ok { - return nil, ErrBadJSONPatch - } - - if docErr == nil && *doc == nil { - return nil, ErrBadJSONDoc - } - - if patchErr == nil && *patch == nil { - return nil, ErrBadJSONPatch - } - - if docErr != nil || patchErr != nil { - // Not an error, just not a doc, so we turn straight into the patch - if patchErr == nil { - if mergeMerge { - doc = patch - } else { - doc = pruneDocNulls(patch) - } - } else { - patchAry := &partialArray{} - patchErr = json.Unmarshal(patchData, patchAry) - - if patchErr != nil { - return nil, ErrBadJSONPatch - } - - pruneAryNulls(patchAry) - - out, patchErr := json.Marshal(patchAry) - - if patchErr != nil { - return nil, ErrBadJSONPatch - } - - return out, nil - } - } else { - mergeDocs(doc, patch, mergeMerge) - } - - return json.Marshal(doc) -} - -// resemblesJSONArray indicates whether the byte-slice "appears" to be -// a JSON array or not. -// False-positives are possible, as this function does not check the internal -// structure of the array. It only checks that the outer syntax is present and -// correct. -func resemblesJSONArray(input []byte) bool { - input = bytes.TrimSpace(input) - - hasPrefix := bytes.HasPrefix(input, []byte("[")) - hasSuffix := bytes.HasSuffix(input, []byte("]")) - - return hasPrefix && hasSuffix -} - -// CreateMergePatch will return a merge patch document capable of converting -// the original document(s) to the modified document(s). -// The parameters can be bytes of either two JSON Documents, or two arrays of -// JSON documents. -// The merge patch returned follows the specification defined at http://tools.ietf.org/html/draft-ietf-appsawg-json-merge-patch-07 -func CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalResemblesArray := resemblesJSONArray(originalJSON) - modifiedResemblesArray := resemblesJSONArray(modifiedJSON) - - // Do both byte-slices seem like JSON arrays? - if originalResemblesArray && modifiedResemblesArray { - return createArrayMergePatch(originalJSON, modifiedJSON) - } - - // Are both byte-slices are not arrays? Then they are likely JSON objects... - if !originalResemblesArray && !modifiedResemblesArray { - return createObjectMergePatch(originalJSON, modifiedJSON) - } - - // None of the above? Then return an error because of mismatched types. - return nil, errBadMergeTypes -} - -// createObjectMergePatch will return a merge-patch document capable of -// converting the original document to the modified document. -func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalDoc := map[string]interface{}{} - modifiedDoc := map[string]interface{}{} - - err := json.Unmarshal(originalJSON, &originalDoc) - if err != nil { - return nil, ErrBadJSONDoc - } - - err = json.Unmarshal(modifiedJSON, &modifiedDoc) - if err != nil { - return nil, ErrBadJSONDoc - } - - dest, err := getDiff(originalDoc, modifiedDoc) - if err != nil { - return nil, err - } - - return json.Marshal(dest) -} - -// createArrayMergePatch will return an array of merge-patch documents capable -// of converting the original document to the modified document for each -// pair of JSON documents provided in the arrays. -// Arrays of mismatched sizes will result in an error. -func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalDocs := []json.RawMessage{} - modifiedDocs := []json.RawMessage{} - - err := json.Unmarshal(originalJSON, &originalDocs) - if err != nil { - return nil, ErrBadJSONDoc - } - - err = json.Unmarshal(modifiedJSON, &modifiedDocs) - if err != nil { - return nil, ErrBadJSONDoc - } - - total := len(originalDocs) - if len(modifiedDocs) != total { - return nil, ErrBadJSONDoc - } - - result := []json.RawMessage{} - for i := 0; i < len(originalDocs); i++ { - original := originalDocs[i] - modified := modifiedDocs[i] - - patch, err := createObjectMergePatch(original, modified) - if err != nil { - return nil, err - } - - result = append(result, json.RawMessage(patch)) - } - - return json.Marshal(result) -} - -// Returns true if the array matches (must be json types). -// As is idiomatic for go, an empty array is not the same as a nil array. -func matchesArray(a, b []interface{}) bool { - if len(a) != len(b) { - return false - } - if (a == nil && b != nil) || (a != nil && b == nil) { - return false - } - for i := range a { - if !matchesValue(a[i], b[i]) { - return false - } - } - return true -} - -// Returns true if the values matches (must be json types) -// The types of the values must match, otherwise it will always return false -// If two map[string]interface{} are given, all elements must match. -func matchesValue(av, bv interface{}) bool { - if reflect.TypeOf(av) != reflect.TypeOf(bv) { - return false - } - switch at := av.(type) { - case string: - bt := bv.(string) - if bt == at { - return true - } - case float64: - bt := bv.(float64) - if bt == at { - return true - } - case bool: - bt := bv.(bool) - if bt == at { - return true - } - case nil: - // Both nil, fine. - return true - case map[string]interface{}: - bt := bv.(map[string]interface{}) - if len(bt) != len(at) { - return false - } - for key := range bt { - av, aOK := at[key] - bv, bOK := bt[key] - if aOK != bOK { - return false - } - if !matchesValue(av, bv) { - return false - } - } - return true - case []interface{}: - bt := bv.([]interface{}) - return matchesArray(at, bt) - } - return false -} - -// getDiff returns the (recursive) difference between a and b as a map[string]interface{}. -func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { - into := map[string]interface{}{} - for key, bv := range b { - av, ok := a[key] - // value was added - if !ok { - into[key] = bv - continue - } - // If types have changed, replace completely - if reflect.TypeOf(av) != reflect.TypeOf(bv) { - into[key] = bv - continue - } - // Types are the same, compare values - switch at := av.(type) { - case map[string]interface{}: - bt := bv.(map[string]interface{}) - dst := make(map[string]interface{}, len(bt)) - dst, err := getDiff(at, bt) - if err != nil { - return nil, err - } - if len(dst) > 0 { - into[key] = dst - } - case string, float64, bool: - if !matchesValue(av, bv) { - into[key] = bv - } - case []interface{}: - bt := bv.([]interface{}) - if !matchesArray(at, bt) { - into[key] = bv - } - case nil: - switch bv.(type) { - case nil: - // Both nil, fine. - default: - into[key] = bv - } - default: - panic(fmt.Sprintf("Unknown type:%T in key %s", av, key)) - } - } - // Now add all deleted values as nil - for key := range a { - _, found := b[key] - if !found { - into[key] = nil - } - } - return into, nil -} diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go deleted file mode 100644 index 95136681b..000000000 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ /dev/null @@ -1,850 +0,0 @@ -package jsonpatch - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" -) - -const ( - eRaw = iota - eDoc - eAry -) - -var ( - // SupportNegativeIndices decides whether to support non-standard practice of - // allowing negative indices to mean indices starting at the end of an array. - // Default to true. - SupportNegativeIndices bool = true - // AccumulatedCopySizeLimit limits the total size increase in bytes caused by - // "copy" operations in a patch. - AccumulatedCopySizeLimit int64 = 0 -) - -var ( - ErrTestFailed = errors.New("test failed") - ErrMissing = errors.New("missing value") - ErrUnknownType = errors.New("unknown object type") - ErrInvalid = errors.New("invalid state detected") - ErrInvalidIndex = errors.New("invalid index referenced") -) - -type lazyNode struct { - raw *json.RawMessage - doc partialDoc - ary partialArray - which int -} - -// Operation is a single JSON-Patch step, such as a single 'add' operation. -type Operation map[string]*json.RawMessage - -// Patch is an ordered collection of Operations. -type Patch []Operation - -type partialDoc map[string]*lazyNode -type partialArray []*lazyNode - -type container interface { - get(key string) (*lazyNode, error) - set(key string, val *lazyNode) error - add(key string, val *lazyNode) error - remove(key string) error -} - -func newLazyNode(raw *json.RawMessage) *lazyNode { - return &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw} -} - -func (n *lazyNode) MarshalJSON() ([]byte, error) { - switch n.which { - case eRaw: - return json.Marshal(n.raw) - case eDoc: - return json.Marshal(n.doc) - case eAry: - return json.Marshal(n.ary) - default: - return nil, ErrUnknownType - } -} - -func (n *lazyNode) UnmarshalJSON(data []byte) error { - dest := make(json.RawMessage, len(data)) - copy(dest, data) - n.raw = &dest - n.which = eRaw - return nil -} - -func deepCopy(src *lazyNode) (*lazyNode, int, error) { - if src == nil { - return nil, 0, nil - } - a, err := src.MarshalJSON() - if err != nil { - return nil, 0, err - } - sz := len(a) - ra := make(json.RawMessage, sz) - copy(ra, a) - return newLazyNode(&ra), sz, nil -} - -func (n *lazyNode) intoDoc() (*partialDoc, error) { - if n.which == eDoc { - return &n.doc, nil - } - - if n.raw == nil { - return nil, ErrInvalid - } - - err := json.Unmarshal(*n.raw, &n.doc) - - if err != nil { - return nil, err - } - - n.which = eDoc - return &n.doc, nil -} - -func (n *lazyNode) intoAry() (*partialArray, error) { - if n.which == eAry { - return &n.ary, nil - } - - if n.raw == nil { - return nil, ErrInvalid - } - - err := json.Unmarshal(*n.raw, &n.ary) - - if err != nil { - return nil, err - } - - n.which = eAry - return &n.ary, nil -} - -func (n *lazyNode) compact() []byte { - buf := &bytes.Buffer{} - - if n.raw == nil { - return nil - } - - err := json.Compact(buf, *n.raw) - - if err != nil { - return *n.raw - } - - return buf.Bytes() -} - -func (n *lazyNode) tryDoc() bool { - if n.raw == nil { - return false - } - - err := json.Unmarshal(*n.raw, &n.doc) - - if err != nil { - return false - } - - n.which = eDoc - return true -} - -func (n *lazyNode) tryAry() bool { - if n.raw == nil { - return false - } - - err := json.Unmarshal(*n.raw, &n.ary) - - if err != nil { - return false - } - - n.which = eAry - return true -} - -func (n *lazyNode) equal(o *lazyNode) bool { - if n.which == eRaw { - if !n.tryDoc() && !n.tryAry() { - if o.which != eRaw { - return false - } - - return bytes.Equal(n.compact(), o.compact()) - } - } - - if n.which == eDoc { - if o.which == eRaw { - if !o.tryDoc() { - return false - } - } - - if o.which != eDoc { - return false - } - - if len(n.doc) != len(o.doc) { - return false - } - - for k, v := range n.doc { - ov, ok := o.doc[k] - - if !ok { - return false - } - - if (v == nil) != (ov == nil) { - return false - } - - if v == nil && ov == nil { - continue - } - - if !v.equal(ov) { - return false - } - } - - return true - } - - if o.which != eAry && !o.tryAry() { - return false - } - - if len(n.ary) != len(o.ary) { - return false - } - - for idx, val := range n.ary { - if !val.equal(o.ary[idx]) { - return false - } - } - - return true -} - -// Kind reads the "op" field of the Operation. -func (o Operation) Kind() string { - if obj, ok := o["op"]; ok && obj != nil { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown" - } - - return op - } - - return "unknown" -} - -// Path reads the "path" field of the Operation. -func (o Operation) Path() (string, error) { - if obj, ok := o["path"]; ok && obj != nil { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown", err - } - - return op, nil - } - - return "unknown", fmt.Errorf("operation missing path field: %w", ErrMissing) -} - -// From reads the "from" field of the Operation. -func (o Operation) From() (string, error) { - if obj, ok := o["from"]; ok && obj != nil { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown", err - } - - return op, nil - } - - return "unknown", fmt.Errorf("operation, missing from field: %w", ErrMissing) -} - -func (o Operation) value() *lazyNode { - if obj, ok := o["value"]; ok { - return newLazyNode(obj) - } - - return nil -} - -// ValueInterface decodes the operation value into an interface. -func (o Operation) ValueInterface() (interface{}, error) { - if obj, ok := o["value"]; ok && obj != nil { - var v interface{} - - err := json.Unmarshal(*obj, &v) - - if err != nil { - return nil, err - } - - return v, nil - } - - return nil, fmt.Errorf("operation, missing value field: %w", ErrMissing) -} - -func isArray(buf []byte) bool { -Loop: - for _, c := range buf { - switch c { - case ' ': - case '\n': - case '\t': - continue - case '[': - return true - default: - break Loop - } - } - - return false -} - -func findObject(pd *container, path string) (container, string) { - doc := *pd - - split := strings.Split(path, "/") - - if len(split) < 2 { - return nil, "" - } - - parts := split[1 : len(split)-1] - - key := split[len(split)-1] - - var err error - - for _, part := range parts { - - next, ok := doc.get(decodePatchKey(part)) - - if next == nil || ok != nil || next.raw == nil { - return nil, "" - } - - if isArray(*next.raw) { - doc, err = next.intoAry() - - if err != nil { - return nil, "" - } - } else { - doc, err = next.intoDoc() - - if err != nil { - return nil, "" - } - } - } - - return doc, decodePatchKey(key) -} - -func (d *partialDoc) set(key string, val *lazyNode) error { - (*d)[key] = val - return nil -} - -func (d *partialDoc) add(key string, val *lazyNode) error { - (*d)[key] = val - return nil -} - -func (d *partialDoc) get(key string) (*lazyNode, error) { - return (*d)[key], nil -} - -func (d *partialDoc) remove(key string) error { - _, ok := (*d)[key] - if !ok { - return fmt.Errorf("Unable to remove nonexistent key: %s: %w", key, ErrMissing) - } - - delete(*d, key) - return nil -} - -// set should only be used to implement the "replace" operation, so "key" must -// be an already existing index in "d". -func (d *partialArray) set(key string, val *lazyNode) error { - idx, err := strconv.Atoi(key) - if err != nil { - return err - } - - if idx < 0 { - if !SupportNegativeIndices { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - if idx < -len(*d) { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - idx += len(*d) - } - - (*d)[idx] = val - return nil -} - -func (d *partialArray) add(key string, val *lazyNode) error { - if key == "-" { - *d = append(*d, val) - return nil - } - - idx, err := strconv.Atoi(key) - if err != nil { - return fmt.Errorf("value was not a proper array index: '%s': %w", key, err) - } - - sz := len(*d) + 1 - - ary := make([]*lazyNode, sz) - - cur := *d - - if idx >= len(ary) { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - - if idx < 0 { - if !SupportNegativeIndices { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - if idx < -len(ary) { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - idx += len(ary) - } - - copy(ary[0:idx], cur[0:idx]) - ary[idx] = val - copy(ary[idx+1:], cur[idx:]) - - *d = ary - return nil -} - -func (d *partialArray) get(key string) (*lazyNode, error) { - idx, err := strconv.Atoi(key) - - if err != nil { - return nil, err - } - - if idx < 0 { - if !SupportNegativeIndices { - return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - if idx < -len(*d) { - return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - idx += len(*d) - } - - if idx >= len(*d) { - return nil, fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - - return (*d)[idx], nil -} - -func (d *partialArray) remove(key string) error { - idx, err := strconv.Atoi(key) - if err != nil { - return err - } - - cur := *d - - if idx >= len(cur) { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - - if idx < 0 { - if !SupportNegativeIndices { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - if idx < -len(cur) { - return fmt.Errorf("Unable to access invalid index: %d: %w", idx, ErrInvalidIndex) - } - idx += len(cur) - } - - ary := make([]*lazyNode, len(cur)-1) - - copy(ary[0:idx], cur[0:idx]) - copy(ary[idx:], cur[idx+1:]) - - *d = ary - return nil - -} - -func (p Patch) add(doc *container, op Operation) error { - path, err := op.Path() - if err != nil { - return fmt.Errorf("add operation failed to decode path: %w", ErrMissing) - } - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("add operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) - } - - err = con.add(key, op.value()) - if err != nil { - return fmt.Errorf("error in add for path: '%s': %w", path, err) - } - - return nil -} - -func (p Patch) remove(doc *container, op Operation) error { - path, err := op.Path() - if err != nil { - return fmt.Errorf("remove operation failed to decode path: %w", ErrMissing) - } - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("remove operation does not apply: doc is missing path: \"%s\": %w", path, ErrMissing) - } - - err = con.remove(key) - if err != nil { - return fmt.Errorf("error in remove for path: '%s': %w", path, err) - } - - return nil -} - -func (p Patch) replace(doc *container, op Operation) error { - path, err := op.Path() - if err != nil { - return fmt.Errorf("replace operation failed to decode path: %w", err) - } - - if path == "" { - val := op.value() - - if val.which == eRaw { - if !val.tryDoc() { - if !val.tryAry() { - return fmt.Errorf("replace operation value must be object or array: %w", err) - } - } - } - - switch val.which { - case eAry: - *doc = &val.ary - case eDoc: - *doc = &val.doc - case eRaw: - return fmt.Errorf("replace operation hit impossible case: %w", err) - } - - return nil - } - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("replace operation does not apply: doc is missing path: %s: %w", path, ErrMissing) - } - - _, ok := con.get(key) - if ok != nil { - return fmt.Errorf("replace operation does not apply: doc is missing key: %s: %w", path, ErrMissing) - } - - err = con.set(key, op.value()) - if err != nil { - return fmt.Errorf("error in remove for path: '%s': %w", path, err) - } - - return nil -} - -func (p Patch) move(doc *container, op Operation) error { - from, err := op.From() - if err != nil { - return fmt.Errorf("move operation failed to decode from: %w", err) - } - - con, key := findObject(doc, from) - - if con == nil { - return fmt.Errorf("move operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) - } - - val, err := con.get(key) - if err != nil { - return fmt.Errorf("error in move for path: '%s': %w", key, err) - } - - err = con.remove(key) - if err != nil { - return fmt.Errorf("error in move for path: '%s': %w", key, err) - } - - path, err := op.Path() - if err != nil { - return fmt.Errorf("move operation failed to decode path: %w", err) - } - - con, key = findObject(doc, path) - - if con == nil { - return fmt.Errorf("move operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) - } - - err = con.add(key, val) - if err != nil { - return fmt.Errorf("error in move for path: '%s': %w", path, err) - } - - return nil -} - -func (p Patch) test(doc *container, op Operation) error { - path, err := op.Path() - if err != nil { - return fmt.Errorf("test operation failed to decode path: %w", err) - } - - if path == "" { - var self lazyNode - - switch sv := (*doc).(type) { - case *partialDoc: - self.doc = *sv - self.which = eDoc - case *partialArray: - self.ary = *sv - self.which = eAry - } - - if self.equal(op.value()) { - return nil - } - - return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) - } - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("test operation does not apply: is missing path: %s: %w", path, ErrMissing) - } - - val, err := con.get(key) - if err != nil { - return fmt.Errorf("error in test for path: '%s': %w", path, err) - } - - if val == nil { - if op.value() == nil || op.value().raw == nil { - return nil - } - return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) - } else if op.value() == nil { - return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) - } - - if val.equal(op.value()) { - return nil - } - - return fmt.Errorf("testing value %s failed: %w", path, ErrTestFailed) -} - -func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) error { - from, err := op.From() - if err != nil { - return fmt.Errorf("copy operation failed to decode from: %w", err) - } - - con, key := findObject(doc, from) - - if con == nil { - return fmt.Errorf("copy operation does not apply: doc is missing from path: %s: %w", from, ErrMissing) - } - - val, err := con.get(key) - if err != nil { - return fmt.Errorf("error in copy for from: '%s': %w", from, err) - } - - path, err := op.Path() - if err != nil { - return fmt.Errorf("copy operation failed to decode path: %w", ErrMissing) - } - - con, key = findObject(doc, path) - - if con == nil { - return fmt.Errorf("copy operation does not apply: doc is missing destination path: %s: %w", path, ErrMissing) - } - - valCopy, sz, err := deepCopy(val) - if err != nil { - return fmt.Errorf("error while performing deep copy: %w", err) - } - - (*accumulatedCopySize) += int64(sz) - if AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > AccumulatedCopySizeLimit { - return NewAccumulatedCopySizeError(AccumulatedCopySizeLimit, *accumulatedCopySize) - } - - err = con.add(key, valCopy) - if err != nil { - return fmt.Errorf("error while adding value during copy: %w", err) - } - - return nil -} - -// Equal indicates if 2 JSON documents have the same structural equality. -func Equal(a, b []byte) bool { - ra := make(json.RawMessage, len(a)) - copy(ra, a) - la := newLazyNode(&ra) - - rb := make(json.RawMessage, len(b)) - copy(rb, b) - lb := newLazyNode(&rb) - - return la.equal(lb) -} - -// DecodePatch decodes the passed JSON document as an RFC 6902 patch. -func DecodePatch(buf []byte) (Patch, error) { - var p Patch - - err := json.Unmarshal(buf, &p) - - if err != nil { - return nil, err - } - - return p, nil -} - -// Apply mutates a JSON document according to the patch, and returns the new -// document. -func (p Patch) Apply(doc []byte) ([]byte, error) { - return p.ApplyIndent(doc, "") -} - -// ApplyIndent mutates a JSON document according to the patch, and returns the new -// document indented. -func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { - if len(doc) == 0 { - return doc, nil - } - - var pd container - if doc[0] == '[' { - pd = &partialArray{} - } else { - pd = &partialDoc{} - } - - err := json.Unmarshal(doc, pd) - - if err != nil { - return nil, err - } - - err = nil - - var accumulatedCopySize int64 - - for _, op := range p { - switch op.Kind() { - case "add": - err = p.add(&pd, op) - case "remove": - err = p.remove(&pd, op) - case "replace": - err = p.replace(&pd, op) - case "move": - err = p.move(&pd, op) - case "test": - err = p.test(&pd, op) - case "copy": - err = p.copy(&pd, op, &accumulatedCopySize) - default: - err = fmt.Errorf("Unexpected kind: %s", op.Kind()) - } - - if err != nil { - return nil, err - } - } - - if indent != "" { - return json.MarshalIndent(pd, "", indent) - } - - return json.Marshal(pd) -} - -// From http://tools.ietf.org/html/rfc6901#section-4 : -// -// Evaluation of each reference token begins by decoding any escaped -// character sequence. This is performed by first transforming any -// occurrence of the sequence '~1' to '/', and then transforming any -// occurrence of the sequence '~0' to '~'. - -var ( - rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") -) - -func decodePatchKey(k string) string { - return rfc6901Decoder.Replace(k) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6e8815d2d..006b2e83f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -119,11 +119,11 @@ github.com/ProtonMail/go-crypto/openpgp/packet github.com/ProtonMail/go-crypto/openpgp/s2k github.com/ProtonMail/go-crypto/openpgp/x25519 github.com/ProtonMail/go-crypto/openpgp/x448 -# github.com/argoproj-labs/argocd-operator v0.15.0-rc1 -## explicit; go 1.24.4 +# github.com/argoproj-labs/argocd-operator v0.15.0 +## explicit; go 1.24.6 github.com/argoproj-labs/argocd-operator/api/v1beta1 github.com/argoproj-labs/argocd-operator/common -# github.com/argoproj/argo-cd/v3 v3.0.14 +# github.com/argoproj/argo-cd/v3 v3.0.16 ## explicit; go 1.24.6 github.com/argoproj/argo-cd/v3/assets github.com/argoproj/argo-cd/v3/common @@ -157,14 +157,16 @@ github.com/argoproj/argo-cd/v3/util/regex github.com/argoproj/argo-cd/v3/util/security github.com/argoproj/argo-cd/v3/util/versions github.com/argoproj/argo-cd/v3/util/workloadidentity -# github.com/argoproj/gitops-engine v0.7.1-0.20250521000818-c08b0a72c1f1 -## explicit; go 1.22.0 +# github.com/argoproj/gitops-engine v0.7.1-0.20250905153922-d96c3d51e4c4 +## explicit; go 1.23.5 github.com/argoproj/gitops-engine/internal/kubernetes_vendor/pkg/api/v1/endpoints github.com/argoproj/gitops-engine/internal/kubernetes_vendor/pkg/util/hash github.com/argoproj/gitops-engine/pkg/diff github.com/argoproj/gitops-engine/pkg/diff/internal/fieldmanager github.com/argoproj/gitops-engine/pkg/health github.com/argoproj/gitops-engine/pkg/sync/common +github.com/argoproj/gitops-engine/pkg/sync/hook +github.com/argoproj/gitops-engine/pkg/sync/hook/helm github.com/argoproj/gitops-engine/pkg/sync/resource github.com/argoproj/gitops-engine/pkg/utils/io github.com/argoproj/gitops-engine/pkg/utils/json @@ -266,9 +268,6 @@ github.com/emirpasic/gods/lists/arraylist github.com/emirpasic/gods/trees github.com/emirpasic/gods/trees/binaryheap github.com/emirpasic/gods/utils -# github.com/evanphx/json-patch v5.9.11+incompatible -## explicit -github.com/evanphx/json-patch # github.com/evanphx/json-patch/v5 v5.9.11 ## explicit; go 1.18 github.com/evanphx/json-patch/v5