Skip to content

Commit

Permalink
Option to disable the default creation of RBAC resources
Browse files Browse the repository at this point in the history
  • Loading branch information
savitaashture committed Sep 29, 2021
1 parent b925224 commit 2cd400e
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ spec:
value: "true"
- name: pipelineTemplates
value: "true"
params:
- name: createRbacResource
value: "true"
4 changes: 2 additions & 2 deletions pkg/apis/operator/v1alpha1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func (c *CommonSpec) GetTargetNamespace() string {

// Param declares an string value to use for the parameter called name.
type Param struct {
Name string `json:"name"`
Value string `json:"value"`
Name string `json:"name,omitempty"`
Value string `json:"value,omitempty"`
}

// ParamValue defines a default value and possible values for a param
Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/operator/v1alpha1/tektonconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ type TektonConfigSpec struct {
// Dashboard holds the customizable options for dashboards component
// +optional
Dashboard Dashboard `json:"dashboard,omitempty"`
// Params is the list of params passed for all platforms
// +optional
Params []Param `json:"params,omitempty"`
}

// TektonConfigStatus defines the observed state of TektonConfig
Expand All @@ -97,6 +100,10 @@ type TektonConfigStatus struct {
// The version of the installed release
// +optional
Version string `json:"version,omitempty"`

// The current installer set name
// +optional
TektonInstallerSet map[string]string `json:"tektonInstallerSets,omitempty"`
}

// TektonConfigList contains a list of TektonConfig
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

147 changes: 143 additions & 4 deletions pkg/reconciler/openshift/tektonconfig/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/tektoncd/operator/pkg/reconciler/openshift/tektonconfig/extension"
openshiftPipeline "github.com/tektoncd/operator/pkg/reconciler/openshift/tektonpipeline"
openshiftTrigger "github.com/tektoncd/operator/pkg/reconciler/openshift/tektontrigger"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -67,10 +68,37 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto
r := rbac{
kubeClientSet: oe.kubeClientSet,
operatorClientSet: oe.operatorClientSet,
ownerRef: configOwnerRef(tc),
version: os.Getenv(versionKey),
tektonConfig: config,
}
return r.createResources(ctx)

var createResourceError error
if len(config.Spec.Params) == 0 {
createResourceError = r.createResources(ctx)
}
for _, v := range config.Spec.Params {
// check for param name and if its matches to createRbacResource
// then disable auto creation of RBAC resources by deleting installerSet
if v.Name == "createRbacResource" {
if v.Value == "false" {
if err := r.deleteInstallerSet(ctx, r.tektonConfig, componentName); err != nil {
return err
}
// remove openshift-pipelines.tekton.dev/namespace-reconcile-version label from namespaces while deleting RBAC resources.
if err := r.cleanUp(ctx); err != nil {
return err
}

} else {
createResourceError = r.createResources(ctx)
}
} else {
createResourceError = r.createResources(ctx)
}
continue
}

return createResourceError
}
func (oe openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error {
configInstance := comp.(*v1alpha1.TektonConfig)
Expand Down Expand Up @@ -103,6 +131,117 @@ func (oe openshiftExtension) Finalize(ctx context.Context, comp v1alpha1.TektonC
}

// configOwnerRef returns owner reference pointing to passed instance
func configOwnerRef(tc v1alpha1.TektonComponent) metav1.OwnerReference {
return *metav1.NewControllerRef(tc, tc.GroupVersionKind())
func configOwnerRef(tc v1alpha1.TektonInstallerSet) metav1.OwnerReference {
return *metav1.NewControllerRef(&tc, tc.GetGroupVersionKind())
}

func createInstallerSet(ctx context.Context, oc versioned.Interface, ta *v1alpha1.TektonConfig,
releaseVersion, component, installerSetName string) error {

is := makeInstallerSet(ta, installerSetName, releaseVersion)

createdIs, err := oc.OperatorV1alpha1().TektonInstallerSets().
Create(ctx, is, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
return err
}

if len(ta.Status.TektonInstallerSet) == 0 {
ta.Status.TektonInstallerSet = map[string]string{}
}

// Update the status of addon with created installerSet name
ta.Status.TektonInstallerSet[component] = createdIs.Name
ta.Status.SetVersion(releaseVersion)

_, err = oc.OperatorV1alpha1().TektonConfigs().
UpdateStatus(ctx, ta, metav1.UpdateOptions{})

return err
}

func makeInstallerSet(tc *v1alpha1.TektonConfig, name, releaseVersion string) *v1alpha1.TektonInstallerSet {
ownerRef := *metav1.NewControllerRef(tc, tc.GetGroupVersionKind())
return &v1alpha1.TektonInstallerSet{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
createdByKey: createdByValue,
},
Annotations: map[string]string{
releaseVersionKey: releaseVersion,
targetNamespaceKey: tc.Spec.TargetNamespace,
},
OwnerReferences: []metav1.OwnerReference{ownerRef},
},
}
}

func (r *rbac) deleteInstallerSet(ctx context.Context, tc *v1alpha1.TektonConfig, component string) error {

compInstallerSet, ok := tc.Status.TektonInstallerSet[component]
if !ok {
return nil
}

if compInstallerSet != "" {
// delete the installer set
err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
Delete(ctx, tc.Status.TektonInstallerSet[component], metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return err
}

// clear the name of installer set from TektonAddon status
delete(tc.Status.TektonInstallerSet, component)
_, err = r.operatorClientSet.OperatorV1alpha1().TektonConfigs().
UpdateStatus(ctx, tc, metav1.UpdateOptions{})
if err != nil && !errors.IsNotFound(err) {
return err
}
}

return nil
}

// checkIfInstallerSetExist checks if installer set exists for a component and return true/false based on it
// and if installer set which already exist is of older version then it deletes and return false to create a new
// installer set
func checkIfInstallerSetExist(ctx context.Context, oc versioned.Interface, relVersion string,
tc *v1alpha1.TektonConfig, component string) (bool, error) {

// Check if installer set is already created
compInstallerSet, ok := tc.Status.TektonInstallerSet[component]
if !ok {
return false, nil
}

if compInstallerSet != "" {
// if already created then check which version it is
ctIs, err := oc.OperatorV1alpha1().TektonInstallerSets().
Get(ctx, compInstallerSet, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}

if version, ok := ctIs.Annotations[releaseVersionKey]; ok && version == relVersion {
// if installer set already exist and release version is same
// then ignore and move on
return true, nil
}

// release version doesn't exist or is different from expected
// deleted existing InstallerSet and create a new one

err = oc.OperatorV1alpha1().TektonInstallerSets().
Delete(ctx, compInstallerSet, metav1.DeleteOptions{})
if err != nil {
return false, err
}
}

return false, nil
}
34 changes: 30 additions & 4 deletions pkg/reconciler/openshift/tektonconfig/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"regexp"

"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
"github.com/tektoncd/operator/pkg/reconciler/common"
corev1 "k8s.io/api/core/v1"
Expand All @@ -41,6 +42,11 @@ const (
trustedCABundleConfigMap = "config-trusted-cabundle"
clusterInterceptors = "openshift-pipelines-clusterinterceptors"
namespaceVersionLabel = "openshift-pipelines.tekton.dev/namespace-reconcile-version"
createdByKey = "operator.tekton.dev/created-by"
createdByValue = "RBAC"
releaseVersionKey = "operator.tekton.dev/release-version"
targetNamespaceKey = "operator.tekton.dev/target-namespace"
componentName = "rbacTaskInstallerSet"
)

// Namespace Regex to ignore the namespace for creating rbac resources.
Expand All @@ -51,12 +57,13 @@ type rbac struct {
operatorClientSet clientset.Interface
ownerRef metav1.OwnerReference
version string
tektonConfig *v1alpha1.TektonConfig
}

func (r *rbac) cleanUp(ctx context.Context) error {

// fetch the list of all namespaces which have label
// `openshift-pipelines.tekton.dev/namespace-ready: <release-version>`
// `openshift-pipelines.tekton.dev/namespace-reconcile-version: <release-version>`
namespaces, err := r.kubeClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s = %s", namespaceVersionLabel, r.version),
})
Expand All @@ -80,7 +87,7 @@ func (r *rbac) createResources(ctx context.Context) error {
logger := logging.FromContext(ctx)

// fetch the list of all namespaces which doesn't have label
// `openshift-pipelines.tekton.dev/namespace-ready: <release-version>`
// `openshift-pipelines.tekton.dev/namespace-reconcile-version: <release-version>`
namespaces, err := r.kubeClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s != %s", namespaceVersionLabel, r.version),
})
Expand All @@ -104,6 +111,25 @@ func (r *rbac) createResources(ctx context.Context) error {
return nil
}

