Skip to content

Commit

Permalink
Add automated tests for TransportServer status (#1516)
Browse files Browse the repository at this point in the history
  • Loading branch information
soneillf5 authored Apr 9, 2021
1 parent 43adb84 commit 082d957
Show file tree
Hide file tree
Showing 10 changed files with 471 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/edge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ jobs:
tag: ${{ github.sha }}
marker: 'vs'
type: oss
- os: ubuntu-20.04
image: nginx-ingress
tag: ${{ github.sha }}
marker: 'ts'
type: oss
- os: ubuntu-20.04
image: nginx-ingress
tag: ${{ github.sha }}
Expand All @@ -263,6 +268,11 @@ jobs:
tag: ${{ github.sha }}
marker: 'vs'
type: plus
- os: ubuntu-20.04
image: nginx-plus-ingress
tag: ${{ github.sha }}
marker: 'ts'
type: plus
- os: ubuntu-20.04
image: nginx-plus-ingress
tag: ${{ github.sha }}
Expand Down
15 changes: 15 additions & 0 deletions tests/data/transport-server-status/rejected-invalid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
name: transport-server
spec:
listener:
name: dns-tcp
# we specify an invalid protocol to generate an 'Invalid' state
protocol: invalid-protocol
upstreams:
- name: dns-app
service: coredns
port: 5353
action:
pass: dns-app
15 changes: 15 additions & 0 deletions tests/data/transport-server-status/rejected-warning.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
name: transport-server
spec:
listener:
# we specify a missing listener to generate a 'Warning' state
name: invalid-listener
protocol: TCP
upstreams:
- name: dns-app
service: coredns
port: 5353
action:
pass: dns-app
64 changes: 64 additions & 0 deletions tests/data/transport-server-status/standard/dns.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
data:
Corefile: |
.:5353 {
forward . 8.8.8.8:53
log
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
spec:
replicas: 2
selector:
matchLabels:
app: coredns
template:
metadata:
labels:
app: coredns
spec:
containers:
- name: coredns
image: coredns/coredns:1.6.7
args: [ "-conf", "/etc/coredns/Corefile" ]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
readOnly: true
ports:
- containerPort: 5353
name: dns
protocol: UDP
- containerPort: 5353
name: dns-tcp
protocol: TCP
securityContext:
readOnlyRootFilesystem: true
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
---
apiVersion: v1
kind: Service
metadata:
name: coredns
spec:
selector:
app: coredns
ports:
- name: dns
port: 5353
protocol: UDP
- name: dns-tcp
port: 5353
protocol: TCP
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: k8s.nginx.org/v1alpha1
kind: GlobalConfiguration
metadata:
name: nginx-configuration
spec:
listeners:
- name: dns-udp
port: 5353
protocol: UDP
- name: dns-tcp
port: 5353
protocol: TCP
14 changes: 14 additions & 0 deletions tests/data/transport-server-status/standard/transport-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
name: transport-server
spec:
listener:
name: dns-tcp
protocol: TCP
upstreams:
- name: dns-app
service: coredns
port: 5353
action:
pass: dns-app
1 change: 1 addition & 0 deletions tests/pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ markers =
vsr: mark test as a VirtualServerRoute test
policies: mark test as an AccessControl policy test
vs: mark test as a VirtualServer test
ts: mark test as a TransportServer test
ingresses: mark test as an Ingresses test
appprotect: mark test as an AppProtect test
rewrite: mark test as an uri rewrite test
Expand Down
167 changes: 167 additions & 0 deletions tests/suite/custom_resources_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,36 @@ def read_custom_resource(custom_objects: CustomObjectsApi, namespace, plural, na
raise


def read_custom_resource_v1alpha1(custom_objects: CustomObjectsApi, namespace, plural, name) -> object:
"""
Get CRD information (kubectl describe output)
:param custom_objects: CustomObjectsApi
:param namespace: The custom resource's namespace
:param plural: the custom resource's plural name
:param name: the custom object's name
:return: object
"""
print(f"Getting info for v1alpha1 crd {name} in namespace {namespace}")
try:
response = custom_objects.get_namespaced_custom_object(
"k8s.nginx.org", "v1alpha1", namespace, plural, name
)
pprint(response)
return response

except ApiException:
logging.exception(f"Exception occurred while reading CRD")
raise


def read_ts(custom_objects: CustomObjectsApi, namespace, name) -> object:
"""
Read TransportService resource.
"""
return read_custom_resource_v1alpha1(custom_objects, namespace, "transportservers", name)


def read_ap_crd(custom_objects: CustomObjectsApi, namespace, plural, name) -> object:
"""
Get AppProtect CRD information (kubectl describe output)
Expand Down Expand Up @@ -249,6 +279,117 @@ def create_virtual_server_from_yaml(
raise


def patch_ts_from_yaml(custom_objects: CustomObjectsApi, yaml_manifest, namespace) -> dict:
"""
Create a TransportServer Resource based on yaml file.
:param custom_objects: CustomObjectsApi
:param yaml_manifest: an absolute path to file
:param namespace:
:return: a dictionary representing the resource
"""
return create_resource_from_yaml(custom_objects, yaml_manifest, namespace, "transportservers")


def create_gc_from_yaml(custom_objects: CustomObjectsApi, yaml_manifest, namespace) -> dict:
"""
Create a GlobalConfiguration Resource based on yaml file.
:param custom_objects: CustomObjectsApi
:param yaml_manifest: an absolute path to file
:param namespace:
:return: a dictionary representing the resource
"""
return create_resource_from_yaml(custom_objects, yaml_manifest, namespace, "globalconfigurations")


def create_resource_from_yaml(custom_objects: CustomObjectsApi, yaml_manifest, namespace, plural) -> dict:
"""
Create a Resource based on yaml file.
:param custom_objects: CustomObjectsApi
:param yaml_manifest: an absolute path to file
:param namespace:
:param plural: the plural of the resource
:return: a dictionary representing the resource
"""

with open(yaml_manifest) as f:
body = yaml.safe_load(f)
try:
print("Create a Custom Resource: " + body["kind"])
group, version = body["apiVersion"].split("/")
custom_objects.create_namespaced_custom_object(
group, version, namespace, plural, body
)
print(f"Custom resource {body['kind']} created with name '{body['metadata']['name']}'")
return body
except ApiException as ex:
logging.exception(
f"Exception: {ex} occurred while creating {body['kind']}: {body['metadata']['name']}"
)
raise


def delete_ts(custom_objects: CustomObjectsApi, resource, namespace) -> None:
"""
Delete a TransportServer Resource.
:param custom_objects: CustomObjectsApi
:param namespace: namespace
:param resource: a dictionary representation of the resource yaml
:param namespace:
:return:
"""
return delete_resource(custom_objects, resource, namespace, "transportservers")


def delete_gc(custom_objects: CustomObjectsApi, resource, namespace) -> None:
"""
Delete a GlobalConfiguration Resource.
:param custom_objects: CustomObjectsApi
:param namespace: namespace
:param resource: a dictionary representation of the resource yaml
:param namespace:
:return:
"""
return delete_resource(custom_objects, resource, namespace, "globalconfigurations")


def delete_resource(custom_objects: CustomObjectsApi, resource, namespace, plural) -> None:
"""
Delete a Resource.
:param custom_objects: CustomObjectsApi
:param namespace: namespace
:param resource: a dictionary representation of the resource yaml
:param namespace:
:param plural: the plural of the resource
:return:
"""

name = resource['metadata']['name']
kind = resource['kind']
group, version = resource["apiVersion"].split("/")

print(f"Delete a: {kind}, name: {name}")
delete_options = client.V1DeleteOptions()

custom_objects.delete_namespaced_custom_object(
group, version, namespace, plural, name, delete_options
)
ensure_item_removal(
custom_objects.get_namespaced_custom_object,
group,
version,
namespace,
plural,
name,
)
print(f"Resource:{kind} was removed with name '{name}'")


def create_ap_logconf_from_yaml(custom_objects: CustomObjectsApi, yaml_manifest, namespace) -> str:
"""
Create a logconf for AppProtect based on yaml file.
Expand Down Expand Up @@ -448,6 +589,32 @@ def patch_virtual_server_from_yaml(
raise


def patch_ts(
custom_objects: CustomObjectsApi, name, yaml_manifest, namespace
) -> None:
"""
Patch a TransportServer based on yaml manifest
"""
return patch_custom_resource_v1alpha1(custom_objects, name, yaml_manifest, namespace, "transportservers")


def patch_custom_resource_v1alpha1(custom_objects: CustomObjectsApi, name, yaml_manifest, namespace, plural) -> None:
"""
Patch a custom resource based on yaml manifest
"""
print(f"Update a Resource: {name}")
with open(yaml_manifest) as f:
dep = yaml.safe_load(f)

try:
custom_objects.patch_namespaced_custom_object(
"k8s.nginx.org", "v1alpha1", namespace, plural, name, dep
)
except ApiException:
logging.exception(f"Failed with exception while patching custom resource: {name}")
raise


def delete_and_create_vs_from_yaml(
custom_objects: CustomObjectsApi, name, yaml_manifest, namespace
) -> None:
Expand Down
Loading

0 comments on commit 082d957

Please sign in to comment.