Skip to content

Commit

Permalink
add toolchaincluster SA templates
Browse files Browse the repository at this point in the history
  • Loading branch information
mfrancisc committed Feb 27, 2024
1 parent 0f4717d commit 4263bea
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 0 deletions.
3 changes: 3 additions & 0 deletions deploy/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ import "embed"

//go:embed templates/notificationtemplates/*
var NotificationTemplateFS embed.FS

//go:embed templates/toolchaincluster/*
var ToolchainClusterTemplateFS embed.FS
25 changes: 25 additions & 0 deletions deploy/templates/toolchaincluster/host-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: toolchaincluster-host
namespace: toolchain-host-operator
rules:
- apiGroups:
- toolchain.dev.openshift.com
resources:
- "bannedusers"
- "masteruserrecords"
- "notifications"
- "nstemplatetiers"
- "spaces"
- "spacebindings"
- "tiertemplates"
- "toolchainconfigs"
- "toolchainclusters"
- "toolchainstatuses"
- "usersignups"
- "usertiers"
- "proxyplugins"
- "spaceprovisionerconfigs"
verbs:
- "*"
12 changes: 12 additions & 0 deletions deploy/templates/toolchaincluster/host-rolebinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: toolchaincluster-host
namespace: toolchain-host-operator
subjects:
- kind: ServiceAccount
name: toolchaincluster-host
roleRef:
kind: Role
name: toolchaincluster-host
apiGroup: rbac.authorization.k8s.io
6 changes: 6 additions & 0 deletions deploy/templates/toolchaincluster/host-sa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: toolchaincluster-host
namespace: toolchain-host-operator
60 changes: 60 additions & 0 deletions pkg/templates/toolchaincluster/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package toolchaincluster

import (
"embed"

v1 "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes/scheme"
)

// GetServiceAccountFromTemplate returns the toolchaincluster service account object from the template content
func GetServiceAccountFromTemplate(toolchainclusterFS *embed.FS, templateName string, into runtime.Object) (*v1.ServiceAccount, error) {
obj, gkv, err := decodeTemplate(toolchainclusterFS, templateName, into)
if err != nil {
return nil, err
}
if gkv.Kind == "ServiceAccount" {
return obj.(*v1.ServiceAccount), nil
}
return nil, nil
}

// GetRoleFromTemplate returns the toolchaincluster Role object from the template content
func GetRoleFromTemplate(toolchainclusterFS *embed.FS, templateName string, into runtime.Object) (*rbac.Role, error) {
obj, gkv, err := decodeTemplate(toolchainclusterFS, templateName, into)
if err != nil {
return nil, err
}
if gkv.Kind == "Role" {
return obj.(*rbac.Role), nil
}
return nil, nil
}

// GetRoleBindingFromTemplate returns the toolchaincluster RoleBinding object from the template content
func GetRoleBindingFromTemplate(toolchainclusterFS *embed.FS, templateName string, into runtime.Object) (*rbac.RoleBinding, error) {
obj, gkv, err := decodeTemplate(toolchainclusterFS, templateName, into)
if err != nil {
return nil, err
}
if gkv.Kind == "RoleBinding" {
return obj.(*rbac.RoleBinding), nil
}
return nil, nil
}

func decodeTemplate(toolchainclusterFS *embed.FS, templateName string, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
saContent, err := toolchainclusterFS.ReadFile("templates/toolchaincluster/" + templateName)
if err != nil {
return nil, nil, err
}
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, gkv, err := decode(saContent, nil, into)
if err != nil {
return nil, nil, err
}
return obj, gkv, nil
}
106 changes: 106 additions & 0 deletions pkg/templates/toolchaincluster/template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package toolchaincluster

import (
"testing"

"github.com/codeready-toolchain/host-operator/deploy"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
)

func TestGetServiceAccountTemplate(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// when
sa, err := GetServiceAccountFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-sa.yaml", &v1.ServiceAccount{})
// then
require.NoError(t, err)
require.NotNil(t, sa)
assert.Equal(t, "toolchaincluster-host", sa.Name)
assert.Equal(t, "toolchain-host-operator", sa.Namespace)
})

t.Run("error reading template", func(t *testing.T) {
// when
// we pass an invalid template path
sa, err := GetServiceAccountFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-sa-invalid.yaml", &v1.ServiceAccount{})
// then
require.Error(t, err)
require.Nil(t, sa)
})

t.Run("no service account found", func(t *testing.T) {
// when
// we pass a template that contains a different Kind
sa, err := GetServiceAccountFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-role.yaml", &v1.ServiceAccount{})
// then
require.Nil(t, err)
require.Nil(t, sa)
})
}

func TestGetRoleTemplate(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// when
role, err := GetRoleFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-role.yaml", &rbac.Role{})
// then
require.NoError(t, err)
require.NotNil(t, role)
assert.Equal(t, "toolchaincluster-host", role.Name)
assert.Equal(t, "toolchain-host-operator", role.Namespace)
require.NotEmpty(t, role.Rules)
})

t.Run("error reading template", func(t *testing.T) {
// when
// we pass an invalid template path
sa, err := GetRoleFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-role-invalid.yaml", &rbac.Role{})
// then
require.Error(t, err)
require.Nil(t, sa)
})

t.Run("no role found", func(t *testing.T) {
// when
// we pass a template that contains a different Kind
sa, err := GetRoleFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-sa.yaml", &rbac.Role{})
// then
require.Nil(t, err)
require.Nil(t, sa)
})
}

func TestGetRoleBindingTemplate(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// when
rolebinding, err := GetRoleBindingFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-rolebinding.yaml", &rbac.RoleBinding{})
// then
require.NoError(t, err)
require.NotNil(t, rolebinding)
assert.Equal(t, "toolchaincluster-host", rolebinding.Name)
assert.Equal(t, "toolchain-host-operator", rolebinding.Namespace)
assert.Equal(t, "ServiceAccount", rolebinding.Subjects[0].Kind)
assert.Equal(t, "toolchaincluster-host", rolebinding.Subjects[0].Name)
assert.Equal(t, "Role", rolebinding.RoleRef.Kind)
assert.Equal(t, "toolchaincluster-host", rolebinding.RoleRef.Name)
})

t.Run("error reading template", func(t *testing.T) {
// when
// we pass an invalid template path
rb, err := GetRoleBindingFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-rolebinding-invalid.yaml", &rbac.RoleBinding{})
// then
require.Error(t, err)
require.Nil(t, rb)
})

t.Run("no rolebinding found", func(t *testing.T) {
// when
// we pass a template that contains a different Kind
rb, err := GetRoleBindingFromTemplate(&deploy.ToolchainClusterTemplateFS, "host-role.yaml", &rbac.RoleBinding{})
// then
require.Nil(t, err)
require.Nil(t, rb)
})
}

0 comments on commit 4263bea

Please sign in to comment.