exist, err := checkIfInstallerSetExist(ctx, r.operatorClientSet, r.version, r.tektonConfig, componentName)
if err != nil {
return err
}
if !exist {
if err := createInstallerSet(ctx, r.operatorClientSet, r.tektonConfig,
r.version, componentName, "rbac-resources"); err != nil {
return err
}
}

getdIs, err := r.operatorClientSet.OperatorV1alpha1().TektonInstallerSets().
Get(ctx, "rbac-resources", metav1.GetOptions{})
if err != nil {
return err
}

r.ownerRef = configOwnerRef(*getdIs)

// Maintaining a separate cluster role for the scc declaration.
// to assist us in managing this the scc association in a
// granular way.
Expand Down Expand Up @@ -136,7 +162,7 @@ func (r *rbac) createResources(ctx context.Context) error {
return err
}

// Add `openshift-pipelines.tekton.dev/namespace-ready` label to namespace
// Add `openshift-pipelines.tekton.dev/namespace-reconcile-version` label to namespace
// so that rbac won't loop on it again
nsLabels := n.GetLabels()
if len(nsLabels) == 0 {
Expand Down Expand Up @@ -384,7 +410,7 @@ func (r *rbac) updateRoleBinding(ctx context.Context, rb *rbacv1.RoleBinding, sa
rb.SetOwnerReferences(ownerRef)

if hasSubject && (len(ownerRef) != 0) {
logger.Info("rolebinding is up to date", "action", "none")
logger.Info("rolebinding is up to date ", "action ", "none")
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ type LRUCache interface {
// Clears all cache entries.
Purge()

// Resizes cache, returning number evicted
Resize(int) int
// Resizes cache, returning number evicted
Resize(int) int
}

0 comments on commit 2cd400e

Please sign in to comment.