122 lines
4.0 KiB
Python
122 lines
4.0 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import json
|
|
import requests
|
|
import os
|
|
import subprocess
|
|
import uuid
|
|
|
|
|
|
def getVendordataFromMetadataAPI():
|
|
response = requests.get(
|
|
'http://169.254.169.254/openstack/latest/vendor_data2.json',
|
|
)
|
|
assert response.status_code == 200
|
|
return json.loads(response.content)
|
|
|
|
|
|
def getInstanceAndProjectIdFromMetadataAPI():
|
|
response = requests.get(
|
|
'http://169.254.169.254/openstack/latest/meta_data.json',
|
|
)
|
|
assert response.status_code == 200
|
|
metadata = json.loads(response.content)
|
|
assert 'uuid' in metadata
|
|
assert 'project_id' in metadata
|
|
return metadata['uuid'], metadata['project_id']
|
|
|
|
|
|
def getVendordataFromConfigDrive():
|
|
path = '/mnt/config/openstack/latest/vendor_data2.json'
|
|
with open(path, 'r') as f:
|
|
json_string = f.read()
|
|
return json.loads(json_string)
|
|
|
|
|
|
def getInstanceAndProjectIdFromConfigDrive():
|
|
path = '/mnt/config/openstack/latest/meta_data.json'
|
|
with open(path, 'r') as f:
|
|
json_string = f.read()
|
|
metadata = json.loads(json_string)
|
|
assert 'uuid' in metadata
|
|
assert 'project_id' in metadata
|
|
return str(uuid.UUID(metadata['uuid'], version=4)), str(uuid.UUID(metadata['project_id'], version=4))
|
|
|
|
|
|
vendordata = getVendordataFromConfigDrive()
|
|
# vendordata = getVendordataFromMetadataAPI()
|
|
instance_id, project_id = getInstanceAndProjectIdFromConfigDrive()
|
|
# instance_id, project_id = getInstanceIdFromMetadataAPI()
|
|
|
|
assert 'tatu' in vendordata
|
|
tatu = vendordata['tatu']
|
|
assert 'token' in tatu
|
|
assert 'auth_pub_key_user' in tatu
|
|
assert 'principals' in tatu
|
|
principals = tatu['principals'].split(',')
|
|
|
|
with open('/etc/ssh/ssh_host_rsa_key.pub', 'r') as f:
|
|
host_key_pub = f.read()
|
|
|
|
server = 'http://172.24.4.1:18321'
|
|
|
|
hostcert_request = {
|
|
'token_id': tatu['token'],
|
|
'host_id': instance_id,
|
|
'key.pub': host_key_pub
|
|
}
|
|
|
|
response = requests.post(
|
|
# Hard-coded SSHaaS API address will only work for devstack and requires
|
|
# routing and SNAT or DNAT.
|
|
# This eventually needs to be either:
|
|
# 1) 169.254.169.254 if there's a SSHaaS-proxy; OR
|
|
# 2) the real address of the API, possibly supplied in the vendordata and
|
|
# still requiring routing and SNAT or DNAT.
|
|
server + '/hostcerts',
|
|
data=json.dumps(hostcert_request)
|
|
)
|
|
assert response.status_code == 201
|
|
assert 'location' in response.headers
|
|
location = response.headers['location']
|
|
print location
|
|
|
|
response = requests.get(server + location)
|
|
hostcert = json.loads(response.content)
|
|
assert 'host_id' in hostcert
|
|
assert hostcert['host_id'] == instance_id
|
|
assert 'fingerprint' in hostcert
|
|
assert 'auth_id' in hostcert
|
|
auth_id = str(uuid.UUID(hostcert['auth_id'], version=4))
|
|
assert auth_id == project_id
|
|
assert 'key-cert.pub' in hostcert
|
|
|
|
# Write the host's certificate
|
|
with open('/etc/ssh/ssh_host_rsa_key-cert.pub', 'w') as f:
|
|
f.write(hostcert['key-cert.pub'])
|
|
|
|
# Write the authorized principals file
|
|
os.mkdir('/etc/ssh/auth_principals')
|
|
with open('/etc/ssh/auth_principals/ubuntu', 'w') as f:
|
|
for p in principals:
|
|
f.write(p + os.linesep)
|
|
|
|
# Write the User CA public key file
|
|
with open('/etc/ssh/ca_user.pub', 'w') as f:
|
|
f.write(tatu['auth_pub_key_user'])
|
|
|
|
subprocess.check_output("sed -i -e '$aTrustedUserCAKeys /etc/ssh/ca_user.pub' /etc/ssh/sshd_config")
|
|
subprocess.check_output("sed -i -e '$aAuthorizedPrincipalsFile /etc/ssh/auth_principals/%u' /etc/ssh/sshd_config")
|
|
subprocess.check_output("sed -i -e '$aHostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' /etc/ssh/sshd_config")
|
|
subprocess.check_output("systemctl restart ssh")
|