From 9661ee012c8c80f6df5cf865fc58fd2255ed4c0b Mon Sep 17 00:00:00 2001 From: yiraeChristineKim Date: Fri, 7 Mar 2025 10:46:52 -0500 Subject: [PATCH 1/2] Fix Issue with Mapping File Not Working MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dryrun worked when users didn't specify a mappings file. When users provide one, the dryrun didn't manually create the mappings file. It displays "Error: the resource version was not found for kind LimitRange: if this is a custom resource, it may need an entry in the mappings file" instead. Ref: https://issues.redhat.com/browse/ACM-18134 Signed-off-by: yiraeChristineKim (cherry picked from commit 1fd6fabd881552cd9cc60e88468414ce183a7aff) --- pkg/dryrun/dryrun_test.go | 8 +++++++ .../test_mappings/input_resource.yaml | 11 +++++++++ .../testdata/test_mappings/mappings.yaml | 12 ++++++++++ pkg/dryrun/testdata/test_mappings/output.txt | 5 ++++ pkg/dryrun/testdata/test_mappings/policy.yaml | 23 +++++++++++++++++++ pkg/mappings/mappings.go | 12 +++++----- 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 pkg/dryrun/testdata/test_mappings/input_resource.yaml create mode 100644 pkg/dryrun/testdata/test_mappings/mappings.yaml create mode 100644 pkg/dryrun/testdata/test_mappings/output.txt create mode 100644 pkg/dryrun/testdata/test_mappings/policy.yaml diff --git a/pkg/dryrun/dryrun_test.go b/pkg/dryrun/dryrun_test.go index 00f6d251..4de53f88 100644 --- a/pkg/dryrun/dryrun_test.go +++ b/pkg/dryrun/dryrun_test.go @@ -91,6 +91,14 @@ func cliTest(scenarioPath string) func(t *testing.T) { } } + mappingsPath := path.Join(scenarioPath, "mappings.yaml") + if PathExists(mappingsPath) { + err = cmd.Flags().Set("mappings-file", mappingsPath) + if err != nil { + t.Fatal(err) + } + } + err = cmd.Execute() if err != nil && !errors.Is(err, ErrNonCompliant) { t.Fatal(err) diff --git a/pkg/dryrun/testdata/test_mappings/input_resource.yaml b/pkg/dryrun/testdata/test_mappings/input_resource.yaml new file mode 100644 index 00000000..f5313cbd --- /dev/null +++ b/pkg/dryrun/testdata/test_mappings/input_resource.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange # limit memory usage +metadata: + name: mem-limit-range +spec: + limits: + - default: + memory: 512Mi + defaultRequest: + memory: 256Mi + type: Container diff --git a/pkg/dryrun/testdata/test_mappings/mappings.yaml b/pkg/dryrun/testdata/test_mappings/mappings.yaml new file mode 100644 index 00000000..abfd1fe8 --- /dev/null +++ b/pkg/dryrun/testdata/test_mappings/mappings.yaml @@ -0,0 +1,12 @@ +- Group: "" + Kind: LimitRange + Plural: limitranges + Scope: namespace + Singular: limitrange + Version: v1 +- Group: "" + Kind: Fake + Plural: fakes + Scope: root + Singular: fake + Version: beta1 diff --git a/pkg/dryrun/testdata/test_mappings/output.txt b/pkg/dryrun/testdata/test_mappings/output.txt new file mode 100644 index 00000000..e0bd57d5 --- /dev/null +++ b/pkg/dryrun/testdata/test_mappings/output.txt @@ -0,0 +1,5 @@ +# Diffs: +v1 LimitRange default/mem-limit-range: + +# Compliance messages: +Compliant; notification - limitranges [mem-limit-range] found as specified in namespace default diff --git a/pkg/dryrun/testdata/test_mappings/policy.yaml b/pkg/dryrun/testdata/test_mappings/policy.yaml new file mode 100644 index 00000000..08fcddb6 --- /dev/null +++ b/pkg/dryrun/testdata/test_mappings/policy.yaml @@ -0,0 +1,23 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: hello + namespace: default +spec: + remediationAction: enforce + namespaceSelector: + include: ["default"] + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: LimitRange # limit memory usage + metadata: + name: mem-limit-range + spec: + limits: + - default: + memory: 512Mi + defaultRequest: + memory: 256Mi + type: Container diff --git a/pkg/mappings/mappings.go b/pkg/mappings/mappings.go index 446cca4d..e8a88964 100644 --- a/pkg/mappings/mappings.go +++ b/pkg/mappings/mappings.go @@ -19,12 +19,12 @@ import ( // APIMapping stores information required for mapping between GroupVersionKinds // and GroupVersionResources, as well as whether the API is namespaced. type APIMapping struct { - Group string - Version string - Kind string - Singular string - Plural string - Scope Scope + Group string `yaml:"Group"` //nolint:tagliatelle + Version string `yaml:"Version"` //nolint:tagliatelle + Kind string `yaml:"Kind"` //nolint:tagliatelle + Singular string `yaml:"Singular"` //nolint:tagliatelle + Plural string `yaml:"Plural"` //nolint:tagliatelle + Scope Scope `yaml:"Scope"` //nolint:tagliatelle } func (a APIMapping) String() string { From 6ace6de3a7fed6f26b4ee787c1ab6ab30531b5af Mon Sep 17 00:00:00 2001 From: Dale Haiducek <19750917+dhaiducek@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:02:50 -0400 Subject: [PATCH 2/2] Use lowercase APIMapping Signed-off-by: Dale Haiducek <19750917+dhaiducek@users.noreply.github.com> (cherry picked from commit 0d84aeeea563064a485087f52fdc0380a4d516d8) --- pkg/dryrun/dryrun.go | 4 +- pkg/mappings/default-mappings.yaml | 709 ++++++++++++++--------------- pkg/mappings/mappings.go | 14 +- 3 files changed, 363 insertions(+), 364 deletions(-) diff --git a/pkg/dryrun/dryrun.go b/pkg/dryrun/dryrun.go index 1ea87c91..5d20feac 100644 --- a/pkg/dryrun/dryrun.go +++ b/pkg/dryrun/dryrun.go @@ -490,13 +490,13 @@ func (d *DryRunner) setupReconciler( } if d.mappingsPath != "" { - reader, err := os.Open(d.mappingsPath) + mFile, err := os.ReadFile(d.mappingsPath) if err != nil { return nil, err } apiMappings := []mappings.APIMapping{} - if err := yaml.NewDecoder(reader).Decode(&apiMappings); err != nil { + if err := k8syaml.Unmarshal(mFile, &apiMappings); err != nil { return nil, err } diff --git a/pkg/mappings/default-mappings.yaml b/pkg/mappings/default-mappings.yaml index 3c0772a2..d04ff3d4 100644 --- a/pkg/mappings/default-mappings.yaml +++ b/pkg/mappings/default-mappings.yaml @@ -1,355 +1,354 @@ -- Group: "" - Kind: Binding - Plural: bindings - Scope: namespace - Singular: binding - Version: v1 -- Group: "" - Kind: ComponentStatus - Plural: componentstatuses - Scope: root - Singular: componentstatus - Version: v1 -- Group: "" - Kind: ConfigMap - Plural: configmaps - Scope: namespace - Singular: configmap - Version: v1 -- Group: "" - Kind: Endpoints - Plural: endpoints - Scope: namespace - Singular: endpoints - Version: v1 -- Group: "" - Kind: Event - Plural: events - Scope: namespace - Singular: event - Version: v1 -- Group: "" - Kind: LimitRange - Plural: limitranges - Scope: namespace - Singular: limitrange - Version: v1 -- Group: "" - Kind: Namespace - Plural: namespaces - Scope: root - Singular: namespace - Version: v1 -- Group: "" - Kind: Node - Plural: nodes - Scope: root - Singular: node - Version: v1 -- Group: "" - Kind: PersistentVolumeClaim - Plural: persistentvolumeclaims - Scope: namespace - Singular: persistentvolumeclaim - Version: v1 -- Group: "" - Kind: PersistentVolume - Plural: persistentvolumes - Scope: root - Singular: persistentvolume - Version: v1 -- Group: "" - Kind: Pod - Plural: pods - Scope: namespace - Singular: pod - Version: v1 -- Group: "" - Kind: PodTemplate - Plural: podtemplates - Scope: namespace - Singular: podtemplate - Version: v1 -- Group: "" - Kind: ReplicationController - Plural: replicationcontrollers - Scope: namespace - Singular: replicationcontroller - Version: v1 -- Group: "" - Kind: ResourceQuota - Plural: resourcequotas - Scope: namespace - Singular: resourcequota - Version: v1 -- Group: "" - Kind: Secret - Plural: secrets - Scope: namespace - Singular: secret - Version: v1 -- Group: "" - Kind: ServiceAccount - Plural: serviceaccounts - Scope: namespace - Singular: serviceaccount - Version: v1 -- Group: "" - Kind: Service - Plural: services - Scope: namespace - Singular: service - Version: v1 -- Group: admissionregistration.k8s.io - Kind: MutatingWebhookConfiguration - Plural: mutatingwebhookconfigurations - Scope: root - Singular: mutatingwebhookconfiguration - Version: v1 -- Group: admissionregistration.k8s.io - Kind: ValidatingWebhookConfiguration - Plural: validatingwebhookconfigurations - Scope: root - Singular: validatingwebhookconfiguration - Version: v1 -- Group: apiextensions.k8s.io - Kind: CustomResourceDefinition - Plural: customresourcedefinitions - Scope: root - Singular: customresourcedefinition - Version: v1 -- Group: apiregistration.k8s.io - Kind: APIService - Plural: apiservices - Scope: root - Singular: apiservice - Version: v1 -- Group: apps - Kind: ControllerRevision - Plural: controllerrevisions - Scope: namespace - Singular: controllerrevision - Version: v1 -- Group: apps - Kind: DaemonSet - Plural: daemonsets - Scope: namespace - Singular: daemonset - Version: v1 -- Group: apps - Kind: Deployment - Plural: deployments - Scope: namespace - Singular: deployment - Version: v1 -- Group: apps - Kind: ReplicaSet - Plural: replicasets - Scope: namespace - Singular: replicaset - Version: v1 -- Group: apps - Kind: StatefulSet - Plural: statefulsets - Scope: namespace - Singular: statefulset - Version: v1 -- Group: authentication.k8s.io - Kind: SelfSubjectReview - Plural: selfsubjectreviews - Scope: root - Singular: selfsubjectreview - Version: v1 -- Group: authentication.k8s.io - Kind: TokenReview - Plural: tokenreviews - Scope: root - Singular: tokenreview - Version: v1 -- Group: authorization.k8s.io - Kind: LocalSubjectAccessReview - Plural: localsubjectaccessreviews - Scope: namespace - Singular: localsubjectaccessreview - Version: v1 -- Group: authorization.k8s.io - Kind: SelfSubjectAccessReview - Plural: selfsubjectaccessreviews - Scope: root - Singular: selfsubjectaccessreview - Version: v1 -- Group: authorization.k8s.io - Kind: SelfSubjectRulesReview - Plural: selfsubjectrulesreviews - Scope: root - Singular: selfsubjectrulesreview - Version: v1 -- Group: authorization.k8s.io - Kind: SubjectAccessReview - Plural: subjectaccessreviews - Scope: root - Singular: subjectaccessreview - Version: v1 -- Group: autoscaling - Kind: HorizontalPodAutoscaler - Plural: horizontalpodautoscalers - Scope: namespace - Singular: horizontalpodautoscaler - Version: v1 -- Group: autoscaling - Kind: HorizontalPodAutoscaler - Plural: horizontalpodautoscalers - Scope: namespace - Singular: horizontalpodautoscaler - Version: v2 -- Group: batch - Kind: CronJob - Plural: cronjobs - Scope: namespace - Singular: cronjob - Version: v1 -- Group: batch - Kind: Job - Plural: jobs - Scope: namespace - Singular: job - Version: v1 -- Group: certificates.k8s.io - Kind: CertificateSigningRequest - Plural: certificatesigningrequests - Scope: root - Singular: certificatesigningrequest - Version: v1 -- Group: coordination.k8s.io - Kind: Lease - Plural: leases - Scope: namespace - Singular: lease - Version: v1 -- Group: discovery.k8s.io - Kind: EndpointSlice - Plural: endpointslices - Scope: namespace - Singular: endpointslice - Version: v1 -- Group: events.k8s.io - Kind: Event - Plural: events - Scope: namespace - Singular: event - Version: v1 -- Group: flowcontrol.apiserver.k8s.io - Kind: FlowSchema - Plural: flowschemas - Scope: root - Singular: flowschema - Version: v1 -- Group: flowcontrol.apiserver.k8s.io - Kind: PriorityLevelConfiguration - Plural: prioritylevelconfigurations - Scope: root - Singular: prioritylevelconfiguration - Version: v1 -- Group: flowcontrol.apiserver.k8s.io - Kind: FlowSchema - Plural: flowschemas - Scope: root - Singular: flowschema - Version: v1beta3 -- Group: flowcontrol.apiserver.k8s.io - Kind: PriorityLevelConfiguration - Plural: prioritylevelconfigurations - Scope: root - Singular: prioritylevelconfiguration - Version: v1beta3 -- Group: networking.k8s.io - Kind: IngressClass - Plural: ingressclasses - Scope: root - Singular: ingressclass - Version: v1 -- Group: networking.k8s.io - Kind: Ingress - Plural: ingresses - Scope: namespace - Singular: ingress - Version: v1 -- Group: networking.k8s.io - Kind: NetworkPolicy - Plural: networkpolicies - Scope: namespace - Singular: networkpolicy - Version: v1 -- Group: node.k8s.io - Kind: RuntimeClass - Plural: runtimeclasses - Scope: root - Singular: runtimeclass - Version: v1 -- Group: policy - Kind: PodDisruptionBudget - Plural: poddisruptionbudgets - Scope: namespace - Singular: poddisruptionbudget - Version: v1 -- Group: rbac.authorization.k8s.io - Kind: ClusterRoleBinding - Plural: clusterrolebindings - Scope: root - Singular: clusterrolebinding - Version: v1 -- Group: rbac.authorization.k8s.io - Kind: ClusterRole - Plural: clusterroles - Scope: root - Singular: clusterrole - Version: v1 -- Group: rbac.authorization.k8s.io - Kind: RoleBinding - Plural: rolebindings - Scope: namespace - Singular: rolebinding - Version: v1 -- Group: rbac.authorization.k8s.io - Kind: Role - Plural: roles - Scope: namespace - Singular: role - Version: v1 -- Group: scheduling.k8s.io - Kind: PriorityClass - Plural: priorityclasses - Scope: root - Singular: priorityclass - Version: v1 -- Group: storage.k8s.io - Kind: CSIDriver - Plural: csidrivers - Scope: root - Singular: csidriver - Version: v1 -- Group: storage.k8s.io - Kind: CSINode - Plural: csinodes - Scope: root - Singular: csinode - Version: v1 -- Group: storage.k8s.io - Kind: CSIStorageCapacity - Plural: csistoragecapacities - Scope: namespace - Singular: csistoragecapacity - Version: v1 -- Group: storage.k8s.io - Kind: StorageClass - Plural: storageclasses - Scope: root - Singular: storageclass - Version: v1 -- Group: storage.k8s.io - Kind: VolumeAttachment - Plural: volumeattachments - Scope: root - Singular: volumeattachment - Version: v1 - +- group: "" + kind: Binding + plural: bindings + scope: namespace + singular: binding + version: v1 +- group: "" + kind: ComponentStatus + plural: componentstatuses + scope: root + singular: componentstatus + version: v1 +- group: "" + kind: ConfigMap + plural: configmaps + scope: namespace + singular: configmap + version: v1 +- group: "" + kind: Endpoints + plural: endpoints + scope: namespace + singular: endpoints + version: v1 +- group: "" + kind: Event + plural: events + scope: namespace + singular: event + version: v1 +- group: "" + kind: LimitRange + plural: limitranges + scope: namespace + singular: limitrange + version: v1 +- group: "" + kind: Namespace + plural: namespaces + scope: root + singular: namespace + version: v1 +- group: "" + kind: Node + plural: nodes + scope: root + singular: node + version: v1 +- group: "" + kind: PersistentVolumeClaim + plural: persistentvolumeclaims + scope: namespace + singular: persistentvolumeclaim + version: v1 +- group: "" + kind: PersistentVolume + plural: persistentvolumes + scope: root + singular: persistentvolume + version: v1 +- group: "" + kind: Pod + plural: pods + scope: namespace + singular: pod + version: v1 +- group: "" + kind: PodTemplate + plural: podtemplates + scope: namespace + singular: podtemplate + version: v1 +- group: "" + kind: ReplicationController + plural: replicationcontrollers + scope: namespace + singular: replicationcontroller + version: v1 +- group: "" + kind: ResourceQuota + plural: resourcequotas + scope: namespace + singular: resourcequota + version: v1 +- group: "" + kind: Secret + plural: secrets + scope: namespace + singular: secret + version: v1 +- group: "" + kind: ServiceAccount + plural: serviceaccounts + scope: namespace + singular: serviceaccount + version: v1 +- group: "" + kind: Service + plural: services + scope: namespace + singular: service + version: v1 +- group: admissionregistration.k8s.io + kind: MutatingWebhookConfiguration + plural: mutatingwebhookconfigurations + scope: root + singular: mutatingwebhookconfiguration + version: v1 +- group: admissionregistration.k8s.io + kind: ValidatingWebhookConfiguration + plural: validatingwebhookconfigurations + scope: root + singular: validatingwebhookconfiguration + version: v1 +- group: apiextensions.k8s.io + kind: CustomResourceDefinition + plural: customresourcedefinitions + scope: root + singular: customresourcedefinition + version: v1 +- group: apiregistration.k8s.io + kind: APIService + plural: apiservices + scope: root + singular: apiservice + version: v1 +- group: apps + kind: ControllerRevision + plural: controllerrevisions + scope: namespace + singular: controllerrevision + version: v1 +- group: apps + kind: DaemonSet + plural: daemonsets + scope: namespace + singular: daemonset + version: v1 +- group: apps + kind: Deployment + plural: deployments + scope: namespace + singular: deployment + version: v1 +- group: apps + kind: ReplicaSet + plural: replicasets + scope: namespace + singular: replicaset + version: v1 +- group: apps + kind: StatefulSet + plural: statefulsets + scope: namespace + singular: statefulset + version: v1 +- group: authentication.k8s.io + kind: SelfSubjectReview + plural: selfsubjectreviews + scope: root + singular: selfsubjectreview + version: v1 +- group: authentication.k8s.io + kind: TokenReview + plural: tokenreviews + scope: root + singular: tokenreview + version: v1 +- group: authorization.k8s.io + kind: LocalSubjectAccessReview + plural: localsubjectaccessreviews + scope: namespace + singular: localsubjectaccessreview + version: v1 +- group: authorization.k8s.io + kind: SelfSubjectAccessReview + plural: selfsubjectaccessreviews + scope: root + singular: selfsubjectaccessreview + version: v1 +- group: authorization.k8s.io + kind: SelfSubjectRulesReview + plural: selfsubjectrulesreviews + scope: root + singular: selfsubjectrulesreview + version: v1 +- group: authorization.k8s.io + kind: SubjectAccessReview + plural: subjectaccessreviews + scope: root + singular: subjectaccessreview + version: v1 +- group: autoscaling + kind: HorizontalPodAutoscaler + plural: horizontalpodautoscalers + scope: namespace + singular: horizontalpodautoscaler + version: v1 +- group: autoscaling + kind: HorizontalPodAutoscaler + plural: horizontalpodautoscalers + scope: namespace + singular: horizontalpodautoscaler + version: v2 +- group: batch + kind: CronJob + plural: cronjobs + scope: namespace + singular: cronjob + version: v1 +- group: batch + kind: Job + plural: jobs + scope: namespace + singular: job + version: v1 +- group: certificates.k8s.io + kind: CertificateSigningRequest + plural: certificatesigningrequests + scope: root + singular: certificatesigningrequest + version: v1 +- group: coordination.k8s.io + kind: Lease + plural: leases + scope: namespace + singular: lease + version: v1 +- group: discovery.k8s.io + kind: EndpointSlice + plural: endpointslices + scope: namespace + singular: endpointslice + version: v1 +- group: events.k8s.io + kind: Event + plural: events + scope: namespace + singular: event + version: v1 +- group: flowcontrol.apiserver.k8s.io + kind: FlowSchema + plural: flowschemas + scope: root + singular: flowschema + version: v1 +- group: flowcontrol.apiserver.k8s.io + kind: PriorityLevelConfiguration + plural: prioritylevelconfigurations + scope: root + singular: prioritylevelconfiguration + version: v1 +- group: flowcontrol.apiserver.k8s.io + kind: FlowSchema + plural: flowschemas + scope: root + singular: flowschema + version: v1beta3 +- group: flowcontrol.apiserver.k8s.io + kind: PriorityLevelConfiguration + plural: prioritylevelconfigurations + scope: root + singular: prioritylevelconfiguration + version: v1beta3 +- group: networking.k8s.io + kind: IngressClass + plural: ingressclasses + scope: root + singular: ingressclass + version: v1 +- group: networking.k8s.io + kind: Ingress + plural: ingresses + scope: namespace + singular: ingress + version: v1 +- group: networking.k8s.io + kind: NetworkPolicy + plural: networkpolicies + scope: namespace + singular: networkpolicy + version: v1 +- group: node.k8s.io + kind: RuntimeClass + plural: runtimeclasses + scope: root + singular: runtimeclass + version: v1 +- group: policy + kind: PodDisruptionBudget + plural: poddisruptionbudgets + scope: namespace + singular: poddisruptionbudget + version: v1 +- group: rbac.authorization.k8s.io + kind: ClusterRoleBinding + plural: clusterrolebindings + scope: root + singular: clusterrolebinding + version: v1 +- group: rbac.authorization.k8s.io + kind: ClusterRole + plural: clusterroles + scope: root + singular: clusterrole + version: v1 +- group: rbac.authorization.k8s.io + kind: RoleBinding + plural: rolebindings + scope: namespace + singular: rolebinding + version: v1 +- group: rbac.authorization.k8s.io + kind: Role + plural: roles + scope: namespace + singular: role + version: v1 +- group: scheduling.k8s.io + kind: PriorityClass + plural: priorityclasses + scope: root + singular: priorityclass + version: v1 +- group: storage.k8s.io + kind: CSIDriver + plural: csidrivers + scope: root + singular: csidriver + version: v1 +- group: storage.k8s.io + kind: CSINode + plural: csinodes + scope: root + singular: csinode + version: v1 +- group: storage.k8s.io + kind: CSIStorageCapacity + plural: csistoragecapacities + scope: namespace + singular: csistoragecapacity + version: v1 +- group: storage.k8s.io + kind: StorageClass + plural: storageclasses + scope: root + singular: storageclass + version: v1 +- group: storage.k8s.io + kind: VolumeAttachment + plural: volumeattachments + scope: root + singular: volumeattachment + version: v1 diff --git a/pkg/mappings/mappings.go b/pkg/mappings/mappings.go index e8a88964..266852e1 100644 --- a/pkg/mappings/mappings.go +++ b/pkg/mappings/mappings.go @@ -19,12 +19,12 @@ import ( // APIMapping stores information required for mapping between GroupVersionKinds // and GroupVersionResources, as well as whether the API is namespaced. type APIMapping struct { - Group string `yaml:"Group"` //nolint:tagliatelle - Version string `yaml:"Version"` //nolint:tagliatelle - Kind string `yaml:"Kind"` //nolint:tagliatelle - Singular string `yaml:"Singular"` //nolint:tagliatelle - Plural string `yaml:"Plural"` //nolint:tagliatelle - Scope Scope `yaml:"Scope"` //nolint:tagliatelle + Group string `json:"group"` + Version string `json:"version"` + Kind string `json:"kind"` + Singular string `json:"singular"` + Plural string `json:"plural"` + Scope Scope `json:"scope"` } func (a APIMapping) String() string { @@ -140,7 +140,7 @@ func GenerateMappings(cmd *cobra.Command, _ []string) error { return err } - cmd.Println(string(out)) + cmd.Print(string(out)) return nil }