Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds webhook for Repository Validation #708

Merged
merged 9 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ghcr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ env:
REGISTRY: ghcr.io
CONTROLLER_IMAGE_NAME: ${{ github.repository }}-controller
WATCHER_IMAGE_NAME: ${{ github.repository }}-watcher
WEBHOOK_IMAGE_NAME: ${{ github.repository }}-webhook
TKN_PAC_IMAGE_NAME: ${{ github.repository }}-tkn-pac

jobs:
Expand Down Expand Up @@ -58,6 +59,22 @@ jobs:
tags: ${{ steps.meta-watcher.outputs.tags }}
labels: ${{ steps.meta-watcher.outputs.labels }}

- name: Extract metadata (tags, labels) for Docker (Webhook)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think there is.a way to do "matrix" in google actions for not have to copy and paste large block everytime, i guess we can do that if we have to add another image again 🙃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use matrix but there will 4 jobs created currently we execute all in one

id: meta-webhook
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.WEBHOOK_IMAGE_NAME }}

- name: Build and push webhook docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
build-args: |
BINARY_NAME=pipelines-as-code-webhook
push: true
tags: ${{ steps.meta-webhook.outputs.tags }}
labels: ${{ steps.meta-webhook.outputs.labels }}

- name: Extract metadata (tags, labels) for tkn-pac
id: meta-cli
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
Expand Down
59 changes: 59 additions & 0 deletions cmd/pipelines-as-code-webhook/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"context"
"os"

validation_webhook "github.com/openshift-pipelines/pipelines-as-code/pkg/webhook"
"knative.dev/pkg/configmap"
"knative.dev/pkg/controller"
"knative.dev/pkg/injection"
"knative.dev/pkg/injection/sharedmain"
"knative.dev/pkg/signals"
"knative.dev/pkg/webhook"
"knative.dev/pkg/webhook/certificates"
)

func main() {
ctx := signals.NewContext()

serviceName := os.Getenv("WEBHOOK_SERVICE_NAME")
if serviceName == "" {
serviceName = "pipelines-as-code-webhook"
}
secretName := os.Getenv("WEBHOOK_SECRET_NAME")
if secretName == "" {
secretName = "pipelines-as-code-webhook-certs"
}
// Set up a signal context with our webhook options
ctx = webhook.WithOptions(ctx, webhook.Options{
ServiceName: serviceName,
Port: 8443,
SecretName: secretName,
})

sharedmain.WebhookMainWithConfig(ctx, "pipelines-as-code-webhook",
injection.ParseAndGetRESTConfigOrDie(),
certificates.NewController,
newValidationAdmissionController,
)
}

