Skip to content

Commit

Permalink
github-jira-proxy, prow, plugin: add plugin that checks github webhooks
Browse files Browse the repository at this point in the history
Signed-off-by: avlitman <alitman@redhat.com>
  • Loading branch information
avlitman committed Jul 9, 2024
1 parent 9a7e357 commit 7cbf1e0
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 0 deletions.
20 changes: 20 additions & 0 deletions external-plugins/github-jira-proxy/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

.PHONY: all build test format push
all: format push
bazelbin := bazelisk
CONTAINER_TAG := $(shell ../../hack/container-tag.sh)
CONTAINER_IMAGE := github-jira-proxy
CONTAINER_REPO := quay.io/kubevirtci/$(CONTAINER_IMAGE)

build:
$(bazelbin) build //external-plugins/github-jira-proxy/...

test:
$(bazelbin) test //external-plugins/github-jira-proxy/...

format:
gofmt -w .

push:
podman build -f ../../images/$(CONTAINER_IMAGE)/Containerfile -t $(CONTAINER_REPO):$(CONTAINER_TAG) && podman push $(CONTAINER_REPO):$(CONTAINER_TAG)
bash -x ../../hack/update-deployments-with-latest-image.sh $(CONTAINER_REPO)
82 changes: 82 additions & 0 deletions external-plugins/github-jira-proxy/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
)

func verifySignature(message, messageMAC, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(message))
expectedMAC := mac.Sum(nil)
signature := "sha256=" + hex.EncodeToString(expectedMAC)
return hmac.Equal([]byte(signature), []byte(messageMAC))
}

func forwardRequest(r *http.Request, url string) (*http.Response, error) {
client := &http.Client{}
req, err := http.NewRequest(r.Method, url, r.Body)
if err != nil {
return nil, err
}

// Copy headers, exclude the 'X-Hub-Signature-256' header
for name, values := range r.Header {
if strings.ToLower(name) != "x-hub-signature-256" {
for _, value := range values {
req.Header.Add(name, value)
}
}
}

return client.Do(req)
}

func handler(w http.ResponseWriter, r *http.Request) {
secret := os.Getenv("SECRET")
forwardTo := os.Getenv("FORWARD_TO")

body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to read body", http.StatusInternalServerError)
return
}
// Restore the body for forwarding
r.Body = ioutil.NopCloser(bytes.NewReader(body))

signatureHeader := r.Header.Get("X-Hub-Signature-256")
if !verifySignature(string(body), signatureHeader, secret) {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}

// Forward the request to Jira
resp, err := forwardRequest(r, forwardTo)
if err != nil {
http.Error(w, "Failed to forward request", http.StatusInternalServerError)
return
}

defer resp.Body.Close()
for name, values := range resp.Header {
for _, value := range values {
w.Header().Add(name, value)
}
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}

func main() {
http.HandleFunc("/github-proxy-forwarder", handler)
port := "9900"
println("Listening on port " + port)
http.ListenAndServe(":"+port, nil)
}
14 changes: 14 additions & 0 deletions external-plugins/github-jira-proxy/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"testing"
)

func TestVerifySignature(t *testing.T) {
secret := "testsecret"
message := "hello"
correctSignature := "sha256=f6cf7145c300e5aefed1f5b60d1b8f7f74aa955f5ca2a2e88d1a4a1b8e7b9c0b"
if !verifySignature(message, correctSignature, secret) {
t.Errorf("Signature verification failed.")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,35 @@ postsubmits:
memory: "8Gi"
securityContext:
privileged: true
- name: publish-github-jira-proxy-image
always_run: false
run_if_changed: "^(external-plugins|images)/github-jira-proxy/.*"
annotations:
testgrid-create-test-group: "false"
decorate: true
cluster: kubevirt-prow-control-plane
max_concurrency: 1
labels:
preset-bazel-cache: "true"
preset-kubevirtci-quay-credential: "true"
preset-podman-in-container-enabled: "true"
spec:
containers:
- image: quay.io/kubevirtci/bootstrap:v20240607-febc467
command:
- "/usr/local/bin/runner.sh"
- "/bin/bash"
- "-c"
- |
cat "$QUAY_PASSWORD" | podman login --username $(cat "$QUAY_USER") --password-stdin=true quay.io
make -C ./external-plugins/github-jira-proxy push
resources:
requests:
memory: "8Gi"
limits:
memory: "8Gi"
securityContext:
privileged: true
- name: publish-kubevirt-infra-bootstrap-image
always_run: false
run_if_changed: "images/kubevirt-infra-bootstrap/.*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,10 @@ external_plugins:
endpoint: http://referee:9900
events:
- issue_comment
- name: github-jira-proxy
endpoint: http://github-jira-proxy:9900
events:
- pull_request

triggers:
- repos:
Expand Down
2 changes: 2 additions & 0 deletions github/ci/prow-deploy/kustom/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ resources:
- manifests/local/prow-phased-service.yaml
- manifests/local/referee-deployment.yaml
- manifests/local/referee-service.yaml
- manifests/local/github-jira-proxy-deployment.yaml
- manifests/local/github-jira-proxy-service.yaml
- manifests/local/referee-servicemonitor.yaml
- manifests/local/release-blocker_deployment.yaml
- manifests/local/release-blocker_service.yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-jira-proxy
labels:
app: github-jira-proxy
spec:
replicas: 1
selector:
matchLabels:
app: github-jira-proxy
template:
metadata:
labels:
app: github-jira-proxy
spec:
terminationGracePeriodSeconds: 180
containers:
- name: github-jira-proxy
image: quay.io/kubevirtci/github-jira-proxy:latest
args:
- --dry-run=false
- --port=9900
- --github-token-path=/etc/github/oauth
- --github-endpoint=http://ghproxy
- --github-endpoint=https://api.github.com
ports:
- name: http
containerPort: 9900
volumeMounts:
- name: hmac
mountPath: /etc/webhook
readOnly: true
- name: oauth
mountPath: /etc/github
readOnly: true
- name: plugins
mountPath: /etc/plugins
readOnly: true
- name: cache
mountPath: /var/run/cache
readOnly: false
volumes:
- name: hmac
secret:
secretName: hmac-token
- name: oauth
secret:
secretName: commenter-oauth-token
- name: plugins
configMap:
name: plugins
- name: cache
emptyDir: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
apiVersion: v1
kind: Service
metadata:
name: github-jira-proxy
labels:
app: github-jira-proxy
spec:
ports:
- name: default
port: 9900
protocol: TCP
targetPort: 9900
selector:
app: github-jira-proxy
type: ClusterIP
12 changes: 12 additions & 0 deletions images/github-jira-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM docker.io/library/golang:1.21 as builder
WORKDIR /go/src/github.com/kubevirt/project-infra/
RUN mkdir -p /go/src/kubevirt/ && \
cd /go/src/kubevirt/ && \
git clone https://github.com/kubevirt/project-infra.git && \
cd project-infra/ && \
go mod vendor && \
env GOPROXY=off GOFLAGS=-mod=vendor CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /go/bin/github-jira-proxy ./external-plugins/github-jira-proxy/main.go

FROM gcr.io/k8s-prow/git:latest
COPY --from=builder /go/bin/github-jira-proxy /usr/bin/github-jira-proxy
ENTRYPOINT ["/usr/bin/github-jira-proxy"]

0 comments on commit 7cbf1e0

Please sign in to comment.