summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2023-04-20 08:27:04 +0200
committerThomas Haller <thaller@redhat.com>2023-05-12 12:42:55 +0200
commit41f0f6fec825fc5f4be11ca0ba314a7d9aa8e2fd (patch)
treedc883c623a7f29d2ed6fa0bc50684ba79538e963
parente56df68464cacc28553f515e1d2edcdfa690ead8 (diff)
downloadNetworkManager-41f0f6fec825fc5f4be11ca0ba314a7d9aa8e2fd.tar.gz
test/cloud-meta-mock: allow putting the resources
This reworks the cloud metadata mock server in a significant way. Most importantly this makes it possible for the client to add and modify the resources for later retrieval using the PUT method. This allows the test to create the fixture for itself. The default set of resources is still provided, so that the too remains useful as a development aid. If that is not desirable, the --empty parameter might be passed to cause the server to start with no resources.
-rwxr-xr-xtools/test-cloud-meta-mock.py74
1 files changed, 58 insertions, 16 deletions
diff --git a/tools/test-cloud-meta-mock.py b/tools/test-cloud-meta-mock.py
index 262dc2ffb3..5c4fcad4a7 100755
--- a/tools/test-cloud-meta-mock.py
+++ b/tools/test-cloud-meta-mock.py
@@ -1,13 +1,23 @@
#!/usr/bin/env python
+# A service that mocks up various metadata providers. Used for testing,
+# can also be used standalone as a development aid.
+#
+# To run standalone:
+#
# run: $ systemd-socket-activate -l 8000 python tools/test-cloud-meta-mock.py &
# $ NM_CLOUD_SETUP_EC2_HOST=http://localhost:8000 \
# NM_CLOUD_SETUP_LOG=trace \
# NM_CLOUD_SETUP_EC2=yes src/nm-cloud-setup/nm-cloud-setup
# or just: $ python tools/test-cloud-meta-mock.py
+#
+# By default, the utility will server some resources for each known cloud
+# providers, for convenience. The tests start this with "--empty" argument,
+# which starts with no resources.
import os
import socket
+from sys import argv
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
@@ -20,36 +30,40 @@ class MockCloudMDRequestHandler(BaseHTTPRequestHandler):
Currently implements a fairly minimal subset of AWS EC2 API.
"""
- _ec2_macs = "/2018-09-24/meta-data/network/interfaces/macs/"
- _meta_resources = {
- "/latest/meta-data/": b"ami-id\n",
- _ec2_macs: b"9e:c0:3e:92:24:2d\n53:e9:7e:52:8d:a8",
- _ec2_macs + "9e:c0:3e:92:24:2d/subnet-ipv4-cidr-block": b"172.31.16.0/20",
- _ec2_macs + "9e:c0:3e:92:24:2d/local-ipv4s": b"172.31.26.249",
- _ec2_macs + "53:e9:7e:52:8d:a8/subnet-ipv4-cidr-block": b"172.31.166.0/20",
- _ec2_macs + "53:e9:7e:52:8d:a8/local-ipv4s": b"172.31.176.249",
- }
-
def log_message(self, format, *args):
pass
def do_GET(self):
- if self.path in self._meta_resources:
+ path = self.path.encode("ascii")
+ if path in self.server._resources:
self.send_response(200)
self.end_headers()
- self.wfile.write(self._meta_resources[self.path])
+ self.wfile.write(self.server._resources[path])
else:
self.send_response(404)
self.end_headers()
def do_PUT(self):
- if self.path == "/latest/api/token":
+ path = self.path.encode("ascii")
+ if path == b"/latest/api/token":
self.send_response(200)
self.end_headers()
self.wfile.write(
b"AQAAALH-k7i18JMkK-ORLZQfAa7nkNjQbKwpQPExNHqzk1oL_7eh-A=="
)
else:
+ length = int(self.headers["content-length"])
+ self.server._resources[path] = self.rfile.read(length)
+ self.send_response(201)
+ self.end_headers()
+
+ def do_DELETE(self):
+ path = self.path.encode("ascii")
+ if path in self.server._resources:
+ del self.server._resources[path]
+ self.send_response(204)
+ self.end_headers()
+ else:
self.send_response(404)
self.end_headers()
@@ -61,11 +75,40 @@ class SocketHTTPServer(HTTPServer):
fron the test runner.
"""
- def __init__(self, server_address, RequestHandlerClass, socket):
+ def __init__(self, server_address, RequestHandlerClass, socket, resources):
BaseServer.__init__(self, server_address, RequestHandlerClass)
self.socket = socket
self.server_address = self.socket.getsockname()
+ self._resources = resources
+
+def default_resources():
+ ec2_macs = b"/2018-09-24/meta-data/network/interfaces/macs/"
+
+ mac1 = b"9e:c0:3e:92:24:2d"
+ mac2 = b"53:e9:7e:52:8d:a8"
+
+ ip1 = b"172.31.26.249"
+ ip2 = b"172.31.176.249"
+
+ return {
+ b"/latest/meta-data/": b"ami-id\n",
+ ec2_macs: mac2 + b"\n" + mac1,
+ ec2_macs + mac2 + b"/subnet-ipv4-cidr-block": b"172.31.16.0/20",
+ ec2_macs + mac2 + b"/local-ipv4s": ip1,
+ ec2_macs + mac1 + b"/subnet-ipv4-cidr-block": b"172.31.166.0/20",
+ ec2_macs + mac1 + b"/local-ipv4s": ip2,
+ }
+
+
+resources = None
+try:
+ if argv[1] == "--empty":
+ resources = {}
+except IndexError:
+ pass
+if resources is None:
+ resources = default_resources()
# See sd_listen_fds(3)
fileno = os.getenv("LISTEN_FDS")
@@ -80,8 +123,7 @@ else:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(addr)
-
-httpd = SocketHTTPServer(None, MockCloudMDRequestHandler, socket=s)
+httpd = SocketHTTPServer(None, MockCloudMDRequestHandler, socket=s, resources=resources)
print("Listening on http://%s:%d" % (httpd.server_address[0], httpd.server_address[1]))
httpd.server_activate()