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

Fix provider handling of CustomResources with Patch suffix #2438

Merged
merged 5 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Unreleased

- Fix provider handling of CustomResources with Patch suffix (https://github.com/pulumi/pulumi-kubernetes/pull/2438)

## 3.29.0 (June 2, 2023)

- Fix regression in file/folder checking logic that caused incorrect parsing of compressed chart files (https://github.com/pulumi/pulumi-kubernetes/pull/2428)
Expand Down
5 changes: 3 additions & 2 deletions provider/cmd/pulumi-gen-kubernetes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func mustRenderGoTemplate(path string, resources interface{}) []byte {
}

func genK8sResourceTypes(pkg *schema.Package) {
groupVersions, kinds := codegen.NewStringSet(), codegen.NewStringSet()
groupVersions, kinds, patchKinds := codegen.NewStringSet(), codegen.NewStringSet(), codegen.NewStringSet()
for _, resource := range pkg.Resources {
if resourcesToFilterFromTemplate.Has(resource.Token) {
continue
Expand All @@ -460,14 +460,15 @@ func genK8sResourceTypes(pkg *schema.Package) {
continue
}
if strings.HasSuffix(kind, "Patch") {
patchKinds.Add(resource.Token)
continue
}

groupVersions.Add(groupVersion)
kinds.Add(kind)
}

gvk := gen.GVK{Kinds: kinds.SortedValues()}
gvk := gen.GVK{Kinds: kinds.SortedValues(), PatchKinds: patchKinds.SortedValues()}
gvStrings := groupVersions.SortedValues()
for _, gvString := range gvStrings {
gvk.GroupVersions = append(gvk.GroupVersions, gen.GroupVersion(gvString))
Expand Down
3 changes: 1 addition & 2 deletions provider/pkg/await/await.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"fmt"
"os"
"regexp"
"strings"

"github.com/pulumi/pulumi-kubernetes/provider/v3/pkg/clients"
"github.com/pulumi/pulumi-kubernetes/provider/v3/pkg/cluster"
Expand Down Expand Up @@ -576,7 +575,7 @@ func Deletion(c DeleteConfig) error {
return nilIfGVKDeleted(err)
}

patchResource := strings.HasSuffix(c.URN.Type().String(), "Patch")
patchResource := kinds.PatchQualifiedTypes.Has(c.URN.QualifiedType().String())
if c.ServerSideApply && patchResource {
err = ssa.Relinquish(c.Context, client, c.Inputs, c.FieldManager)
return err
Expand Down
8 changes: 8 additions & 0 deletions provider/pkg/gen/kinds/kinds.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,11 @@ var KnownGroupVersions = codegen.NewStringSet(
{{- end}}
"v1", // alias for "core/v1"
)

// PatchQualifiedTypes is the set of "Patch" resource QualifiedType URN tokens. Checking against this known set rather
// than using the Patch suffix avoids unintended clashes with CustomResources that also contain a Patch suffix.
var PatchQualifiedTypes = codegen.NewStringSet(
{{- range .PatchKinds}}
"{{.}}",
{{- end}}
)
1 change: 1 addition & 0 deletions provider/pkg/gen/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func (tr GoTemplateResources) Imports() []string {
type GVK struct {
GroupVersions []GroupVersion
Kinds []string
PatchKinds []string
}

// GroupVersion is the GroupVersion for a k8s resource.
Expand Down
125 changes: 125 additions & 0 deletions provider/pkg/kinds/kinds.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,128 @@ var KnownGroupVersions = codegen.NewStringSet(
"storage.k8s.io/v1beta1",
"v1", // alias for "core/v1"
)

// PatchQualifiedTypes is the set of "Patch" resource QualifiedType URN tokens. Checking against this known set rather
// than using the Patch suffix avoids unintended clashes with CustomResources that also contain a Patch suffix.
var PatchQualifiedTypes = codegen.NewStringSet(
"kubernetes:admissionregistration.k8s.io/v1:MutatingWebhookConfigurationPatch",
"kubernetes:admissionregistration.k8s.io/v1:ValidatingWebhookConfigurationPatch",
"kubernetes:admissionregistration.k8s.io/v1alpha1:ValidatingAdmissionPolicyBindingPatch",
"kubernetes:admissionregistration.k8s.io/v1alpha1:ValidatingAdmissionPolicyPatch",
"kubernetes:admissionregistration.k8s.io/v1beta1:MutatingWebhookConfigurationPatch",
"kubernetes:admissionregistration.k8s.io/v1beta1:ValidatingWebhookConfigurationPatch",
"kubernetes:apiextensions.k8s.io/v1:CustomResourceDefinitionPatch",
"kubernetes:apiextensions.k8s.io/v1beta1:CustomResourceDefinitionPatch",
"kubernetes:apiregistration.k8s.io/v1:APIServicePatch",
"kubernetes:apiregistration.k8s.io/v1beta1:APIServicePatch",
"kubernetes:apps/v1:ControllerRevisionPatch",
"kubernetes:apps/v1:DaemonSetPatch",
"kubernetes:apps/v1:DeploymentPatch",
"kubernetes:apps/v1:ReplicaSetPatch",
"kubernetes:apps/v1:StatefulSetPatch",
"kubernetes:apps/v1beta1:ControllerRevisionPatch",
"kubernetes:apps/v1beta1:DeploymentPatch",
"kubernetes:apps/v1beta1:StatefulSetPatch",
"kubernetes:apps/v1beta2:ControllerRevisionPatch",
"kubernetes:apps/v1beta2:DaemonSetPatch",
"kubernetes:apps/v1beta2:DeploymentPatch",
"kubernetes:apps/v1beta2:ReplicaSetPatch",
"kubernetes:apps/v1beta2:StatefulSetPatch",
"kubernetes:auditregistration.k8s.io/v1alpha1:AuditSinkPatch",
"kubernetes:autoscaling/v1:HorizontalPodAutoscalerPatch",
"kubernetes:autoscaling/v2:HorizontalPodAutoscalerPatch",
"kubernetes:autoscaling/v2beta1:HorizontalPodAutoscalerPatch",
"kubernetes:autoscaling/v2beta2:HorizontalPodAutoscalerPatch",
"kubernetes:batch/v1:CronJobPatch",
"kubernetes:batch/v1:JobPatch",
"kubernetes:batch/v1beta1:CronJobPatch",
"kubernetes:batch/v2alpha1:CronJobPatch",
"kubernetes:certificates.k8s.io/v1:CertificateSigningRequestPatch",
"kubernetes:certificates.k8s.io/v1alpha1:ClusterTrustBundlePatch",
"kubernetes:certificates.k8s.io/v1beta1:CertificateSigningRequestPatch",
"kubernetes:coordination.k8s.io/v1:LeasePatch",
"kubernetes:coordination.k8s.io/v1beta1:LeasePatch",
"kubernetes:core/v1:BindingPatch",
"kubernetes:core/v1:ConfigMapPatch",
"kubernetes:core/v1:EndpointsPatch",
"kubernetes:core/v1:EventPatch",
"kubernetes:core/v1:LimitRangePatch",
"kubernetes:core/v1:NamespacePatch",
"kubernetes:core/v1:NodePatch",
"kubernetes:core/v1:PersistentVolumeClaimPatch",
"kubernetes:core/v1:PersistentVolumePatch",
"kubernetes:core/v1:PodPatch",
"kubernetes:core/v1:PodTemplatePatch",
"kubernetes:core/v1:ReplicationControllerPatch",
"kubernetes:core/v1:ResourceQuotaPatch",
"kubernetes:core/v1:SecretPatch",
"kubernetes:core/v1:ServiceAccountPatch",
"kubernetes:core/v1:ServicePatch",
"kubernetes:discovery.k8s.io/v1:EndpointSlicePatch",
"kubernetes:discovery.k8s.io/v1beta1:EndpointSlicePatch",
"kubernetes:events.k8s.io/v1:EventPatch",
"kubernetes:events.k8s.io/v1beta1:EventPatch",
"kubernetes:extensions/v1beta1:DaemonSetPatch",
"kubernetes:extensions/v1beta1:DeploymentPatch",
"kubernetes:extensions/v1beta1:IngressPatch",
"kubernetes:extensions/v1beta1:NetworkPolicyPatch",
"kubernetes:extensions/v1beta1:PodSecurityPolicyPatch",
"kubernetes:extensions/v1beta1:ReplicaSetPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1alpha1:FlowSchemaPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1alpha1:PriorityLevelConfigurationPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta1:FlowSchemaPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta1:PriorityLevelConfigurationPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta2:FlowSchemaPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta2:PriorityLevelConfigurationPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta3:FlowSchemaPatch",
"kubernetes:flowcontrol.apiserver.k8s.io/v1beta3:PriorityLevelConfigurationPatch",
"kubernetes:meta/v1:StatusPatch",
"kubernetes:networking.k8s.io/v1:IngressClassPatch",
"kubernetes:networking.k8s.io/v1:IngressPatch",
"kubernetes:networking.k8s.io/v1:NetworkPolicyPatch",
"kubernetes:networking.k8s.io/v1alpha1:ClusterCIDRPatch",
"kubernetes:networking.k8s.io/v1alpha1:IPAddressPatch",
"kubernetes:networking.k8s.io/v1beta1:IngressClassPatch",
"kubernetes:networking.k8s.io/v1beta1:IngressPatch",
"kubernetes:node.k8s.io/v1:RuntimeClassPatch",
"kubernetes:node.k8s.io/v1alpha1:RuntimeClassPatch",
"kubernetes:node.k8s.io/v1beta1:RuntimeClassPatch",
"kubernetes:policy/v1:PodDisruptionBudgetPatch",
"kubernetes:policy/v1beta1:PodDisruptionBudgetPatch",
"kubernetes:policy/v1beta1:PodSecurityPolicyPatch",
"kubernetes:rbac.authorization.k8s.io/v1:ClusterRoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1:ClusterRolePatch",
"kubernetes:rbac.authorization.k8s.io/v1:RoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1:RolePatch",
"kubernetes:rbac.authorization.k8s.io/v1alpha1:ClusterRoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1alpha1:ClusterRolePatch",
"kubernetes:rbac.authorization.k8s.io/v1alpha1:RoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1alpha1:RolePatch",
"kubernetes:rbac.authorization.k8s.io/v1beta1:ClusterRoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1beta1:ClusterRolePatch",
"kubernetes:rbac.authorization.k8s.io/v1beta1:RoleBindingPatch",
"kubernetes:rbac.authorization.k8s.io/v1beta1:RolePatch",
"kubernetes:resource.k8s.io/v1alpha1:PodSchedulingPatch",
"kubernetes:resource.k8s.io/v1alpha1:ResourceClaimPatch",
"kubernetes:resource.k8s.io/v1alpha1:ResourceClaimTemplatePatch",
"kubernetes:resource.k8s.io/v1alpha1:ResourceClassPatch",
"kubernetes:resource.k8s.io/v1alpha2:PodSchedulingContextPatch",
"kubernetes:resource.k8s.io/v1alpha2:ResourceClaimPatch",
"kubernetes:resource.k8s.io/v1alpha2:ResourceClaimTemplatePatch",
"kubernetes:resource.k8s.io/v1alpha2:ResourceClassPatch",
"kubernetes:scheduling.k8s.io/v1:PriorityClassPatch",
"kubernetes:scheduling.k8s.io/v1alpha1:PriorityClassPatch",
"kubernetes:scheduling.k8s.io/v1beta1:PriorityClassPatch",
"kubernetes:settings.k8s.io/v1alpha1:PodPresetPatch",
"kubernetes:storage.k8s.io/v1:CSIDriverPatch",
"kubernetes:storage.k8s.io/v1:CSINodePatch",
"kubernetes:storage.k8s.io/v1:CSIStorageCapacityPatch",
"kubernetes:storage.k8s.io/v1:StorageClassPatch",
"kubernetes:storage.k8s.io/v1:VolumeAttachmentPatch",
"kubernetes:storage.k8s.io/v1alpha1:VolumeAttachmentPatch",
"kubernetes:storage.k8s.io/v1beta1:CSIDriverPatch",
"kubernetes:storage.k8s.io/v1beta1:CSINodePatch",
"kubernetes:storage.k8s.io/v1beta1:CSIStorageCapacityPatch",
"kubernetes:storage.k8s.io/v1beta1:StorageClassPatch",
"kubernetes:storage.k8s.io/v1beta1:VolumeAttachmentPatch",
)
2 changes: 1 addition & 1 deletion provider/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2536,7 +2536,7 @@ func (k *kubeProvider) Delete(ctx context.Context, req *pulumirpc.DeleteRequest)

// isPatchURN returns true if the URN is for a Patch resource.
func isPatchURN(urn resource.URN) bool {
return strings.HasSuffix(urn.Type().String(), "Patch")
return kinds.PatchQualifiedTypes.Has(urn.QualifiedType().String())
}

// GetPluginInfo returns generic information about this plugin, like its version.
Expand Down
38 changes: 38 additions & 0 deletions provider/pkg/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,41 @@ func Test_equalNumbers(t *testing.T) {
})
}
}

func Test_isPatchURN(t *testing.T) {
type args struct {
urn resource.URN
}
tests := []struct {
name string
args args
want bool
}{
{
name: "patch URN",
args: args{
urn: resource.NewURN("test", "test", "", "kubernetes:apps/v1:DeploymentPatch", "test"),
},
want: true,
},
{
name: "regular URN",
args: args{
urn: resource.NewURN("test", "test", "", "kubernetes:apps/v1:Deployment", "test"),
},
want: false,
},
{
name: "CustomResource with Patch suffix",
args: args{
urn: resource.NewURN("test", "test", "", "kubernetes:kuma.io/v1alpha1:MeshProxyPatch", "test"),
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, isPatchURN(tt.args.urn), "isPatchURN(%v)", tt.args.urn)
})
}
}