Skip to content

Commit

Permalink
gh-221 Support networking.k8s.io/v1/Ingress and networking.k8s.io/v1b…
Browse files Browse the repository at this point in the history
…eta1/Ingress (#247)

* gh-221 Support networking.k8s.io/v1/Ingress and networking.k8s.io/v1beta1/Ingress

* gh-221 Add tests
  • Loading branch information
ctas582 committed Aug 15, 2022
1 parent 61df018 commit e1c5729
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/integration-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Start KinD
run: |
source ./docker/accumulo/.env
kind create cluster --config ./cd/kind.yaml --image kindest/node:v1.21.10
kind create cluster --config ./cd/kind.yaml
kind load docker-image gchq/hdfs:$HADOOP_VERSION
kind load docker-image gchq/gaffer:$GAFFER_VERSION
kind load docker-image gchq/gaffer-rest:$GAFFER_VERSION
Expand Down
2 changes: 1 addition & 1 deletion cd/deploy_to_kind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

set -e

kind create cluster --quiet --config ./cd/kind.yaml --image kindest/node:v1.21.10
kind create cluster --quiet --config ./cd/kind.yaml

# This sets the values for:
# HADOOP_VERSION
Expand Down
2 changes: 1 addition & 1 deletion docker/gaffer-jhub-options-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:15.3.0-alpine3.12
FROM node:16.16.0-alpine3.15

WORKDIR /srv/app
COPY package.json ./
Expand Down
5 changes: 2 additions & 3 deletions docker/gaffer-jhub-options-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "src/server.js",
"scripts": {
"start": "node src/server.js",
"test": "mocha"
"test": "jest"
},
"author": "",
"license": "ISC",
Expand All @@ -18,7 +18,6 @@
"pug": "^3.0.0"
},
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^8.2.1"
"jest": "^28.1.3"
}
}
103 changes: 103 additions & 0 deletions docker/gaffer-jhub-options-server/src/k8s-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ const templating = require('./templating.js')
class K8sUtils {

constructor(kubeConfig) {
this.kubeConfig = kubeConfig
this.client = k8s.KubernetesObjectApi.makeApiClient(kubeConfig)
this.ingressApiVersion = null
}

async applySpec(spec) {
Expand Down Expand Up @@ -48,6 +50,107 @@ class K8sUtils {
return spec
}

async getSupportedIngressApiVersion() {
if (this.ingressApiVersion !== null)
return this.ingressApiVersion

const apiClient = this.kubeConfig.makeApiClient(k8s.ApisApi)
const apiResponse = await apiClient.getAPIVersions()
const apiVersions = apiResponse.body.groups.flatMap(group => group.versions.map(version => version.groupVersion))

if (apiVersions.indexOf('networking.k8s.io/v1') != -1) {
const response = await this.kubeConfig.makeApiClient(k8s.NetworkingV1Api).getAPIResources()
if (response.body.resources.filter(resource => resource.kind === 'Ingress').length > 0) {
this.ingressApiVersion = 'networking.k8s.io/v1'
return this.ingressApiVersion
}
}

if (apiVersions.indexOf("networking.k8s.io/v1beta1") != -1) {
const response = await this.kubeConfig.makeApiClient(k8s.NetworkingV1beta1Api).getAPIResources()
if (response.body.resources.filter(resource => resource.kind === 'Ingress').length > 0) {
this.ingressApiVersion = 'networking.k8s.io/v1beta1'
return this.ingressApiVersion
}
}

throw 'Failed to detect the API version supported by the Kubernetes cluster'
}

async createIngress(name, namespace, labels, host, path, serviceName, servicePort) {
const ingressApiVersion = await this.getSupportedIngressApiVersion()
if (ingressApiVersion === 'networking.k8s.io/v1') {
return this.createIngressV1(name, namespace, labels, host, path, serviceName, servicePort)
} else if (ingressApiVersion === 'networking.k8s.io/v1beta1') {
return this.createIngressV1Beta1(name, namespace, labels, host, path, serviceName, servicePort)
} else {
throw `Unable to create ingress ${namespace}:${name} as support is missing for the Ingress version used by the Kubernetes cluster: ${this.ingressApiVersion}`
}
}

async createIngressV1(name, namespace, labels, host, path, serviceName, servicePort) {
const ingressPath = {
pathType: 'ImplementationSpecific',
backend: {
service: {
name: serviceName,
port: {
number: servicePort
}
}
}
}
if (path) ingressPath.path = path

const rule = {
http: {
paths: [ingressPath]
}
}
if (host) rule.host = host

const ingress = {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: { name, namespace, labels },
spec: {
rules: [rule]
}
}

const response = await this.applySpec(ingress)
return response
}

async createIngressV1Beta1(name, namespace, labels, host, path, serviceName, servicePort) {
const ingressPath = {
backend: {
serviceName,
servicePort
}
}
if (path) ingressPath.path = path

const rule = {
http: {
paths: [ingressPath]
}
}
if (host) rule.host = host

const ingress = {
apiVersion: 'networking.k8s.io/v1beta1',
kind: 'Ingress',
metadata: { name, namespace, labels },
spec: {
rules: [rule]
}
}

const response = await this.applySpec(ingress)
return response
}

}

module.exports = K8sUtils
43 changes: 8 additions & 35 deletions docker/gaffer-jhub-options-server/src/spark-config-provisioner.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,43 +127,16 @@ class SparkConfigProvisioner {
async provisionDriverIngress(name, namespace, host, path, serviceName, servicePort, username, servername) {
if (!host && !path) return null

const ingressPath = {
backend: {
serviceName: serviceName,
servicePort: servicePort
}
const labels = {
'app.kubernetes.io/name': 'jhub-notebook-config',
'app.kubernetes.io/component': 'spark-ui-ingress',
'app.kubernetes.io/managed-by': appInfo.name,
'app.kubernetes.io/version': appInfo.version,
'hub.jupyter.org/username': username,
'hub.jupyter.org/servername': servername
}
if (path) ingressPath.path = path

const rule = {
http: {
paths: [ingressPath]
}
}
if (host) rule.host = host

const ingress = {
apiVersion: 'extensions/v1beta1',
kind: 'Ingress',
metadata: {
name: name,
namespace: namespace,
labels: {
'app.kubernetes.io/name': 'jhub-notebook-config',
'app.kubernetes.io/component': 'spark-ui-ingress',
'app.kubernetes.io/managed-by': appInfo.name,
'app.kubernetes.io/version': appInfo.version,
'hub.jupyter.org/username': username,
'hub.jupyter.org/servername': servername
}
},
spec: {
rules: [rule]
}
}

const response = await this.utils.applySpec(ingress)
return response
return this.utils.createIngress(name, namespace, labels, host, path, serviceName, servicePort)
}

async getPodSpecConfig(username, servername, driverServiceName, namespace, sparkContainerImage, serviceAccountName, executorCores, executorMemory, hdfsEnabled, ingressHost, ingressPath) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

const k8s = require('@kubernetes/client-node')
const SparkConfigProvisioner = require('./spark-config-provisioner.js')

const kubeConfig = new k8s.KubeConfig()
kubeConfig.loadFromDefault()

const spark = new SparkConfigProvisioner(kubeConfig)

test('can provision Spark service', async () => {
await spark.provisionDriverService("spark-test-svc", "default", "user1", "server1", 80)
})

test('can provision Spark ingress', async () => {
await spark.provisionDriverIngress("spark-test-ingress", "default", "localhost", "/", "spark-test-svc", 80, "user1", "server1")
})
2 changes: 1 addition & 1 deletion kubernetes/docs/kind-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The following instructions will guide you through provisioning and configuring a

Simply run the following command to spin up a local Kubernetes cluster, running inside a Docker container:
```
kind create cluster --image kindest/node:v1.21.10
kind create cluster
```


Expand Down
11 changes: 11 additions & 0 deletions kubernetes/gaffer-jhub/templates/options-server/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ rules:
- "create"
- "patch"
- "update"
- apiGroups:
- "networking.k8s.io"
resources:
- "ingresses"
verbs:
- "get"
- "list"
- "watch"
- "create"
- "patch"
- "update"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down

0 comments on commit e1c5729

Please sign in to comment.