mirror of https://github.com/knative/docs.git
Update the gitwebhook sample (#215)
* Clean up sample * Swap token IDs to the right values * Set format to json * Remove old yaml
This commit is contained in:
parent
654804a423
commit
d0b78289f0
|
@ -14,14 +14,22 @@
|
|||
|
||||
FROM golang AS builder
|
||||
|
||||
WORKDIR /go/src/github.com/knative/docs/
|
||||
ADD . /go/src/github.com/knative/docs/
|
||||
# copy the source
|
||||
ADD . /go/src/github.com/knative/docs/serving/samples/gitwebhook-go
|
||||
WORKDIR /go/src/github.com/knative/docs/serving/samples/gitwebhook-go
|
||||
|
||||
RUN CGO_ENABLED=0 go build ./serving/samples/gitwebhook-go/
|
||||
# install dependencies
|
||||
RUN go get github.com/google/go-github/github
|
||||
RUN go get golang.org/x/oauth2
|
||||
RUN go get gopkg.in/go-playground/webhooks.v3
|
||||
RUN go get gopkg.in/go-playground/webhooks.v3/github
|
||||
|
||||
FROM gcr.io/distroless/base
|
||||
# build the sample
|
||||
RUN CGO_ENABLED=0 go build -o /go/bin/webhook-sample .
|
||||
|
||||
FROM golang:alpine
|
||||
|
||||
EXPOSE 8080
|
||||
COPY --from=builder /go/src/github.com/knative/docs/gitwebhook-go /sample
|
||||
COPY --from=builder /go/bin/webhook-sample /app/webhook-sample
|
||||
|
||||
ENTRYPOINT ["/sample"]
|
||||
ENTRYPOINT ["/app/webhook-sample"]
|
||||
|
|
|
@ -1,84 +1,153 @@
|
|||
# gitwebhook
|
||||
# GitHub Webhook - Go sample
|
||||
|
||||
A simple git webhook handler that demonstrates interacting with
|
||||
github.
|
||||
[Modeled after GCF example](https://cloud.google.com/community/tutorials/github-auto-assign-reviewers-cloud-functions)
|
||||
A handler written in Go that demonstrates interacting with GitHub
|
||||
through a webhook.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. [Install Knative Serving](https://github.com/knative/docs/blob/master/install/README.md)
|
||||
1. Install [docker](https://www.docker.com/)
|
||||
* A Kubernetes cluster with Knative installed. Follow the
|
||||
[installation instructions](https://github.com/knative/docs/blob/master/install/README.md)
|
||||
if you need to create one.
|
||||
* [Docker](https://www.docker.com) installed and running on your local machine,
|
||||
and a Docker Hub account configured (we'll use it for a container registry).
|
||||
* An account on [GitHub](https://github.com) with read/write access to a
|
||||
repository.
|
||||
|
||||
## Setup
|
||||
## Build the sample code
|
||||
|
||||
Build the app container and publish it to your registry of choice:
|
||||
1. Use Docker to build a container image for this service. Replace
|
||||
`{username}` with your Docker Hub username in the following commands.
|
||||
|
||||
```shell
|
||||
export DOCKER_HUB_USERNAME=username
|
||||
|
||||
# Build the container, run from the project folder
|
||||
docker build -t ${DOCKER_HUB_USERNAME}/gitwebhook-go .
|
||||
|
||||
# Push the container to the registry
|
||||
docker push ${DOCKER_HUB_USERNAME}/gitwebhook-go
|
||||
```
|
||||
|
||||
1. Create a secret that holds two values from GitHub, a personal access token
|
||||
used to make API requests to GitHub, and a webhook secret, used to validate
|
||||
incoming requests.
|
||||
|
||||
1. Follow the GitHub instructions to [create a personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/).
|
||||
Ensure to grant the `repo` permission to give read/write access to the
|
||||
personal access token.
|
||||
1. Base64 encode the access token:
|
||||
|
||||
```shell
|
||||
$ echo -n "45d382d4a9a93c453fb7c8adc109121e7c29fa3ca" | base64
|
||||
NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E=
|
||||
```
|
||||
|
||||
1. Copy the encoded access token into `github-secret.yaml` next to `personalAccessToken:`.
|
||||
1. Create a webhook secert value unique to this sample, base64 encode it, and
|
||||
copy it into `github-secret.yaml` next to `webhookSecret:`:
|
||||
|
||||
```shell
|
||||
$ echo -n "mygithubwebhooksecret" | base64
|
||||
bXlnaXRodWJ3ZWJob29rc2VjcmV0
|
||||
```
|
||||
|
||||
1. Apply the secret to your cluster:
|
||||
|
||||
```shell
|
||||
kubectl apply -f github-secret.yaml
|
||||
```
|
||||
|
||||
1. Next, update the `service.yaml` file in the project to reference the tagged
|
||||
image from step 1.
|
||||
|
||||
```yaml
|
||||
apiVersion: serving.knative.dev/v1alpha1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitwebhook
|
||||
namespace: default
|
||||
spec:
|
||||
runLatest:
|
||||
configuration:
|
||||
revisionTemplate:
|
||||
spec:
|
||||
container:
|
||||
# Replace {DOCKER_HUB_USERNAME} with your actual docker hub username
|
||||
image: docker.io/{DOCKER_HUB_USERNAME}/gitwebhook-go
|
||||
env:
|
||||
- name: SECRET_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: secretToken
|
||||
- name: ACCESS_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: accessToken
|
||||
```
|
||||
|
||||
1. Use `kubectl` to apply the `service.yaml` file.
|
||||
|
||||
```shell
|
||||
REPO="gcr.io/<your-project-here>"
|
||||
|
||||
# Build and publish the container, run from the root directory.
|
||||
docker build \
|
||||
--tag "${REPO}/serving/samples/gitwebhook-go" \
|
||||
--file=serving/samples/gitwebhook-go/Dockerfile .
|
||||
docker push "${REPO}/serving/samples/gitwebhook-go"
|
||||
|
||||
# Replace the image reference with our published image.
|
||||
perl -pi -e "s@github.com/knative/docs/serving/samples/gitwebhook-go@${REPO}/serving/samples/gitwebhook-go@g" serving/samples/gitwebhook-go/*.yaml
|
||||
|
||||
# Deploy the Knative Serving sample
|
||||
kubectl apply -f serving/samples/gitwebhook-go/sample.yaml
|
||||
$ kubectl apply -f service.yaml
|
||||
service "gitwebhook" created
|
||||
```
|
||||
|
||||
1. Finally, once the service is running, create the webhook from your GitHub repo
|
||||
to the URL for this service. For this to work properly you will
|
||||
need to [configure a custom domain](https://github.com/knative/docs/blob/master/serving/using-a-custom-domain.md)
|
||||
and [assign a static IP address](https://github.com/knative/docs/blob/master/serving/gke-assigning-static-ip-address.md).
|
||||
|
||||
1. Retrieve the hostname for this service, using the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl get services.serving.knative.dev gitwebhook \
|
||||
-o=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
|
||||
|
||||
NAME DOMAIN
|
||||
gitwebhook gitwebhook.default.example.com
|
||||
```
|
||||
|
||||
1. Browse on GitHub to the repository where you want to create a webhook.
|
||||
1. Click **Settings**, then **Webhooks**, then **Add webhook**.
|
||||
1. Enter the **Payload URL** as `http://{DOMAIN}`, with the value of DOMAIN listed above.
|
||||
1. Set the **Content type** to `application/json`.
|
||||
1. Enter the **Secret** value to be the same as the original base used for
|
||||
`webhookSecret` above (the original value, not the base64 encoded value).
|
||||
1. Select **Disable** under SSL Validation, unless you've [enabled SSL](https://github.com/knative/docs/blob/master/serving/using-an-ssl-cert.md).
|
||||
1. Click **Add webhook** to create the webhook.
|
||||
|
||||
## Exploring
|
||||
|
||||
Once deployed, you can inspect the created resources with `kubectl` commands:
|
||||
|
||||
```shell
|
||||
# This will show the Route that we created:
|
||||
# This will show the Knative service that we created:
|
||||
kubectl get service.serving.knative.dev -o yaml
|
||||
|
||||
# This will show the Route, created by the service:
|
||||
kubectl get route -o yaml
|
||||
|
||||
# This will show the Configuration that we created:
|
||||
# This will show the Configuration, created by the service:
|
||||
kubectl get configurations -o yaml
|
||||
|
||||
# This will show the Revision that was created by our configuration:
|
||||
# This will show the Revision, created by the Configuration:
|
||||
kubectl get revisions -o yaml
|
||||
|
||||
```
|
||||
|
||||
To make this service accessible to github, we first need to determine its ingress address
|
||||
(might have to wait a little while until `EXTERNAL-IP` gets assigned):
|
||||
```shell
|
||||
watch kubectl get svc knative-ingressgateway -n istio-system
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
knative-ingressgateway LoadBalancer 10.23.247.74 35.203.155.229 80:32380/TCP,443:32390/TCP,32400:32400/TCP 2d
|
||||
```
|
||||
## Testing the service
|
||||
|
||||
Once the `EXTERNAL-IP` gets assigned to the cluster, you need to assign a DNS name for that IP address.
|
||||
[Using GCP DNS](https://support.google.com/domains/answer/3290350)
|
||||
|
||||
So, you'd need to create an A record for demostuff.aikas.org pointing to 35.202.30.59.
|
||||
|
||||
Then you need to go to github and [set up a webhook](https://cloud.google.com/community/tutorials/github-auto-assign-r
|
||||
eviewers-cloud-functions).
|
||||
For the Payload URL however, use your DNS entry you created above, so for my example it would be:
|
||||
http://demostuff.aikas.org/
|
||||
|
||||
Create a secret that has access to the tokens. Take the Secret you used for the webhook
|
||||
(secretToken) and the generated access token (accessToken) (as per the above webhook)
|
||||
|
||||
```shell
|
||||
echo -n "your-chosen-secret-token" > secretToken
|
||||
echo -n "github-generated-access-token" > accessToken
|
||||
kubectl create secret generic githubsecret --from-file=./secretToken --from-file=./accessToken
|
||||
```
|
||||
|
||||
Then create a PR for the repo you configured the webhook for, and you'll see that the Title
|
||||
will be modified with the suffix '(looks pretty legit)'
|
||||
Now that you have the service running and the webhook created, send a Pull
|
||||
Request to the same GitHub repo where you added the webhook. If all is working
|
||||
right, you'll see the title of the PR will be modified, with the text
|
||||
`(looks pretty legit)` appended the end of the title.
|
||||
|
||||
## Cleaning up
|
||||
|
||||
To clean up the sample service:
|
||||
|
||||
```shell
|
||||
kubectl delete -f serving/samples/gitwebhook-go/sample.yaml
|
||||
kubectl delete -f service.yaml
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: githubsecret
|
||||
type: Opaque
|
||||
data:
|
||||
# Generate a personal access token from GitHub
|
||||
# See https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
|
||||
personalAccessToken: <base64 encoded personal access token>
|
||||
# The secret specified when creating the webhook on GitHub
|
||||
# This is used to validate incoming webhook messages.
|
||||
webhookSecret: <base64 encoded webhook secret>
|
|
@ -24,19 +24,18 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
ghclient "github.com/google/go-github/github"
|
||||
"golang.org/x/oauth2"
|
||||
webhooks "gopkg.in/go-playground/webhooks.v3"
|
||||
"gopkg.in/go-playground/webhooks.v3/github"
|
||||
|
||||
ghclient "github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
const (
|
||||
// Secret given to github. Used for verifying the incoming objects.
|
||||
accessTokenKey = "ACCESS_TOKEN"
|
||||
personalAccessTokenKey = "GITHUB_PERSONAL_TOKEN"
|
||||
// Personal Access Token created in github that allows us to make
|
||||
// calls into github.
|
||||
secretTokenKey = "SECRET_TOKEN"
|
||||
webhookSecretKey = "WEBHOOK_SECRET"
|
||||
// this is what we tack onto each PR title if not there already
|
||||
titleSuffix = "looks pretty legit"
|
||||
)
|
||||
|
@ -82,15 +81,15 @@ func (handler *GithubHandler) HandlePullRequest(payload interface{}, header webh
|
|||
func main() {
|
||||
flag.Parse()
|
||||
log.Print("gitwebhook sample started.")
|
||||
accessToken := os.Getenv(accessTokenKey)
|
||||
secretToken := os.Getenv(secretTokenKey)
|
||||
personalAccessToken := os.Getenv(personalAccessTokenKey)
|
||||
secretToken := os.Getenv(webhookSecretKey)
|
||||
|
||||
// Set up the auth for being able to talk to Github. It's
|
||||
// odd that you have to also pass context around for the
|
||||
// calls even after giving it to client. But, whatever.
|
||||
ctx := context.Background()
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: accessToken},
|
||||
&oauth2.Token{AccessToken: personalAccessToken},
|
||||
)
|
||||
tc := oauth2.NewClient(ctx, ts)
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
# Copyright 2018 The Knative 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
|
||||
#
|
||||
# https://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: serving.knative.dev/v1alpha1
|
||||
kind: Route
|
||||
metadata:
|
||||
name: git-webhook
|
||||
namespace: default
|
||||
spec:
|
||||
traffic:
|
||||
- configurationName: git-webhook
|
||||
percent: 100
|
||||
---
|
||||
apiVersion: serving.knative.dev/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: git-webhook
|
||||
namespace: default
|
||||
spec:
|
||||
revisionTemplate:
|
||||
metadata:
|
||||
labels:
|
||||
knative.dev/type: app
|
||||
spec:
|
||||
container:
|
||||
# This is the Go import path for the binary to containerize
|
||||
# and substitute here.
|
||||
image: github.com/knative/docs/serving/samples/gitwebhook-go
|
||||
env:
|
||||
- name: SECRET_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: secretToken
|
||||
- name: ACCESS_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: accessToken
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright 2018 The Knative 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
|
||||
#
|
||||
# https://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: serving.knative.dev/v1alpha1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitwebhook
|
||||
namespace: default
|
||||
spec:
|
||||
runLatest:
|
||||
configuration:
|
||||
revisionTemplate:
|
||||
spec:
|
||||
container:
|
||||
# Replace {DOCKER_HUB_USERNAME} with your actual docker hub username
|
||||
image: docker.io/{DOCKER_HUB_USERNAME}/gitwebhook:latest
|
||||
env:
|
||||
- name: GITHUB_PERSONAL_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: personalAccessToken
|
||||
- name: WEBHOOK_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: githubsecret
|
||||
key: webhookSecret
|
Loading…
Reference in New Issue