fluxcd / image-automation-controller

GitOps Toolkit controller that patches container image tags in Git
https://fluxcd.io
Apache License 2.0
172 stars 70 forks source link

inline image policy marker comments merge problem #312

Open bob-rohan opened 2 years ago

bob-rohan commented 2 years ago

Supposing podinfo supported release branches (which I recommend against, but lots of places do use), then you might have a test environment setup with image automation defining inline image policy marker comments such as follows

newTag: release-dcd9b99-1643898245 # {"$imagepolicy": "flux-system:podinfo-release:tag"}

To deploy to production, these image IDs would be merged from the release branch, to the main.

In addition to supporting release branch based deployments, podinfo maintainers would also like Flux to support pain free hotfixes, with a view to using this for continuous delivery on other services. Then you might have an production environment setup with image automation defining inline image policy marker comments such as follows.

newTag: main-dcd9b99-1643898245 # {"$imagepolicy": "flux-system:podinfo-main:tag"}

However by merging the release branch to main, the inline image policy marker comment is erroneously updated to from podinfo-main to podinfo-release. The goal is to have

newTag: release-dcd9b99-1643898245 # {"$imagepolicy": "flux-system:podinfo-main:tag"}

See the tag is now set to release-dcd9b99-1643898245, but the image policy will continue to identify hotfixes from podinfo-main.

It would be better not to use inline comments

stefanprodan commented 2 years ago

You can place these markers on the Flux Kustomization object that applies the app on an environment. The one in clusters/staging will use different policy than the one in clusters/production e.g.:

clusters/staging/podinfo.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
  namespace: default
spec:
  images:
    - name: ghcr.io/stefanprodan/podinfo
      newName: ghcr.io/stefanprodan/podinfo # {"$imagepolicy": "flux-system:podinfo-release:name"}
      newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo-release:tag"}

clusters/production/podinfo.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
  namespace: default
spec:
  images:
    - name: ghcr.io/stefanprodan/podinfo
      newName: ghcr.io/stefanprodan/podinfo # {"$imagepolicy": "flux-system:podinfo-main:name"}
      newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo-main:tag"}
bob-rohan commented 2 years ago

I believe in your example, you may have reduced the effectiveness of Flux by introducing additional overhead, or risk, or both - depending on what your strategy is for promotion.

In the example quoted there are a few material differences

Based on this feedback, if you could elaborate on the mechanism/process you see for promoting between environments, I can provide further clarity.

stefanprodan commented 2 years ago

Ok so there are no overlays for each env, the staging cluster is identical to the production one, nothing differs between the 2 branches but the image tags?

bob-rohan commented 2 years ago

I think the short answer is nothing relevant, but I'll include some detail incase you're driving at a point I don't yet understand.

In the fleet repo, both staging and production clusters declare a several GitRepository kind's.

Flux Kustomization yaml enacts reconcile loop on image-ids. Both manifests and application-configuration are embedded via include, with kustomization.yaml referring to relative paths.

The GitRepository refspec if different per environment

Few additional things are fed through from the fleet repo to the manifests via Flux Kustomization overlay, things like the environment name for nonprod would be staging, as apposed to the uat environment also within the nonprod cluster. But your terminology of staging cluster is entirely sufficient to frame the issue.

In terms of image-ids repo, multiple branches

Both will have the same structure, i.e a kustomization.yaml file declaring a collection of the tenant's images. Both the image tags and the inline image policy marker comments will differ between branches.

stefanprodan commented 2 years ago

Ok so you could use a single policy and swap the filter based on the target cluster, that marker will be the same (no merge issues) but they will act differently depending on the cluster.

bob-rohan commented 2 years ago

Yes, I think I can see how that would work for the example above.

We have multiple policies in some clusters, but by refactoring the image automation CRDs from flux-system namespace to the tenant namespace, I think that could work also.

I will have a go. Thanks @stefanprodan

bob-rohan commented 2 years ago

Been a bit of a day going back and forth on this one. Main fumble point seems to be around what namespace various components logically reside within, Secret (for git), GitRepository, ecr-credentails-sync, ImagePolicy, ImageRegistry, ImageAutomation etc

I think I'm just about where I want to be on this one but for one snag. I feel lucky this merges some cross namespace functionality I'd like to use, for better or worse

https://github.com/fluxcd/image-automation-controller/commit/3de51e7a1e755541dbc97a01777c8dd247ccf922

While Flux cli 0.26.2 (latest) includes image-automation-controller > 0.20.0 (see link above), it would seem the ImageUpdateAutomation schema defined by flux boostrap does not set namespace as a valid arg.

If the above is correct, how long to get that functionality available please?

stefanprodan commented 2 years ago

While Flux cli 0.26.2 (latest) includes image-automation-controller > 0.20.0 (see link above), it would seem the ImageUpdateAutomation schema defined by flux boostrap does not set namespace as a valid arg.

Have you upgraded your cluster? Can you post here kubectl get crd imageupdateautomations.image.toolkit.fluxcd.io -oyaml?

bob-rohan commented 2 years ago

Yes, well, sort of. We dump the flux bootstrap results out to disk and store in git for bootstrapping via terraform initiated custom ECS task. Gives us a sensible way to PR and control rollout.

Anyway result for your command suggests I upgraded to 0.24, but if you at the results from flux boostrap with cli 0.26 - it's my interpretation that the ImageUpdateAutomation showsnamespace` is not a valid attribute under that schema for sourceref. I will post another comment with that output as size is large

kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.5.0
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{"controller-gen.kubebuilder.io/version":"v0.5.0"},"creationTimestamp":null,"labels":{"app.kubernetes.io/instance":"flux-system","app.kubernetes.io/part-of":"flux","app.kubernetes.io/version":"v0.24.1"},"name":"imageupdateautomations.image.toolkit.fluxcd.io"},"spec":{"group":"image.toolkit.fluxcd.io","names":{"kind":"ImageUpdateAutomation","listKind":"ImageUpdateAutomationList","plural":"imageupdateautomations","singular":"imageupdateautomation"},"scope":"Namespaced","versions":[{"additionalPrinterColumns":[{"jsonPath":".status.lastAutomationRunTime","name":"Last run","type":"string"}],"name":"v1alpha1","schema":{"openAPIV3Schema":{"description":"ImageUpdateAutomation is the Schema for the imageupdateautomations API","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds","type":"string"},"metadata":{"type":"object"},"spec":{"description":"ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation","properties":{"checkout":{"description":"Checkout gives the parameters for cloning the git repository, ready to make changes.","properties":{"branch":{"description":"Branch gives the branch to clone from the git repository. If `.spec.push` is not supplied, commits will also be pushed to this branch.","type":"string"},"gitRepositoryRef":{"description":"GitRepositoryRef refers to the resource giving access details to a git repository to update files in.","properties":{"name":{"description":"Name of the referent","type":"string"}},"required":["name"],"type":"object"}},"required":["branch","gitRepositoryRef"],"type":"object"},"commit":{"description":"Commit specifies how to commit to the git repository.","properties":{"authorEmail":{"description":"AuthorEmail gives the email to provide when making a commit","type":"string"},"authorName":{"description":"AuthorName gives the name to provide when making a commit","type":"string"},"messageTemplate":{"description":"MessageTemplate provides a template for the commit message, into which will be interpolated the details of the change made.","type":"string"},"signingKey":{"description":"SigningKey provides the option to sign commits with a GPG key","properties":{"secretRef":{"description":"SecretRef holds the name to a secret that contains a 'git.asc' key corresponding to the ASCII Armored file containing the GPG signing keypair as the value. It must be in the same namespace as the ImageUpdateAutomation.","properties":{"name":{"description":"Name of the referent","type":"string"}},"required":["name"],"type":"object"}},"type":"object"}},"required":["authorEmail","authorName"],"type":"object"},"interval":{"description":"Interval gives an lower bound for how often the automation run should be attempted.","type":"string"},"push":{"description":"Push specifies how and where to push commits made by the automation. If missing, commits are pushed (back) to `.spec.checkout.branch`.","properties":{"branch":{"description":"Branch specifies that commits should be pushed to the branch named. The branch is created using `.spec.checkout.branch` as the starting point, if it doesn't already exist.","type":"string"}},"required":["branch"],"type":"object"},"suspend":{"description":"Suspend tells the controller to not run this automation, until it is unset (or set to false). Defaults to false.","type":"boolean"},"update":{"default":{"strategy":"Setters"},"description":"Update gives the specification for how to update the files in the repository. This can be left empty, to use the default value.","properties":{"path":{"description":"Path to the directory containing the manifests to be updated. Defaults to 'None', which translates to the root path of the GitRepositoryRef.","type":"string"},"strategy":{"default":"Setters","description":"Strategy names the strategy to be used.","enum":["Setters"],"type":"string"}},"required":["strategy"],"type":"object"}},"required":["checkout","commit","interval"],"type":"object"},"status":{"description":"ImageUpdateAutomationStatus defines the observed state of ImageUpdateAutomation","properties":{"conditions":{"items":{"description":"Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions.  For example, type FooStatus struct{     // Represents the observations of a foo's current state.     // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type     // +patchStrategy=merge     // +listType=map     // +listMapKey=type     Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n     // other fields }","properties":{"lastTransitionTime":{"description":"lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.","format":"date-time","type":"string"},"message":{"description":"message is a human readable message indicating details about the transition. This may be an empty string.","maxLength":32768,"type":"string"},"observedGeneration":{"description":"observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.","format":"int64","minimum":0,"type":"integer"},"reason":{"description":"reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.","maxLength":1024,"minLength":1,"pattern":"^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$","type":"string"},"status":{"description":"status of the condition, one of True, False, Unknown.","enum":["True","False","Unknown"],"type":"string"},"type":{"description":"type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)","maxLength":316,"pattern":"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$","type":"string"}},"required":["lastTransitionTime","message","reason","status","type"],"type":"object"},"type":"array"},"lastAutomationRunTime":{"description":"LastAutomationRunTime records the last time the controller ran this automation through to completion (even if no updates were made).","format":"date-time","type":"string"},"lastHandledReconcileAt":{"description":"LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change can be detected.","type":"string"},"lastPushCommit":{"description":"LastPushCommit records the SHA1 of the last commit made by the controller, for this automation object","type":"string"},"lastPushTime":{"description":"LastPushTime records the time of the last pushed change.","format":"date-time","type":"string"},"observedGeneration":{"format":"int64","type":"integer"}},"type":"object"}},"type":"object"}},"served":true,"storage":false,"subresources":{"status":{}}},{"additionalPrinterColumns":[{"jsonPath":".status.lastAutomationRunTime","name":"Last run","type":"string"}],"name":"v1alpha2","schema":{"openAPIV3Schema":{"description":"ImageUpdateAutomation is the Schema for the imageupdateautomations API","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds","type":"string"},"metadata":{"type":"object"},"spec":{"description":"ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation","properties":{"git":{"description":"GitSpec contains all the git-specific definitions. This is technically optional, but in practice mandatory until there are other kinds of source allowed.","properties":{"checkout":{"description":"Checkout gives the parameters for cloning the git repository, ready to make changes. If not present, the `spec.ref` field from the referenced `GitRepository` or its default will be used.","properties":{"ref":{"description":"Reference gives a branch, tag or commit to clone from the Git repository.","properties":{"branch":{"description":"The Git branch to checkout, defaults to master.","type":"string"},"commit":{"description":"The Git commit SHA to checkout, if specified Tag filters will be ignored.","type":"string"},"semver":{"description":"The Git tag semver expression, takes precedence over Tag.","type":"string"},"tag":{"description":"The Git tag to checkout, takes precedence over Branch.","type":"string"}},"type":"object"}},"required":["ref"],"type":"object"},"commit":{"description":"Commit specifies how to commit to the git repository.","properties":{"author":{"description":"Author gives the email and optionally the name to use as the author of commits.","properties":{"email":{"description":"Email gives the email to provide when making a commit.","type":"string"},"name":{"description":"Name gives the name to provide when making a commit.","type":"string"}},"required":["email"],"type":"object"},"messageTemplate":{"description":"MessageTemplate provides a template for the commit message, into which will be interpolated the details of the change made.","type":"string"},"signingKey":{"description":"SigningKey provides the option to sign commits with a GPG key","properties":{"secretRef":{"description":"SecretRef holds the name to a secret that contains a 'git.asc' key corresponding to the ASCII Armored file containing the GPG signing keypair as the value. It must be in the same namespace as the ImageUpdateAutomation.","properties":{"name":{"description":"Name of the referent","type":"string"}},"required":["name"],"type":"object"}},"type":"object"}},"required":["author"],"type":"object"},"push":{"description":"Push specifies how and where to push commits made by the automation. If missing, commits are pushed (back) to `.spec.checkout.branch` or its default.","properties":{"branch":{"description":"Branch specifies that commits should be pushed to the branch named. The branch is created using `.spec.checkout.branch` as the starting point, if it doesn't already exist.","type":"string"}},"required":["branch"],"type":"object"}},"required":["commit"],"type":"object"},"interval":{"description":"Interval gives an lower bound for how often the automation run should be attempted.","type":"string"},"sourceRef":{"description":"SourceRef refers to the resource giving access details to a git repository.","properties":{"apiVersion":{"description":"API version of the referent","type":"string"},"kind":{"default":"GitRepository","description":"Kind of the referent","enum":["GitRepository"],"type":"string"},"name":{"description":"Name of the referent","type":"string"}},"required":["kind","name"],"type":"object"},"suspend":{"description":"Suspend tells the controller to not run this automation, until it is unset (or set to false). Defaults to false.","type":"boolean"},"update":{"default":{"strategy":"Setters"},"description":"Update gives the specification for how to update the files in the repository. This can be left empty, to use the default value.","properties":{"path":{"description":"Path to the directory containing the manifests to be updated. Defaults to 'None', which translates to the root path of the GitRepositoryRef.","type":"string"},"strategy":{"default":"Setters","description":"Strategy names the strategy to be used.","enum":["Setters"],"type":"string"}},"required":["strategy"],"type":"object"}},"required":["interval","sourceRef"],"type":"object"},"status":{"description":"ImageUpdateAutomationStatus defines the observed state of ImageUpdateAutomation","properties":{"conditions":{"items":{"description":"Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions.  For example, type FooStatus struct{     // Represents the observations of a foo's current state.     // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type     // +patchStrategy=merge     // +listType=map     // +listMapKey=type     Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n     // other fields }","properties":{"lastTransitionTime":{"description":"lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.","format":"date-time","type":"string"},"message":{"description":"message is a human readable message indicating details about the transition. This may be an empty string.","maxLength":32768,"type":"string"},"observedGeneration":{"description":"observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.","format":"int64","minimum":0,"type":"integer"},"reason":{"description":"reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.","maxLength":1024,"minLength":1,"pattern":"^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$","type":"string"},"status":{"description":"status of the condition, one of True, False, Unknown.","enum":["True","False","Unknown"],"type":"string"},"type":{"description":"type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)","maxLength":316,"pattern":"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$","type":"string"}},"required":["lastTransitionTime","message","reason","status","type"],"type":"object"},"type":"array"},"lastAutomationRunTime":{"description":"LastAutomationRunTime records the last time the controller ran this automation through to completion (even if no updates were made).","format":"date-time","type":"string"},"lastHandledReconcileAt":{"description":"LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change can be detected.","type":"string"},"lastPushCommit":{"description":"LastPushCommit records the SHA1 of the last commit made by the controller, for this automation object","type":"string"},"lastPushTime":{"description":"LastPushTime records the time of the last pushed change.","format":"date-time","type":"string"},"observedGeneration":{"format":"int64","type":"integer"}},"type":"object"}},"type":"object"}},"served":true,"storage":false,"subresources":{"status":{}}},{"additionalPrinterColumns":[{"jsonPath":".status.lastAutomationRunTime","name":"Last run","type":"string"}],"name":"v1beta1","schema":{"openAPIV3Schema":{"description":"ImageUpdateAutomation is the Schema for the imageupdateautomations API","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds","type":"string"},"metadata":{"type":"object"},"spec":{"description":"ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation","properties":{"git":{"description":"GitSpec contains all the git-specific definitions. This is technically optional, but in practice mandatory until there are other kinds of source allowed.","properties":{"checkout":{"description":"Checkout gives the parameters for cloning the git repository, ready to make changes. If not present, the `spec.ref` field from the referenced `GitRepository` or its default will be used.","properties":{"ref":{"description":"Reference gives a branch, tag or commit to clone from the Git repository.","properties":{"branch":{"description":"The Git branch to checkout, defaults to master.","type":"string"},"commit":{"description":"The Git commit SHA to checkout, if specified Tag filters will be ignored.","type":"string"},"semver":{"description":"The Git tag semver expression, takes precedence over Tag.","type":"string"},"tag":{"description":"The Git tag to checkout, takes precedence over Branch.","type":"string"}},"type":"object"}},"required":["ref"],"type":"object"},"commit":{"description":"Commit specifies how to commit to the git repository.","properties":{"author":{"description":"Author gives the email and optionally the name to use as the author of commits.","properties":{"email":{"description":"Email gives the email to provide when making a commit.","type":"string"},"name":{"description":"Name gives the name to provide when making a commit.","type":"string"}},"required":["email"],"type":"object"},"messageTemplate":{"description":"MessageTemplate provides a template for the commit message, into which will be interpolated the details of the change made.","type":"string"},"signingKey":{"description":"SigningKey provides the option to sign commits with a GPG key","properties":{"secretRef":{"description":"SecretRef holds the name to a secret that contains a 'git.asc' key corresponding to the ASCII Armored file containing the GPG signing keypair as the value. It must be in the same namespace as the ImageUpdateAutomation.","properties":{"name":{"description":"Name of the referent","type":"string"}},"required":["name"],"type":"object"}},"type":"object"}},"required":["author"],"type":"object"},"push":{"description":"Push specifies how and where to push commits made by the automation. If missing, commits are pushed (back) to `.spec.checkout.branch` or its default.","properties":{"branch":{"description":"Branch specifies that commits should be pushed to the branch named. The branch is created using `.spec.checkout.branch` as the starting point, if it doesn't already exist.","type":"string"}},"required":["branch"],"type":"object"}},"required":["commit"],"type":"object"},"interval":{"description":"Interval gives an lower bound for how often the automation run should be attempted.","type":"string"},"sourceRef":{"description":"SourceRef refers to the resource giving access details to a git repository.","properties":{"apiVersion":{"description":"API version of the referent","type":"string"},"kind":{"default":"GitRepository","description":"Kind of the referent","enum":["GitRepository"],"type":"string"},"name":{"description":"Name of the referent","type":"string"}},"required":["kind","name"],"type":"object"},"suspend":{"description":"Suspend tells the controller to not run this automation, until it is unset (or set to false). Defaults to false.","type":"boolean"},"update":{"default":{"strategy":"Setters"},"description":"Update gives the specification for how to update the files in the repository. This can be left empty, to use the default value.","properties":{"path":{"description":"Path to the directory containing the manifests to be updated. Defaults to 'None', which translates to the root path of the GitRepositoryRef.","type":"string"},"strategy":{"default":"Setters","description":"Strategy names the strategy to be used.","enum":["Setters"],"type":"string"}},"required":["strategy"],"type":"object"}},"required":["interval","sourceRef"],"type":"object"},"status":{"description":"ImageUpdateAutomationStatus defines the observed state of ImageUpdateAutomation","properties":{"conditions":{"items":{"description":"Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions.  For example, type FooStatus struct{     // Represents the observations of a foo's current state.     // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type     // +patchStrategy=merge     // +listType=map     // +listMapKey=type     Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n     // other fields }","properties":{"lastTransitionTime":{"description":"lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.","format":"date-time","type":"string"},"message":{"description":"message is a human readable message indicating details about the transition. This may be an empty string.","maxLength":32768,"type":"string"},"observedGeneration":{"description":"observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.","format":"int64","minimum":0,"type":"integer"},"reason":{"description":"reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.","maxLength":1024,"minLength":1,"pattern":"^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$","type":"string"},"status":{"description":"status of the condition, one of True, False, Unknown.","enum":["True","False","Unknown"],"type":"string"},"type":{"description":"type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)","maxLength":316,"pattern":"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$","type":"string"}},"required":["lastTransitionTime","message","reason","status","type"],"type":"object"},"type":"array"},"lastAutomationRunTime":{"description":"LastAutomationRunTime records the last time the controller ran this automation through to completion (even if no updates were made).","format":"date-time","type":"string"},"lastHandledReconcileAt":{"description":"LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change can be detected.","type":"string"},"lastPushCommit":{"description":"LastPushCommit records the SHA1 of the last commit made by the controller, for this automation object","type":"string"},"lastPushTime":{"description":"LastPushTime records the time of the last pushed change.","format":"date-time","type":"string"},"observedGeneration":{"format":"int64","type":"integer"}},"type":"object"}},"type":"object"}},"served":true,"storage":true,"subresources":{"status":{}}}]},"status":{"acceptedNames":{"kind":"","plural":""},"conditions":[],"storedVersions":[]}}
  creationTimestamp: "2022-02-09T20:58:20Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: flux-system
    app.kubernetes.io/part-of: flux
    app.kubernetes.io/version: v0.24.1
  name: imageupdateautomations.image.toolkit.fluxcd.io
  resourceVersion: "881"
  uid: 354da05f-9606-4fd7-8302-d3838f9a8b03
