Remove outdated samples (#509)

This commit is contained in:
Ville Aikas 2018-11-06 12:58:36 -08:00 committed by Knative Prow Robot
parent 44cd74fe68
commit 67224a6786
19 changed files with 0 additions and 1140 deletions

View File

@ -1,119 +0,0 @@
# Sample: Binding running services to an IoT core
This sample shows how to bind a running service to an IoT core using PubSub as the event source.
> For the ease of the demonstration, a few variables here are hard-coded.
## Setup
Define environment variables:
```shell
export IOTCORE_PROJECT="s9-demo"
export IOTCORE_REG="next18-demo"
export IOTCORE_DEVICE="next18-demo-client"
export IOTCORE_REGION="us-central1"
export IOTCORE_TOPIC_DATA="iot-demo"
export IOTCORE_TOPIC_DEVICE="iot-demo-device"
```
## Create a device registry
Run the following command to create a device registry:
```shell
gcloud iot registries create $IOTCORE_REG \
--project=$IOTCORE_PROJECT \
--region=$IOTCORE_REGION \
--event-notification-config=$IOTCORE_TOPIC_DATA \
--state-pubsub-topic=$IOTCORE_TOPIC_DEVICE
```
## Create device certificates
Create certificates to connect the device to the IoT Core gateway:
```shell
openssl genrsa -out rsa_private.pem 2048
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem
```
## Register the IoT device
Once created, add the public key to the IoT core registry:
```shell
gcloud iot devices create $IOTCORE_DEVICE \
--project=$IOTCORE_PROJECT \
--region=$IOTCORE_REGION \
--registry=$IOTCORE_REG \
--public-key path=./rsa_public.pem,type=rs256
```
## Generate data
To mimic an IoT device sending data to the IoT gateway, run the provided
Node.js client with the following parameters:
```shell
node send-data.js \
--projectId=$IOTCORE_PROJECT \
--cloudRegion=$IOTCORE_REGION \
--registryId=$IOTCORE_REG \
--deviceId=$IOTCORE_DEVICE \
--privateKeyFile=./iot_demo_private.pem \
--algorithm=RS256
```
This "device" will publish one event per second to the IoT Core gateway.
The gateway will automatically publish the received events to the configured
PubSub topic (`iot-demo`).
The following payload is sent by this simulated IoT client:
```shell
{
source_id: 'next18-demo-client',
event_id: '41e13421-25aa-4e93-bca8-0ffeb5c040c8',
event_ts: 1531515192370,
metric: 9
}
```
The `event_id` value here is a unique UUIDv4 ID, `event_ts` is UNIX Epoch time, and `metric`
is a random number 1-10.
## Create a function that handles events
Now we want to consume these IoT events, so let's create the function to handle the events:
```shell
kubectl apply --filename route.yaml
kubectl apply --filename configuration.yaml
```
## Create an event source
Before we can bind an action to an event source, we have to create an event source
that knows how to wire events into actions for that particular event type.
First let's create a ServiceAccount, so that we can run the local receive adapter
in Pull mode to poll for the events from this topic.
Then let's create a GCP PubSub as an event source that we can bind to.
```shell
kubectl apply --filename serviceaccount.yaml
kubectl apply --filename serviceaccountbinding.yaml
kubectl apply --filename eventsource.yaml
kubectl apply --filename eventtype.yaml
```
## Bind IoT events to our function
We have now created a function that we want to consume our IoT events, and we have an event
source that's sending events via GCP PubSub, so let's wire the two together:
```shell
kubectl apply --filename flow.yaml
```

View File

@ -1,27 +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: Configuration
metadata:
name: iot-function
namespace: default
spec:
revisionTemplate:
metadata:
labels:
knative.dev/type: container
spec:
container:
image: github.com/mchmarny/next18/event-flow

View File

@ -1,20 +0,0 @@
{
"name": "demo-device",
"version": "0.0.1",
"description": "MQTT Demo Device for Google Cloud IoT Core using NodeJS",
"main": "device.js",
"license": "Apache-2.0",
"author": "Google Inc.",
"dependencies": {
"@google-cloud/nodejs-repo-tools": "2.2.1",
"@google-cloud/pubsub": "0.16.4",
"MD5": "^1.3.0",
"ava": "0.25.0",
"jsonwebtoken": "8.2.0",
"mqtt": "2.16.0",
"node-uuid": "1.4.8",
"uuid": "3.2.1",
"yargs": "11.0.0"
},
"devDependencies": {}
}

View File

@ -1,296 +0,0 @@
/**
* Copyright 2017, Google, Inc.
* 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.
*/
'use strict';
// [START iot_mqtt_include]
const fs = require('fs');
const jwt = require('jsonwebtoken');
const mqtt = require('mqtt');
const uuid = require('node-uuid');
const os = require('os');
// [END iot_mqtt_include]
// The initial backoff time after a disconnection occurs, in seconds.
var MINIMUM_BACKOFF_TIME = 1;
// The maximum backoff time before giving up, in seconds.
var MAXIMUM_BACKOFF_TIME = 59;
// Whether to wait with exponential backoff before publishing.
var shouldBackoff = false;
// The current backoff time.
var backoffTime = 1;
// Whether an asynchronous publish chain is in progress.
var publishChainInProgress = false;
console.log('Knative IoT Example');
var argv = require(`yargs`)
.options({
projectId: {
default: process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT,
description: 'The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT environment variables.',
requiresArg: true,
type: 'string'
},
cloudRegion: {
default: 'us-central1',
description: 'GCP cloud region.',
requiresArg: true,
type: 'string'
},
registryId: {
description: 'Cloud IoT registry ID.',
requiresArg: true,
demandOption: true,
type: 'string'
},
deviceId: {
description: 'Cloud IoT device ID.',
requiresArg: true,
demandOption: true,
type: 'string'
},
privateKeyFile: {
description: 'Path to private key file.',
requiresArg: true,
demandOption: true,
type: 'string'
},
algorithm: {
description: 'Encryption algorithm to generate the JWT.',
requiresArg: true,
demandOption: true,
choices: ['RS256', 'ES256'],
type: 'string'
},
numMessages: {
default: 100,
description: 'Number of messages to publish.',
requiresArg: true,
type: 'number'
},
tokenExpMins: {
default: 20,
description: 'Minutes to JWT token expiration.',
requiresArg: true,
type: 'number'
},
mqttBridgeHostname: {
default: 'mqtt.googleapis.com',
description: 'MQTT bridge hostname.',
requiresArg: true,
type: 'string'
},
mqttBridgePort: {
default: 8883,
description: 'MQTT bridge port.',
requiresArg: true,
type: 'number'
},
messageType: {
default: 'events',
description: 'Message type to publish.',
requiresArg: true,
choices: ['events', 'state'],
type: 'string'
}
})
.example(`node $0 send-data.js --projectId=blue-jet-123 \\\n\t--registryId=my-registry --deviceId=my-node-device \\\n\t--privateKeyFile=../rsa_private.pem --algorithm=RS256 \\\n\t --cloudRegion=us-west1`)
.wrap(120)
.recommendCommands()
.epilogue(`For more information, see https://cloud.google.com/iot-core/docs`)
.help()
.strict()
.argv;
// Create a Cloud IoT Core JWT for the given project id, signed with the given
// private key.
// [START iot_mqtt_jwt]
function createJwt(projectId, privateKeyFile, algorithm) {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project id.
const token = {
'iat': parseInt(Date.now() / 1000),
'exp': parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
'aud': projectId
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, { algorithm: algorithm });
}
// [END iot_mqtt_jwt]
// Mock some data
var mockData = function () {
var load = os.loadavg();
var msg = {
'source_id': "next18-demo-client",
'event_id': uuid.v4(),
'event_ts': new Date().getTime(),
'metric': Math.floor(Math.random() * 10) + 1
};
console.dir(msg);
return Buffer.from(JSON.stringify(msg)).toString('base64');
}
// Publish numMessages messages asynchronously, starting from message
// messagesSent.
// [START iot_mqtt_publish]
function publishAsync(messagesSent, numMessages) {
// If we have published enough messages or backed off too many times, stop.
if (messagesSent > numMessages || backoffTime >= MAXIMUM_BACKOFF_TIME) {
if (backoffTime >= MAXIMUM_BACKOFF_TIME) {
console.log('Backoff time is too high. Giving up.');
}
console.log('Closing connection to MQTT. Goodbye!');
client.end();
publishChainInProgress = false;
return;
}
// Publish and schedule the next publish.
publishChainInProgress = true;
var publishDelayMs = 0;
if (shouldBackoff) {
publishDelayMs = 1000 * (backoffTime + Math.random());
backoffTime *= 2;
console.log(`Backing off for ${publishDelayMs}ms before publishing.`);
}
setTimeout(function () {
// const payload = `${argv.registryId}/${argv.deviceId}-payload-${messagesSent}`;
const payload = mockData();
// Publish "payload" to the MQTT topic. qos=1 means at least once delivery.
// Cloud IoT Core also supports qos=0 for at most once delivery.
console.log('Publishing message:', payload);
client.publish(mqttTopic, payload, { qos: 1 }, function (err) {
if (!err) {
shouldBackoff = false;
backoffTime = MINIMUM_BACKOFF_TIME;
}
});
var schedulePublishDelayMs = argv.messageType === 'events' ? 1000 : 2000;
setTimeout(function () {
// [START iot_mqtt_jwt_refresh]
let secsFromIssue = parseInt(Date.now() / 1000) - iatTime;
if (secsFromIssue > argv.tokenExpMins * 60) {
iatTime = parseInt(Date.now() / 1000);
console.log(`\tRefreshing token after ${secsFromIssue} seconds.`);
client.end();
connectionArgs.password = createJwt(argv.projectId, argv.privateKeyFile, argv.algorithm);
client = mqtt.connect(connectionArgs);
client.on('connect', (success) => {
console.log('connect');
if (!success) {
console.log('Client not connected...');
} else if (!publishChainInProgress) {
publishAsync(1, argv.numMessages);
}
});
client.on('close', () => {
console.log('close');
shouldBackoff = true;
});
client.on('error', (err) => {
console.log('error', err);
});
client.on('message', (topic, message, packet) => {
console.log('message received: ', Buffer.from(message, 'base64').toString('ascii'));
});
client.on('packetsend', () => {
// Note: logging packet send is very verbose
});
}
// [END iot_mqtt_jwt_refresh]
publishAsync(messagesSent + 1, numMessages);
}, schedulePublishDelayMs);
}, publishDelayMs);
}
// [END iot_mqtt_publish]
// [START iot_mqtt_run]
// The mqttClientId is a unique string that identifies this device. For Google
// Cloud IoT Core, it must be in the format below.
const mqttClientId = `projects/${argv.projectId}/locations/${argv.cloudRegion}/registries/${argv.registryId}/devices/${argv.deviceId}`;
// With Google Cloud IoT Core, the username field is ignored, however it must be
// non-empty. The password field is used to transmit a JWT to authorize the
// device. The "mqtts" protocol causes the library to connect using SSL, which
// is required for Cloud IoT Core.
let connectionArgs = {
host: argv.mqttBridgeHostname,
port: argv.mqttBridgePort,
clientId: mqttClientId,
username: 'unused',
password: createJwt(argv.projectId, argv.privateKeyFile, argv.algorithm),
protocol: 'mqtts',
secureProtocol: 'TLSv1_2_method'
};
// Create a client, and connect to the Google MQTT bridge.
let iatTime = parseInt(Date.now() / 1000);
let client = mqtt.connect(connectionArgs);
// Subscribe to the /devices/{device-id}/config topic to receive config updates.
client.subscribe(`/devices/${argv.deviceId}/config`);
// The MQTT topic that this device will publish data to. The MQTT
// topic name is required to be in the format below. The topic name must end in
// 'state' to publish state and 'events' to publish telemetry. Note that this is
// not the same as the device registry's Cloud Pub/Sub topic.
const mqttTopic = `/devices/${argv.deviceId}/${argv.messageType}`;
client.on('connect', (success) => {
console.log('connect');
if (!success) {
console.log('Client not connected...');
} else if (!publishChainInProgress) {
publishAsync(1, argv.numMessages);
}
});
client.on('close', () => {
console.log('close');
shouldBackoff = true;
});
client.on('error', (err) => {
console.log('error', err);
});
client.on('message', (topic, message, packet) => {
console.log('message received: ', Buffer.from(message, 'base64').toString('ascii'));
});
client.on('packetsend', () => {
// Note: logging packet send is very verbose
});
// Once all of the messages have been published, the connection to Google Cloud
// IoT will be closed and the process will exit. See the publishAsync method.
// [END iot_mqtt_run]

View File

@ -1,25 +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: feeds.knative.dev/v1alpha1
kind: EventSource
metadata:
name: gcppubsub
namespace: default
spec:
type: gcppubsub
source: gcppubsub
image: github.com/knative/eventing/pkg/sources/gcppubsub
parameters:
image: github.com/knative/eventing/pkg/sources/gcppubsub/receive_adapter

View File

@ -1,22 +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: feeds.knative.dev/v1alpha1
kind: EventType
metadata:
name: receive
namespace: default
spec:
eventSource: gcppubsub
description: "subscription for receiving pubsub messages"

View File

@ -1,34 +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: flows.knative.dev/v1alpha1
kind: Flow
metadata:
name: iot-example
namespace: default
spec:
serviceAccountName: binder
trigger:
service: gcppubsub
eventType: receive
resource: gcppubsub/receive
parameters:
projectID: s9-demo
topic: iot-demo
action:
target:
kind: Route
apiVersion: serving.knative.dev/v1alpha1
name: iot-function

View File

@ -1,78 +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.
*/
package main
import (
"encoding/base64"
"encoding/json"
"io/ioutil"
"log"
"net/http"
)
// Event represents PubSub payload
type Event struct {
ID string `json:"ID"`
Data string `json:"Data"`
Attributes map[string]string `json:"Attributes"`
}
// EventPayload represents PubSub Data payload
type EventPayload struct {
ID string `json:"event_id"`
SourceID string `json:"source_id"`
SentOn int `json:"event_ts"`
Metric int `json:"metric"`
}
func handlePost(rw http.ResponseWriter, req *http.Request) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
panic(err)
}
//log.Println(string(body))
// decode the pubsub message
// var event map[string]string
var event Event
if err := json.Unmarshal(body, &event); err != nil {
log.Printf("Failed to unmarshal event: %s", err)
return
}
// decode pubsub payload
rawEvent, _ := base64.StdEncoding.DecodeString(event.Data)
// decode iot data
data, _ := base64.StdEncoding.DecodeString(string(rawEvent))
// decode the pubsub message payload
var payload EventPayload
if err := json.Unmarshal(data, &payload); err != nil {
log.Printf("Failed to unmarshal payload: %s", err)
return
}
log.Printf("Data sent by device %q: [metric: %d, on: %v]",
event.Attributes["deviceId"], payload.Metric, payload.SentOn)
}
func main() {
http.HandleFunc("/", handlePost)
log.Fatal(http.ListenAndServe(":8080", nil))
}

