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

prune cluster scoped resources does not work when specify namespace in app config #4269

Open
kevin-namba opened this issue Mar 15, 2023 · 9 comments
Assignees
Labels
kind/bug Something isn't working

Comments

@kevin-namba
Copy link
Contributor

What happened:
prune cluster scoped resources (such as clusterrole) does not work when specify namespace in app config

What you expected to happen:

How to reproduce it:

Environment:

  • piped version:
  • control-plane version:
  • Others:
@ffjlabo
Copy link
Member

ffjlabo commented Mar 28, 2024

Reproduced on QuickSync like this↓ (name: pod-reader)

[result]

before

% k get clusterrole                                                                          (git)-[delete-cluster-role]
NAME                                                                   CREATED AT
admin                                                                  2024-03-25T07:29:57Z
cluster-admin                                                          2024-03-25T07:29:56Z
edit                                                                   2024-03-25T07:29:57Z
kindnet                                                                2024-03-25T07:30:01Z
kubeadm:get-nodes                                                      2024-03-25T07:29:58Z
local-path-provisioner-role                                            2024-03-25T07:30:02Z
pod-reader                                                             2024-03-28T09:37:08Z
system:aggregate-to-admin                                              2024-03-25T07:29:57Z

after

% k get clusterrole                                                                                 (git)-[delete-cluster-role]
NAME                                                                   CREATED AT
admin                                                                  2024-03-25T07:29:57Z
cluster-admin                                                          2024-03-25T07:29:56Z
edit                                                                   2024-03-25T07:29:57Z
kindnet                                                                2024-03-25T07:30:01Z
kubeadm:get-nodes                                                      2024-03-25T07:29:58Z
local-path-provisioner-role                                            2024-03-25T07:30:02Z
pod-reader                                                             2024-03-28T09:37:08Z
system:aggregate-to-admin                                              2024-03-25T07:29:57Z

Image

[sample]

apiVersion: pipecd.dev/v1beta1
kind: KubernetesApp
spec:
  name: clusterrole-test
  input:
    namespace: test
  labels:
    env: clusterrole-test
    team: product
  quickSync:
    prune: true
  description: |
    This is a test app for clusterrole. Especially for testing the prune on QuickSync.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
  annotations:
    pipecd.dev/order: "1"
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
apiVersion: v1
kind: Namespace
metadata:
  name: test
  labels:
    name: test
  annotations:
    pipecd.dev/order: "0"

@ffjlabo
Copy link
Member

ffjlabo commented Mar 28, 2024

This might happen because the resource key in the live resource differs from the resource used when pruning.

  • The actual resource key: rbac.authorization.k8s.io/v1:ClusterRole:test:pod-reader
  • The one used when pruning: rbac.authorization.k8s.io/v1:ClusterRole:default:pod-reader (estimated by the code below)

Image

Image

@ffjlabo
Copy link
Member

ffjlabo commented Mar 28, 2024

As this PR #3991, all of the resources for the application belong to the namespace set on the spec.input.namespace in app.pipecd.yaml.
So in PipeCD, the ClusterRole resource is also treated as the one which belong the namespace.

@ffjlabo
Copy link
Member

ffjlabo commented Apr 2, 2024

Root cause:

the resource key stored as livestate and the one on the annotation of actual k8s resource are different values, but actually, they are compared as if they are equal.

The Code:

if k.String() != m.GetAnnotations()[LabelResourceKey] {
return ErrNotFound
}

Details

The resource key stored as livestate

  • created by the livestatestre.reflector after applying
  • based on the actual k8s resource on the cluster with MakeResourceKey
    func MakeResourceKey(obj *unstructured.Unstructured) ResourceKey {
    k := ResourceKey{
    APIVersion: obj.GetAPIVersion(),
    Kind: obj.GetKind(),
    Namespace: obj.GetNamespace(),
    Name: obj.GetName(),
    }
    if k.Namespace == "" {
    k.Namespace = DefaultNamespace
    }
    return k
    }
More details

The resource key on the annotation of actual k8s resource

  • created by before applying
  • based on the k8s resource manifest, then fixed by app.pipecd.yaml (spec.input.namespace)
More details

Example:

Consider the case to apply ClusterRole

@ffjlabo
Copy link
Member

ffjlabo commented Apr 3, 2024

Solution candidates

The point is whether to fix or not as if they are equal.

  1. fix not to compare them. (they are not equal)
  2. fix to use of annotation when creating the resourceKey on the livestate. (they are equal)

In both cases, there is no user effect.
Considering the effective scope for the fix, 1 is safer. But I think it is confusing that they are not equal.

@ffjlabo
Copy link
Member

ffjlabo commented Apr 3, 2024

Other stages

Baseline

load manifests in the same way with K8S_SYNC stage indirectly.
(by using loadRunningManifests)

manifests, err := e.loadRunningManifests(ctx)

So the resourceKey is based on the k8s resource manifest, then fixed by app.pipecd.yaml (spec.input.namespace).

then, store it and use it on the BASELINE_CLEAN

@ffjlabo
Copy link
Member

ffjlabo commented Apr 4, 2024

📝 the namespace of the resourceKey is spec.input.namespace > original namespace

setNamespace(manifests, l.input.Namespace)
sortManifests(manifests)

@ffjlabo
Copy link
Member

ffjlabo commented Apr 4, 2024

There are two problems

  1. We can't delete the cluster scoped resources if we set the namespace to the app.pipecd.yaml.
  • This is because the resource key stored as livestate and the one on the annotation of actual k8s resource are different. values.
  1. The resourceKey rule of cluster scoped resources is undefined.
  • Currently, if we set the namespace with app.pipecd.yaml (spec.input.namespace), resourceKey is also affected by it.

So I'll resolve 1 in this issue, and later will try 2.

@ffjlabo
Copy link
Member

ffjlabo commented Apr 8, 2024

📝 Prepared the issue for 2
#4861

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working
Projects
Status: In Progress
Status: In Progress
2 participants