Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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