Skip to content

Commit 6668a0c

Browse files
committed
Replicating SyncTarget-related rbac objects
Signed-off-by: David Festal <[email protected]>
1 parent 91d5124 commit 6668a0c

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright 2023 The KCP Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package replicateclusterrole
18+
19+
import (
20+
kcprbacinformers "github.com/kcp-dev/client-go/informers/rbac/v1"
21+
kcpkubernetesclientset "github.com/kcp-dev/client-go/kubernetes"
22+
"github.com/kcp-dev/logicalcluster/v3"
23+
24+
rbacv1 "k8s.io/api/rbac/v1"
25+
"k8s.io/kube-openapi/pkg/util/sets"
26+
27+
"github.com/kcp-dev/kcp/pkg/reconciler/cache/labelclusterroles"
28+
"github.com/kcp-dev/kcp/sdk/apis/workload"
29+
)
30+
31+
const (
32+
ControllerName = "kcp-workloads-replicate-clusterrole"
33+
)
34+
35+
// NewController returns a new controller for labelling ClusterRole that should be replicated.
36+
func NewController(
37+
kubeClusterClient kcpkubernetesclientset.ClusterInterface,
38+
clusterRoleInformer kcprbacinformers.ClusterRoleClusterInformer,
39+
clusterRoleBindingInformer kcprbacinformers.ClusterRoleBindingClusterInformer,
40+
) labelclusterroles.Controller {
41+
return labelclusterroles.NewController(
42+
ControllerName,
43+
workload.GroupName,
44+
HasSyncRule,
45+
func(clusterName logicalcluster.Name, crb *rbacv1.ClusterRoleBinding) bool { return false },
46+
kubeClusterClient,
47+
clusterRoleInformer,
48+
clusterRoleBindingInformer,
49+
)
50+
}
51+
52+
func HasSyncRule(clusterName logicalcluster.Name, cr *rbacv1.ClusterRole) bool {
53+
for _, rule := range cr.Rules {
54+
apiGroups := sets.NewString(rule.APIGroups...)
55+
if !apiGroups.Has(workload.GroupName) {
56+
continue
57+
}
58+
resources := sets.NewString(rule.Resources...)
59+
verbs := sets.NewString(rule.Verbs...)
60+
if resources.Has("synctargets") && verbs.Has("sync") && len(rule.ResourceNames) == 1 {
61+
return true
62+
}
63+
}
64+
return false
65+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2023 The KCP Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package replicateclusterrolebinding
18+
19+
import (
20+
kcprbacinformers "github.com/kcp-dev/client-go/informers/rbac/v1"
21+
kcpkubernetesclientset "github.com/kcp-dev/client-go/kubernetes"
22+
"github.com/kcp-dev/logicalcluster/v3"
23+
24+
rbacv1 "k8s.io/api/rbac/v1"
25+
26+
"github.com/kcp-dev/kcp/pkg/reconciler/cache/labelclusterrolebindings"
27+
"github.com/kcp-dev/kcp/pkg/reconciler/workload/replicateclusterrole"
28+
"github.com/kcp-dev/kcp/sdk/apis/workload"
29+
)
30+
31+
const (
32+
ControllerName = "kcp-workloads-replicate-clusterrolebinding"
33+
)
34+
35+
// NewController returns a new controller for labelling ClusterRoleBinding that should be replicated.
36+
func NewController(
37+
kubeClusterClient kcpkubernetesclientset.ClusterInterface,
38+
clusterRoleBindingInformer kcprbacinformers.ClusterRoleBindingClusterInformer,
39+
clusterRoleInformer kcprbacinformers.ClusterRoleClusterInformer,
40+
) labelclusterrolebindings.Controller {
41+
return labelclusterrolebindings.NewController(
42+
ControllerName,
43+
workload.GroupName,
44+
replicateclusterrole.HasSyncRule,
45+
func(clusterName logicalcluster.Name, crb *rbacv1.ClusterRoleBinding) bool { return false },
46+
kubeClusterClient,
47+
clusterRoleBindingInformer,
48+
clusterRoleInformer,
49+
)
50+
}

tmc/pkg/server/controllers.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import (
3737
"github.com/kcp-dev/kcp/pkg/reconciler/workload/heartbeat"
3838
workloadnamespace "github.com/kcp-dev/kcp/pkg/reconciler/workload/namespace"
3939
workloadplacement "github.com/kcp-dev/kcp/pkg/reconciler/workload/placement"
40+
workloadreplicateclusterrole "github.com/kcp-dev/kcp/pkg/reconciler/workload/replicateclusterrole"
41+
workloadreplicateclusterrolebinding "github.com/kcp-dev/kcp/pkg/reconciler/workload/replicateclusterrolebinding"
4042
workloadresource "github.com/kcp-dev/kcp/pkg/reconciler/workload/resource"
4143
synctargetcontroller "github.com/kcp-dev/kcp/pkg/reconciler/workload/synctarget"
4244
"github.com/kcp-dev/kcp/pkg/reconciler/workload/synctargetexports"
@@ -403,3 +405,57 @@ func (s *Server) installSyncTargetController(ctx context.Context, config *rest.C
403405
return nil
404406
})
405407
}
408+
409+
func (s *Server) installWorkloadReplicateClusterRoleControllers(ctx context.Context, config *rest.Config) error {
410+
config = rest.CopyConfig(config)
411+
config = rest.AddUserAgent(config, workloadreplicateclusterrole.ControllerName)
412+
kubeClusterClient, err := kcpkubernetesclientset.NewForConfig(config)
413+
if err != nil {
414+
return err
415+
}
416+
417+
c := workloadreplicateclusterrole.NewController(
418+
kubeClusterClient,
419+
s.Core.KubeSharedInformerFactory.Rbac().V1().ClusterRoles(),
420+
s.Core.KubeSharedInformerFactory.Rbac().V1().ClusterRoleBindings(),
421+
)
422+
423+
return s.Core.AddPostStartHook(postStartHookName(workloadreplicateclusterrole.ControllerName), func(hookContext genericapiserver.PostStartHookContext) error {
424+
logger := klog.FromContext(ctx).WithValues("postStartHook", postStartHookName(workloadreplicateclusterrole.ControllerName))
425+
if err := s.Core.WaitForSync(hookContext.StopCh); err != nil {
426+
logger.Error(err, "failed to finish post-start-hook")
427+
return nil // don't klog.Fatal. This only happens when context is cancelled.
428+
}
429+
430+
go c.Start(goContext(hookContext), 2)
431+
432+
return nil
433+
})
434+
}
435+
436+
func (s *Server) installWorkloadReplicateClusterRoleBindingControllers(ctx context.Context, config *rest.Config) error {
437+
config = rest.CopyConfig(config)
438+
config = rest.AddUserAgent(config, workloadreplicateclusterrolebinding.ControllerName)
439+
kubeClusterClient, err := kcpkubernetesclientset.NewForConfig(config)
440+
if err != nil {
441+
return err
442+
}
443+
444+
c := workloadreplicateclusterrolebinding.NewController(
445+
kubeClusterClient,
446+
s.Core.KubeSharedInformerFactory.Rbac().V1().ClusterRoleBindings(),
447+
s.Core.KubeSharedInformerFactory.Rbac().V1().ClusterRoles(),
448+
)
449+
450+
return s.Core.AddPostStartHook(postStartHookName(workloadreplicateclusterrolebinding.ControllerName), func(hookContext genericapiserver.PostStartHookContext) error {
451+
logger := klog.FromContext(ctx).WithValues("postStartHook", postStartHookName(workloadreplicateclusterrolebinding.ControllerName))
452+
if err := s.Core.WaitForSync(hookContext.StopCh); err != nil {
453+
logger.Error(err, "failed to finish post-start-hook")
454+
return nil // don't klog.Fatal. This only happens when context is cancelled.
455+
}
456+
457+
go c.Start(goContext(hookContext), 2)
458+
459+
return nil
460+
})
461+
}

tmc/pkg/server/server.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ func (s *Server) Run(ctx context.Context) error {
102102
if err := s.installWorkloadsSyncTargetExportController(ctx, controllerConfig); err != nil {
103103
return err
104104
}
105+
106+
if err := s.installWorkloadReplicateClusterRoleControllers(ctx, controllerConfig); err != nil {
107+
return err
108+
}
109+
110+
if err := s.installWorkloadReplicateClusterRoleBindingControllers(ctx, controllerConfig); err != nil {
111+
return err
112+
}
105113
}
106114

107115
if s.Options.Core.Controllers.EnableAll || enabled.Has("resource-scheduler") {

0 commit comments

Comments
 (0)