spec:
  conversion:
    strategy: None
  group: image.toolkit.fluxcd.io
  names:
    kind: ImageUpdateAutomation
    listKind: ImageUpdateAutomationList
    plural: imageupdateautomations
    singular: imageupdateautomation
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - jsonPath: .status.lastAutomationRunTime
      name: Last run
      type: string
    name: v1alpha1
    schema:
      openAPIV3Schema:
        description: ImageUpdateAutomation is the Schema for the imageupdateautomations
          API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
            properties:
              checkout:
                description: Checkout gives the parameters for cloning the git repository,
                  ready to make changes.
                properties:
                  branch:
                    description: Branch gives the branch to clone from the git repository.
                      If `.spec.push` is not supplied, commits will also be pushed
                      to this branch.
                    type: string
                  gitRepositoryRef:
                    description: GitRepositoryRef refers to the resource giving access
                      details to a git repository to update files in.
                    properties:
                      name:
                        description: Name of the referent
                        type: string
                    required:
                    - name
                    type: object
                required:
                - branch
                - gitRepositoryRef
                type: object
              commit:
                description: Commit specifies how to commit to the git repository.
                properties:
                  authorEmail:
                    description: AuthorEmail gives the email to provide when making
                      a commit
                    type: string
                  authorName:
                    description: AuthorName gives the name to provide when making
                      a commit
                    type: string
                  messageTemplate:
                    description: MessageTemplate provides a template for the commit
                      message, into which will be interpolated the details of the
                      change made.
                    type: string
                  signingKey:
                    description: SigningKey provides the option to sign commits with
                      a GPG key
                    properties:
                      secretRef:
                        description: SecretRef holds the name to a secret that contains
                          a 'git.asc' key corresponding to the ASCII Armored file
                          containing the GPG signing keypair as the value. It must
                          be in the same namespace as the ImageUpdateAutomation.
                        properties:
                          name:
                            description: Name of the referent
                            type: string
                        required:
                        - name
                        type: object
                    type: object
                required:
                - authorEmail
                - authorName
                type: object
              interval:
                description: Interval gives an lower bound for how often the automation
                  run should be attempted.
                type: string
              push:
                description: Push specifies how and where to push commits made by
                  the automation. If missing, commits are pushed (back) to `.spec.checkout.branch`.
                properties:
                  branch:
                    description: Branch specifies that commits should be pushed to
                      the branch named. The branch is created using `.spec.checkout.branch`
                      as the starting point, if it doesn't already exist.
                    type: string
                required:
                - branch
                type: object
              suspend:
                description: Suspend tells the controller to not run this automation,
                  until it is unset (or set to false). Defaults to false.
                type: boolean
              update:
                default:
                  strategy: Setters
                description: Update gives the specification for how to update the
                  files in the repository. This can be left empty, to use the default
                  value.
                properties:
                  path:
                    description: Path to the directory containing the manifests to
                      be updated. Defaults to 'None', which translates to the root
                      path of the GitRepositoryRef.
                    type: string
                  strategy:
                    default: Setters
                    description: Strategy names the strategy to be used.
                    enum:
                    - Setters
                    type: string
                required:
                - strategy
                type: object
            required:
            - checkout
            - commit
            - interval
            type: object
          status:
            description: ImageUpdateAutomationStatus defines the observed state of
              ImageUpdateAutomation
            properties:
              conditions:
                items:
                  description: "Condition contains details for one aspect of the current
                    state of this API Resource. --- This struct is intended for direct
                    use as an array at the field path .status.conditions.  For example,
                    type FooStatus struct{     // Represents the observations of a
                    foo's current state.     // Known .status.conditions.type are:
                    \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type
                    \    // +patchStrategy=merge     // +listType=map     // +listMapKey=type
                    \    Conditions []metav1.Condition `json:\"conditions,omitempty\"
                    patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
                    \n     // other fields }"
                  properties:
                    lastTransitionTime:
                      description: lastTransitionTime is the last time the condition
                        transitioned from one status to another. This should be when
                        the underlying condition changed.  If that is not known, then
                        using the time when the API field changed is acceptable.
                      format: date-time
                      type: string
                    message:
                      description: message is a human readable message indicating
                        details about the transition. This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: observedGeneration represents the .metadata.generation
                        that the condition was set based upon. For instance, if .metadata.generation
                        is currently 12, but the .status.conditions[x].observedGeneration
                        is 9, the condition is out of date with respect to the current
                        state of the instance.
                      format: int64
                      minimum: 0
                      type: integer
                    reason:
                      description: reason contains a programmatic identifier indicating
                        the reason for the condition's last transition. Producers
                        of specific condition types may define expected values and
                        meanings for this field, and whether the values are considered
                        a guaranteed API. The value should be a CamelCase string.
                        This field may not be empty.
                      maxLength: 1024
                      minLength: 1
                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
                      type: string
                    status:
                      description: status of the condition, one of True, False, Unknown.
                      enum:
                      - "True"
                      - "False"
                      - Unknown
                      type: string
                    type:
                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
                        --- Many .condition.type values are consistent across resources
                        like Available, but because arbitrary conditions can be useful
                        (see .node.status.conditions), the ability to deconflict is
                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
                      maxLength: 316
                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
                      type: string
                  required:
                  - lastTransitionTime
                  - message
                  - reason
                  - status
                  - type
                  type: object
                type: array
              lastAutomationRunTime:
                description: LastAutomationRunTime records the last time the controller
                  ran this automation through to completion (even if no updates were
                  made).
                format: date-time
                type: string
              lastHandledReconcileAt:
                description: LastHandledReconcileAt holds the value of the most recent
                  reconcile request value, so a change can be detected.
                type: string
              lastPushCommit:
                description: LastPushCommit records the SHA1 of the last commit made
                  by the controller, for this automation object
                type: string
              lastPushTime:
                description: LastPushTime records the time of the last pushed change.
                format: date-time
                type: string
              observedGeneration:
                format: int64
                type: integer
            type: object
        type: object
    served: true
    storage: false
    subresources:
      status: {}
  - additionalPrinterColumns:
    - jsonPath: .status.lastAutomationRunTime
      name: Last run
      type: string
    name: v1alpha2
    schema:
      openAPIV3Schema:
        description: ImageUpdateAutomation is the Schema for the imageupdateautomations
          API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
            properties:
              git:
                description: GitSpec contains all the git-specific definitions. This
                  is technically optional, but in practice mandatory until there are
                  other kinds of source allowed.
                properties:
                  checkout:
                    description: Checkout gives the parameters for cloning the git
                      repository, ready to make changes. If not present, the `spec.ref`
                      field from the referenced `GitRepository` or its default will
                      be used.
                    properties:
                      ref:
                        description: Reference gives a branch, tag or commit to clone
                          from the Git repository.
                        properties:
                          branch:
                            description: The Git branch to checkout, defaults to master.
                            type: string
                          commit:
                            description: The Git commit SHA to checkout, if specified
                              Tag filters will be ignored.
                            type: string
                          semver:
                            description: The Git tag semver expression, takes precedence
                              over Tag.
                            type: string
                          tag:
                            description: The Git tag to checkout, takes precedence
                              over Branch.
                            type: string
                        type: object
                    required:
                    - ref
                    type: object
                  commit:
                    description: Commit specifies how to commit to the git repository.
                    properties:
                      author:
                        description: Author gives the email and optionally the name
                          to use as the author of commits.
                        properties:
                          email:
                            description: Email gives the email to provide when making
                              a commit.
                            type: string
                          name:
                            description: Name gives the name to provide when making
                              a commit.
                            type: string
                        required:
                        - email
                        type: object
                      messageTemplate:
                        description: MessageTemplate provides a template for the commit
                          message, into which will be interpolated the details of
                          the change made.
                        type: string
                      signingKey:
                        description: SigningKey provides the option to sign commits
                          with a GPG key
                        properties:
                          secretRef:
                            description: SecretRef holds the name to a secret that
                              contains a 'git.asc' key corresponding to the ASCII
                              Armored file containing the GPG signing keypair as the
                              value. It must be in the same namespace as the ImageUpdateAutomation.
                            properties:
                              name:
                                description: Name of the referent
                                type: string
                            required:
                            - name
                            type: object
                        type: object
                    required:
                    - author
                    type: object
                  push:
                    description: Push specifies how and where to push commits made
                      by the automation. If missing, commits are pushed (back) to
                      `.spec.checkout.branch` or its default.
                    properties:
                      branch:
                        description: Branch specifies that commits should be pushed
                          to the branch named. The branch is created using `.spec.checkout.branch`
                          as the starting point, if it doesn't already exist.
                        type: string
                    required:
                    - branch
                    type: object
                required:
                - commit
                type: object
              interval:
                description: Interval gives an lower bound for how often the automation
                  run should be attempted.
                type: string
              sourceRef:
                description: SourceRef refers to the resource giving access details
                  to a git repository.
                properties:
                  apiVersion:
                    description: API version of the referent
                    type: string
                  kind:
                    default: GitRepository
                    description: Kind of the referent
                    enum:
                    - GitRepository
                    type: string
                  name:
                    description: Name of the referent
                    type: string
                required:
                - kind
                - name
                type: object
              suspend:
                description: Suspend tells the controller to not run this automation,
                  until it is unset (or set to false). Defaults to false.
                type: boolean
              update:
                default:
                  strategy: Setters
                description: Update gives the specification for how to update the
                  files in the repository. This can be left empty, to use the default
                  value.
                properties:
                  path:
                    description: Path to the directory containing the manifests to
                      be updated. Defaults to 'None', which translates to the root
                      path of the GitRepositoryRef.
                    type: string
                  strategy:
                    default: Setters
                    description: Strategy names the strategy to be used.
                    enum:
                    - Setters
                    type: string
                required:
                - strategy
                type: object
            required:
            - interval
            - sourceRef
            type: object
          status:
            description: ImageUpdateAutomationStatus defines the observed state of
              ImageUpdateAutomation
            properties:
              conditions:
                items:
                  description: "Condition contains details for one aspect of the current
                    state of this API Resource. --- This struct is intended for direct
                    use as an array at the field path .status.conditions.  For example,
                    type FooStatus struct{     // Represents the observations of a
                    foo's current state.     // Known .status.conditions.type are:
                    \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type
                    \    // +patchStrategy=merge     // +listType=map     // +listMapKey=type
                    \    Conditions []metav1.Condition `json:\"conditions,omitempty\"
                    patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
                    \n     // other fields }"
                  properties:
                    lastTransitionTime:
                      description: lastTransitionTime is the last time the condition
                        transitioned from one status to another. This should be when
                        the underlying condition changed.  If that is not known, then
                        using the time when the API field changed is acceptable.
                      format: date-time
                      type: string
                    message:
                      description: message is a human readable message indicating
                        details about the transition. This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: observedGeneration represents the .metadata.generation
                        that the condition was set based upon. For instance, if .metadata.generation
                        is currently 12, but the .status.conditions[x].observedGeneration
                        is 9, the condition is out of date with respect to the current
                        state of the instance.
                      format: int64
                      minimum: 0
                      type: integer
                    reason:
                      description: reason contains a programmatic identifier indicating
                        the reason for the condition's last transition. Producers
                        of specific condition types may define expected values and
                        meanings for this field, and whether the values are considered
                        a guaranteed API. The value should be a CamelCase string.
                        This field may not be empty.
                      maxLength: 1024
                      minLength: 1
                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
                      type: string
                    status:
                      description: status of the condition, one of True, False, Unknown.
                      enum:
                      - "True"
                      - "False"
                      - Unknown
                      type: string
                    type:
                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
                        --- Many .condition.type values are consistent across resources
                        like Available, but because arbitrary conditions can be useful
                        (see .node.status.conditions), the ability to deconflict is
                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
                      maxLength: 316
                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
                      type: string
                  required:
                  - lastTransitionTime
                  - message
                  - reason
                  - status
                  - type
                  type: object
                type: array
              lastAutomationRunTime:
                description: LastAutomationRunTime records the last time the controller
                  ran this automation through to completion (even if no updates were
                  made).
                format: date-time
                type: string
              lastHandledReconcileAt:
                description: LastHandledReconcileAt holds the value of the most recent
                  reconcile request value, so a change can be detected.
                type: string
              lastPushCommit:
                description: LastPushCommit records the SHA1 of the last commit made
                  by the controller, for this automation object
                type: string
              lastPushTime:
                description: LastPushTime records the time of the last pushed change.
                format: date-time
                type: string
              observedGeneration:
                format: int64
                type: integer
            type: object
        type: object
    served: true
    storage: false
    subresources:
      status: {}
  - additionalPrinterColumns:
    - jsonPath: .status.lastAutomationRunTime
      name: Last run
      type: string
    name: v1beta1
    schema:
      openAPIV3Schema:
        description: ImageUpdateAutomation is the Schema for the imageupdateautomations
          API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
            properties:
              git:
                description: GitSpec contains all the git-specific definitions. This
                  is technically optional, but in practice mandatory until there are
                  other kinds of source allowed.
                properties:
                  checkout:
                    description: Checkout gives the parameters for cloning the git
                      repository, ready to make changes. If not present, the `spec.ref`
                      field from the referenced `GitRepository` or its default will
                      be used.
                    properties:
                      ref:
                        description: Reference gives a branch, tag or commit to clone
                          from the Git repository.
                        properties:
                          branch:
                            description: The Git branch to checkout, defaults to master.
                            type: string
                          commit:
                            description: The Git commit SHA to checkout, if specified
                              Tag filters will be ignored.
                            type: string
                          semver:
                            description: The Git tag semver expression, takes precedence
                              over Tag.
                            type: string
                          tag:
                            description: The Git tag to checkout, takes precedence
                              over Branch.
                            type: string
                        type: object
                    required:
                    - ref
                    type: object
                  commit:
                    description: Commit specifies how to commit to the git repository.
                    properties:
                      author:
                        description: Author gives the email and optionally the name
                          to use as the author of commits.
                        properties:
                          email:
                            description: Email gives the email to provide when making
                              a commit.
                            type: string
                          name:
                            description: Name gives the name to provide when making
                              a commit.
                            type: string
                        required:
                        - email
                        type: object
                      messageTemplate:
                        description: MessageTemplate provides a template for the commit
                          message, into which will be interpolated the details of
                          the change made.
                        type: string
                      signingKey:
                        description: SigningKey provides the option to sign commits
                          with a GPG key
                        properties:
                          secretRef:
                            description: SecretRef holds the name to a secret that
                              contains a 'git.asc' key corresponding to the ASCII
                              Armored file containing the GPG signing keypair as the
                              value. It must be in the same namespace as the ImageUpdateAutomation.
                            properties:
                              name:
                                description: Name of the referent
                                type: string
                            required:
                            - name
                            type: object
                        type: object
                    required:
                    - author
                    type: object
                  push:
                    description: Push specifies how and where to push commits made
                      by the automation. If missing, commits are pushed (back) to
                      `.spec.checkout.branch` or its default.
                    properties:
                      branch:
                        description: Branch specifies that commits should be pushed
                          to the branch named. The branch is created using `.spec.checkout.branch`
                          as the starting point, if it doesn't already exist.
                        type: string
                    required:
                    - branch
                    type: object
                required:
                - commit
                type: object
              interval:
                description: Interval gives an lower bound for how often the automation
                  run should be attempted.
                type: string
              sourceRef:
                description: SourceRef refers to the resource giving access details
                  to a git repository.
                properties:
                  apiVersion:
                    description: API version of the referent
                    type: string
                  kind:
                    default: GitRepository
                    description: Kind of the referent
                    enum:
                    - GitRepository
                    type: string
                  name:
                    description: Name of the referent
                    type: string
                required:
                - kind
                - name
                type: object
              suspend:
                description: Suspend tells the controller to not run this automation,
                  until it is unset (or set to false). Defaults to false.
                type: boolean
              update:
                default:
                  strategy: Setters
                description: Update gives the specification for how to update the
                  files in the repository. This can be left empty, to use the default
                  value.
                properties:
                  path:
                    description: Path to the directory containing the manifests to
                      be updated. Defaults to 'None', which translates to the root
                      path of the GitRepositoryRef.
                    type: string
                  strategy:
                    default: Setters
                    description: Strategy names the strategy to be used.
                    enum:
                    - Setters
                    type: string
                required:
                - strategy
                type: object
            required:
            - interval
            - sourceRef
            type: object
          status:
            description: ImageUpdateAutomationStatus defines the observed state of
              ImageUpdateAutomation
            properties:
              conditions:
                items:
                  description: "Condition contains details for one aspect of the current
                    state of this API Resource. --- This struct is intended for direct
                    use as an array at the field path .status.conditions.  For example,
                    type FooStatus struct{     // Represents the observations of a
                    foo's current state.     // Known .status.conditions.type are:
                    \"Available\", \"Progressing\", and \"Degraded\"     // +patchMergeKey=type
                    \    // +patchStrategy=merge     // +listType=map     // +listMapKey=type
                    \    Conditions []metav1.Condition `json:\"conditions,omitempty\"
                    patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
                    \n     // other fields }"
                  properties:
                    lastTransitionTime:
                      description: lastTransitionTime is the last time the condition
                        transitioned from one status to another. This should be when
                        the underlying condition changed.  If that is not known, then
                        using the time when the API field changed is acceptable.
                      format: date-time
                      type: string
                    message:
                      description: message is a human readable message indicating
                        details about the transition. This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: observedGeneration represents the .metadata.generation
                        that the condition was set based upon. For instance, if .metadata.generation
                        is currently 12, but the .status.conditions[x].observedGeneration
                        is 9, the condition is out of date with respect to the current
                        state of the instance.
                      format: int64
                      minimum: 0
                      type: integer
                    reason:
                      description: reason contains a programmatic identifier indicating
                        the reason for the condition's last transition. Producers
                        of specific condition types may define expected values and
                        meanings for this field, and whether the values are considered
                        a guaranteed API. The value should be a CamelCase string.
                        This field may not be empty.
                      maxLength: 1024
                      minLength: 1
                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
                      type: string
                    status:
                      description: status of the condition, one of True, False, Unknown.
                      enum:
                      - "True"
                      - "False"
                      - Unknown
                      type: string
                    type:
                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
                        --- Many .condition.type values are consistent across resources
                        like Available, but because arbitrary conditions can be useful
                        (see .node.status.conditions), the ability to deconflict is
                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
                      maxLength: 316
                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
                      type: string
                  required:
                  - lastTransitionTime
                  - message
                  - reason
                  - status
                  - type
                  type: object
                type: array
              lastAutomationRunTime:
                description: LastAutomationRunTime records the last time the controller
                  ran this automation through to completion (even if no updates were
                  made).
                format: date-time
                type: string
              lastHandledReconcileAt:
                description: LastHandledReconcileAt holds the value of the most recent
                  reconcile request value, so a change can be detected.
                type: string
              lastPushCommit:
                description: LastPushCommit records the SHA1 of the last commit made
                  by the controller, for this automation object
                type: string
              lastPushTime:
                description: LastPushTime records the time of the last pushed change.
                format: date-time
                type: string
              observedGeneration:
                format: int64
                type: integer
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}
status:
  acceptedNames:
    kind: ImageUpdateAutomation
    listKind: ImageUpdateAutomationList
    plural: imageupdateautomations
    singular: imageupdateautomation
  conditions:
  - lastTransitionTime: "2022-02-09T20:58:20Z"
    message: no conflicts found
    reason: NoConflicts
    status: "True"
    type: NamesAccepted
  - lastTransitionTime: "2022-02-09T20:58:20Z"
    message: the initial names have been accepted
    reason: InitialNamesAccepted
    status: "True"
    type: Established
  storedVersions:
  - v1beta1
stefanprodan commented 2 years ago

Your cluster is way behind app.kubernetes.io/version: v0.24.1, you need to update to v0.26.2.

bob-rohan commented 2 years ago

Yep, fair point. The upgrade did get me past that issue thanks.

After many more refactoring, can confirm while your suggestion is very useful for those looking to run a single image policy per service per cluster, it does not work where there are many instances within the same cluster.

I had hoped that by refactoring the ImagePolicy, ImageRepository and ImageUpdateAutomation from flux-system namespace, to tenant environment namespace (<tenant>-staging, <tenant>-uat), I would be able to build on your idea of a common policy name.

However a better mind than mine would have noted without the need for two days refactoring, that the namespace is part of the inline image policy marker, and as such falls to the same merge issue described above.