Pep8 fixes
This commit is contained in:
parent
3cee92f37f
commit
0a0f5f6e84
@ -1,121 +0,0 @@
|
|||||||
# 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")
|
|
@ -21,7 +21,7 @@ from tatu.db import models as db
|
|||||||
|
|
||||||
def validate_uuid(map, key):
|
def validate_uuid(map, key):
|
||||||
try:
|
try:
|
||||||
# Verify it's a valid UUID, then convert to canonical string representation
|
# Verify UUID is valid, then convert to canonical string representation
|
||||||
# to avoiid DB errors.
|
# to avoiid DB errors.
|
||||||
map[key] = str(uuid.UUID(map[key], version=4))
|
map[key] = str(uuid.UUID(map[key], version=4))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -55,10 +55,8 @@ class Logger(object):
|
|||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def process_resource(self, req, resp, resource, params):
|
def process_resource(self, req, resp, resource, params):
|
||||||
self.logger.debug(
|
self.logger.debug('Received request {0} {1} with headers {2}'
|
||||||
'Received request {0} {1} with headers {2}'.format(req.method,
|
.format(req.method, req.relative_uri, req.headers))
|
||||||
req.relative_uri,
|
|
||||||
req.headers))
|
|
||||||
|
|
||||||
def process_response(self, req, resp, resource, params):
|
def process_response(self, req, resp, resource, params):
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
@ -150,7 +148,7 @@ class HostCerts(object):
|
|||||||
@falcon.before(validate)
|
@falcon.before(validate)
|
||||||
def on_post(self, req, resp):
|
def on_post(self, req, resp):
|
||||||
# Note that we could have found the host_id using the token_id.
|
# Note that we could have found the host_id using the token_id.
|
||||||
# But requiring the host_id makes it a little harder to steal the token.
|
# But requiring the host_id makes it a bit harder to steal the token.
|
||||||
try:
|
try:
|
||||||
host = db.createHostCert(
|
host = db.createHostCert(
|
||||||
self.session,
|
self.session,
|
||||||
|
@ -53,6 +53,7 @@ def api():
|
|||||||
|
|
||||||
def delete_secret(id, ctx=None):
|
def delete_secret(id, ctx=None):
|
||||||
"""delete a secret from the external key manager
|
"""delete a secret from the external key manager
|
||||||
|
|
||||||
:param id: The identifier of the secret to delete
|
:param id: The identifier of the secret to delete
|
||||||
:param ctx: The context, and associated authentication, to use with
|
:param ctx: The context, and associated authentication, to use with
|
||||||
this operation (defaults to the current context)
|
this operation (defaults to the current context)
|
||||||
@ -62,6 +63,7 @@ def delete_secret(id, ctx=None):
|
|||||||
|
|
||||||
def get_secret(id, ctx=None):
|
def get_secret(id, ctx=None):
|
||||||
"""get a secret associated with an id
|
"""get a secret associated with an id
|
||||||
|
|
||||||
:param id: The identifier of the secret to retrieve
|
:param id: The identifier of the secret to retrieve
|
||||||
:param ctx: The context, and associated authentication, to use with
|
:param ctx: The context, and associated authentication, to use with
|
||||||
this operation (defaults to the current context)
|
this operation (defaults to the current context)
|
||||||
@ -72,6 +74,7 @@ def get_secret(id, ctx=None):
|
|||||||
|
|
||||||
def store_secret(secret, ctx=None):
|
def store_secret(secret, ctx=None):
|
||||||
"""store a secret and return its identifier
|
"""store a secret and return its identifier
|
||||||
|
|
||||||
:param secret: The secret to store, this should be a string
|
:param secret: The secret to store, this should be a string
|
||||||
:param ctx: The context, and associated authentication, to use with
|
:param ctx: The context, and associated authentication, to use with
|
||||||
this operation (defaults to the current context)
|
this operation (defaults to the current context)
|
||||||
@ -107,7 +110,8 @@ class TatuKeyManager(KeyManager):
|
|||||||
|
|
||||||
def store(self, context, key, expiration=None, **kwargs):
|
def store(self, context, key, expiration=None, **kwargs):
|
||||||
"""store a key
|
"""store a key
|
||||||
in normal usage a store_key will return the UUID of the key as
|
|
||||||
|
In normal usage a store_key will return the UUID of the key as
|
||||||
dictated by the key manager. Tatu would then store this UUID in
|
dictated by the key manager. Tatu would then store this UUID in
|
||||||
its database to use for retrieval. As tatu is not actually using
|
its database to use for retrieval. As tatu is not actually using
|
||||||
a key manager in this context it will return the key's payload for
|
a key manager in this context it will return the key's payload for
|
||||||
@ -117,7 +121,8 @@ class TatuKeyManager(KeyManager):
|
|||||||
|
|
||||||
def get(self, context, key_id, **kwargs):
|
def get(self, context, key_id, **kwargs):
|
||||||
"""get a key
|
"""get a key
|
||||||
since tatu is not actually storing key UUIDs the key_id to this
|
|
||||||
|
Since tatu is not actually storing key UUIDs the key_id to this
|
||||||
function should actually be the key payload. this function will
|
function should actually be the key payload. this function will
|
||||||
simply return a new TatuKey based on that value.
|
simply return a new TatuKey based on that value.
|
||||||
"""
|
"""
|
||||||
@ -125,7 +130,8 @@ class TatuKeyManager(KeyManager):
|
|||||||
|
|
||||||
def delete(self, context, key_id, **kwargs):
|
def delete(self, context, key_id, **kwargs):
|
||||||
"""delete a key
|
"""delete a key
|
||||||
as there is no external key manager, this function will not
|
|
||||||
|
As there is no external key manager, this function will not
|
||||||
perform any external actions. therefore, it won't change anything.
|
perform any external actions. therefore, it won't change anything.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -24,8 +24,7 @@ def get_url():
|
|||||||
|
|
||||||
class SQLAlchemySessionManager:
|
class SQLAlchemySessionManager:
|
||||||
"""
|
"""
|
||||||
Create a scoped session for every request and close it when the request
|
Create scoped session for every request and close it when the request ends
|
||||||
ends.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -20,7 +20,7 @@ from oslo_serialization import jsonutils
|
|||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker, scoped_session
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||||||
|
|
||||||
from tatu.db.models import Base, createAuthority
|
from tatu.db.models import createAuthority
|
||||||
from tatu.db.persistence import get_url
|
from tatu.db.persistence import get_url
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -54,8 +54,8 @@ class NotificationEndpoint(object):
|
|||||||
createAuthority(se, auth_id)
|
createAuthority(se, auth_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(
|
LOG.error(
|
||||||
"Failed to create Tatu CA for new project with ID {} due to exception {}".format(
|
"Failed to create Tatu CA for new project with ID {} "
|
||||||
proj_id, e))
|
"due to exception {}".format(proj_id, e))
|
||||||
se.rollback()
|
se.rollback()
|
||||||
self.Session.remove()
|
self.Session.remove()
|
||||||
else:
|
else:
|
||||||
@ -65,9 +65,8 @@ class NotificationEndpoint(object):
|
|||||||
def main():
|
def main():
|
||||||
logging.register_options(CONF)
|
logging.register_options(CONF)
|
||||||
extra_log_level_defaults = ['tatu=DEBUG', '__main__=DEBUG']
|
extra_log_level_defaults = ['tatu=DEBUG', '__main__=DEBUG']
|
||||||
logging.set_defaults(
|
logging.set_defaults(default_log_levels=logging.get_default_log_levels() +
|
||||||
default_log_levels=logging.get_default_log_levels() +
|
extra_log_level_defaults)
|
||||||
extra_log_level_defaults)
|
|
||||||
logging.setup(CONF, DOMAIN)
|
logging.setup(CONF, DOMAIN)
|
||||||
|
|
||||||
transport = oslo_messaging.get_notification_transport(CONF)
|
transport = oslo_messaging.get_notification_transport(CONF)
|
||||||
|
@ -19,7 +19,6 @@ from Crypto.PublicKey import RSA
|
|||||||
from falcon import testing
|
from falcon import testing
|
||||||
|
|
||||||
from tatu.api.app import create_app
|
from tatu.api.app import create_app
|
||||||
from tatu.db.models import Authority
|
|
||||||
from tatu.db.persistence import SQLAlchemySessionManager
|
from tatu.db.persistence import SQLAlchemySessionManager
|
||||||
from tatu.utils import random_uuid
|
from tatu.utils import random_uuid
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ def random_uuid():
|
|||||||
|
|
||||||
|
|
||||||
def generateCert(auth_key, entity_key, hostname=None, principals='root'):
|
def generateCert(auth_key, entity_key, hostname=None, principals='root'):
|
||||||
# Temporarily write the authority private key and entity public key to files
|
# Temporarily write the authority private key, entity public key to files
|
||||||
prefix = uuid.uuid4().hex
|
prefix = uuid.uuid4().hex
|
||||||
# Todo: make the temporary directory configurable or secure it.
|
# Todo: make the temporary directory configurable or secure it.
|
||||||
dir = '/tmp/sshaas'
|
dir = '/tmp/sshaas'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user