Skip to content

Commit

Permalink
testing: add e2e namespace/admin test
Browse files Browse the repository at this point in the history
  • Loading branch information
mplsgrant committed Oct 1, 2024
1 parent 9395fb2 commit 353a3cf
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
users:
- name: warnet-user
roles:
- pod-viewer
- pod-manager
# the pod-viewer and pod-manager roles are the default
# roles defined in values.yaml for the namespaces charts
#
# if you need a different set of roles for a particular namespaces
# deployment, you can override values.yaml by providing your own
# role definitions below
#
# roles:
# - name: my-custom-role
# rules:
# - apiGroups: ""
# resources: ""
# verbs: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespaces:
- name: wargames-red-team
users:
- name: alice
roles:
- pod-viewer
- name: bob
roles:
- pod-viewer
- pod-manager
- name: wargames-blue-team
users:
- name: mallory
roles:
- pod-viewer
- name: carol
roles:
- pod-viewer
- pod-manager
34 changes: 34 additions & 0 deletions test/data/admin/networks/6_node_bitcoin/network.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
nodes:
- name: tank-0001
image:
tag: "26.0"
connect:
- tank-0002.wargames-red-team.svc.cluster.local
- tank-0003.wargames-blue-team.svc.cluster.local
- name: tank-0002
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
connect:
- tank-0003.wargames-red-team.svc.cluster.local
- tank-0004.wargames-blue-team.svc.cluster.local
- name: tank-0003
connect:
- tank-0004.wargames-red-team.svc.cluster.local
- tank-0005.wargames-blue-team.svc.cluster.local
- name: tank-0004
connect:
- tank-0005.wargames-red-team.svc.cluster.local
- tank-0006.wargames-blue-team.svc.cluster.local
- name: tank-0005
connect:
- tank-0006.wargames-red-team.svc.cluster.local
- name: tank-0006
fork_observer:
enabled: false
caddy:
enabled: false
26 changes: 26 additions & 0 deletions test/data/admin/networks/6_node_bitcoin/node-defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
chain: regtest

collectLogs: false
metricsExport: false

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi

image:
repository: bitcoindevproject/bitcoin
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "27.0"

config: |
dns=1
debug=rpc
126 changes: 126 additions & 0 deletions test/namespace_admin_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env python3

import os
from pathlib import Path
from typing import Callable, Optional

from test_base import TestBase

from warnet.k8s import get_kubeconfig_value
from warnet.process import run_command


class NamespaceAdminTest(TestBase):
def __init__(self):
super().__init__()
self.namespace_dir = (
Path(os.path.dirname(__file__))
/ "data"
/ "admin"
/ "namespaces"
/ "two_namespaces_two_users"
)
self.network_dir = (
Path(os.path.dirname(__file__)) / "data" / "admin" / "networks" / "6_node_bitcoin"
)

def run_test(self):
try:
self.setup_namespaces()
self.setup_service_accounts()
self.deploy_network_in_team_namespaces()
self.authenticate_and_become_bob()
self.become_minikube_once_again()
finally:
self.cleanup()

def become_minikube_once_again(self):
minikube = "minikube"
cmd = f"kubectl config use-context {minikube}"
self.log.info(run_command(cmd))
self.wait_for_predicate(self.this_is_the_current_context(minikube))

def this_is_the_current_context(self, context: str) -> Callable[[], bool]:
cmd = "kubectl config current-context"
current_context = run_command(cmd).strip()
self.log.info(f"Current context: {current_context} {context == current_context}")
return lambda: current_context == context

def setup_namespaces(self):
self.log.info("Setting up the namespaces")
self.log.info(self.warnet(f"deploy {self.namespace_dir}"))
self.wait_for_predicate(self.two_namespaces_are_validated)
self.log.info("Namespace setup complete")

def setup_service_accounts(self):
self.log.info("Creating service accounts...")
self.log.info(self.warnet("admin create-kubeconfigs"))
self.wait_for_predicate(self.service_accounts_are_validated)

def deploy_network_in_team_namespaces(self):
self.log.info("Deploy networks to team namespaces")
for namespace in self.get_namespaces():
self.log.info(f"Deploying network into: {namespace}")
self.log.info(self.warnet(f"deploy {self.network_dir} --namespace {namespace}"))
self.wait_for_all_tanks_status()
self.log.info("Waiting for all edges")
self.wait_for_all_edges()

def authenticate_and_become_bob(self):
self.log.info("Authenticating and becoming bob...")
assert get_kubeconfig_value("{.current-context}") == "minikube"
self.log.info(self.warnet("auth kubeconfigs/bob-wargames-red-team-kubeconfig"))
assert get_kubeconfig_value("{.current-context}") == "bob-wargames-red-team"

def get_service_accounts(self) -> Optional[dict[str, str]]:
self.log.info("Setting up service accounts")
resp = self.warnet("admin service-accounts list")
if resp == "Could not find any matching service accounts.":
return None
service_accounts: dict[str, [str]] = {}
current_namespace = ""
for line in resp.splitlines():
if line.startswith("Service"):
current_namespace = line.split(": ")[1]
service_accounts[current_namespace] = []
if line.startswith("- "):
sa = line.lstrip("- ")
service_accounts[current_namespace].append(sa)
self.log.info(f"Service accounts: {service_accounts}")
return service_accounts

def service_accounts_are_validated(self) -> bool:
self.log.info("Checking service accounts")
maybe_service_accounts = self.get_service_accounts()
expected = {
"wargames-blue-team": ["carol", "default", "mallory"],
"wargames-red-team": ["alice", "bob", "default"],
}
return maybe_service_accounts == expected

def get_namespaces(self) -> Optional[list[str]]:
self.log.info("Querying the namespaces...")
resp = self.warnet("admin namespaces list")
if resp == "No warnet namespaces found.":
return None
namespaces = []
for line in resp.splitlines():
if line.startswith("- "):
namespaces.append(line.lstrip("- "))
self.log.info(f"Namespaces: {namespaces}")
return namespaces

def two_namespaces_are_validated(self) -> bool:
maybe_namespaces = self.get_namespaces()
if maybe_namespaces is None:
return False
if len(maybe_namespaces) != 2:
return False
if "wargames-blue-team" not in maybe_namespaces:
return False
return "wargames-red-team" in maybe_namespaces


if __name__ == "__main__":
test = NamespaceAdminTest()
test.run_test()

0 comments on commit 353a3cf

Please sign in to comment.