View File

@ -1,23 +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: iot-function
namespace: default
spec:
traffic:
- configurationName: iot-function
percent: 100

View File

@ -1,18 +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
#
# 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: binder
namespace: default

View File

@ -1,25 +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
#
# 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: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: bind-admin
subjects:
- kind: ServiceAccount
name: binder
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

View File

@ -1,27 +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.
FROM golang AS builder
WORKDIR /go/src/github.com/knative/docs/
ADD . /go/src/github.com/knative/docs/
RUN CGO_ENABLED=0 go build ./eventing/samples/github-events
FROM gcr.io/distroless/base
COPY --from=builder /go/src/github.com/knative/docs/github-events /sample
ENTRYPOINT ["/sample"]
EXPOSE 8080

View File

@ -1,181 +0,0 @@
# Reacting to GitHub Events
In response to a pull request event, the sample app _legit_ Service will add
`(looks pretty legit)` to the PR title.
A GitHub webhook will be created on a repository and a Knative `Service` will be
deployed to receive the webhook's event deliveries and forward them into a
`Channel`, through a `Bus`, and out to the consumer via a `Subscription`. The
`Flow` resource takes care of provisioning the webhook, the `Service`, the
`Channel`, and the `Subscription`.
## Prerequisites
You will need:
- A Kubernetes cluster with Knative serving 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 (you'll use it for a container registry).
- Knative eventing core installed on your Kubernetes cluster. You can install
with:
```shell
kubectl apply --filename https://storage.googleapis.com/knative-releases/eventing/latest/release.yaml
```
- A domain name that allows GitHub to call into the cluster: Follow the
[assign a static IP address](https://github.com/knative/docs/blob/master/serving/gke-assigning-static-ip-address.md)
and
[configure a custom domain](https://github.com/knative/docs/blob/master/serving/using-a-custom-domain.md)
instructions.
## Configuring Knative
To use this sample, you'll need to install the `stub` ClusterBus and the
`github` EventSource:
```shell
# Installs ClusterBus
kubectl apply --filename https://storage.googleapis.com/knative-releases/eventing/latest/release-clusterbus-stub.yaml
# Installs EventSource
kubectl apply --filename https://storage.googleapis.com/knative-releases/eventing/latest/release-source-github.yaml
```
## Granting permissions
Because the `github` EventSource needs to create a Knative Service, you'll need
to provision a special ServiceAccount with the necessary permissions.
The `auth.yaml` file provisions a service
account, and creates a role which can create a Knative Service in the `default`
namespace. In a production environment, you might want to limit the access of
this service account to only specific namespaces.
```shell
kubectl apply --filename auth.yaml
```
## Building and deploying the sample
1. Create a [personal access token](https://github.com/settings/tokens) to
GitHub repo that the GitHub source can use to register webhooks with the
GitHub API. Also decide on a token that your code will use to authenticate
the incoming webhooks from GitHub (*accessToken*).
The token can be named anything you find convenient. This sample requires
full `repo` control to be able update the title of the _Pull Request_.
The Source requires `admin:repo_hook`, this allows it to create webhooks
into repos that your account is allowed to do so. Copy and save this token;
GitHub will force you to generate it again if misplaced.
Here I named my token "EventingSample" and have selected the recommended
scopes:
![GitHub UI](personal_access_token.png "GitHub personal access token screenshot")
Update `githubsecret.yaml` with those
values. If your generated access token is `'asdfasfdsaf'` and you choose
your *secretToken* as `'personal_access_token_value'`, you'd modify
`githubsecret.yaml` like so:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: githubsecret
type: Opaque
stringData:
githubCredentials: >
{
"accessToken": "asdfasfdsaf",
"secretToken": "personal_access_token_value"
}
```
Hint: you can makeup a random *accessToken* with:
```shell
head -c 8 /dev/urandom | base64
```
Then, apply the githubsecret using `kubectl`:
```shell
kubectl apply --filename githubsecret.yaml
```
1. Use Docker to build the sample code into a container. To build and push with
Docker Hub, run the following commands, replacing `{username}` with your
Docker Hub username. Run the following commands from the _root_ directory of
the `knative/docs` repo:
```shell
# Build the container on your local machine
# Note: The relative path points to the _root_ of the `knative/docs` repo
docker build -t {username}/github-events --file=Dockerfile ../../../
# Push the container to docker registry
docker push {username}/github-events
```
1. After the build has completed and the container is pushed to Docker Hub, you
can deploy the function into your cluster. **Ensure that the container image
value in `function.yaml` matches the container you built in the previous
step.** Apply the configuration using `kubectl`:
```shell
kubectl apply --filename function.yaml
```
1. Check that your service is running using:
```shell
kubectl get ksvc --output "custom-columns=NAME:.metadata.name,READY:.status.conditions[2].status,REASON:.status.conditions[2].message"
NAME READY REASON
legit True <none>
```
> Note: `ksvc` is an alias for `services.serving.knative.dev`. If you have
an older version (version 0.1.0) of Knative installed, you'll need to use
the long name until you upgrade to version 0.1.1 or higher. See
[Checking Knative Installation Version](../../../install/check-install-version.md)
to learn how to see what version you have installed.
1. Update the resource inside `flow.yaml` to the
org/repo of your choosing. Note that the personal access token must be valid
for the chosen org/repo.
Then create the flow sending GitHub Events to the service:
```shell
kubectl apply --filename flow.yaml
```
1. 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)`
## Understanding what happened
`TODO: similar to k8s-events.`
<!--TODO:
explain the resources and communication channels, as well as where the secret
is used. In particular include a note to look at
https://github.com/<owner>/<repo>/settings/hooks to see the webhook registered
and then deleted.
-->
## Cleaning up
To clean up the function, `Flow`, auth, and secret:
```shell
kubectl delete --filename function.yaml
kubectl delete --filename flow.yaml
kubectl delete --filename auth.yaml
kubectl delete --filename githubsecret.yaml
```
And then delete the [personal access token](https://github.com/settings/tokens)
created from GitHub.

View File

@ -1,43 +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
#
# 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: feed-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: create-knative-service
namespace: default
rules:
- apiGroups: ["serving.knative.dev"]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
---
# This enables the feed-sa to deploy the receive adapter.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: feed-sa-deploy
namespace: default
subjects:
- kind: ServiceAccount
name: feed-sa
namespace: default
roleRef:
kind: Role
name: create-knative-service
apiGroup: rbac.authorization.k8s.io

View File

@ -1,37 +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: flows.knative.dev/v1alpha1
kind: Flow
metadata:
name: github-flow
namespace: default
spec:
serviceAccountName: feed-sa
trigger:
eventType: dev.knative.github.pullrequest
resource: <org>/<repo> # TODO: update this
service: github
parameters:
secretName: githubsecret
secretKey: githubCredentials
parametersFrom:
- secretKeyRef:
name: githubsecret
key: githubCredentials
action:
target:
kind: Service
apiVersion: serving.knative.dev/v1alpha1
name: legit

View File

@ -1,106 +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.
*/
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
ghclient "github.com/google/go-github/github"
"github.com/knative/eventing/pkg/event"
"golang.org/x/oauth2"
"gopkg.in/go-playground/webhooks.v3/github"
"log"
"net/http"
"os"
"strings"
)
const (
// Environment variable containing json credentials
envSecret = "GITHUB_SECRET"
// this is what we tack onto each PR title if not there already
titleSuffix = "looks pretty legit"
)
// GithubHandler holds necessary objects for communicating with the Github.
type GithubHandler struct {
client *ghclient.Client
ctx context.Context
}
type GithubSecrets struct {
AccessToken string `json:"accessToken"`
SecretToken string `json:"secretToken"`
}
func (h *GithubHandler) newPullRequestPayload(ctx context.Context, pl *github.PullRequestPayload) {
title := pl.PullRequest.Title
log.Printf("GOT PR with Title: %q", title)
// Check the title and if it contains 'looks pretty legit' leave it alone
if strings.Contains(title, titleSuffix) {
// already modified, leave it alone.
return
}
newTitle := fmt.Sprintf("%s (%s)", title, titleSuffix)
updatedPR := ghclient.PullRequest{
Title: &newTitle,
}
newPR, response, err := h.client.PullRequests.Edit(h.ctx,
pl.Repository.Owner.Login, pl.Repository.Name, int(pl.Number), &updatedPR)
if err != nil {
log.Printf("Failed to update PR: %s\n%s", err, response)
return
}
if newPR.Title != nil {
log.Printf("New PR Title: %q", *newPR.Title)
} else {
log.Printf("New PR title is nil")
}
}
func main() {
flag.Parse()
githubSecrets := os.Getenv(envSecret)
var credentials GithubSecrets
err := json.Unmarshal([]byte(githubSecrets), &credentials)
if err != nil {
log.Fatalf("Failed to unmarshal credentials: %s", err)
return
}
// Set up the auth for being able to talk to Github.
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: credentials.AccessToken},
)
tc := oauth2.NewClient(ctx, ts)
client := ghclient.NewClient(tc)
h := &GithubHandler{
client: client,
ctx: ctx,
}
log.Fatal(http.ListenAndServe(":8080", event.Handler(h.newPullRequestPayload)))
}

View File

@ -1,34 +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: Service
metadata:
name: legit
spec:
runLatest:
configuration:
revisionTemplate:
metadata:
labels:
knative.dev/type: function
spec:
container:
image: docker.io/{username}/github-events # TODO: fill username out
env:
- name: GITHUB_SECRET
valueFrom:
secretKeyRef:
key: githubCredentials
name: githubsecret

View File

@ -1,25 +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: v1
kind: Secret
metadata:
name: githubsecret
type: Opaque
stringData:
githubCredentials: >
{
"accessToken": "<YOUR PERSONAL TOKEN FROM GITHUB>",
"secretToken": "<YOUR RANDOM STRING>"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB