Remove key_manager section of config.

This commit is contained in:
Pino de Candia 2018-01-16 14:45:54 +00:00
parent d83fca3537
commit 54874d4c41
9 changed files with 78 additions and 47 deletions

View File

@ -5,7 +5,7 @@ port = 18322
[composite:main] [composite:main]
use = egg:Paste#urlmap use = egg:Paste#urlmap
/ = auth / = myapp
/noauth = myapp /noauth = myapp
[pipeline:auth] [pipeline:auth]
@ -16,7 +16,7 @@ paste.filter_factory = keystonemiddleware.auth_token:filter_factory
www_authenticate_uri = http://localhost/identity www_authenticate_uri = http://localhost/identity
identity_uri = http://localhost/identity identity_uri = http://localhost/identity
#auth_version = v2 #auth_version = v2
admin_token = gAAAAABaO-LnZQ03QZArlHYnXJL9Lg6valCBRUQ0n4eu4JOhIR3lHnxxoNuK1Zod41V_xDbkEqk75BO5rdvjuwDqDNOptje6E-XsE4dCu1WFJAhVyzLDd9DLctlNoeY8fnia-L8VacaNWQQ3EGX3uay434ZOErqKJ6Joxal11cG6u7VmYtu10xQ admin_token = gAAAAABaPEXR3jF2TqsraXh7qkpKOiPcVbnmHdMEsrSYRKUnfQvpCAR9Sq02vDZNcQLoodVLdxu449zc0AwGXeleRMuf7pEPBgjHPfR6ykkYV6_WXNuMt_Cmqvo_fnRdvPh8bJzjsWEqvEM9s_aCM-le8DkaatoacDrUDA3odBAP1AVdJ0PdJdM
#admin_user = nova #admin_user = nova
#admin_password = pinot #admin_password = pinot
#admin_tenant_name = service #admin_tenant_name = service

View File

@ -2,11 +2,13 @@
[tatu] [tatu]
use_barbican_key_manager = True use_barbican_key_manager = True
#use_pat_bastions = True
[key_manager] #num_total_pats = 3
auth_url = http://147.75.72.229/identity #num_pat_bastions_per_server = 2
auth_type = keystone_password #pat_dns_zone_name = tatuPAT.com.
username = admin #pat_dns_zone_email = tatu@nono.nono
#sqlalchemy_engine = mysql+pymysql://root:pinot@127.0.0.1/neutron?charset=utf8
auth_url = http://localhost/identity/v3
user_id = fab01a1f2a7749b78a53dffe441a1879
password = pinot password = pinot
project_id = 2e6c998ad16f4045821304470a57d160 project_id = 2e6c998ad16f4045821304470a57d160
user_domain_name = default

View File

