Skip to content

Commit 6c8dee4

Browse files
committed
fix: check REST scope before setting namespace on resources
GetClientByGroupVersionKind now returns RESTMapping to allow callers to properly determine if a resource is cluster-scoped. Apply() uses this to only set namespace on namespaced resources, fixing 404 errors when applying CRDs and other cluster-scoped resources.
1 parent 1a4d84e commit 6c8dee4

2 files changed

Lines changed: 14 additions & 13 deletions

File tree

connection/cnrm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func (t *CNRMConnection) KubernetesClient(ctx context.Context, freshToken bool)
3131
return nil, nil, fmt.Errorf("failed to create Kubernetes client for GKE: %w", err)
3232
}
3333

34-
containerResourceKubeClient, err := dutyKube.NewKubeClient(ctx.Logger, cnrmCluster, restConfig).
34+
containerResourceKubeClient, _, err := dutyKube.NewKubeClient(ctx.Logger, cnrmCluster, restConfig).
3535
GetClientByGroupVersionKind(ctx, "container.cnrm.cloud.google.com", "v1beta1", "ContainerCluster")
3636
if err != nil {
3737
return nil, nil, fmt.Errorf("failed to get client by GroupVersionKind: %w", err)

kubernetes/dynamic.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (c *Client) FetchResources(
9595
items := make(chan unstructured.Unstructured, len(resources))
9696
for i := range resources {
9797
resource := resources[i]
98-
client, err := c.GetClientByGroupVersionKind(
98+
client, _, err := c.GetClientByGroupVersionKind(
9999
ctx,
100100
resource.GroupVersionKind().Group,
101101
resource.GroupVersionKind().Version,
@@ -126,15 +126,15 @@ func (c *Client) FetchResources(
126126

127127
func (c *Client) GetClientByGroupVersionKind(
128128
ctx context.Context, group, version, kind string,
129-
) (dynamic.NamespaceableResourceInterface, error) {
129+
) (dynamic.NamespaceableResourceInterface, *meta.RESTMapping, error) {
130130
dynamicClient, err := c.GetDynamicClient()
131131
if err != nil {
132-
return nil, err
132+
return nil, nil, err
133133
}
134134

135135
cacheKey := group + version + kind
136136
if res, err := c.gvkClientResourceCache.Get(ctx, cacheKey); err == nil {
137-
return dynamicClient.Resource(res.gvr), nil
137+
return dynamicClient.Resource(res.gvr), res.mapping, nil
138138
}
139139

140140
rm, _ := c.GetRestMapper()
@@ -144,17 +144,17 @@ func (c *Client) GetClientByGroupVersionKind(
144144
Version: version,
145145
})
146146
if err != nil {
147-
return nil, err
147+
return nil, nil, err
148148
}
149149

150150
gk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
151151
mapping, err := rm.RESTMapping(gk, gvk.Version)
152152
if err != nil {
153-
return nil, err
153+
return nil, nil, err
154154
}
155155

156156
_ = c.gvkClientResourceCache.Set(ctx, cacheKey, gvkClientResourceCacheValue{gvr: mapping.Resource, mapping: mapping})
157-
return dynamicClient.Resource(mapping.Resource), nil
157+
return dynamicClient.Resource(mapping.Resource), mapping, nil
158158
}
159159

160160
func (c *Client) RestConfig() *rest.Config {
@@ -226,7 +226,7 @@ func (c *Client) GetClientByKind(kind string) (dynamic.NamespaceableResourceInte
226226
}
227227

228228
func (c *Client) DeleteByGVK(ctx context.Context, namespace, name string, gvk schema.GroupVersionKind) (bool, error) {
229-
client, err := c.GetClientByGroupVersionKind(ctx, gvk.Group, gvk.Version, gvk.Kind)
229+
client, _, err := c.GetClientByGroupVersionKind(ctx, gvk.Group, gvk.Version, gvk.Kind)
230230
if err != nil {
231231
return false, err
232232
}
@@ -824,14 +824,15 @@ func (c *Client) Apply(ctx context.Context, manifest string) (Resources, error)
824824
}
825825

826826
for _, o := range in {
827-
if !strings.HasPrefix(o.GetKind(), "Cluster") {
828-
o.SetNamespace(c.defaultNamespace)
829-
}
830827
c.logger.Infof("Applying %s", NewResources(o).Pretty().ANSI())
831-
dynClient, err := c.GetClientByGroupVersionKind(ctx, o.GroupVersionKind().Group, o.GroupVersionKind().Version, o.GetKind())
828+
dynClient, mapping, err := c.GetClientByGroupVersionKind(ctx, o.GroupVersionKind().Group, o.GroupVersionKind().Version, o.GetKind())
832829
if err != nil {
833830
return nil, fmt.Errorf("Failed to get client for %s/%s/%s", o.GroupVersionKind().Group, o.GroupVersionKind().Version, o.GetKind())
834831
}
832+
// Only set namespace for namespaced resources that don't already have one
833+
if mapping.Scope.Name() == meta.RESTScopeNameNamespace && o.GetNamespace() == "" {
834+
o.SetNamespace(c.defaultNamespace)
835+
}
835836
saved, err := dynClient.Namespace(o.GetNamespace()).Apply(ctx, o.GetName(), &o, metav1.ApplyOptions{
836837
FieldManager: "flanksource-commons",
837838
})

0 commit comments

Comments
 (0)