Skip to content

Commit

Permalink
manage pipeline console plugin deployment on openshift
Browse files Browse the repository at this point in the history
Signed-off-by: Jeeva Kandasamy <jkandasa@redhat.com>
  • Loading branch information
jkandasa authored and tekton-robot committed Jan 19, 2024
1 parent bb04040 commit 4e280db
Show file tree
Hide file tree
Showing 11 changed files with 887 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Copyright 2024 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# to know about dynamic plugin visit,
# https://github.com/openshift/enhancements/blob/master/enhancements/console/dynamic-plugins.md

# service to access static contents: js, CSS, HTML. etc.,
# this service creates and manages secret called "pipeline-console-plugin-cert"
# generated secret will be used in the console plugin container (nginx + static content)
---
apiVersion: v1
kind: Service
metadata:
name: pipeline-console-plugin
namespace: openshift-pipelines
annotations:
# https://docs.openshift.com/container-platform/4.13/security/certificates/service-serving-certificate.html
service.beta.openshift.io/serving-cert-secret-name: pipeline-console-plugin-cert
labels:
app.kubernetes.io/part-of: tekton-config
spec:
ports:
- name: 8443-tcp
protocol: TCP
port: 8443
targetPort: 8443
selector:
name: pipeline-console-plugin
app: pipeline-console-plugin

# nginx configuration
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pipeline-console-plugin
namespace: openshift-pipelines
labels:
app.kubernetes.io/part-of: tekton-config
data:
nginx.conf: |
error_log /dev/stdout warn;
events {}
http {
access_log /dev/stdout;
include /etc/nginx/mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 8443 ssl;
listen [::]:8443 ssl;
ssl_certificate /var/cert/tls.crt;
ssl_certificate_key /var/cert/tls.key;
root /usr/share/nginx/html;
}
}
# nginx + pipeline dynamic console custom static contents
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pipeline-console-plugin
namespace: openshift-pipelines
labels:
app.kubernetes.io/part-of: tekton-config
spec:
replicas: 1
selector:
matchLabels:
name: pipeline-console-plugin
app: pipeline-console-plugin
template:
metadata:
labels:
name: pipeline-console-plugin
app: pipeline-console-plugin
app.kubernetes.io/part-of: tekton-config
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- name: pipeline-console-plugin-cert
secret:
secretName: pipeline-console-plugin-cert
defaultMode: 420
- name: nginx-conf
configMap:
name: pipeline-console-plugin
defaultMode: 420
containers:
- name: pipeline-console-plugin
image: ghcr.io/openshift-pipelines/console-plugin:main
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8443
volumeMounts:
- name: pipeline-console-plugin-cert
readOnly: true
mountPath: /var/cert
- name: nginx-conf
readOnly: true
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf

# Console plugin is a cluster wide resource
# updates pipeline dynamic content provider service details
---
apiVersion: console.openshift.io/v1
kind: ConsolePlugin
metadata:
name: pipeline-console-plugin
labels:
app.kubernetes.io/part-of: tekton-config
spec:
displayName: Pipeline Console Plugin
backend:
type: Service
service:
name: pipeline-console-plugin
namespace: openshift-pipelines
port: 8443
basePath: "/"
i18n:
loadType: Preload # options: Preload, Lazy
13 changes: 13 additions & 0 deletions config/openshift/base/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,16 @@ rules:
- delete
- update
- patch
# to manage ConsolePlugin custom resource
- apiGroups:
- console.openshift.io
resources:
- consoleplugins
verbs:
- get
- list
- watch
- create
- delete
- update
- patch
9 changes: 9 additions & 0 deletions operatorhub/openshift/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ image-substitutions:
envKeys:
- IMAGE_ADDONS_PARAM_MAVEN_IMAGE

# pipelines console plugin image
- image: ghcr.io/openshift-pipelines/console-plugin:main
replaceLocations:
envTargets:
- deploymentName: openshift-pipelines-operator
containerName: openshift-pipelines-operator-lifecycle
envKeys:
- IMAGE_PIPELINE_CONSOLE_PLUGIN

