Skip to content

Commit ec78b8b

Browse files
markus-hentschfkr
authored andcommitted
Add conformance test script
Signed-off-by: Markus Hentsch <[email protected]>
1 parent 546728c commit ec78b8b

File tree

3 files changed

+189
-1
lines changed

3 files changed

+189
-1
lines changed

Standards/scs-01xx-v1-dns.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,8 @@ In Neutron, this can be done by activating either the `subnet_dns_publish_fixed_
160160

161161
## Conformance Tests
162162

163-
Conformance Tests, OPTIONAL
163+
Conformance tests verify the existence of necessary APIs and API extensions as mandated by the standard.
164+
165+
There is a test suite in [`dns-extensions-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/dns-extensions/dns-extensions-check.py).
166+
The test suite connects to the OpenStack API and queries the applicable APIs and extensions related to the DNS features.
167+
Please consult the associated [README.md](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/dns-extensions/README.md) for detailed setup and testing instructions.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# DNS Extensions Test Suite
2+
3+
## Test Environment Setup
4+
5+
### Test Execution Environment
6+
7+
> **NOTE:** The test execution procedure does not require cloud admin rights.
8+
9+
To execute the test suite a valid cloud configuration for the OpenStack SDK in the shape of "`clouds.yaml`" is mandatory[^1].
10+
**The file is expected to be located in the current working directory where the test script is executed unless configured otherwise.**
11+
12+
[^1]: [OpenStack Documentation: Configuring OpenStack SDK Applications](https://docs.openstack.org/openstacksdk/latest/user/config/configuration.html)
13+
14+
The test execution environment can be located on any system outside of the cloud infrastructure that has OpenStack API access.
15+
Make sure that the API access is configured properly in "`clouds.yaml`".
16+
17+
It is recommended to use a Python virtual environment[^2].
18+
Next, install the OpenStack SDK required by the test suite:
19+
20+
```bash
21+
pip3 install openstacksdk
22+
```
23+
24+
Within this environment execute the test suite.
25+
26+
[^2]: [Python 3 Documentation: Virtual Environments and Packages](https://docs.python.org/3/tutorial/venv.html)
27+
28+
## Test Execution
29+
30+
The test suite is executed as follows:
31+
32+
```bash
33+
python3 dns-extensions-check.py --os-cloud mycloud
34+
```
35+
36+
As an alternative to "`--os-cloud`", the "`OS_CLOUD`" environment variable may be specified instead.
37+
The parameter is used to look up the correct cloud configuration in "`clouds.yaml`".
38+
For the example command above, this file should contain a `clouds.mycloud` section like this:
39+
40+
```yaml
41+
---
42+
clouds:
43+
mycloud:
44+
auth:
45+
auth_url: ...
46+
...
47+
...
48+
```
49+
50+
For any further options consult the output of "`python3 dns-extensions-check.py --help`".
51+
52+
### Script Behavior & Test Results
53+
54+
The script will print all executed tests and their results to `stdout`.
55+
56+
If all tests pass, the script will return with an exit code of `0`.
57+
58+
If any test fails, the script will abort, print the failed test to `stdout` and return with a non-zero exit code.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"""Networking API extension checker for DNS functionality
2+
3+
This script uses the OpenStack SDK to check conformance to the SCS standard
4+
concerning DNS API extensions.
5+
"""
6+
7+
import openstack
8+
import os
9+
import sys
10+
import argparse
11+
12+
13+
def connect(cloud_name: str,
14+
auth_overrides: dict = None) -> openstack.connection.Connection:
15+
"""Create a connection to an OpenStack cloud
16+
17+
:param string cloud_name:
18+
The name of the configuration to load from clouds.yaml.
19+
:param dict auth_overrides:
20+
A dict that overrides option of the auth section of the cloud
21+
configuration of the loaded clouds.yaml. Allows to authenticate
22+
as a different user based on the same general cloud settings.
23+
Example:
24+
25+
{
26+
"username": "claudia",
27+
"password": "foobar123!%",
28+
"project_name": "customer1"
29+
}
30+
31+
:returns: openstack.connnection.Connection
32+
"""
33+
34+
if auth_overrides:
35+
return openstack.connect(
36+
cloud=cloud_name,
37+
auth=auth_overrides
38+
)
39+
else:
40+
return openstack.connect(
41+
cloud=cloud_name,
42+
)
43+
44+
45+
def has_extension(conn: openstack.connection.Connection, name: str) -> bool:
46+
"""Checks whether a given Networking API extension is present.
47+
48+
Connects to the Extension API of the Networking API and checks if the
49+
extension given by `name` is present and in case it is returns True.
50+
Otherwise returns False.
51+
"""
52+
ext = conn.network.find_extension(name, ignore_missing=True)
53+
if ext:
54+
# note that ext.name is a human-readable description, the name as
55+
# referenced in the standard is the ext.alias
56+
return ext.alias == name
57+
else:
58+
return False
59+
60+
61+
def has_dns_api(conn: openstack.connection.Connection) -> bool:
62+
"""Checks whether the OpenStack DNS API is offered by the connected cloud.
63+
64+
Returns True if the DNS API is offered and False otherwise.
65+
"""
66+
# "[...] the dns member of a Connection object [...]"
67+
# "[...] will only be added if the service is detected."
68+
# see https://docs.openstack.org/openstacksdk/latest/user/proxies/dns.html
69+
return hasattr(conn, "dns")
70+
71+
72+
def main():
73+
parser = argparse.ArgumentParser(
74+
description="SCS Domain Manager Conformance Checker")
75+
parser.add_argument(
76+
"--os-cloud", type=str,
77+
help="Name of the cloud from clouds.yaml, alternative "
78+
"to the OS_CLOUD environment variable"
79+
)
80+
parser.add_argument(
81+
"--debug", action="store_true",
82+
help="Enable OpenStack SDK debug logging"
83+
)
84+
args = parser.parse_args()
85+
openstack.enable_logging(debug=args.debug)
86+
87+
# parse cloud name for lookup in clouds.yaml
88+
cloud = os.environ.get("OS_CLOUD", None)
89+
if args.os_cloud:
90+
cloud = args.os_cloud
91+
assert cloud, (
92+
"You need to have the OS_CLOUD environment variable set to your cloud "
93+
"name or pass it via --os-cloud"
94+
)
95+
conn = connect(cloud)
96+
97+
# bare minimum: dns-integration extension
98+
if has_extension(conn, "dns-integration"):
99+
print(
100+
"Networking API MUST offer 'dns-integration' extension: PASS"
101+
)
102+
else:
103+
print(
104+
"Networking API MUST offer 'dns-integration' extension: FAIL"
105+
)
106+
sys.exit(1)
107+
108+
has_designate = has_dns_api(conn)
109+
print("Is DNS API present (OPTIONAL):", has_designate)
110+
111+
if has_designate:
112+
if has_extension(conn, "dns-domain-ports"):
113+
print(
114+
"When the DNS API is present, the Networking API MUST offer "
115+
"the 'dns-domain-ports' extension: PASS"
116+
)
117+
else:
118+
print(
119+
"When the DNS API is present, the Networking API MUST offer "
120+
"the 'dns-domain-ports' extension: FAIL"
121+
)
122+
sys.exit(1)
123+
124+
125+
if __name__ == "__main__":
126+
main()

0 commit comments

Comments
 (0)