Add the ability to add random unmanaged instances
The s390x host as such an example
diff --git a/README.md b/README.md
index 11719a2..1604aaa 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,11 @@
crn = crn:v1:...
instance_id = 123-abc...
+ [extra.<instancename>]
+ ip_addr = x.y.z.w
+ arch = s390x
+ num_cpus = 4
+ ram = 8
`<environment>` is a tag used to differentiate multiple environments. It allows
fetching instances from more than one IBM Cloud accounts. If `api_url` is
@@ -90,6 +95,8 @@
`CRN: <crn>` header if provided. `instance_id` is used only by the `power`
environment. (See `Power Instances` section for more details).
+`extra.<instancename>` can be an extra unmanaged manually added instance which
+is not discoverable via cloud.ibm.com with an API key.
The `tools/gen-config` script can then be used to generate our `production`
inventory and `ssh.cfg` configuration:
diff --git a/production b/production
index cbda855..3e374ad 100644
--- a/production
+++ b/production
@@ -35,7 +35,7 @@
public: 158.175.161.155
system:
arch: power
- num_cpu: 2
+ num_cpus: 2
ram: 16
couchdb-worker-x86-64-debian-dal-1-01:
instance:
@@ -173,3 +173,15 @@
arch: amd64
num_cpus: 4
ram: 8
+ couchdb01:
+ instance:
+ id: couchdb01
+ name: couchdb01
+ subnet: null
+ ip_addrs:
+ bastion: null
+ public: 148.100.113.138
+ system:
+ arch: s390x
+ num_cpus: 4
+ ram: 8
diff --git a/ssh.cfg b/ssh.cfg
index 7e80b5b..ee7098d 100644
--- a/ssh.cfg
+++ b/ssh.cfg
@@ -88,3 +88,12 @@
ControlPath /tmp/ansible-%r@%h:%p
ControlPersist 30m
+Host couchdb01
+ Hostname 148.100.113.138
+ User ubuntu
+ ForwardAgent yes
+ StrictHostKeyChecking no
+ ControlMaster auto
+ ControlPath /tmp/ansible-%r@%h:%p
+ ControlPersist 30m
+
diff --git a/tools/gen-config b/tools/gen-config
index b37cbf1..2af4933 100755
--- a/tools/gen-config
+++ b/tools/gen-config
@@ -17,6 +17,9 @@
#
ENV = {}
+# Hard-coded VMs managed by someone else without access to cloud.ibm.com
+EXTRA = {}
+
IBM_CLOUD_URL = "https://us-south.iaas.cloud.ibm.com/v1"
IAM_URL = "https://iam.cloud.ibm.com/identity/token"
@@ -38,6 +41,25 @@
parser.read([path])
for section in parser.sections():
+ if section.startswith("extra"):
+ split = section.split(".")
+ if len(split) != 2:
+ print(f"Invalid 'extra' section {section}")
+ exit(1)
+
+ (_, name) = split
+
+ EXTRA[name] = {
+ "name" : name,
+ "instance_id" : parser.get(section, "id", fallback=name),
+ "ip_addr": parser.get(section, "ip_addr"),
+ "system": {
+ "arch": parser.get(section, "arch"),
+ "num_cpus": int(parser.get(section, "num_cpus")),
+ "ram": int(parser.get(section, "ram"))
+ }
+ }
+
if not section.startswith("ibmcloud"):
continue
@@ -97,6 +119,8 @@
yield from list_x86_instances(env)
if env == "power":
yield from list_power_instances(env)
+ for inst in EXTRA.values():
+ yield inst
def list_x86_instances(env):
@@ -125,6 +149,7 @@
resp = sess.get(url, params=params(env))
instance = resp.json()
instance["name"] = instance["serverName"]
+ instance["system"] = {"arch": "power"}
yield instance
@@ -243,12 +268,32 @@
},
"system": {
"arch": "power",
- "num_cpu": instance["virtualCores"]["assigned"],
+ "num_cpus": instance["virtualCores"]["assigned"],
"ram": instance["memory"]
}
}
+def load_s390x_ci_agent(ci_agents, instance):
+ name = instance["name"]
+ if name in ci_agents:
+ print(f"Duplicate ci_agent found {name}")
+ exit(2)
+
+ ci_agents[name] = {
+ "instance": {
+ "id": instance["instance_id"],
+ "name" : instance["name"],
+ "subnet": None
+ },
+ "ip_addrs": {
+ "bastion": None,
+ "public": instance["ip_addr"]
+ },
+ "system": instance["system"]
+ }
+
+
def get_private_ip(instance):
ip = instance["primary_network_interface"]["primary_ipv4_address"]
if ip:
@@ -269,8 +314,8 @@
assert subnet not in subnets
subnets[subnet] = ip_addr
for (host, ci_agent) in ci_agents.items():
- if ci_agent["system"]["arch"] == "power":
- # Power systems use an external IP without bastions
+ if ci_agent["system"]["arch"] in ["power", "s390x"]:
+ # Power & s390x an external IP without bastions
continue
subnet = ci_agent["instance"]["subnet"]
assert subnet in subnets
@@ -326,8 +371,8 @@
entry = bastion_tmpl.format(**args)
handle.write(entry)
for host, info in sorted(ci_agents.items()):
- if info["system"]["arch"] == "power":
- # Power systems use an external IP directly
+ if info["system"]["arch"] in ["power", "s390x"]:
+ # Power or s390x use an external IP directly
args = {
"user": "ubuntu",
"host": host,
@@ -377,8 +422,10 @@
load_bastion(bastions, instance)
elif instance["name"].startswith("couchdb-worker"):
load_ci_agent(ci_agents, instance)
- elif instance["name"].startswith("couchdb-ci"):
+ elif instance["system"]["arch"] == "power":
load_power_ci_agent(ci_agents, instance)
+ elif instance["system"]["arch"] == "s390x":
+ load_s390x_ci_agent(ci_agents, instance)
assign_bastions(bastions, ci_agents)