Skip to content

Commit 2601444

Browse files
WIP - Convert e2e test to Python test + unpriviliged user test case
1 parent 0feab0f commit 2601444

28 files changed

+226
-200
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

poetry.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/e2e/config

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: v1
2+
kind: Config
3+
clusters:
4+
- cluster:
5+
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1USXhNakV3TWpneE4xb1hEVE16TVRJd09URXdNamd4TjFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTGFPCi9vY1dITXVnS1BOMEwxcjM5b1Nqa0Z3TXlSMkpQTXlmeHFpdHZaclo4TUVsNEN5ekk0emVaakp5V1RTaG1ZTTEKT08yN1BqeE11QTZSQUtMekE3QVR3Z05wSUNQYm1lL1pYNTFaaks1SWFETG83SHUwZXc4Z2ZGQW9qSWs4eG4rOApENS9kaHlBeTRlbVhUUXpSbGd1MENnZjE3ZEl3Sm9YU0dBaU9nSytYcEtUQ3p4bGNad1RvdWNGUjNYa0YyeUhjCnliaTdJV3M5RDl4V3B6WXB3Z1RXemh2SDdNcU1UdVppRU93L2lQOEJxZVhTZVhiN21NV3MyNGh5aTVYczQwS2cKUmtzRFFCWUFhUCsrRzZmOEptRVo0SGQxUTl6a01ZQThGSXp1L29ZVEdoKzZ0THRhS3FYaTRNOHc5WWM4OEZLNwp1ZWlQQlhXbitONmFUM3dWcGo4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZFanE4ampuOTA3c1A1UkNXZFc0bkQ1MXAya2xNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1VINVVsU2UzVE1hdHQrWXZPWgpHZkcwSzZDd0hBQUlGVVhFQVdUa3Fyb0pKVjhCT3NkVEh4SGhJOFZtWlkrMEJoU3pCckZsek13NmVLNHhtR3V6CnRucFVMQnUvZXVjQXNhNWd2ZU8wWjZQamY4VER2MXhJcmdDS044RlgydWx6TEZjdEJrdXB1MXByM2g1MVd1eGEKL3NGNS9vU0dMR0VtcEZ2bGZFNFdub1FwejAyeEFGSE1QS0poRVpGQ3dndmJ6dWNUVDZPYWRuQ2RQdVMrcVRnVgo4TlVlMVgyTkE5RHFDZlllZ2VpWm5PTXlFY2o3WVpiL1BGZ09QdWtFYU1NOHh1YXZpbm9tenlLVHFKd1VJcG5iCkhBNzFKK3IyWFdBellPN1gyRkRWNnhyanlJdFVSWithcFJFREEwL29maTB5andzRjBtV01oMVJSY0tCQ1ZJUzMKWHBJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
6+
server: https://127.0.0.1:34211
7+
name: kind-kind
8+
contexts:
9+
- context:
10+
cluster: kind-kind
11+
user: sdk-user
12+
name: sdk-user
13+
users:
14+
- name: sdk-user
15+
user:
16+
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN3VENDQWFrQ0ZCT0FEQ1l4OUxDczZDNVdPZzFQRWRuQlc5YkpNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1CVXgKRXpBUkJnTlZCQU1UQ210MVltVnlibVYwWlhNd0hoY05Nak14TWpFeU1UQXlPRFEwV2hjTk1qUXhNakEyTVRBeQpPRFEwV2pBbE1SRXdEd1lEVlFRRERBaHpaR3N0ZFhObGNqRVFNQTRHQTFVRUNnd0hkR1Z1WVc1ME1UQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFPMkw0UnJuMlB2TEQweGZSL2g3MDBhNnB3aG0KSmtrTGttWHFYY3ZISmdiS1VkZG5QcU5rTzVsN2w4STR6MjMydWZiYllCbFZHL1ljbTd3OGNlK2RFbmpoTHAxeQozRWU0RUdsQ1JETHU5U080SUZUSTUwRHk4WUxhUTU5TitteXQ5UDBENW14RmEremREYUQ1Q2E2NTFtd3B1R2g3CkNDbnZhaFNnYmt5MytlQ0FiOU1FdGFwZi82bjlvT045dHNVZTNOQlo1aUZ2cTV4bER6Q0k2dWlUKzJTVytCWWIKM3dXbkhsTkoxTVZuVHVSbUVJc3pPUXltREZkQVcyVDJjNkl2dnJKZndCNzVOd1Q5c2poUGY4SHV0M0tIUGErVQpQazVYRVErdVlYcjFiMlVQZUdrT3VtdkZnN1JQRHZMK1JFL0t0QXpDOGNaYVNycE5sWUk2TVZMVVV5OENBd0VBCkFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNeGJWdGx5UkpGNVN6VmtiMmFnNlNHRTJoeWlWUVVRT1VlNzQKd3UyNWQ0RW9RWWJBNHU2OXVXOXJJUkE4ZmlLN1VaSU1KbFhvUU1UYmlQblg0MWdmRVY2eUhqMzFkSjZmQUhRYQphVG5tbUt5N2lUQjNWUzBKc0dobURDbUdNblZWWHNnSy9GS08yeER2M2ZkYzkyODI1SGpRM2hwd28reFJwTjYvCkliaHlHdUtHaXB4VzJsUjRydlYvTGd3UHhvcHZ2YkNScmxQQUNVeHd2bU04aHo2WVlNakdndGZPRzRtcnhPRDcKWGY2RXJBV3ZRQy9BaVBlVmhXMm5WWWRNNHlUSVdoNEorcXY0SGd0NHBDQ0FVMzNkMnJvR0dIY29VWTNkY1pteApQeTdlaExIbHFWLzY1REpycnU4cS9YSzZWYnIyTjQyUzVQOHlINUlxeGVsSytkeDlpUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
17+
client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRHRpK0VhNTlqN3l3OU0KWDBmNGU5Tkd1cWNJWmlaSkM1Smw2bDNMeHlZR3lsSFhaejZqWkR1WmU1ZkNPTTl0OXJuMjIyQVpWUnYySEp1OApQSEh2blJKNDRTNmRjdHhIdUJCcFFrUXk3dlVqdUNCVXlPZEE4dkdDMmtPZlRmcHNyZlQ5QStac1JXdnMzUTJnCitRbXV1ZFpzS2Job2V3Z3A3Mm9Vb0c1TXQvbmdnRy9UQkxXcVgvK3AvYURqZmJiRkh0elFXZVloYjZ1Y1pROHcKaU9yb2svdGtsdmdXRzk4RnB4NVRTZFRGWjA3a1poQ0xNemtNcGd4WFFGdGs5bk9pTDc2eVg4QWUrVGNFL2JJNApUMy9CN3JkeWh6MnZsRDVPVnhFUHJtRjY5VzlsRDNocERycHJ4WU8wVHc3eS9rUlB5clFNd3ZIR1drcTZUWldDCk9qRlMxRk12QWdNQkFBRUNnZ0VBSTN3bnpsc2dBTTBlcGV2OTFsSzVCdkhQRGVRa2gvamdqN1RvK2czdjBrZmEKM2ZDZ1hNd1dVeUV4VkdRa0tHc1k4SlZvejUvMUkxaTJzdkhjbTB5OWU2MDN4M0ZuRXBlZWEvcm9NU3VkRnc3awpWWVlGZGFCVkQ1VUhVUDdYRC9FVWpjOU5WcE13UWh2cmMwYUFlY2R0RG85VTZ0YW1LNDJHTFRxaC8zZmtMZkw0CkVQMWVuNDc5ZjVjcUVkNzdpOUNhRE1RSGVYMEtScXdmWldhSTNQellrYmQ3M3ZMZVVJQ0FXMzQzUEJVdUdXci8KV1hMekRsbVVkd3hjbG1OYTlGR1RRdnNxcGFFeFR4b0duNVZ6NGpWN2xFbGs5aW1aeUxJN2FRL2FhN3BaMXZiTQorVUk3TDB5YnR6K0ZqRjZLSEIzNWdBMkt1MjQvcVFycGN6TVdJQkpPOFFLQmdRRDdTdTl3a2Z0VzY2ZklFb2xsCnV1VzlvNStLd1pjYUhvOGo5Y0ZLZzRmcC95cXpoWnRtUlBHTW1CWExvUlZmcGJFUTBzZjJpOWlwejBsUklaUTIKYWF3a3hKMEhyU3NBVlB5bnFrbXpSNVMyVSsySVd1eDM0TC9VRU9zRC9LZUUzU24vZzlTTmpZTEcrNTdMZGxjSwpueVZjU1BJaEl0TlJlNUViNmJpUk1EbjZoUUtCZ1FEeC93WXFjNEhDKzJjQ2VJcnpaN3FDM3lybGdiakc4cWpXCkFreXFtdmxvdURXdDRjRUc2bmxuWHF3eXRoQ0JNWnFSZHNiZmhWWHFFbUI3b0ZHNjV1bzRzUlZjaVNKK2J0dWEKVlRtSklHcEdVUEF0VUlKVXVWRjROeHVOdVN3SnhWU0F5bmlvKy9pMVowZXkxVEVmazNZVFFPTEkrbEVUNzRxcwpsV2dmSXlxM0l3S0JnR3lLRWwvSi9naXVJcnN0SG9GOU40d3dwMUdVaW9KeW5wc0dwQ1ZlS0k5dWNuQTJEa2dmCkVVSUwwcVl3Zm4zZ29GbEc0YTNnKzRWbERpTG40UStibHdvT2psRHBnQUJWdFFkcWF3anZxeEVSc1RCTExZWWQKNGwxanJVNzhpeEs5UUUyb0VGL1B0cVBodk5YZTJIdXkvNzBibU5HdExCOHV3eCtPVlBVSklwSE5Bb0dCQUpHSgpaRFhubmFTYitZbDg0V1FkZ0FmeEd5Vkg3TTZKWll5L2VVZ3BSOUg0NXgrWjQ3SzdGU1JieFlnQ0FzOFArL3Q3CnlZTG45NUY4VjlaQnhxVjI5bW45NWZEdThIWEZTZ0Q1UEU4QjFhaFFTUUdYcDZvNGdZeWc1OHRHRC93WVZ3ZlYKdk5jMElwRkdlZEpOY091aWphSnFwWGxsUVptUnVINnVwQjRGMGt5dEFvR0JBTzh5ZVVOVmhQNWhjandQVmNFawpYV0FSS3ErNnhBM3d3R0ZLV25CY1JSd2xOcFNjMUkrWWo0dFZaLzN5R3VxVndCL2JqWm1UemlQOG5HK3FGL3NoCm1zTzFsN0JZVlcrMDFpQ1k5c0M1S3FBR0lyTG5yUkd6LzdSZUhvWDdIVFVTM29PQW9YSmtkSWZPRkJVNVdDVGkKMzg3dHFTTDBjQkN6bHlEU2dGZUJFZWVyCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K