@ -11,13 +11,25 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import argparse
import json import json
import requests import requests
import sys import sys
import uuid import uuid
server = 'http://172.24.4.1:18322' parser = argparse.ArgumentParser(description="Get the CA's public keys from Tatu API.")
auth_id = str(uuid.UUID(sys.argv[1], version=4)) parser.add_argument('--projid', '-P', required=True)
parser.add_argument('--tatu-url', default= 'http://127.0.0.1:18322',
help='URL of the Tatu API')
args = parser.parse_args()
try:
auth_id = str(uuid.UUID(args.projid, version=4))
except:
print '--projid should be the UUID of a Tatu CA (usually a cloud tenant/project).'
exit()
server = args.tatu_url
response = requests.post( response = requests.post(
server + '/authorities', server + '/authorities',
data=json.dumps({'auth_id': auth_id}) data=json.dumps({'auth_id': auth_id})

View File

@ -86,6 +86,24 @@ class Authorities(object):
resp.status = falcon.HTTP_201 resp.status = falcon.HTTP_201
resp.location = '/authorities/' + req.body['auth_id'] resp.location = '/authorities/' + req.body['auth_id']
@falcon.before(validate)
def on_get(self, req, resp):
auths = db.getAuthorities(self.session)
items = []
for auth in auths:
user_key = RSA.importKey(db.getAuthUserKey(auth))
user_pub_key = user_key.publickey().exportKey('OpenSSH')
host_key = RSA.importKey(db.getAuthHostKey(auth))
host_pub_key = host_key.publickey().exportKey('OpenSSH')
items.append({
'auth_id': auth.auth_id,
'user_key.pub': user_pub_key,
'host_key.pub': host_pub_key
})
body = {'items': items}
resp.body = json.dumps(body)
resp.status = falcon.HTTP_OK
class Authority(object): class Authority(object):
@falcon.before(validate) @falcon.before(validate)

View File

@ -17,48 +17,35 @@ from castellan.key_manager.key_manager import KeyManager
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from tatu.config import CONTEXT
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
_context = None _api = API()
_api = None
def context(): def delete_secret(id):
global _context
if _context is None and cfg.CONF.tatu.use_barbican_key_manager:
_context = credential_factory(conf=cfg.CONF)
return _context
def api():
global _api
if _api is None:
_api = API()
return _api
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)
""" """
api().delete(ctx or context(), id) _api.delete(CONTEXT, id)
def get_secret(id, ctx=None): def get_secret(id):
"""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)
""" """
key = api().get(ctx or context(), id) key = _api.get(CONTEXT, id)
return key.get_encoded() return key.get_encoded()
def store_secret(secret, ctx=None): def store_secret(secret):
"""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
@ -66,7 +53,7 @@ def store_secret(secret, ctx=None):
this operation (defaults to the current context) this operation (defaults to the current context)
""" """
key = Passphrase(secret) key = Passphrase(secret)
return api().store(ctx or context(), key) return _api.store(CONTEXT, key)
""" """

View File

@ -18,6 +18,7 @@ from keystoneauth1.identity import v3
from novaclient import client as nova_client from novaclient import client as nova_client
from neutronclient.v2_0 import client as neutron_client from neutronclient.v2_0 import client as neutron_client
from oslo_config import cfg from oslo_config import cfg
from oslo_context import context
from oslo_log import log as logging from oslo_log import log as logging
from castellan.options import set_defaults as set_castellan_defaults from castellan.options import set_defaults as set_castellan_defaults
@ -63,11 +64,9 @@ logging.register_options(CONF)
log_levels = logging.get_default_log_levels() + \ log_levels = logging.get_default_log_levels() + \
['tatu=DEBUG', '__main__=DEBUG'] ['tatu=DEBUG', '__main__=DEBUG']
logging.set_defaults(default_log_levels=log_levels) logging.set_defaults(default_log_levels=log_levels)
try: try:
CONF(args=[], CONF(args=[],
default_config_files=['/etc/tatu/tatu.conf', default_config_files=['/etc/tatu/tatu.conf',
'tatu.conf',
'files/tatu.conf' 'files/tatu.conf'
] ]
) )
@ -92,6 +91,10 @@ NOVA = nova_client.Client('2', session=session)
NEUTRON = neutron_client.Client(session=session) NEUTRON = neutron_client.Client(session=session)
DESIGNATE = designate_client.Client(session=session) DESIGNATE = designate_client.Client(session=session)
dragonflow_cfg.CONF(default_config_files=['/etc/neutron/dragonflow.ini']) dragonflow_cfg.CONF(args=[], default_config_files=['/etc/neutron/dragonflow.ini'])
dragonflow_cfg.CONF.set_override('enable_df_pub_sub', False, group='df') dragonflow_cfg.CONF.set_override('enable_df_pub_sub', False, group='df')
DRAGONFLOW = api_nb.NbApi.get_instance(False) DRAGONFLOW = api_nb.NbApi.get_instance(False)
# Create a context for use by Castellan
CONTEXT = context.RequestContext(auth_token=auth.get_token(session),
tenant=auth.get_project_id(session))

View File

@ -36,6 +36,10 @@ def getAuthority(session, auth_id):
return session.query(Authority).get(auth_id) return session.query(Authority).get(auth_id)
def getAuthorities(session):
return session.query(Authority)
def getAuthUserKey(auth): def getAuthUserKey(auth):
return get_secret(auth.user_key) return get_secret(auth.user_key)

View File

@ -26,7 +26,7 @@ def _setup_zone():
ZONE = DESIGNATE.zones.create(CONF.tatu.pat_dns_zone_name, ZONE = DESIGNATE.zones.create(CONF.tatu.pat_dns_zone_name,
email=CONF.tatu.pat_dns_zone_email) email=CONF.tatu.pat_dns_zone_email)
except Conflict: except Conflict:
pass ZONE = DESIGNATE.zones.get(CONF.tatu.pat_dns_zone_name)
def bastion_name_from_ip(ip_address): def bastion_name_from_ip(ip_address):

View File

@ -12,7 +12,7 @@
from dragonflow.db.models.core import Chassis from dragonflow.db.models.core import Chassis
from dragonflow.db.models.l2 import LogicalPort from dragonflow.db.models.l2 import LogicalPort
from dragonflow.db.models.l2 import LogicalRouter from dragonflow.db.models.l3 import LogicalRouter
from dragonflow.db.models.l3 import PAT from dragonflow.db.models.l3 import PAT
from dragonflow.db.models.l3 import PATEntry from dragonflow.db.models.l3 import PATEntry
from oslo_log import log as logging from oslo_log import log as logging
@ -28,15 +28,15 @@ def _sync_pats():
# TODO(pino): re-bind PATs when hypervisors fail (here and on notification) # TODO(pino): re-bind PATs when hypervisors fail (here and on notification)
all_chassis = DRAGONFLOW.get_all(Chassis) all_chassis = DRAGONFLOW.get_all(Chassis)
# Filter the chassis that already have PATS assigned # Filter the chassis that already have PATS assigned
# TODO: This doesn't work now because the p.chassis is a ChassisProxy
free_chassis = set(all_chassis).difference(p.chassis for p in PATS) free_chassis = set(all_chassis).difference(p.chassis for p in PATS)
# Don't make more PATs than there are free chassis # Don't make more PATs than there are free chassis
num_to_make = min(CONF.tatu.num_total_pats - len(PATS), num_to_make = min(CONF.tatu.num_total_pats - len(PATS),
len(free_chassis)) len(free_chassis))
if num_to_make <= 0: if num_to_make > 0:
return assigned_chassis = random.sample(free_chassis, num_to_make)
assigned_chassis = random.sample(free_chassis, num_to_make) for c in assigned_chassis:
for c in assigned_chassis: _add_pat(c)
_add_pat(c)
dns.sync_bastions(str(p.ip_address) for p in PATS) dns.sync_bastions(str(p.ip_address) for p in PATS)
@ -49,16 +49,19 @@ def _add_pat(chassis):
"admin_state_up": True, "admin_state_up": True,
"name": 'TatuPAT', # TODO(pino): set device owner to Tatu? "name": 'TatuPAT', # TODO(pino): set device owner to Tatu?
"network_id": network_id, "network_id": network_id,
"port_security_enabled": False,
"security_groups": [],
} }
} }
neutron_port = NEUTRON.create_port(body) neutron_port = NEUTRON.create_port(body)
lport = DRAGONFLOW.get(LogicalPort(id=neutron_port['port']['id'])) lport = DRAGONFLOW.get(LogicalPort(id=neutron_port['port']['id']))
ip = get_ip4_from_lport(lport) ip = _get_ip4_from_lport(lport)
pat = PAT( pat = PAT(
id = str(ip), id = str(ip),
topic = 'tatu', # TODO(pino): What topic? Admin project_id? topic = 'tatu', # TODO(pino): What topic? Admin project_id?
ip_address = ip, ip_address = ip,
lport = lport lport = lport,
chassis = chassis,
) )
# We only need to store the PAT in dragonflow's DB, not API/MySQL # We only need to store the PAT in dragonflow's DB, not API/MySQL
DRAGONFLOW.create(pat) DRAGONFLOW.create(pat)
@ -72,7 +75,7 @@ def _get_ip4_from_lport(lport):
return None return None
def df_find_lrouter_by_lport(lport): def _df_find_lrouter_by_lport(lport):
lrouters = DRAGONFLOW.get_all(LogicalRouter) lrouters = DRAGONFLOW.get_all(LogicalRouter)
for lr in lrouters: for lr in lrouters:
for lp in lr.ports: for lp in lr.ports:
@ -88,7 +91,7 @@ def create_pat_entries(sql_session, instance_id, fixed_l4_port,
for iface in ifaces: for iface in ifaces:
lport = DRAGONFLOW.get(LogicalPort(id=iface['port_id'])) lport = DRAGONFLOW.get(LogicalPort(id=iface['port_id']))
# TODO(pino): no router? consider SNAT of source IP to 169.254.169.254 # TODO(pino): no router? consider SNAT of source IP to 169.254.169.254
lrouter = df_find_lrouter_by_lport(lport) lrouter = _df_find_lrouter_by_lport(lport)
if lrouter is None: continue if lrouter is None: continue
# Reserve N l4 ports on distinct IPs. # Reserve N l4 ports on distinct IPs.
pats = PATS pats = PATS
@ -97,6 +100,8 @@ def create_pat_entries(sql_session, instance_id, fixed_l4_port,
for pat in pats: for pat in pats:
pat_l4_port = tatu_db.reserve_l4_port(sql_session, str(pat.ip)) pat_l4_port = tatu_db.reserve_l4_port(sql_session, str(pat.ip))
pat_entry = PATEntry( pat_entry = PATEntry(
id = '{}:{}'.format(pat.id, pat_l4_port),
topic = 'tatu',
pat = pat, pat = pat,
pat_l4_port = pat_l4_port, pat_l4_port = pat_l4_port,
fixed_ip_address = _get_ip4_from_lport(lport), fixed_ip_address = _get_ip4_from_lport(lport),
@ -111,4 +116,4 @@ def create_pat_entries(sql_session, instance_id, fixed_l4_port,
return port_ip_tuples return port_ip_tuples
_sync_pats() _sync_pats()