# add third party images which are not replaced by operator
# but pulled directly by tasks here
defaultRelatedImages: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ metadata:
capabilities: Full Lifecycle
categories: Developer Tools, Integration & Delivery
certified: "false"
console.openshift.io/plugins: '["pipeline-console-plugin"]'
description: Red Hat OpenShift Pipelines is a cloud-native CI/CD solution for building pipelines using Tekton concepts which run natively on OpenShift and Kubernetes.
operators.operatorframework.io/builder: operator-sdk-v1.7.2
operators.openshift.io/infrastructure-features: '["disconnected","proxy-aware"]'
Expand Down
58 changes: 58 additions & 0 deletions pkg/reconciler/common/testdata/test-replace-namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sample-sa
namespace: tekton-pipelines

---
apiVersion: v1
kind: Service
metadata:
name: sample-service
namespace: tekton-pipelines

---
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-config-map
namespace: tekton-pipelines

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-config-map
namespace: tekton-pipelines

---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
namespace: tekton-pipelines

---
apiVersion: v1
kind: Secret
metadata:
name: sample-secret
namespace: tekton-pipelines

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sample-cluster-role-binding
subjects:
- kind: ServiceAccount
name: tekton-resource-pruner
namespace: hello
- kind: ServiceAccount
name: tekton-resource-pruner2
namespace: tekton-pipelines
roleRef:
kind: ClusterRole
name: tekton-resource-pruner
apiGroup: rbac.authorization.k8s.io
35 changes: 35 additions & 0 deletions pkg/reconciler/common/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,38 @@ func ReplaceNamespaceInClusterRoleBinding(targetNamespace string) mf.Transformer
return nil
}
}

// updates "metadata.namespace" and under "spec"
// TODO: we have different transformer for each kind
// TODO: replaces all the existing transformers(used to update namespace) with this.
func ReplaceNamespace(newNamespace string) mf.Transformer {
return func(u *unstructured.Unstructured) error {
// update metadata.namespace for all the resources
// this change will be updated in cluster wide resource too
// there is no effect on updating namespace on cluster wide resource
u.SetNamespace(newNamespace)

switch u.GetKind() {
case "ClusterRoleBinding":
crb := &rbacv1.ClusterRoleBinding{}
err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, crb)
if err != nil {
return err
}

// update namespace
for index := range crb.Subjects {
crb.Subjects[index].Namespace = newNamespace
}

obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(crb)
if err != nil {
return err
}
u.SetUnstructuredContent(obj)

}

return nil
}
}
47 changes: 47 additions & 0 deletions pkg/reconciler/common/transformers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,3 +811,50 @@ func TestCopyConfigMap(t *testing.T) {
})
}
}

func TestReplaceNamespace(t *testing.T) {
tests := []struct {
name string
targetNamespace string
}{
{
name: "target-ns-foo",
targetNamespace: "foo",
},
{
name: "target-ns-bar",
targetNamespace: "bar",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// get a manifest
testData := path.Join("testdata", "test-replace-namespace.yaml")
manifest, err := mf.ManifestFrom(mf.Recursive(testData))
assert.NilError(t, err)

manifest, err = manifest.Transform(ReplaceNamespace(test.targetNamespace))
assert.NilError(t, err)

// verify the changes
for _, resource := range manifest.Resources() {
// assert namespace
assert.Equal(t, test.targetNamespace, resource.GetNamespace())

switch resource.GetKind() {
case "ClusterRoleBinding":
crb := &rbacv1.ClusterRoleBinding{}
err := runtime.DefaultUnstructuredConverter.FromUnstructured(resource.Object, crb)
assert.NilError(t, err)
// verify namespace
for index := range crb.Subjects {
assert.Equal(t, test.targetNamespace, crb.Subjects[index].Namespace)

}
}

}
})
}
}
Loading

0 comments on commit 4e280db

Please sign in to comment.