Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creation timestamp set to invalid value "null" when using kustomize v5.0.0 #5031

Closed
abhay-krishna opened this issue Feb 3, 2023 · 20 comments
Assignees
Labels
kind/bug Categorizes issue or PR as related to a bug. priority/backlog Higher priority than priority/awaiting-more-evidence. triage/accepted Indicates an issue or PR is ready to be actively worked on. triage/resolved Indicates an issue has been resolved or doesn't need to be resolved.

Comments

@abhay-krishna
Copy link

abhay-krishna commented Feb 3, 2023

What happened?

I was trying to generate manifests for a cluster-api-provider project (tinkerbell/cluster-api-provider) and installed kustomize using the install_kustomize script. But the generated manifests had some spurious values for creationTimestamp

➜ kustomize version
v5.0.0
➜ kustomize build config/default | grep "creationTimestamp"
  creationTimestamp: "null"
  creationTimestamp: "null"
  creationTimestamp: "null"
  creationTimestamp: null
  creationTimestamp: null
  creationTimestamp: null

Note the quotes around null. This is causing issues when trying to parse time in a client-go applicatio.

Error: unable to convert unstructured object to apiextensions.k8s.io/v1, Kind=CustomResourceDefinition: parsing time "null" as "2006-01-02T15:04:05Z07:00": cannot parse "null" as "2006"

However I don't see this issue in an older version of kustomize.

➜ kustomize version
{Version:kustomize/v4.5.5 GitCommit:daa3e5e2c2d3a4b8c94021a7384bfb06734bcd26 BuildDate:2022-05-20T20:25:40Z GoOs:darwin GoArch:amd64}
➜ kustomize build config/default | grep "creationTimestamp"
  creationTimestamp: null
  creationTimestamp: null
  creationTimestamp: null

What did you expect to happen?

I expect that the generated manifest should conform to types of metav1.ObjectMeta where creationTimestamp is a Time object and not string, i.e., null instead of "null".

How can we reproduce it (as minimally and precisely as possible)?

kustomization.yaml under config/crd in https://github.com/tinkerbell/cluster-api-provider-tinkerbell. Commenting out some of the CRDs to reproduce minimally

# This kustomization.yaml is not intended to be run by itself,
# since it depends on service name and namespace that are out of this kustomize package.
# It should be run by config/default
commonLabels:
  cluster.x-k8s.io/v1beta1: v1beta1
resources:
- bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml
#- bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml  # THIS LINE HAS BEEN COMMENTED OUT FOR SAKE OF MINIMALITY
#- bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml  # THIS LINE HAS BEEN COMMENTED OUT FOR SAKE OF MINIMALITY
# +kubebuilder:scaffold:crdkustomizeresource

patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
- patches/webhook_in_tinkerbellclusters.yaml
#- patches/webhook_in_tinkerbellmachines.yaml
#- patches/webhook_in_tinkerbellmachinetemplates.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
- patches/cainjection_in_tinkerbellclusters.yaml
#- patches/cainjection_in_tinkerbellmachines.yaml
#- patches/cainjection_in_tinkerbellmachinetemplates.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch

# the following config is for teaching kustomize how to do kustomization for CRDs.
configurations:
- kustomizeconfig.yaml

bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml under config/crd in https://github.com/tinkerbell/cluster-api-provider-tinkerbell

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.10.0
  creationTimestamp: null
  name: tinkerbellclusters.infrastructure.cluster.x-k8s.io