tests/e2e/install-codeflare-sdk.sh

100644100755
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
1-
#!/bin/bash
2-
3-
cd ..
1+
# !/bin/bash
42

53
# Install Poetry and configure virtualenvs
64
pip install poetry
75
poetry config virtualenvs.create false
86

9-
cd codeflare-sdk
10-
117
# Lock dependencies and install them
128
poetry lock --no-update
139
poetry install --with test,docs
14-
15-
# Return to the workdir
16-
cd ..
17-
cd workdir

tests/e2e/kind.sh

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/bin/bash
2+
3+
# Copyright 2022 IBM, Red Hat
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -euo pipefail
18+
: "${INGRESS_NGINX_VERSION:=controller-v1.6.4}"
19+
20+
echo "Creating KinD cluster"
21+
cat <<EOF | kind create cluster --config=-
22+
kind: Cluster
23+
apiVersion: kind.x-k8s.io/v1alpha4
24+
nodes:
25+
- role: control-plane
26+
image: kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1
27+
kubeadmConfigPatches:
28+
- |
29+
kind: InitConfiguration
30+
nodeRegistration:
31+
kubeletExtraArgs:
32+
node-labels: "ingress-ready=true"
33+
EOF
34+
35+
echo "Deploying Ingress controller into KinD cluster"
36+
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/"${INGRESS_NGINX_VERSION}"/deploy/static/provider/kind/deploy.yaml | sed "s/--publish-status-address=localhost/--report-node-internal-ip-address\\n - --status-update-interval=10/g" | kubectl apply -f -
37+
kubectl annotate ingressclass nginx "ingressclass.kubernetes.io/is-default-class=true"
38+
kubectl -n ingress-nginx wait --timeout=300s --for=condition=Available deployments --all
39+
40+
## Create a user with limited permissions to test the SDK
41+
# Create a CA and a user certificate and key
42+
docker cp kind-control-plane:/etc/kubernetes/pki/ca.crt .
43+
docker cp kind-control-plane:/etc/kubernetes/pki/ca.key .
44+
openssl genrsa -out sdk-user.key 2048
45+
openssl req -new -key sdk-user.key -out sdk-user.csr -subj /CN=sdk-user/O=tenant1
46+
openssl x509 -req -in sdk-user.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out sdk-user.crt -days 360
47+
base64 -w 0 < ca.crt > ca.crt.base64
48+
base64 -w 0 < sdk-user.crt > sdk-user.crt.base64
49+
base64 -w 0 < sdk-user.key > sdk-user.key.base64
50+
SERVER_ADDRESS=$(kubectl cluster-info | grep -o "https://127.0.0.1:[0-9]*" | head -n 1)
51+
52+
# Replace the placeholders in the user config file with the actual values
53+
sed -i 's|certificate-authority-data:.*|certificate-authority-data: '$(cat ca.crt.base64)'|g' ./tests/e2e/config
54+
sed -i 's|client-certificate-data:.*|client-certificate-data: '$(cat sdk-user.crt.base64)'|g' ./tests/e2e/config
55+
sed -i 's|client-key-data:.*|client-key-data: '$(cat sdk-user.key.base64)'|g' ./tests/e2e/config
56+
sed -i 's|server:.*|server: '$(echo $SERVER_ADDRESS)'|g' ./tests/e2e/config
57+
58+
# Apply to the user limited RBAC permissions
59+
cat <<EOF | kubectl apply -f -
60+
apiVersion: rbac.authorization.k8s.io/v1
61+
kind: Role
62+
metadata:
63+
name: tenant-user
64+
rules:
65+
- apiGroups: [""]
66+
resources: ["namespaces"]
67+
verbs: ["get", "watch", "list"]
68+
- apiGroups: ["mcadv1beta1.groupname"]
69+
resources: ["appwrappers"]
70+
verbs: ["get", "create", "delete", "list", "patch", "update"]
71+
- apiGroups: ["rayv1.groupversion.group"]
72+
resources: ["rayclusters", "rayclusters/status"]
73+
verbs: ["get", "list"]
74+
- apiGroups: ["route.openshift.io"]
75+
resources: ["routes"]
76+
verbs: ["get", "list"]
77+
- apiGroups: ["networking.k8s.io"]
78+
resources: ["ingresses"]
79+
verbs: ["get", "list"]
80+
EOF
81+
82+
cat <<EOF | kubectl apply -f -
83+
apiVersion: rbac.authorization.k8s.io/v1
84+
kind: RoleBinding
85+
metadata:
86+
name: tenant-user
87+
subjects:
88+
- kind: User
89+
name: sdk-user
90+
apiGroup: rbac.authorization.k8s.io
91+
roleRef:
92+
kind: Role
93+
name: tenant-user
94+
apiGroup: rbac.authorization.k8s.io
95+
EOF
96+
97+
# Temporary ClusterRoles
98+
cat <<EOF | kubectl apply -f -
99+
kind: ClusterRole
100+
apiVersion: rbac.authorization.k8s.io/v1
101+
metadata:
102+
name: cr-tenant-user
103+
rules:
104+
- apiGroups: ["config.openshift.io"]
105+
resources: ["ingresses"]
106+
verbs: ["get", "list"]
107+
resourceNames: ["cluster"]
108+
EOF
109+
110+
cat <<EOF | kubectl apply -f -
111+
apiVersion: rbac.authorization.k8s.io/v1
112+
kind: ClusterRoleBinding
113+
metadata:
114+
name: cr-tenant-user
115+
subjects:
116+
- kind: User
117+
name: sdk-user
118+
apiGroup: rbac.authorization.k8s.io
119+
roleRef:
120+
kind: ClusterRole
121+
name: cr-tenant-user
122+
apiGroup: rbac.authorization.k8s.io
123+
EOF
124+
125+
# Cleanup csr/crt/keys from local machine
126+
rm -f ca.crt.base64 sdk-user.crt.base64 sdk-user.key.base64 ca.crt sdk-user.crt sdk-user.key sdk-user.csr ca.key ca.srl kind.csr
127+
128+
# Install CodeFlare SDK
129+
chmod +x ./tests/e2e/install-codeflare-sdk.sh
130+
./tests/e2e/install-codeflare-sdk.sh
131+
132+
# Confirming the user can access the cluster
133+
kubectl get ns default --as sdk-user

tests/e2e/mnist_raycluster_sdk.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from codeflare_sdk.job.jobs import DDPJobDefinition
1212

1313
namespace = sys.argv[1]
14-
ray_image = os.getenv("RAY_IMAGE")
14+
ray_image = "quay.io/project-codeflare/ray:latest-py39-cu118"
1515
host = os.getenv("CLUSTER_HOSTNAME")
1616

1717
ingress_options = {}
@@ -46,7 +46,6 @@
4646
)
4747
)
4848

49-
5049
cluster.up()
5150

5251
cluster.status()
@@ -62,6 +61,14 @@
6261
script="mnist.py",
6362
scheduler_args={"requirements": "requirements.txt"},
6463
)
64+
65+
# THIS DOESN'T WORK: (CURRENT STATUS: CONNECTION REFUSED)
66+
host_alias = {
67+
"ip": "172.18.0.2", # Replace with the actual node IP
68+
"hostnames": ["kind"], # Replace with the actual hostname
69+
}
70+
jobdef["spec"]["template"]["spec"]["hostAliases"] = [host_alias]
71+
6572
job = jobdef.submit(cluster)
6673

6774
done = False

0 commit comments

Comments
 (0)