Skip to content

Commit

Permalink
Remove obsolete L2/L3 operator bindings from provisioner (kyma-projec…
Browse files Browse the repository at this point in the history
…t#3438)

* Remove obsolete L2/L3 operator bindings from provisioner

* review suggestions
  • Loading branch information
ebensom authored May 21, 2024
1 parent 3dd2578 commit bc0d834
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 135 deletions.
4 changes: 2 additions & 2 deletions components/provisioner/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (c *config) String() string {
"ProvisioningTimeoutInstallation: %s, ProvisioningTimeoutUpgrade: %s, "+
"DeprovisioningNoInstallTimeoutClusterDeletion: %s, DeprovisioningNoInstallTimeoutWaitingForClusterDeletion: %s "+
"ShootUpgradeTimeout: %s, "+
"OperatorRoleBindingL2SubjectName: %s, OperatorRoleBindingL3SubjectName: %s, OperatorRoleBindingCreatingForAdmin: %t "+
"OperatorRoleBindingCreatingForAdmin: %t "+
"GardenerProject: %s, GardenerKubeconfigPath: %s, GardenerAuditLogsPolicyConfigMap: %s, AuditLogsTenantConfigPath: %s, DefaultEnableIMDSv2: %v"+
"EnqueueInProgressOperations: %v"+
"LogLevel: %s",
Expand All @@ -98,7 +98,7 @@ func (c *config) String() string {
c.ProvisioningTimeout.Installation.String(), c.ProvisioningTimeout.Upgrade.String(),
c.DeprovisioningTimeout.ClusterDeletion.String(), c.DeprovisioningTimeout.WaitingForClusterDeletion.String(),
c.ProvisioningTimeout.ShootUpgrade.String(),
c.OperatorRoleBinding.L2SubjectName, c.OperatorRoleBinding.L3SubjectName, c.OperatorRoleBinding.CreatingForAdmin,
c.OperatorRoleBinding.CreatingForAdmin,
c.Gardener.Project, c.Gardener.KubeconfigPath, c.Gardener.AuditLogsPolicyConfigMap, c.Gardener.AuditLogsTenantConfigPath, c.Gardener.DefaultEnableIMDSv2,
c.EnqueueInProgressOperations,
c.LogLevel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func azureGardenerClusterConfigInput(zones ...string) gqlschema.ClusterConfigInp
},
OidcConfig: oidcInput(),
},
Administrators: []string{"testadmin"},
}
}

Expand Down Expand Up @@ -205,6 +206,7 @@ func azureGardenerClusterConfigInputNoSeed(zones ...string) gqlschema.ClusterCon
},
OidcConfig: oidcInput(),
},
Administrators: []string{"testadmin"},
}
}