spec:
  group: infrastructure.cluster.x-k8s.io
  names:
    categories:
    - cluster-api
    kind: TinkerbellCluster
    listKind: TinkerbellClusterList
    plural: tinkerbellclusters
    singular: tinkerbellcluster
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - description: Cluster to which this TinkerbellCluster belongs
      jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name
      name: Cluster
      type: string
    - description: TinkerbellCluster ready status
      jsonPath: .status.ready
      name: Ready
      type: string
    name: v1beta1
    schema:
      openAPIV3Schema:
        description: TinkerbellCluster is the Schema for the tinkerbellclusters 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: TinkerbellClusterSpec defines the desired state of TinkerbellCluster.
            properties:
              controlPlaneEndpoint:
                description: "ControlPlaneEndpoint is a required field by ClusterAPI
                  v1beta1. \n See https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html
                  for more details."
                properties:
                  host:
                    description: The hostname on which the API server is serving.
                    type: string
                  port:
                    description: The port on which the API server is serving.
                    format: int32
                    type: integer
                required:
                - host
                - port
                type: object
              imageLookupBaseRegistry:
                default: ghcr.io/tinkerbell/cluster-api-provider-tinkerbell
                description: ImageLookupBaseRegistry is the base Registry URL that
                  is used for pulling images, if not set, the default will be to use
                  ghcr.io/tinkerbell/cluster-api-provider-tinkerbell.
                type: string
              imageLookupFormat:
                description: 'ImageLookupFormat is the URL naming format to use for
                  machine images when a machine does not specify. When set, this will
                  be used for all cluster machines unless a machine specifies a different
                  ImageLookupFormat. Supports substitutions for {{.BaseRegistry}},
                  {{.OSDistro}}, {{.OSVersion}} and {{.KubernetesVersion}} with the
                  basse URL, OS distribution, OS version, and kubernetes version,
                  respectively. BaseRegistry will be the value in ImageLookupBaseRegistry
                  or ghcr.io/tinkerbell/cluster-api-provider-tinkerbell (the default),
                  OSDistro will be the value in ImageLookupOSDistro or ubuntu (the
                  default), OSVersion will be the value in ImageLookupOSVersion or
                  default based on the OSDistro (if known), and the kubernetes version
                  as defined by the packages produced by kubernetes/release: v1.13.0,
                  v1.12.5-mybuild.1, or v1.17.3. For example, the default image format
                  of {{.BaseRegistry}}/{{.OSDistro}}-{{.OSVersion}}:{{.KubernetesVersion}}.gz
                  will attempt to pull the image from that location. See also: https://golang.org/pkg/text/template/'
                type: string
              imageLookupOSDistro:
                default: ubuntu
                description: ImageLookupOSDistro is the name of the OS distro to use
                  when fetching machine images, if not set it will default to ubuntu.
                type: string
              imageLookupOSVersion:
                description: ImageLookupOSVersion is the version of the OS distribution
                  to use when fetching machine images. If not set it will default
                  based on ImageLookupOSDistro.
                type: string
            type: object
          status:
            description: TinkerbellClusterStatus defines the observed state of TinkerbellCluster.
            properties:
              ready:
                description: Ready denotes that the cluster (infrastructure) is ready.
                type: boolean
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}

Expected output

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
    controller-gen.kubebuilder.io/version: v0.10.0
  labels:
    cluster.x-k8s.io/v1beta1: v1beta1
  name: tinkerbellclusters.infrastructure.cluster.x-k8s.io
