1{
2 system ? builtins.currentSystem,
3 pkgs ? import ../../.. { inherit system; },
4}:
5with import ./base.nix { inherit system; };
6let
7
8 roServiceAccount = pkgs.writeText "ro-service-account.json" (
9 builtins.toJSON {
10 kind = "ServiceAccount";
11 apiVersion = "v1";
12 metadata = {
13 name = "read-only";
14 namespace = "default";
15 };
16 }
17 );
18
19 roRoleBinding = pkgs.writeText "ro-role-binding.json" (
20 builtins.toJSON {
21 apiVersion = "rbac.authorization.k8s.io/v1";
22 kind = "RoleBinding";
23 metadata = {
24 name = "read-pods";
25 namespace = "default";
26 };
27 roleRef = {
28 apiGroup = "rbac.authorization.k8s.io";
29 kind = "Role";
30 name = "pod-reader";
31 };
32 subjects = [
33 {
34 kind = "ServiceAccount";
35 name = "read-only";
36 namespace = "default";
37 }
38 ];
39 }
40 );
41
42 roRole = pkgs.writeText "ro-role.json" (
43 builtins.toJSON {
44 apiVersion = "rbac.authorization.k8s.io/v1";
45 kind = "Role";
46 metadata = {
47 name = "pod-reader";
48 namespace = "default";
49 };
50 rules = [
51 {
52 apiGroups = [ "" ];
53 resources = [ "pods" ];
54 verbs = [
55 "get"
56 "list"
57 "watch"
58 ];
59 }
60 ];
61 }
62 );
63
64 kubectlPod = pkgs.writeText "kubectl-pod.json" (
65 builtins.toJSON {
66 kind = "Pod";
67 apiVersion = "v1";
68 metadata.name = "kubectl";
69 metadata.namespace = "default";
70 metadata.labels.name = "kubectl";
71 spec.serviceAccountName = "read-only";
72 spec.containers = [
73 {
74 name = "kubectl";
75 image = "kubectl:latest";
76 command = [
77 "/bin/tail"
78 "-f"
79 ];
80 imagePullPolicy = "Never";
81 tty = true;
82 }
83 ];
84 }
85 );
86
87 kubectlPod2 = pkgs.writeTextDir "kubectl-pod-2.json" (
88 builtins.toJSON {
89 kind = "Pod";
90 apiVersion = "v1";
91 metadata.name = "kubectl-2";
92 metadata.namespace = "default";
93 metadata.labels.name = "kubectl-2";
94 spec.serviceAccountName = "read-only";
95 spec.containers = [
96 {
97 name = "kubectl-2";
98 image = "kubectl:latest";
99 command = [
100 "/bin/tail"
101 "-f"
102 ];
103 imagePullPolicy = "Never";
104 tty = true;
105 }
106 ];
107 }
108 );
109
110 copyKubectl = pkgs.runCommand "copy-kubectl" { } ''
111 mkdir -p $out/bin
112 cp ${pkgs.kubernetes}/bin/kubectl $out/bin/kubectl
113 '';
114
115 kubectlImage = pkgs.dockerTools.buildImage {
116 name = "kubectl";
117 tag = "latest";
118 copyToRoot = pkgs.buildEnv {
119 name = "image-root";
120 pathsToLink = [ "/bin" ];
121 paths = [
122 copyKubectl
123 pkgs.busybox
124 kubectlPod2
125 ];
126 };
127 config.Entrypoint = [ "/bin/sh" ];
128 };
129
130 base = {
131 name = "rbac";
132 };
133
134 singlenode = base // {
135 test = ''
136 machine1.wait_until_succeeds("kubectl get node machine1.my.zyx | grep -w Ready")
137
138 machine1.wait_until_succeeds(
139 "${pkgs.gzip}/bin/zcat ${kubectlImage} | ${pkgs.containerd}/bin/ctr -n k8s.io image import -"
140 )
141
142 machine1.wait_until_succeeds(
143 "kubectl apply -f ${roServiceAccount}"
144 )
145 machine1.wait_until_succeeds(
146 "kubectl apply -f ${roRole}"
147 )
148 machine1.wait_until_succeeds(
149 "kubectl apply -f ${roRoleBinding}"
150 )
151 machine1.wait_until_succeeds(
152 "kubectl create -f ${kubectlPod}"
153 )
154
155 machine1.wait_until_succeeds("kubectl get pod kubectl | grep Running")
156
157 machine1.wait_until_succeeds("kubectl exec kubectl -- kubectl get pods")
158 machine1.fail("kubectl exec kubectl -- kubectl create -f /kubectl-pod-2.json")
159 machine1.fail("kubectl exec kubectl -- kubectl delete pods -l name=kubectl")
160 '';
161 };
162
163 multinode = base // {
164 test = ''
165 # Node token exchange
166 machine1.wait_until_succeeds(
167 "cp -f /var/lib/cfssl/apitoken.secret /tmp/shared/apitoken.secret"
168 )
169 machine2.wait_until_succeeds(
170 "cat /tmp/shared/apitoken.secret | nixos-kubernetes-node-join"
171 )
172
173 machine1.wait_until_succeeds("kubectl get node machine2.my.zyx | grep -w Ready")
174
175 machine2.wait_until_succeeds(
176 "${pkgs.gzip}/bin/zcat ${kubectlImage} | ${pkgs.containerd}/bin/ctr -n k8s.io image import -"
177 )
178
179 machine1.wait_until_succeeds(
180 "kubectl apply -f ${roServiceAccount}"
181 )
182 machine1.wait_until_succeeds(
183 "kubectl apply -f ${roRole}"
184 )
185 machine1.wait_until_succeeds(
186 "kubectl apply -f ${roRoleBinding}"
187 )
188 machine1.wait_until_succeeds(
189 "kubectl create -f ${kubectlPod}"
190 )
191
192 machine1.wait_until_succeeds("kubectl get pod kubectl | grep Running")
193
194 machine1.wait_until_succeeds("kubectl exec kubectl -- kubectl get pods")
195 machine1.fail("kubectl exec kubectl -- kubectl create -f /kubectl-pod-2.json")
196 machine1.fail("kubectl exec kubectl -- kubectl delete pods -l name=kubectl")
197 '';
198 };
199
200in
201{
202 singlenode = mkKubernetesSingleNodeTest singlenode;
203 multinode = mkKubernetesMultiNodeTest multinode;
204}