Adds project/user bootstrap command to dbsync
So far we have been using external mysql command to insert project/user to bootstrap the process. This caused much frustration since operators needed to insert records in the db. This patch adds commands to dbsync to allow creating project/users. This method also takes care of association_id. To initiate a bootstrap: craton-dbsync --config-file=craton.conf bootstrap which will create a project with a root user. Users using Dockerfile can look at docker logs after creating the container to find this info. Closes Bug: 1670561 Change-Id: I9372961ca6623d530d7844b9f38aade544d961e8
This commit is contained in:
parent
0f7ee6d791
commit
109b4b6dd2
13
Dockerfile
13
Dockerfile
|
@ -11,12 +11,13 @@
|
|||
# under the License.
|
||||
|
||||
############################################################################
|
||||
# Usage:
|
||||
# docker build --pull -t craton-api:latest .
|
||||
# docker run -t --name craton-api -p 127.0.0.1:7780:7780 -d craton-api:latest
|
||||
# python tools/generate_fake_data.py --url http://127.0.0.1:7780/v1 --user demo --project b9f10eca66ac4c279c139d01e65f96b4 --key demo
|
||||
# curl http://127.0.0.1:7780/v1/regions -H "Content-Type: application/json" -H "X-Auth-Token: demo" -H "X-Auth-User: demo" -H "X-Auth-Project: b9f10eca66ac4c279c139d01e65f96b4"
|
||||
#############################################################################
|
||||
## Usage:
|
||||
## docker build --pull -t craton-api:latest .
|
||||
## docker run -t --name craton-api -p 127.0.0.1:7780:7780 -d craton-api:latest
|
||||
## docker logs <container> and copy the username, api_key, and project_id
|
||||
## python tools/generate_fake_data.py --url http://127.0.0.1:7780/v1 --user bootstrap --project <project-id from above> --key <api_key from above>
|
||||
## Use the credentials from above to try different commands using python-cratonclient.
|
||||
##############################################################################
|
||||
|
||||
# Get Ubuntu base image
|
||||
FROM ubuntu:16.04
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import binascii
|
||||
import os
|
||||
from flask import url_for
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
@ -57,3 +59,11 @@ def add_up_link(context, device):
|
|||
|
||||
links = device.setdefault("links", [])
|
||||
links.append(link)
|
||||
|
||||
|
||||
def gen_api_key():
|
||||
"""Generates crypto strong 16 bytes api key."""
|
||||
# NOTE(sulo): this implementation is taken from secrets
|
||||
# moudule available in python 3.6
|
||||
tbytes = os.urandom(16)
|
||||
return binascii.hexlify(tbytes).decode('ascii')
|
||||
|
|
|
@ -23,6 +23,20 @@ class DBCommand(object):
|
|||
def create_schema(self):
|
||||
migration.create_schema()
|
||||
|
||||
def bootstrap_project(self):
|
||||
name = 'bootstrap'
|
||||
project = migration.create_bootstrap_project(
|
||||
name,
|
||||
db_uri=CONF.database.connection)
|
||||
user = migration.create_bootstrap_user(
|
||||
project.id,
|
||||
name,
|
||||
db_uri=CONF.database.connection)
|
||||
|
||||
msg = ("\nProjectId: %s\nUsername: %s\nAPIKey: %s"
|
||||
% (user.project_id, user.username, user.api_key))
|
||||
print(msg)
|
||||
|
||||
|
||||
def add_command_parsers(subparsers):
|
||||
command_object = DBCommand()
|
||||
|
@ -57,6 +71,9 @@ def add_command_parsers(subparsers):
|
|||
help=("Create the database schema."))
|
||||
parser.set_defaults(func=command_object.create_schema)
|
||||
|
||||
parser = subparsers.add_parser('bootstrap')
|
||||
parser.set_defaults(func=command_object.bootstrap_project)
|
||||
|
||||
|
||||
def main():
|
||||
command_opt = cfg.SubCommandOpt('command',
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
import os
|
||||
|
||||
import alembic
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from alembic import config as alembic_config
|
||||
import alembic.migration as alembic_migration
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import exc
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
import sqlalchemy.orm.exc as sa_exc
|
||||
from oslo_db.sqlalchemy import enginefacade
|
||||
|
||||
from craton.api.v1.resources import utils
|
||||
from craton.db.sqlalchemy import models
|
||||
|
||||
|
||||
def _alembic_config():
|
||||
path = os.path.join(os.path.dirname(__file__), 'alembic.ini')
|
||||
|
@ -50,3 +58,57 @@ def revision(message=None, autogenerate=False, config=None):
|
|||
config = config or _alembic_config()
|
||||
return alembic.command.revision(config, message=message,
|
||||
autogenerate=autogenerate)
|
||||
|
||||
|
||||
def create_bootstrap_project(name, project_id=None, db_uri=None):
|
||||
"""Creates a new project.
|
||||
:param name: Name of the new project
|
||||
"""
|
||||
if not project_id:
|
||||
project_id = str(uuid.uuid4())
|
||||
engine = create_engine(db_uri)
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
project = models.Project(name=name,
|
||||
id=project_id)
|
||||
|
||||
try:
|
||||
project = session.query(models.Project).filter_by(name=name).one()
|
||||
except sa_exc.NoResultFound:
|
||||
session.add(project)
|
||||
session.commit()
|
||||
|
||||
return project
|
||||
|
||||
|
||||
def create_bootstrap_user(project_id, username, db_uri=None):
|
||||
"""Creates a new project.
|
||||
:param username: Username for new user
|
||||
:param project_id: Project ID for the user
|
||||
"""
|
||||
engine = create_engine(db_uri)
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
api_key = utils.gen_api_key()
|
||||
|
||||
user = models.User(project_id=project_id,
|
||||
username=username,
|
||||
api_key=api_key,
|
||||
is_admin=True,
|
||||
is_root=True)
|
||||
try:
|
||||
session.add(user)
|
||||
session.commit()
|
||||
except exc.IntegrityError as err:
|
||||
if err.orig.args[0] == 1062:
|
||||
# NOTE(sulo): 1062 is the normal sql duplicate error code
|
||||
# also see pymysql/constants/ER.py#L65
|
||||
session.rollback()
|
||||
user = session.query(models.User).filter_by(username=username)
|
||||
user = user.filter_by(project_id=project_id).one()
|
||||
return user
|
||||
else:
|
||||
raise
|
||||
|
||||
return user
|
||||
|
|
|
@ -143,31 +143,11 @@ Run dbsync
|
|||
# craton-dbsync --config-file=etc/craton
|
||||
-api-conf.sample upgrade
|
||||
|
||||
-----------------------
|
||||
Create Project and User
|
||||
-----------------------
|
||||
* Make sure to run dbsync bootstrap to create initial project and root user::
|
||||
# craton-dbsync --config-file=etc/craton-api-conf.sample bootstrap
|
||||
|
||||
.. note:: These goes away once the API has been setup
|
||||
|
||||
* Connect to database server as root user::
|
||||
|
||||
# mysql -u root -p
|
||||
|
||||
* Use the database craton::
|
||||
|
||||
# use craton;
|
||||
|
||||
* Modify the projects and users as following::
|
||||
|
||||
# insert into projects (created_at, updated_at, name, id) values
|
||||
(NOW(), NOW(), "osic", "717e9a216e2d44e0bc848398563bda06");
|
||||
# insert into users (created_at, updated_at, project_id, username
|
||||
, api_key, is_admin)
|
||||
values (NOW(), NOW(), "717e9a216e2d44e0bc848398563bda06", "demo", "demo", False);
|
||||
|
||||
* Logout from the database server::
|
||||
|
||||
# exit
|
||||
Note: The above command outputs user, project-id and API key to use with
|
||||
python-cratonclient to interact with craton server.
|
||||
|
||||
---------------------
|
||||
Start the API Service
|
||||
|
|
|
@ -19,31 +19,14 @@ mysqladmin flush-privileges
|
|||
##############
|
||||
/craton/bin/craton-dbsync --config-file=/craton/etc/craton-api-conf.sample upgrade
|
||||
|
||||
PROJECT="b9f10eca66ac4c279c139d01e65f96b4"
|
||||
|
||||
BOOTSTRAP_USERNAME="bootstrap"
|
||||
BOOTSTRAP_TOKEN="bootstrap"
|
||||
|
||||
USERNAME="demo"
|
||||
TOKEN="demo"
|
||||
|
||||
ADMIN_USERNAME="demo_admin"
|
||||
ADMIN_TOKEN="demo_admin"
|
||||
|
||||
ROOT_USERNAME="demo_root"
|
||||
ROOT_TOKEN="demo_root"
|
||||
|
||||
PROJECT_DISCRIMINATOR='project'
|
||||
|
||||
####################################
|
||||
# Create initial project and users #
|
||||
####################################
|
||||
PROJECT_VA_ID=$(mysql -u root craton -e "INSERT into variable_association (created_at, updated_at, discriminator) values (NOW(), NOW(), '$PROJECT_DISCRIMINATOR'); SELECT LAST_INSERT_ID();" | grep -Eo '[0-9]+')
|
||||
mysql -u root craton -e "INSERT into projects (created_at, updated_at, name, variable_association_id, id) values (NOW(), NOW(), '$USERNAME', $PROJECT_VA_ID, '$PROJECT')"
|
||||
mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_root, is_admin) values (NOW(), NOW(), '$PROJECT', '$BOOTSTRAP_USERNAME', '$BOOTSTRAP_TOKEN', True, False)"
|
||||
mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_root, is_admin) values (NOW(), NOW(), '$PROJECT', '$USERNAME', '$TOKEN', False, False)"
|
||||
mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_root, is_admin) values (NOW(), NOW(), '$PROJECT', '$ADMIN_USERNAME', '$ADMIN_TOKEN', False, True)"
|
||||
mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_root, is_admin) values (NOW(), NOW(), '$PROJECT', '$ROOT_USERNAME', '$ROOT_TOKEN', True, True)"
|
||||
# NOTE(sulo): One initial bootstrap project with root user will be created by the
|
||||
# bootstrap process. Users can docker logs -f <container-id> to view their api-key
|
||||
# to use with the client.
|
||||
/craton/bin/craton-dbsync --config-file=etc/craton-api-conf.sample bootstrap
|
||||
|
||||
#########################
|
||||
# Start the API service #
|
||||
|
|
Loading…
Reference in New Issue