func newValidationAdmissionController(ctx context.Context, _ configmap.Watcher) *controller.Impl {
return validation_webhook.NewAdmissionController(ctx,

// Name of the resource webhook.
"validation.pipelinesascode.tekton.dev",

// The path on which to serve the webhook.
"/validate",

// A function that infuses the context passed to Validate/SetDefaults with custom metadata.
func(ctx context.Context) context.Context {
return ctx
},

// Whether to disallow unknown fields.
true,
)
}
110 changes: 110 additions & 0 deletions config/203-webhook-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright 2022 Red Hat
#
# 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.
apiVersion: v1
kind: ServiceAccount
metadata:
name: pipelines-as-code-webhook
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pipelines-as-code-webhook-role
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "update"]
resourceNames: ["pipelines-as-code-webhook-certs"]
# The webhook daemon makes a reconciliation loop on webhook-certs. Whenever
# the secret changes it updates the webhook configurations with the certificates
# stored in the secret.
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
# webhook uses leases for leader election
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pipelines-as-code-webhook-binding
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
subjects:
- kind: ServiceAccount
name: pipelines-as-code-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pipelines-as-code-webhook-role
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pipeline-as-code-webhook-clusterrole
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
rules:
- apiGroups: ["pipelinesascode.tekton.dev"]
resources: ["repositories"]
verbs: ["get", "list", "watch"]
# The webhook performs a reconciliation on this resource and continuously
# updates configuration.
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingwebhookconfigurations"]
verbs: ["list", "watch"]
# When there are changes to the configs or secrets, knative updates the validating webhook config
# with the updated certificates or the refreshed set of rules.
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingwebhookconfigurations"]
verbs: ["get", "update", "delete"]
resourceNames: ["validation.pipelinesascode.tekton.dev"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pipelines-as-code-webhook-clusterbinding
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
subjects:
- kind: ServiceAccount
name: pipelines-as-code-webhook
namespace: pipelines-as-code
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pipeline-as-code-webhook-clusterrole
39 changes: 39 additions & 0 deletions config/304-webhook-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2022 Red Hat
#
# 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.
apiVersion: v1
kind: Secret
metadata:
name: pipelines-as-code-webhook-certs
namespace: pipelines-as-code
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/part-of: pipelines-as-code
# The data is populated at install time
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validation.pipelinesascode.tekton.dev
labels:
app.kubernetes.io/version: "devel"
app.kubernetes.io/part-of: pipelines-as-code
webhooks:
- admissionReviewVersions: ["v1"]
clientConfig:
service:
name: pipelines-as-code-webhook
namespace: pipelines-as-code
failurePolicy: Fail
sideEffects: None
name: validation.pipelinesascode.tekton.dev
54 changes: 54 additions & 0 deletions config/600-webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2022 Red Hat
#
# 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.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pipelines-as-code-webhook
namespace: pipelines-as-code
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: webhook
app.kubernetes.io/component: webhook
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
template:
metadata:
labels:
app.kubernetes.io/name: webhook
app.kubernetes.io/component: webhook
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
app.kubernetes.io/version: "devel"
spec:
serviceAccountName: pipelines-as-code-webhook
containers:
- name: pipelines-as-code-webhook
image: "ko://github.com/openshift-pipelines/pipelines-as-code/cmd/pipelines-as-code-webhook"
env:
- name: SYSTEM_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: WEBHOOK_SERVICE_NAME
value: pipelines-as-code-webhook
- name: WEBHOOK_SECRET_NAME
value: pipelines-as-code-webhook-certs
- name: METRICS_DOMAIN
value: tekton.dev/pipelinesascode
ports:
- name: https-webhook
containerPort: 8443
32 changes: 32 additions & 0 deletions config/601-webhook-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2022 Red Hat
#
# 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.
---
apiVersion: v1
kind: Service
metadata:
name: pipelines-as-code-webhook
namespace: pipelines-as-code
labels:
name: pipelines-as-code-webhook
app: pipelines-as-code
spec:
ports:
- name: https-webhook
port: 443
targetPort: 8443
selector:
app.kubernetes.io/name: webhook
app.kubernetes.io/component: webhook
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: pipelines-as-code
2 changes: 2 additions & 0 deletions hack/generate-releaseyaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set -euf

export TARGET_REPO_CONTROLLER=${TARGET_REPO_CONTROLLER:-ghcr.io/openshift-pipelines/pipelines-as-code-controller}
export TARGET_REPO_WATCHER=${TARGET_REPO_WATCHER:-ghcr.io/openshift-pipelines/pipelines-as-code-watcher}
export TARGET_REPO_WEBHOOK=${TARGET_REPO_WEBHOOK:-ghcr.io/openshift-pipelines/pipelines-as-code-webhook}
export TARGET_BRANCH=${TARGET_BRANCH:-main}
export TARGET_NAMESPACE=${TARGET_NAMESPACE:-pipelines-as-code}
export TARGET_OPENSHIFT=${TARGET_OPENSHIFT:-""}
Expand Down Expand Up @@ -34,6 +35,7 @@ for file in ${files};do
head -1 ${file} | grep -q -- "---" || echo -e "\n---\n"
sed -r -e "s,(.*image:.*)ko://github.com/openshift-pipelines/pipelines-as-code/cmd/pipelines-as-code-controller.*,\1${TARGET_REPO_CONTROLLER}:${TARGET_BRANCH}\"," \
-r -e "s,(.*image:.*)ko://github.com/openshift-pipelines/pipelines-as-code/cmd/pipelines-as-code-watcher.*,\1${TARGET_REPO_WATCHER}:${TARGET_BRANCH}\"," \
-r -e "s,(.*image:.*)ko://github.com/openshift-pipelines/pipelines-as-code/cmd/pipelines-as-code-webhook.*,\1${TARGET_REPO_WEBHOOK}:${TARGET_BRANCH}\"," \
-e "s/(namespace: )\w+.*/\1${TARGET_NAMESPACE}/g" \
-e "s,app.kubernetes.io/version:.*,app.kubernetes.io/version: \"${TARGET_PAC_VERSION}\"," \
-e "s/Copyright[ ]*[0-9]{4}/Copyright $(date "+%Y")/" \
Expand Down
11 changes: 7 additions & 4 deletions pkg/test/clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
informersv1alpha1 "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/informers/externalversions/pipelinesascode/v1alpha1"
fakepacclient "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/injection/client/fake"
fakerepositoryinformers "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/injection/informers/pipelinesascode/v1alpha1/repository/fake"
v1alpha12 "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/listers/pipelinesascode/v1alpha1"
pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
fakepipelineclientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake"
"github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1"
Expand All @@ -22,10 +23,11 @@ import (
)

type Clients struct {
Pipeline *fakepipelineclientset.Clientset
PipelineAsCode *fakepacclientset.Clientset
Kube *fakekubeclientset.Clientset
PipelineLister v1beta12.PipelineRunLister
Pipeline *fakepipelineclientset.Clientset
PipelineAsCode *fakepacclientset.Clientset
Kube *fakekubeclientset.Clientset
PipelineLister v1beta12.PipelineRunLister
RepositoryLister v1alpha12.RepositoryLister
}

// Informers holds references to informers which are useful for reconciler tests.
Expand Down Expand Up @@ -55,6 +57,7 @@ func SeedTestData(t *testing.T, ctx context.Context, d Data) (Clients, Informers
PipelineRun: fakepipelineruninformer.Get(ctx),
}
c.PipelineLister = i.PipelineRun.Lister()
c.RepositoryLister = i.Repository.Lister()

for _, pr := range d.PipelineRuns {
if err := i.PipelineRun.Informer().GetIndexer().Add(pr); err != nil {
Expand Down