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

✨ Registration-agent supports multiple bootstrapkubeconfigs. #443

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ metadata:
categories: Integration & Delivery,OpenShift Optional
certified: "false"
containerImage: quay.io/open-cluster-management/registration-operator:latest
createdAt: "2024-05-09T03:09:05Z"
createdAt: "2024-05-22T01:34:44Z"
description: Manages the installation and upgrade of the ClusterManager.
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,16 @@ spec:
format: int32
minimum: 180
type: integer
secretNames:
description: SecretNames is a list of secret names. The
secrets are in the same namespace where the agent controller
runs.
kubeConfigSecrets:
description: KubeConfigSecrets is a list of secret names.
The secrets are in the same namespace where the agent
controller runs.
items:
type: string
properties:
name:
description: Name is the name of the secret.
type: string
type: object
type: array
type: object
type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ metadata:
categories: Integration & Delivery,OpenShift Optional
certified: "false"
containerImage: quay.io/open-cluster-management/registration-operator:latest
createdAt: "2024-05-09T03:09:05Z"
createdAt: "2024-05-22T01:34:44Z"
description: Manages the installation and upgrade of the Klusterlet.
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ spec:
like service accounts, roles and rolebindings, while the agent is
deployed to the namespace with the same name as klusterlet on the
management cluster.
maxLength: 63
maxLength: 57
pattern: ^open-cluster-management-[-a-z0-9]*[a-z0-9]$
type: string
nodePlacement:
Expand Down Expand Up @@ -208,12 +208,16 @@ spec:
format: int32
minimum: 180
type: integer
secretNames:
description: SecretNames is a list of secret names. The
secrets are in the same namespace where the agent controller
runs.
kubeConfigSecrets:
description: KubeConfigSecrets is a list of secret names.
The secrets are in the same namespace where the agent
controller runs.
items:
type: string
properties:
name:
description: Name is the name of the secret.
type: string
type: object
type: array
type: object
type:
Expand Down Expand Up @@ -358,6 +362,14 @@ spec:
workConfiguration:
description: WorkConfiguration contains the configuration of work
properties:
appliedManifestWorkEvictionGracePeriod:
description: AppliedManifestWorkEvictionGracePeriod is the eviction
grace period the work agent will wait before evicting the AppliedManifestWorks,
whose corresponding ManifestWorks are missing on the hub cluster,
from the managed cluster. If not present, the default value
of the work agent will be used.
pattern: ^([0-9]+(s|m|h))+$
type: string
featureGates:
description: 'FeatureGates represents the list of feature gates
for work If it is set empty, default feature gates will be used.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ require (
k8s.io/kube-aggregator v0.29.3
k8s.io/utils v0.0.0-20240310230437-4693a0247e57
open-cluster-management.io/addon-framework v0.9.1-0.20240419070222-e703fc5a2556
open-cluster-management.io/api v0.13.1-0.20240506072237-800b00d9f0db
open-cluster-management.io/api v0.13.1-0.20240521030453-9d94703b9eba
open-cluster-management.io/sdk-go v0.13.1-0.20240520073308-f18d198a844d
sigs.k8s.io/controller-runtime v0.17.3
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,8 @@ k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0g
k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/addon-framework v0.9.1-0.20240419070222-e703fc5a2556 h1:X3vJEx9agC94l7SitpWZFDshISdL1niqVH0+diyqfJo=
open-cluster-management.io/addon-framework v0.9.1-0.20240419070222-e703fc5a2556/go.mod h1:HayKCznnlyW+0dUJQGj5sNR6i3tvylSySD3YnvZkBtY=
open-cluster-management.io/api v0.13.1-0.20240506072237-800b00d9f0db h1:puVfabidvMj0phg34e5PqAmC0jzFiVN5LCNlZIEk+CA=
open-cluster-management.io/api v0.13.1-0.20240506072237-800b00d9f0db/go.mod h1:yrNuMMpciXjXPnj2yznb6LTyrGliiTrFZAJDp/Ck3c4=
open-cluster-management.io/api v0.13.1-0.20240521030453-9d94703b9eba h1:UsXnD4/N7pxYupPgoLvTq8wO73V72vD2D2ZkDd4iws0=
open-cluster-management.io/api v0.13.1-0.20240521030453-9d94703b9eba/go.mod h1:yrNuMMpciXjXPnj2yznb6LTyrGliiTrFZAJDp/Ck3c4=
open-cluster-management.io/sdk-go v0.13.1-0.20240520073308-f18d198a844d h1:5lcrL1DsQdNtDQU6U2oXwLAN0EBczcvI421YNgEzL/4=
open-cluster-management.io/sdk-go v0.13.1-0.20240520073308-f18d198a844d/go.mod h1:XBrldz+AqVBy9miOVNIu+6l8JXS18i795XbTqIqURJU=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I=
Expand Down
133 changes: 133 additions & 0 deletions pkg/common/helpers/ssar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package helpers

import (
"context"

authorizationv1 "k8s.io/api/authorization/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

func CreateSelfSubjectAccessReviews(
ctx context.Context,
kubeClient kubernetes.Interface,
selfSubjectAccessReviews []authorizationv1.SelfSubjectAccessReview) (bool, *authorizationv1.SelfSubjectAccessReview, error) {

for i := range selfSubjectAccessReviews {
subjectAccessReview := selfSubjectAccessReviews[i]

ssar, err := kubeClient.AuthorizationV1().SelfSubjectAccessReviews().Create(ctx, &subjectAccessReview, metav1.CreateOptions{})
if err != nil {
return false, &subjectAccessReview, err
}
if !ssar.Status.Allowed {
return false, &subjectAccessReview, nil
}
}
return true, nil, nil
}

func GetBootstrapSSARs() []authorizationv1.SelfSubjectAccessReview {
var reviews []authorizationv1.SelfSubjectAccessReview
clusterResource := authorizationv1.ResourceAttributes{
Group: "cluster.open-cluster-management.io",
Resource: "managedclusters",
// TODO: add the resourceName @xuezhaojun https://github.com/open-cluster-management-io/ocm/pull/443#discussion_r1609202000
}
xuezhaojun marked this conversation as resolved.
Show resolved Hide resolved
reviews = append(reviews, generateSelfSubjectAccessReviews(clusterResource, "create", "get")...)

certResource := authorizationv1.ResourceAttributes{
Group: "certificates.k8s.io",
Resource: "certificatesigningrequests",
}
return append(reviews, generateSelfSubjectAccessReviews(certResource, "create", "get", "list", "watch")...)
}

func GetHubConfigSSARs(clusterName string) []authorizationv1.SelfSubjectAccessReview {
var reviews []authorizationv1.SelfSubjectAccessReview
// registration resources
certResource := authorizationv1.ResourceAttributes{
Group: "certificates.k8s.io",
Resource: "certificatesigningrequests",
}
reviews = append(reviews, generateSelfSubjectAccessReviews(certResource, "get", "list", "watch")...)

clusterResource := authorizationv1.ResourceAttributes{
Group: "cluster.open-cluster-management.io",
Resource: "managedclusters",
Name: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(clusterResource, "get", "list", "update", "watch")...)

clusterStatusResource := authorizationv1.ResourceAttributes{
Group: "cluster.open-cluster-management.io",
Resource: "managedclusters",
Subresource: "status",
Name: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(clusterStatusResource, "patch", "update")...)

clusterCertResource := authorizationv1.ResourceAttributes{
Group: "register.open-cluster-management.io",
Resource: "managedclusters",
Subresource: "clientcertificates",
}
reviews = append(reviews, generateSelfSubjectAccessReviews(clusterCertResource, "renew")...)

leaseResource := authorizationv1.ResourceAttributes{
Group: "coordination.k8s.io",
Resource: "leases",
Name: "managed-cluster-lease",
Namespace: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(leaseResource, "get", "update")...)

// work resources
eventResource := authorizationv1.ResourceAttributes{
Resource: "events",
Namespace: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(eventResource, "create", "patch", "update")...)

eventResource = authorizationv1.ResourceAttributes{
Group: "events.k8s.io",
Resource: "events",
Namespace: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(eventResource, "create", "patch", "update")...)

workResource := authorizationv1.ResourceAttributes{
Group: "work.open-cluster-management.io",
Resource: "manifestworks",
Namespace: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(workResource, "get", "list", "watch", "update")...)

workStatusResource := authorizationv1.ResourceAttributes{
Group: "work.open-cluster-management.io",
Resource: "manifestworks",
Subresource: "status",
Namespace: clusterName,
}
reviews = append(reviews, generateSelfSubjectAccessReviews(workStatusResource, "patch", "update")...)
return reviews
}

func generateSelfSubjectAccessReviews(resource authorizationv1.ResourceAttributes, verbs ...string) []authorizationv1.SelfSubjectAccessReview {
var reviews []authorizationv1.SelfSubjectAccessReview
for _, verb := range verbs {
reviews = append(reviews, authorizationv1.SelfSubjectAccessReview{
Spec: authorizationv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
Group: resource.Group,
Resource: resource.Resource,
Subresource: resource.Subresource,
Name: resource.Name,
Namespace: resource.Namespace,
Verb: verb,
},
},
})
}
return reviews
}
30 changes: 30 additions & 0 deletions pkg/common/helpers/ssar_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package helpers

import (
"context"
"fmt"
"testing"

fakekube "k8s.io/client-go/kubernetes/fake"
)

// TODO: enhance the u-t in the future @xuezhaojun
func TestCreateSelfSubjectAccessReviews(t *testing.T) {
kubeClient := fakekube.NewSimpleClientset()
ctx := context.TODO()

// Create sample selfSubjectAccessReviews
bootstrapSSARs := GetBootstrapSSARs()
hubConfigSSARs := GetHubConfigSSARs("test-cluster")

// Call the function under test
_, _, err := CreateSelfSubjectAccessReviews(ctx, kubeClient, bootstrapSSARs)
if err != nil {
fmt.Println(err)
}

_, _, err = CreateSelfSubjectAccessReviews(ctx, kubeClient, hubConfigSSARs)
if err != nil {
fmt.Println(err)
}
}