diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2023-03-03 11:49:47 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2023-03-21 23:35:42 +0100 |
commit | 1e114c804b45f0a501f90526f7e762bfeedcf232 (patch) | |
tree | 40d9a92aa4990343969abf2a539b6a7053181b74 | |
parent | fa191c929b532ad28fc1ea916e73c9cc33dcfa7f (diff) | |
download | NetworkManager-1e114c804b45f0a501f90526f7e762bfeedcf232.tar.gz |
tools/test-cloud-meta-mock: add a mock metadata server for cloud-setup
Useful for testing/development.
-rw-r--r-- | Makefile.am | 1 | ||||
-rwxr-xr-x | tools/test-cloud-meta-mock.py | 90 |
2 files changed, 91 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 6fc3d035b6..9c81ef9c90 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5812,6 +5812,7 @@ EXTRA_DIST += \ tools/enums-to-docbook.pl \ tools/meson-post-install.sh \ tools/run-nm-test.sh \ + tools/test-cloud-meta-mock.py \ tools/test-networkmanager-service.py \ tools/test-sudo-wrapper.sh \ \ diff --git a/tools/test-cloud-meta-mock.py b/tools/test-cloud-meta-mock.py new file mode 100755 index 0000000000..262dc2ffb3 --- /dev/null +++ b/tools/test-cloud-meta-mock.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +# 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 + +import os +import socket + +from http.server import HTTPServer +from http.server import BaseHTTPRequestHandler +from socketserver import BaseServer + + +class MockCloudMDRequestHandler(BaseHTTPRequestHandler): + """ + Respond to cloud metadata service requests. + 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: + self.send_response(200) + self.end_headers() + self.wfile.write(self._meta_resources[self.path]) + else: + self.send_response(404) + self.end_headers() + + def do_PUT(self): + if self.path == "/latest/api/token": + self.send_response(200) + self.end_headers() + self.wfile.write( + b"AQAAALH-k7i18JMkK-ORLZQfAa7nkNjQbKwpQPExNHqzk1oL_7eh-A==" + ) + else: + self.send_response(404) + self.end_headers() + + +class SocketHTTPServer(HTTPServer): + """ + A HTTP server that accepts a socket (that has already been + listen()-ed on). This is useful when the socket is passed + fron the test runner. + """ + + def __init__(self, server_address, RequestHandlerClass, socket): + BaseServer.__init__(self, server_address, RequestHandlerClass) + self.socket = socket + self.server_address = self.socket.getsockname() + + +# See sd_listen_fds(3) +fileno = os.getenv("LISTEN_FDS") +if fileno is not None: + if fileno != "1": + raise Exception("Bad LISTEN_FDS") + s = socket.socket(fileno=3) +else: + addr = ("localhost", 0) + s = socket.socket() + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + s.bind(addr) + + +httpd = SocketHTTPServer(None, MockCloudMDRequestHandler, socket=s) + +print("Listening on http://%s:%d" % (httpd.server_address[0], httpd.server_address[1])) +httpd.server_activate() + +httpd.serve_forever() +httpd.server_close() |