Skip to content

Commit 48fe7fe

Browse files
authored
Integration between OpenShift and Quay (#3)
* Integration between OpenShift and Quay * Updated based on ClusterRoles for OCP 4
1 parent 5c708c5 commit 48fe7fe

File tree

6 files changed

+413
-0
lines changed

6 files changed

+413
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ This repository provides small software solutions for providing linkage and inte
99
- [ansible-tower-bridges/github-webhook](ansible-tower-bridges/github-webhook) provides a bridge interfa
1010
ce between GitHub webhooks and Ansible Tower API job launch requests.
1111
- [argo-cd-bridges/gitlab](argo-cd-bridges/gitlab) provides a bridge interface between GitLab and Application resources in an Argo CD instance
12+
- [quay/imagestream-sync](quay/imagestream-sync) synchronizes ImageStreams referencing images from Quay using Quay notification based webhooks

quay/imagestream-sync/README.md

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# quay/imagestream-sync
2+
3+
This implementation is used to synchronize images that are stored in [Quay](https://coreos.com/quay-enterprise/) and are referenced as ImageStreams within the OpenShift Container Platform from [Quay notifications](https://docs.quay.io/guides/notifications.html).
4+
5+
6+
## Requirements
7+
8+
Although this can be run as a regular/standalone `node.js` app, it is recommended that this gets deployed on an OpenShift Container Platform for ease of maintenance. A minimum of NodeJS version 8 is required.
9+
10+
## Configuration Options
11+
12+
The following configuration items tune and control the behavior of the application.
13+
14+
| Variable | Description | Defaults |
15+
|:---------|:------------|:---------|
16+
| HTTP_PORT | The http port for the application to listen on | 8080 |
17+
| HTTPS_PORT | The httpd (SSL) port for the application listen on (choose this or HTTP_PORT above) | 8443 |
18+
| HTTPS_SSL_CERTIFICATE | When HTTPS_PORT above is used, specify the certificate here | |
19+
| HTTPS_SSL_KEY | When the HTTPS_PORT above is used, specify the certificate key here | |
20+
| TOKEN_FILE | Location of a file containing the contents of an OAuth token to authenticate to the OpenShift API | `/var/run/secrets/kubernetes.io/serviceaccount/token` |
21+
| CA_FILE | Location of the certificate to communicate securely with the OpenShift API | `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt` |
22+
| AUTH_TOKEN | Value of the token used to communicate with the OpenShift API | |
23+
| MASTER_URL | Address of the OpenShift Master | `https://kubernetes.default.svc:443` |
24+
| TLS_INSECURE | Allow insecure communication to the OpenShift API | `false` |
25+
| NAMESPACE | Single namespace to allow image synchronization (defaults to entire cluster) | |
26+
27+
## Running in OpenShift
28+
29+
### Prerequisites
30+
31+
This application makes queries to the OpenShift API. The service account associated with the application must have sufficient rights to query for ImageStreams either at a cluster scope or namespace scope.
32+
33+
The following command can be added to grant access to a service account at a cluster level using the included `registry-editor` ClusterRole.
34+
35+
```
36+
$ oc adm policy add-cluster-role-to-user registry-editor -z <service-account>
37+
```
38+
39+
To limit to a single namespace, the following command can be used:
40+
41+
```
42+
$ oc project <namespace>
43+
$ oc policy add-role-to-user registry-editor -z <service-account>
44+
```
45+
46+
### Application Deployment
47+
48+
The `oc new-app` command in combination with `oc expose` command can be used to deploy the application:
49+
50+
```
51+
$ oc new-app --name=quay-imagestream-sync openshift/nodejs:8~https://github.com/redhat-cop/tool-integrations.git --context-dir=quay/imagestream-sync
52+
$ oc expose service quay-imagestream-sync
53+
```
54+
55+
Then add the environment variables below, and add a github webhook (with the `route` url) to test it out.
56+
57+
## Quay Configuration
58+
59+
The final step is to configure Quay to send webhook notifications to the application deployed in OpenShift.
60+
61+
First, obtain the url of the application previously deployed.
62+
63+
```
64+
$ oc get routes quay-imagestream-sync --template='{{ .spec.host }}'
65+
```
66+
67+
Login to quay and locate the repository associated with the image that has been previously configured in OpenShift.
68+
69+
Click on **Settings** and then **Create Notification**
70+
71+
Under _When this event occurs_ dropdown, select **Push to Repository**.
72+
73+
Under _Then issue a Notification_ dropdown, select **Webhook POST**
74+
75+
Enter the URL of the webhook based on the result from the route found previously (such as `http://quay-imagestream-sync.myproject.apps.ocp.example.com`)
76+
77+
Optionally, provide a _Notification title_ to easily identify the webhook.
78+
79+
Select **Create Notification**
80+
81+
82+
License
83+
-------
84+
85+
Apache License 2.0
86+
87+
88+
Author Information
89+
------------------
90+
91+
Red Hat Community of Practice

quay/imagestream-sync/index.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
const http = require('http');
3+
const https = require('https');
4+
const fs = require('fs');
5+
var express = require('express');
6+
var cors = require('cors');
7+
var app = express();
8+
var bodyParser = require('body-parser');
9+
var sync = require('./lib/sync');
10+
11+
const httpPort = process.env.HTTP_PORT || 8080;
12+
const httpsPort = process.env.HTTPS_PORT || 8443;
13+
const httpsSSLKey = process.env.HTTPS_SSL_KEY || '';
14+
const httpsSSLCert = process.env.HTTPS_SSL_CERTIFICATE || '';
15+
16+
17+
app.use(cors());
18+
app.use(bodyParser.urlencoded({ extended: true }));
19+
app.use(bodyParser.json());
20+
21+
app.post('/', function (req, res) {
22+
23+
if("docker_url" in req.body && "updated_tags" in req.body) {
24+
25+
if(req.body.updated_tags instanceof Array) {
26+
27+
sync.syncImageStreams(req.body, function(err, response){
28+
29+
if(err) {
30+
res.status(500).send(err);
31+
}
32+
else {
33+
res.status(200).send(response);
34+
}
35+
36+
});
37+
}
38+
else {
39+
console.info("Request does not contain a list of updated tags");
40+
res.status(204).send();
41+
}
42+
}
43+
else {
44+
res.status(400).send();
45+
}
46+
47+
});
48+
49+
if (httpsSSLCert.trim() && httpsSSLKey.trim()) { // Secure
50+
const options = {
51+
key: fs.readFileSync(httpsSSLKey),
52+
cert: fs.readFileSync(httpsSSLCert)
53+
};
54+
55+
https.createServer(options, app).listen(httpsPort, function () {
56+
console.log('Listening on https://localhost:' + httpsPort);
57+
});
58+
}
59+
else { // non-Secure
60+
http.createServer(app).listen(httpPort, function() {
61+
console.log('Listening on UNSECURE http://localhost:' + httpPort);
62+
});
63+
}
64+

0 commit comments

Comments
 (0)