spec:
  conversion:
    strategy: Webhook
    webhook:
      clientConfig:
        caBundle: Cg==
        service:
          name: webhook-service
          namespace: system
          path: /convert
      conversionReviewVersions:
      - v1
      - v1beta1
  group: infrastructure.cluster.x-k8s.io
  names:
    categories:
    - cluster-api
    kind: TinkerbellCluster
    listKind: TinkerbellClusterList
    plural: tinkerbellclusters
    singular: tinkerbellcluster
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - description: Cluster to which this TinkerbellCluster belongs
      jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name
      name: Cluster
      type: string
    - description: TinkerbellCluster ready status
      jsonPath: .status.ready
      name: Ready
      type: string
    name: v1beta1
    schema:
      openAPIV3Schema:
        description: TinkerbellCluster is the Schema for the tinkerbellclusters 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: TinkerbellClusterSpec defines the desired state of TinkerbellCluster.
            properties:
              controlPlaneEndpoint:
                description: "ControlPlaneEndpoint is a required field by ClusterAPI
                  v1beta1. \n See https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html
                  for more details."
                properties:
                  host:
                    description: The hostname on which the API server is serving.
                    type: string
                  port:
                    description: The port on which the API server is serving.
                    format: int32
                    type: integer
                required:
                - host
                - port
                type: object
              imageLookupBaseRegistry:
                default: ghcr.io/tinkerbell/cluster-api-provider-tinkerbell
                description: ImageLookupBaseRegistry is the base Registry URL that
                  is used for pulling images, if not set, the default will be to use
                  ghcr.io/tinkerbell/cluster-api-provider-tinkerbell.
                type: string
              imageLookupFormat:
                description: 'ImageLookupFormat is the URL naming format to use for
                  machine images when a machine does not specify. When set, this will
                  be used for all cluster machines unless a machine specifies a different
                  ImageLookupFormat. Supports substitutions for {{.BaseRegistry}},
                  {{.OSDistro}}, {{.OSVersion}} and {{.KubernetesVersion}} with the
                  basse URL, OS distribution, OS version, and kubernetes version,
                  respectively. BaseRegistry will be the value in ImageLookupBaseRegistry
                  or ghcr.io/tinkerbell/cluster-api-provider-tinkerbell (the default),
                  OSDistro will be the value in ImageLookupOSDistro or ubuntu (the
                  default), OSVersion will be the value in ImageLookupOSVersion or
                  default based on the OSDistro (if known), and the kubernetes version
                  as defined by the packages produced by kubernetes/release: v1.13.0,
                  v1.12.5-mybuild.1, or v1.17.3. For example, the default image format
                  of {{.BaseRegistry}}/{{.OSDistro}}-{{.OSVersion}}:{{.KubernetesVersion}}.gz
                  will attempt to pull the image from that location. See also: https://golang.org/pkg/text/template/'
                type: string
              imageLookupOSDistro:
                default: ubuntu
                description: ImageLookupOSDistro is the name of the OS distro to use
                  when fetching machine images, if not set it will default to ubuntu.
                type: string
              imageLookupOSVersion:
                description: ImageLookupOSVersion is the version of the OS distribution
                  to use when fetching machine images. If not set it will default
                  based on ImageLookupOSDistro.
                type: string
            type: object
          status:
            description: TinkerbellClusterStatus defines the observed state of TinkerbellCluster.
            properties:
              ready:
                description: Ready denotes that the cluster (infrastructure) is ready.
                type: boolean
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}

Actual output

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
    controller-gen.kubebuilder.io/version: v0.10.0
  creationTimestamp: "null"
  labels:
    cluster.x-k8s.io/v1beta1: v1beta1
  name: tinkerbellclusters.infrastructure.cluster.x-k8s.io
spec:
  conversion:
    strategy: Webhook
    webhook:
      clientConfig:
        caBundle: Cg==
        service:
          name: webhook-service
          namespace: system
          path: /convert
      conversionReviewVersions:
      - v1
      - v1beta1
  group: infrastructure.cluster.x-k8s.io
  names:
    categories:
    - cluster-api
    kind: TinkerbellCluster
    listKind: TinkerbellClusterList
    plural: tinkerbellclusters
    singular: tinkerbellcluster
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - description: Cluster to which this TinkerbellCluster belongs
      jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name
      name: Cluster
      type: string
    - description: TinkerbellCluster ready status
      jsonPath: .status.ready
      name: Ready
      type: string
    name: v1beta1
    schema:
      openAPIV3Schema:
        description: TinkerbellCluster is the Schema for the tinkerbellclusters 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: TinkerbellClusterSpec defines the desired state of TinkerbellCluster.
            properties:
              controlPlaneEndpoint:
                description: "ControlPlaneEndpoint is a required field by ClusterAPI
                  v1beta1. \n See https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html
                  for more details."
                properties:
                  host:
                    description: The hostname on which the API server is serving.
                    type: string
                  port:
                    description: The port on which the API server is serving.
                    format: int32
                    type: integer
                required:
                - host
                - port
                type: object
              imageLookupBaseRegistry:
                default: ghcr.io/tinkerbell/cluster-api-provider-tinkerbell
                description: ImageLookupBaseRegistry is the base Registry URL that
                  is used for pulling images, if not set, the default will be to use
                  ghcr.io/tinkerbell/cluster-api-provider-tinkerbell.
                type: string
              imageLookupFormat:
                description: 'ImageLookupFormat is the URL naming format to use for
                  machine images when a machine does not specify. When set, this will
                  be used for all cluster machines unless a machine specifies a different
                  ImageLookupFormat. Supports substitutions for {{.BaseRegistry}},
                  {{.OSDistro}}, {{.OSVersion}} and {{.KubernetesVersion}} with the
                  basse URL, OS distribution, OS version, and kubernetes version,
                  respectively. BaseRegistry will be the value in ImageLookupBaseRegistry
                  or ghcr.io/tinkerbell/cluster-api-provider-tinkerbell (the default),
                  OSDistro will be the value in ImageLookupOSDistro or ubuntu (the
                  default), OSVersion will be the value in ImageLookupOSVersion or
                  default based on the OSDistro (if known), and the kubernetes version
                  as defined by the packages produced by kubernetes/release: v1.13.0,
                  v1.12.5-mybuild.1, or v1.17.3. For example, the default image format
                  of {{.BaseRegistry}}/{{.OSDistro}}-{{.OSVersion}}:{{.KubernetesVersion}}.gz
                  will attempt to pull the image from that location. See also: https://golang.org/pkg/text/template/'
                type: string
              imageLookupOSDistro:
                default: ubuntu
                description: ImageLookupOSDistro is the name of the OS distro to use
                  when fetching machine images, if not set it will default to ubuntu.
                type: string
              imageLookupOSVersion:
                description: ImageLookupOSVersion is the version of the OS distribution
                  to use when fetching machine images. If not set it will default
                  based on ImageLookupOSDistro.
                type: string
            type: object
          status:
            description: TinkerbellClusterStatus defines the observed state of TinkerbellCluster.
            properties:
              ready:
                description: Ready denotes that the cluster (infrastructure) is ready.
                type: boolean
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}

Comparing this with the expected output, the only difference is the addition of the creationTimestamp field in metadata, with the value of "null".

Kustomize version

v5.0.0

Operating system

MacOS

@abhay-krishna abhay-krishna added the kind/bug Categorizes issue or PR as related to a bug. label Feb 3, 2023
@k8s-ci-robot k8s-ci-robot added the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label Feb 3, 2023
@abhay-krishna abhay-krishna changed the title Creation timestamp set to "null" when running kustomize v5.0.0 Creation timestamp set to invalid value "null" when running kustomize v5.0.0 Feb 3, 2023
@abhay-krishna abhay-krishna changed the title Creation timestamp set to invalid value "null" when running kustomize v5.0.0 Creation timestamp set to invalid value "null" when using kustomize v5.0.0 Feb 3, 2023
@KnVerey
Copy link
Contributor

KnVerey commented Feb 3, 2023

I see that your original resource for the CRD includes the timestamp field in question, and previous version of Kustomize were stripping it out. The behaviour change comes from a bug we fixed in 5.0, where our Strategic Merge Patch implementation violated the spec by removing null values from original documents (whereas nulls only indicate removals when they are in the patch): #4628.

Please reopen if removing the null from the original document does not solve the problem.

/triage resolved
/close

@k8s-ci-robot k8s-ci-robot added the triage/resolved Indicates an issue has been resolved or doesn't need to be resolved. label Feb 3, 2023
@k8s-ci-robot k8s-ci-robot removed the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label Feb 3, 2023
@k8s-ci-robot
Copy link
Contributor

@KnVerey: Closing this issue.

In response to this:

I see that your original resource for the CRD includes the timestamp field in question, and previous version of Kustomize were stripping it out. The behaviour change comes from a bug we fixed in 5.0, where our Strategic Merge Patch implementation violated the spec by removing null values from original documents (whereas nulls only indicate removals when they are in the patch): #4628.

Please reopen if removing the null from the original document does not solve the problem.

/triage resolved
/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@abhay-krishna
Copy link
Author

@KnVerey Thanks for looking into this! Yes removing the creationTimestamp from the CRD did solve the issue. I saw the fix in #4890, but shouldn't it still preserve the original type of the object?

@KnVerey
Copy link
Contributor

KnVerey commented Feb 3, 2023

shouldn't it still preserve the original type of the object?

I agree, but I believe it does? In manual tests, I see either creationTimestamp: "null" or creationTimestamp: null, matching whatever was in the input.

@abhay-krishna
Copy link
Author

That's interesting. I observed that even though my original CRD base had creationTimestamp: null (above) but the one after kustomize build had creationTimestamp: "null".

@james-callahan
Copy link
Contributor

james-callahan commented Mar 21, 2023

I'm getting the same issue: a null is getting transformed by kustomize into the string "null".

I managed to make a minimal replication, it seems to take two patches to trigger:

mycrd.yaml:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: mycrd
  creationTimestamp: null
spec: {}

kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - mycrd.yaml
patches:
  - patch: |
      apiVersion: apiextensions.k8s.io/v1
      kind: CustomResourceDefinition
      metadata:
        name: mycrd
      # empty patch
  - patch: |
      apiVersion: apiextensions.k8s.io/v1
      kind: CustomResourceDefinition
      metadata:
        name: mycrd
      # empty patch

A kustomize build on that results in:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  creationTimestamp: "null"
  name: mycrd
spec: {}

Please reopen!

@nrvnrvn
Copy link

nrvnrvn commented Mar 24, 2023

Quote from the API machinery:

https://github.com/kubernetes/apimachinery/blob/8d1258da8f386b809d312cdda316366d5612f54e/pkg/apis/meta/v1/types.go#L179-L188

Two things here:

  1. What is the reason for changing files in place? It looks like a side effect to a build command which is unexpected.
  2. What is the rationale behind adding CreationTimestamps into manifests at all? The API spec clearly says that this field is Populated by the system. and Read-only.

Suggestion: remove CreationTimestamps injection from all resources.

Edit(answering my own questions):

I faced the issue in the context of kubebuilder. Has nothing to do with kustomize. contorller-gen is responsible for adding creationTimestamp: null to objects' metadata. And it is in turn coupled with kustomize in the Makefile... And creationTimestamp: null are added allegedly by client-go. kubectl create configmap --from-literal lol=woot -o yaml --dry-run lol will produce this field as well for instance and it is not supposed to be in any client-generated resources.

But the issue related to kustomize still stands. null type is converted to string type upon transformation.

@k8s-ci-robot
Copy link
Contributor

@nrvnrvn: You can't reopen an issue/PR unless you authored it or you are a collaborator.

In response to this:

Quote from the API machinery:

https://github.com/kubernetes/apimachinery/blob/8d1258da8f386b809d312cdda316366d5612f54e/pkg/apis/meta/v1/types.go#L179-L188

Two things here:

  1. What is the reason for changing files in place? It looks like a side effect to a build command which is unexpected.
  2. What is the rationale behind adding CreationTimestamps into manifests at all? The API spec clearly says that this field is Populated by the system. and Read-only.

Suggestion: remove CreationTimestamps injection from all resources.

/reopen

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@KnVerey
Copy link
Contributor

KnVerey commented Mar 27, 2023

/reopen
/triage accepted
/priority backlog

Thanks for the minimal example @james-callahan! I was able to reproduce with Kustomize 5.0.1. Please note that in addition to removing the timestamp from the source, another workaround that works is to delete it by including creationTimestamp: null in the patch.

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. priority/backlog Higher priority than priority/awaiting-more-evidence. labels Mar 27, 2023
@k8s-ci-robot k8s-ci-robot reopened this Mar 27, 2023
@k8s-ci-robot
Copy link
Contributor

@KnVerey: Reopened this issue.

In response to this:

/reopen
/triage accepted
/priority backlog

Thanks for the minimal example @james-callahan! I was able to reproduce with Kustomize 5.0.1. Please note that in addition to removing the timestamp from the source, another workaround that works is to delete it by including creationTimestamp: null in the patch.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@joelanford
Copy link
Member

joelanford commented Apr 21, 2023

For those that are coming from kubebuilder/operator-sdk/controller-gen, I have a PR up to remove metadata.creationTimestamp when controller-gen generates CRDs, RBAC, and webhooks: kubernetes-sigs/controller-tools#800