Expand Down Expand Up @@ -236,6 +238,7 @@ func openStackGardenerClusterConfigInput() gqlschema.ClusterConfigInput {
},
OidcConfig: oidcInput(),
},
Administrators: []string{"testadmin"},
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import (
"context"
"encoding/json"
"fmt"
uuidMocks "github.com/kyma-project/control-plane/components/provisioner/internal/uuid/mocks"
"path/filepath"
"strings"
"testing"
"time"

uuidMocks "github.com/kyma-project/control-plane/components/provisioner/internal/uuid/mocks"

"github.com/kyma-project/control-plane/components/provisioner/internal/api/fake/seeds"
"github.com/kyma-project/control-plane/components/provisioner/internal/api/fake/shoots"
provisioning2 "github.com/kyma-project/control-plane/components/provisioner/internal/operations/stages/provisioning"
Expand Down Expand Up @@ -403,8 +404,7 @@ func testDeprovisioningTimeouts() queue.DeprovisioningTimeouts {

func testOperatorRoleBinding() provisioning2.OperatorRoleBinding {
return provisioning2.OperatorRoleBinding{
L2SubjectName: "runtimeOperator",
L3SubjectName: "runtimeAdmin",
CreatingForAdmin: true,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,11 @@ import (
)

const (
l2OperatorClusterRoleBindingName = "l2-operator"
l3OperatorClusterRoleBindingName = "l3-operator-admin"
administratorOperatorClusterRoleBindingName = "administrator"

l3OperatorClusterRoleBindingRoleRefName = "cluster-admin"
ownerClusterRoleBindingRoleRefName = "cluster-admin"
ownerClusterRoleBindingRoleRefName = "cluster-admin"

l2OperatorClusterRoleName = "l2-operator"
l2OperatorRulesClusterRoleName = "l2-operator-rules"
l2OperatorBaseRolesLabelKey = "rbac.authorization.k8s.io/aggregate-to-edit"
l2OperatorExtendedRolesLabelKey = "rbac.authorization.k8s.io/aggregate-to-l2-operator"

groupKindSubject = "Group"
userKindSubject = "User"
userKindSubject = "User"
)

//go:generate mockery --name=DynamicKubeconfigProvider
Expand All @@ -45,9 +36,7 @@ type DynamicKubeconfigProvider interface {
}

type OperatorRoleBinding struct {
L2SubjectName string `envconfig:"default=runtimeOperator"`
L3SubjectName string `envconfig:"default=runtimeAdmin"`
CreatingForAdmin bool `envconfig:"default=false"`
CreatingForAdmin bool `envconfig:"default=false"`
}

type CreateBindingsForOperatorsStep struct {
Expand Down Expand Up @@ -103,58 +92,8 @@ func (s *CreateBindingsForOperatorsStep) Run(cluster model.Cluster, _ model.Oper
return operations.StageResult{}, err
}

clusterRoles := make([]v12.ClusterRole, 0)
clusterRoles = append(clusterRoles,
buildClusterRole(
l2OperatorClusterRoleName,
map[string]string{
"app": "kyma",
},
[]metav1.LabelSelector{
{MatchLabels: map[string]string{l2OperatorBaseRolesLabelKey: "true"}},
{MatchLabels: map[string]string{l2OperatorExtendedRolesLabelKey: "true"}},
},
nil,
),
)
clusterRoles = append(clusterRoles,
buildClusterRole(
l2OperatorRulesClusterRoleName,
map[string]string{
"app": "kyma",
l2OperatorExtendedRolesLabelKey: "true",
},
nil,
[]v12.PolicyRule{
{APIGroups: []string{"*"}, Resources: []string{"*"}, Verbs: []string{"get", "list", "watch"}},
},
),
)

clusterRoleBindings := make([]v12.ClusterRoleBinding, 0)

clusterRoleBindings = append(clusterRoleBindings,
buildClusterRoleBinding(
l2OperatorClusterRoleBindingName,
s.operatorRoleBindingConfig.L2SubjectName,
l2OperatorClusterRoleBindingName,
groupKindSubject,
map[string]string{
"app": "kyma",
"reconciler.kyma-project.io/managed-by": "reconciler",
}))

clusterRoleBindings = append(clusterRoleBindings,
buildClusterRoleBinding(
l3OperatorClusterRoleBindingName,
s.operatorRoleBindingConfig.L3SubjectName,
l3OperatorClusterRoleBindingRoleRefName,
groupKindSubject,
map[string]string{
"app": "kyma",
"reconciler.kyma-project.io/managed-by": "reconciler",
}))

if s.operatorRoleBindingConfig.CreatingForAdmin {
for i, administrator := range cluster.Administrators {
clusterRoleBindings = append(clusterRoleBindings,
Expand All @@ -170,10 +109,6 @@ func (s *CreateBindingsForOperatorsStep) Run(cluster model.Cluster, _ model.Oper
}
}

if err := createClusterRoles(k8sClient.RbacV1().ClusterRoles(), clusterRoles); err != nil {
return operations.StageResult{}, err
}

if err := k8sClient.RbacV1().ClusterRoleBindings().DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "reconciler.kyma-project.io/managed-by=reconciler,app=kyma"}); err != nil {
return operations.StageResult{}, util.K8SErrorToAppError(errors.Wrap(err, "failed to delete cluster role bindings")).SetComponent(apperrors.ErrClusterK8SClient)
}
Expand Down Expand Up @@ -204,39 +139,6 @@ func buildClusterRoleBinding(metaName, subjectName, roleRefName, subjectKind str
}
}

func buildClusterRole(name string, labels map[string]string, aggregationSelectors []metav1.LabelSelector, rules []v12.PolicyRule) v12.ClusterRole {

cr := v12.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: labels,
},
}
if len(aggregationSelectors) > 0 {
cr.AggregationRule = &v12.AggregationRule{
ClusterRoleSelectors: aggregationSelectors,
}
}

if len(rules) > 0 {
cr.Rules = rules
}

return cr
}

func createClusterRoles(crClient v1.ClusterRoleInterface, clusterRoles []v12.ClusterRole) error {
for _, cr := range clusterRoles {
if _, err := crClient.Create(context.Background(), &cr, metav1.CreateOptions{}); err != nil {
if !k8serrors.IsAlreadyExists(err) {
return util.K8SErrorToAppError(errors.Wrapf(err, "failed to create %s ClusterRole", cr.Name)).SetComponent(apperrors.ErrClusterK8SClient)
}
}
}

return nil
}

func createClusterRoleBindings(crbClient v1.ClusterRoleBindingInterface, clusterRoleBindings ...v12.ClusterRoleBinding) error {
for _, crb := range clusterRoleBindings {
if _, err := crbClient.Create(context.Background(), &crb, metav1.CreateOptions{}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
)

const dynamicKubeconfig = "dynamic_kubeconfig"
const testAdministrator1 = "testadmin1"
const testAdministrator2 = "testadmin2"

func TestCreateBindingsForOperatorsStep_Run(t *testing.T) {

Expand All @@ -33,11 +35,11 @@ func TestCreateBindingsForOperatorsStep_Run(t *testing.T) {
ClusterConfig: model.GardenerConfig{
Name: "shoot",
},
Administrators: []string{testAdministrator1, testAdministrator2},
}

operatorBindingConfig := OperatorRoleBinding{
L2SubjectName: "l2name",
L3SubjectName: "l3name",
CreatingForAdmin: true,
}

dynamicKubeconfigProvider := &provisioning_mocks.DynamicKubeconfigProvider{}
Expand All @@ -60,36 +62,20 @@ func TestCreateBindingsForOperatorsStep_Run(t *testing.T) {
assert.Equal(t, time.Duration(0), result.Delay)
})

t.Run("should not fail if cluster role already exists", func(t *testing.T) {
// given
k8sClient := fake.NewSimpleClientset()
clusterRole := buildClusterRole(l2OperatorClusterRoleName, map[string]string{"app": "kyma"}, []metav1.LabelSelector{
{MatchLabels: map[string]string{l2OperatorBaseRolesLabelKey: "true"}},
{MatchLabels: map[string]string{l2OperatorExtendedRolesLabelKey: "true"}},
}, nil)
_, err := k8sClient.RbacV1().ClusterRoles().Create(context.Background(), &clusterRole, metav1.CreateOptions{})
require.NoError(t, err)

k8sClientProvider := &mocks.K8sClientProvider{}
k8sClientProvider.On("CreateK8SClient", dynamicKubeconfig).Return(k8sClient, nil)

step := NewCreateBindingsForOperatorsStep(k8sClientProvider, operatorBindingConfig, dynamicKubeconfigProvider, nextStageName, time.Minute)

// when
result, err := step.Run(cluster, model.Operation{}, &logrus.Entry{})

// then
require.NoError(t, err)
assert.Equal(t, nextStageName, result.Stage)
assert.Equal(t, time.Duration(0), result.Delay)
})

t.Run("should not fail if cluster role binding already exists", func(t *testing.T) {
// given
k8sClient := fake.NewSimpleClientset()
clusterRoleBinding := buildClusterRoleBinding(l2OperatorClusterRoleBindingName, operatorBindingConfig.L2SubjectName, l2OperatorClusterRoleName, groupKindSubject, map[string]string{"app": "kyma"})
_, err := k8sClient.RbacV1().ClusterRoleBindings().Create(context.Background(), &clusterRoleBinding, metav1.CreateOptions{})
require.NoError(t, err)
for i, administrator := range cluster.Administrators {
clusterRoleBinding := buildClusterRoleBinding(
fmt.Sprintf("%s%d", administratorOperatorClusterRoleBindingName, i),
administrator,
ownerClusterRoleBindingRoleRefName,
userKindSubject,
map[string]string{"app": "kyma"},
)
_, err := k8sClient.RbacV1().ClusterRoleBindings().Create(context.Background(), &clusterRoleBinding, metav1.CreateOptions{})
require.NoError(t, err)
}

k8sClientProvider := &mocks.K8sClientProvider{}
k8sClientProvider.On("CreateK8SClient", dynamicKubeconfig).Return(k8sClient, nil)
Expand Down

0 comments on commit bc0d834

Please sign in to comment.