@jbury
Copy link

jbury commented Sep 2, 2023

Added a repro MR for anyone who wants to pick this up.

james-callahan added a commit to james-callahan/aws-load-balancer-controller that referenced this issue Sep 18, 2023
@shuheiktgw
Copy link

/assign

shuheiktgw pushed a commit to shuheiktgw/kustomize that referenced this issue Oct 9, 2023
matthewhughes934 added a commit to matthewhughes934/kustomize that referenced this issue Jan 28, 2024
Related issues:

* kubernetes-sigs#5031
* kubernetes-sigs#5171

After noting this behaviour was not present in
d89b448 a `git bisect` pointed to the
change 1b7db20. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a special flag node that is `null` but never
removed during merges. The added `TestApplySmPatch_Idempotency` test
verifies this behaviour. However, this approach  will may change the
value of the node in the output, e.g. if originally there was `field: ~`
it would be replaced by `field: null`. The added test case in
`kyaml/yaml/merge2/scalar_test.go` demonstrates this behaviour (this
test currently fails as I expect the desired outcome is to preserve the
null marker)

See also kubernetes-sigs#5365 for an
alternative approach
matthewhughes934 added a commit to matthewhughes934/kustomize that referenced this issue Jan 28, 2024
Related issues:

* kubernetes-sigs#5031
* kubernetes-sigs#5171

After noting this behaviour was not present in
d89b448 a `git bisect` pointed to the
change 1b7db20. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a special flag node that is `null` but never
removed during merges. The added `TestApplySmPatch_Idempotency` test
verifies this behaviour. However, this approach  will may change the
value of the node in the output, e.g. if originally there was `field: ~`
it would be replaced by `field: null`. The added test case in
`kyaml/yaml/merge2/scalar_test.go` demonstrates this behaviour (this
test currently fails as I expect the desired outcome is to preserve the
null marker)

See also kubernetes-sigs#5365 for an
alternative approach
james-callahan added a commit to james-callahan/aws-load-balancer-controller that referenced this issue Feb 20, 2024
matthewhughes934 added a commit to matthewhughes934/kustomize that referenced this issue Mar 5, 2024
Related issues:

* kubernetes-sigs#5031
* kubernetes-sigs#5171

After noting this behaviour was not present in
d89b448 a `git bisect` pointed to the
change 1b7db20. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a new attribute on `RNode`s that is checked before
clearing any node we should keep. The added
`TestApplySmPatch_Idempotency` test verifies this behaviour.

See also kubernetes-sigs#5365 for an
alternative approach
matthewhughes934 added a commit to matthewhughes934/kustomize that referenced this issue Mar 9, 2024
Related issues:

* kubernetes-sigs#5031
* kubernetes-sigs#5171

After noting this behaviour was not present in
d89b448 a `git bisect` pointed to the
change 1b7db20. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a new attribute on `RNode`s that is checked before
clearing any node we should keep. The added
`TestApplySmPatch_Idempotency` test verifies this behaviour.

See also kubernetes-sigs#5365 for an
alternative approach
@stormqueen1990
Copy link
Member

This should be fixed via #5519

/close

@k8s-ci-robot
Copy link
Contributor

@stormqueen1990: Closing this issue.

In response to this:

This should be fixed via #5519

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

antoooks pushed a commit to antoooks/kustomize that referenced this issue Mar 24, 2024
Related issues:

* kubernetes-sigs#5031
* kubernetes-sigs#5171

After noting this behaviour was not present in
d89b448 a `git bisect` pointed to the
change 1b7db20. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a new attribute on `RNode`s that is checked before
clearing any node we should keep. The added
`TestApplySmPatch_Idempotency` test verifies this behaviour.

See also kubernetes-sigs#5365 for an
alternative approach
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. priority/backlog Higher priority than priority/awaiting-more-evidence. triage/accepted Indicates an issue or PR is ready to be actively worked on. triage/resolved Indicates an issue has been resolved or doesn't need to be resolved.
Development

Successfully merging a pull request may close this issue.

9 participants