From 096c6450e82a74b87c7e7a1ddd731307bc5e8329 Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Tue, 18 Oct 2016 06:38:57 -0500 Subject: [PATCH] Switch project_id from integer to UUID When looking at integrating craton with Keystone, it became apparent that we could not store project_id's from Keystone in Craton's Database. All of our project_id columns are Integers and Keystone uses UUIDs by default. As a result, we've switched Craton to use UUIDs for Project IDs and tweaked the docker tooling and install documentation. Change-Id: I4b84f6ac23ffd128e0060fd929c6f0c60ee16d52 Closes-bug: 1634191 --- Dockerfile | 4 +- craton/api/middleware.py | 2 +- craton/api/v1/schemas.py | 34 +++++++------- .../ffdc1a500db1_craton_inventory_init.py | 21 ++++++--- craton/db/sqlalchemy/api.py | 3 ++ craton/db/sqlalchemy/models.py | 20 ++++++--- craton/tests/unit/db/test_cells.py | 5 ++- craton/tests/unit/db/test_devices.py | 4 +- craton/tests/unit/db/test_networks.py | 9 ++-- craton/tests/unit/db/test_projects.py | 8 ++-- craton/tests/unit/db/test_regions.py | 5 ++- craton/tests/unit/db/test_users.py | 13 ++++-- craton/tests/unit/test_api.py | 44 ++++++++++--------- doc/source/dev/install.rst | 39 +++++++++------- tools/docker_run.sh | 8 +++- tools/generate_fake_data.py | 6 +-- 16 files changed, 138 insertions(+), 87 deletions(-) diff --git a/Dockerfile b/Dockerfile index b49c906..28d4ea8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,8 +14,8 @@ # Usage: # docker build -t craton-api:latest . # docker run -t --name craton-api -p 127.0.0.1:8080:8080 -d craton-api:latest -# python tools/generate_fake_data.py --url http://127.0.0.1:8080/v1 --user demo --project 1 --key demo -# curl http://127.0.0.1:8080/v1/regions -H "Content-Type: application/json" -H "X-Auth-Token: demo" -H "X-Auth-User: demo" -H "X-Auth-Project: 1" +# python tools/generate_fake_data.py --url http://127.0.0.1:8080/v1 --user demo --project b9f10eca66ac4c279c139d01e65f96b4 --key demo +# curl http://127.0.0.1:8080/v1/regions -H "Content-Type: application/json" -H "X-Auth-Token: demo" -H "X-Auth-User: demo" -H "X-Auth-Project: b9f10eca66ac4c279c139d01e65f96b4" ############################################################################# # Get Ubuntu base image diff --git a/craton/api/middleware.py b/craton/api/middleware.py index b518a8b..3c99f1b 100644 --- a/craton/api/middleware.py +++ b/craton/api/middleware.py @@ -37,7 +37,7 @@ class NoAuthContextMiddleware(ContextMiddleware): request, auth_token='noauth-token', user='noauth-user', - tenant=1, + tenant=None, is_admin=True, is_admin_project=True, ) diff --git a/craton/api/v1/schemas.py b/craton/api/v1/schemas.py index 431340c..d34354f 100644 --- a/craton/api/v1/schemas.py +++ b/craton/api/v1/schemas.py @@ -15,7 +15,7 @@ DefinitionsHost = {'discriminator': 'name', 'name': {'type': 'string'}, 'id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'parent_id': {'type': 'integer', 'description': 'Parent Id of this host'}, 'device_type': {'type': 'string', @@ -36,7 +36,7 @@ DefinitionsHostId = {'discriminator': 'name', 'name': {'type': 'string'}, 'id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'labels': {'type': 'array', 'items': 'string', 'description': 'User defined labels'}, @@ -52,8 +52,8 @@ DefinitionsCell = {'discriminator': 'name', 'type': 'object', 'properties': { 'note': {'type': 'string'}, - 'project_id': {'type': 'integer', - 'description': 'ID of the project'}, + 'project_id': {'type': 'string', + 'description': 'UUID of the project'}, 'name': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'data': {'type': 'allOf', @@ -65,8 +65,8 @@ DefinitionsCellId = {'discriminator': 'name', 'type': 'object', 'properties': { 'note': {'type': 'string'}, - 'project_id': {'type': 'integer', - 'description': 'ID of the project'}, + 'project_id': {'type': 'string', + 'description': 'UUID of the project'}, 'name': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'data': {'type': 'allOf', @@ -101,8 +101,8 @@ DefinitionsRegion = {'discriminator': 'name', 'type': 'string', 'description': 'Region Name.'}, 'project_id': { - 'type': 'integer', - 'description': 'ID of the project'}, + 'type': 'string', + 'description': 'UUID of the project'}, 'cells': { 'items': DefinitionsCell, 'type': 'array', @@ -124,8 +124,8 @@ DefinitionsRegionId = {'discriminator': 'name', 'type': 'string', 'description': 'Region Name.'}, 'project_id': { - 'type': 'integer', - 'description': 'ID of the project'}, + 'type': 'string', + 'description': 'UUID of the project'}, 'cells': { 'items': DefinitionsCell, 'type': 'array', @@ -144,7 +144,7 @@ DefinitionUser = {'discriminator': 'name', 'api_key': {'type': 'string'}, 'username': {'type': 'string'}, 'is_admin': {'type': 'boolean'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'roles': {'type': 'allOf'}}} DefinitionProject = {'discriminator': 'name', @@ -162,7 +162,7 @@ DefinitionNetwork = {'discriminator': 'name', 'type': 'object', 'properties': { 'id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, 'name': {'type': 'string'}, @@ -177,7 +177,7 @@ DefinitionNetworkId = {'discriminator': 'name', 'type': 'object', 'properties': { 'id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, 'name': {'type': 'string'}, @@ -201,7 +201,7 @@ DefinitionNetInterface = {'discriminator': 'name', 'network_id': {'type': 'integer', 'default': None}, 'interface_type': {'type': 'string'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'vlan_id': {'type': 'integer'}, 'vlan': {'type': 'string'}, 'port': {'type': 'integer'}, @@ -218,7 +218,7 @@ DefinitionNetInterfaceId = {'discriminator': 'name', 'id': {'type': 'integer'}, 'name': {'type': 'string'}, 'device_id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'network_id': {'type': 'integer'}, 'interface_type': {'type': 'string'}, 'vlan_id': {'type': 'integer'}, @@ -240,7 +240,7 @@ DefinitionNetDevice = {'discriminator': 'hostname', 'type': 'object', 'properties': { 'id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, 'parent_id': {'type': 'integer'}, @@ -260,7 +260,7 @@ DefinitionNetDeviceId = {'discriminator': 'hostname', 'type': 'object', 'properties': { 'id': {'type': 'integer'}, - 'project_id': {'type': 'integer'}, + 'project_id': {'type': 'string'}, 'region_id': {'type': 'integer'}, 'cell_id': {'type': 'integer'}, 'parent_id': {'type': 'integer'}, diff --git a/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py b/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py index 0c2aeef..470f800 100644 --- a/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py +++ b/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py @@ -51,7 +51,8 @@ def upgrade(): 'projects', sa.Column('created_at', sa.DateTime, nullable=True), sa.Column('updated_at', sa.DateTime, nullable=True), - sa.Column('id', sa.Integer, nullable=False), + sa.Column('id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('variable_association_id', sa.Integer), sa.Column('name', sa.String(length=255), nullable=True), sa.PrimaryKeyConstraint('id'), @@ -64,7 +65,8 @@ def upgrade(): sa.Column('created_at', sa.DateTime, nullable=True), sa.Column('updated_at', sa.DateTime, nullable=True), sa.Column('id', sa.Integer, nullable=False), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('variable_association_id', sa.Integer), sa.Column('name', sa.String(length=255), nullable=True), sa.Column('note', sa.Text, nullable=True), @@ -84,7 +86,8 @@ def upgrade(): sa.Column('created_at', sa.DateTime, nullable=True), sa.Column('updated_at', sa.DateTime, nullable=True), sa.Column('id', sa.Integer, nullable=False), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('variable_association_id', sa.Integer), sa.Column('username', sa.String(length=255), nullable=True), sa.Column('api_key', sa.String(length=36), nullable=True), @@ -108,7 +111,8 @@ def upgrade(): sa.Column('created_at', sa.DateTime, nullable=True), sa.Column('updated_at', sa.DateTime, nullable=True), sa.Column('id', sa.Integer, nullable=False), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('region_id', sa.Integer, nullable=False), sa.Column('variable_association_id', sa.Integer), sa.Column('name', sa.String(length=255), nullable=True), @@ -133,7 +137,8 @@ def upgrade(): sa.Column('created_at', sa.DateTime, nullable=True), sa.Column('updated_at', sa.DateTime, nullable=True), sa.Column('id', sa.Integer, nullable=False), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('region_id', sa.Integer, nullable=False), sa.Column('cell_id', sa.Integer, nullable=True), sa.Column('variable_association_id', sa.Integer), @@ -170,7 +175,8 @@ def upgrade(): sa.Column('type', sa.String(length=50), nullable=True), sa.Column('device_type', sa.String(length=255), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.Column('region_id', sa.Integer, nullable=False), sa.Column('cell_id', sa.Integer, nullable=True), sa.Column('parent_id', sa.Integer, nullable=True), @@ -247,7 +253,8 @@ def upgrade(): sa.Column('security', sa.String(length=255), nullable=True), sa.Column('device_id', sa.Integer, nullable=False), sa.Column('network_id', sa.Integer, nullable=True), - sa.Column('project_id', sa.Integer, nullable=False), + sa.Column('project_id', sqlalchemy_utils.types.UUIDType(binary=False), + nullable=False), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint( 'device_id', 'name', name='uq_netinter0deviceid0name'), diff --git a/craton/db/sqlalchemy/api.py b/craton/db/sqlalchemy/api.py index 331f7f1..fbbfa00 100644 --- a/craton/db/sqlalchemy/api.py +++ b/craton/db/sqlalchemy/api.py @@ -8,6 +8,7 @@ from oslo_db import options as db_options from oslo_db.sqlalchemy import session from oslo_db.sqlalchemy import utils as db_utils from oslo_log import log +from oslo_utils import uuidutils import sqlalchemy.orm.exc as sa_exc from sqlalchemy.orm import with_polymorphic @@ -551,6 +552,8 @@ def projects_create(context, values): """Create a new project with given values.""" session = get_session() project = models.Project() + if not values.get('id'): + values['id'] = uuidutils.generate_uuid() with session.begin(): project.update(values) project.save(session) diff --git a/craton/db/sqlalchemy/models.py b/craton/db/sqlalchemy/models.py index f9c9622..cb1cee7 100644 --- a/craton/db/sqlalchemy/models.py +++ b/craton/db/sqlalchemy/models.py @@ -26,6 +26,7 @@ from sqlalchemy.orm import backref, object_mapper, relationship from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy_utils.types.ip_address import IPAddressType from sqlalchemy_utils.types.json import JSONType +from sqlalchemy_utils.types.uuid import UUIDType # TODO(jimbaker) set up table args for a given database/storage @@ -184,7 +185,7 @@ class VariableMixin(object): class Project(Base): """Supports multitenancy for all other schema elements.""" __tablename__ = 'projects' - id = Column(Integer, primary_key=True) + id = Column(UUIDType(binary=False), primary_key=True) name = Column(String(255)) _repr_columns = [id, name] @@ -207,7 +208,8 @@ class User(Base, VariableMixin): ) id = Column(Integer, primary_key=True) project_id = Column( - Integer, ForeignKey('projects.id'), index=True, nullable=False) + UUIDType(binary=False), ForeignKey('projects.id'), index=True, + nullable=False) username = Column(String(255)) api_key = Column(String(36)) # root = craton admin that can create other pojects/usrs @@ -227,7 +229,8 @@ class Region(Base, VariableMixin): ) id = Column(Integer, primary_key=True) project_id = Column( - Integer, ForeignKey('projects.id'), index=True, nullable=False) + UUIDType(binary=False), ForeignKey('projects.id'), index=True, + nullable=False) name = Column(String(255)) note = Column(Text) _repr_columns = [id, name] @@ -248,7 +251,8 @@ class Cell(Base, VariableMixin): region_id = Column( Integer, ForeignKey('regions.id'), index=True, nullable=False) project_id = Column( - Integer, ForeignKey('projects.id'), index=True, nullable=False) + UUIDType(binary=False), ForeignKey('projects.id'), index=True, + nullable=False) name = Column(String(255)) note = Column(Text) _repr_columns = [id, name] @@ -275,7 +279,8 @@ class Device(Base, VariableMixin): cell_id = Column( Integer, ForeignKey('cells.id'), index=True, nullable=True) project_id = Column( - Integer, ForeignKey('projects.id'), index=True, nullable=False) + UUIDType(binary=False), ForeignKey('projects.id'), index=True, + nullable=False) access_secret_id = Column(Integer, ForeignKey('access_secrets.id')) parent_id = Column(Integer, ForeignKey('devices.id')) ip_address = Column(IPAddressType, nullable=False) @@ -357,7 +362,7 @@ class NetInterface(Base): link = Column(String(255), nullable=True) cdp = Column(String(255), nullable=True) security = Column(String(255), nullable=True) - project_id = Column(Integer, ForeignKey('projects.id'), + project_id = Column(UUIDType(binary=False), ForeignKey('projects.id'), index=True, nullable=False) device_id = Column(Integer, ForeignKey('devices.id')) network_id = Column(Integer, ForeignKey('networks.id'), nullable=True) @@ -386,7 +391,8 @@ class Network(Base, VariableMixin): cell_id = Column( Integer, ForeignKey('cells.id'), index=True, nullable=True) project_id = Column( - Integer, ForeignKey('projects.id'), index=True, nullable=False) + UUIDType(binary=False), ForeignKey('projects.id'), index=True, + nullable=False) devices = relationship('NetInterface', back_populates='network') region = relationship('Region', back_populates='networks') diff --git a/craton/tests/unit/db/test_cells.py b/craton/tests/unit/db/test_cells.py index 212506c..bbac627 100644 --- a/craton/tests/unit/db/test_cells.py +++ b/craton/tests/unit/db/test_cells.py @@ -1,9 +1,12 @@ +import uuid + from craton import exceptions from craton.db import api as dbapi from craton.tests.unit.db import base +project_id1 = uuid.uuid4().hex -cell1 = {'region_id': 1, 'project_id': 1, 'name': 'cell1'} +cell1 = {'region_id': 1, 'project_id': project_id1, 'name': 'cell1'} class CellsDBTestCase(base.DBTestCase): diff --git a/craton/tests/unit/db/test_devices.py b/craton/tests/unit/db/test_devices.py index ce7360b..72f56c3 100644 --- a/craton/tests/unit/db/test_devices.py +++ b/craton/tests/unit/db/test_devices.py @@ -1,3 +1,5 @@ +import uuid + from netaddr import IPAddress from craton.db import api as dbapi @@ -6,7 +8,7 @@ from craton.tests.unit.db import base class HostsDBTestCase(base.DBTestCase): - project_id = 42 + project_id = uuid.uuid4().hex def make_region(self, name, **variables): region = dbapi.regions_create( diff --git a/craton/tests/unit/db/test_networks.py b/craton/tests/unit/db/test_networks.py index 85fb886..83a008b 100644 --- a/craton/tests/unit/db/test_networks.py +++ b/craton/tests/unit/db/test_networks.py @@ -1,24 +1,27 @@ +import uuid + from craton import exceptions from craton.db import api as dbapi from craton.tests.unit.db import base +project_id1 = uuid.uuid4().hex network1 = {"name": "test network", "cidr": "192.168.1.0/24", "gateway": "192.168.1.1", "netmask": "255.255.255.0", "region_id": 1, - "project_id": 1} + "project_id": project_id1} device1 = {"hostname": "switch1", "model_name": "Model-X", "region_id": 1, - "project_id": 1, + "project_id": project_id1, "device_type": "switch", "ip_address": "192.168.1.1"} net_interface1 = {"device_id": 1, - "project_id": 1, + "project_id": project_id1, "name": "eth1", "ip_address": "192.168.0.2", "interface_type": "ethernet"} diff --git a/craton/tests/unit/db/test_projects.py b/craton/tests/unit/db/test_projects.py index 09b05c8..0216b36 100644 --- a/craton/tests/unit/db/test_projects.py +++ b/craton/tests/unit/db/test_projects.py @@ -1,3 +1,5 @@ +from oslo_utils import uuidutils + from craton import exceptions from craton.db import api as dbapi from craton.tests.unit.db import base @@ -7,13 +9,13 @@ project1 = {'name': 'project1'} project2 = {'name': 'project2'} -class PrjectsDBTestCase(base.DBTestCase): +class ProjectsDBTestCase(base.DBTestCase): def test_create_project(self): # Set root, as only admin project can create other projects self.context.is_admin_project = True project = dbapi.projects_create(self.context, project1) - self.assertEqual(project['id'], 1) + self.assertTrue(uuidutils.is_uuid_like(project['id'])) self.assertEqual(project['name'], project1['name']) def test_create_project_no_root_fails(self): @@ -45,4 +47,4 @@ class PrjectsDBTestCase(base.DBTestCase): self.context.is_admin_project = True project = dbapi.projects_create(self.context, project1) res = dbapi.projects_get_by_id(self.context, project['id']) - self.assertEqual(res['id'], project['id']) + self.assertEqual(str(res['id']), project['id']) diff --git a/craton/tests/unit/db/test_regions.py b/craton/tests/unit/db/test_regions.py index d32c326..650f929 100644 --- a/craton/tests/unit/db/test_regions.py +++ b/craton/tests/unit/db/test_regions.py @@ -1,9 +1,12 @@ +import uuid + from craton.db import api as dbapi from craton.tests.unit.db import base from craton import exceptions -region1 = {'project_id': 1, 'name': 'region1'} +project_id1 = uuid.uuid4().hex +region1 = {'project_id': project_id1, 'name': 'region1'} class RegionsDBTestCase(base.DBTestCase): diff --git a/craton/tests/unit/db/test_users.py b/craton/tests/unit/db/test_users.py index 791658c..db9a0fe 100644 --- a/craton/tests/unit/db/test_users.py +++ b/craton/tests/unit/db/test_users.py @@ -1,11 +1,16 @@ +import uuid + from craton import exceptions from craton.db import api as dbapi from craton.tests.unit.db import base -root = {'project_id': 1, 'username': 'root', "is_admin": True, "is_root": True} -user1 = {'project_id': 2, 'username': 'user1', "is_admin": True} -user2 = {'project_id': 2, 'username': 'user2', "is_admin": False} +project_id1 = uuid.uuid4().hex +project_id2 = uuid.uuid4().hex +root = {'project_id': project_id1, 'username': 'root', "is_admin": True, + "is_root": True} +user1 = {'project_id': project_id2, 'username': 'user1', "is_admin": True} +user2 = {'project_id': project_id2, 'username': 'user2', "is_admin": False} class UsersDBTestCase(base.DBTestCase): @@ -41,7 +46,7 @@ class UsersDBTestCase(base.DBTestCase): # Ensure when request has no root context and the request # is not for the same project no user info is given back. self.make_user(user1) - self.context.tenant = '12345' + self.context.tenant = uuid.uuid4().hex res = dbapi.users_get_all(self.context) self.assertEqual(len(res), 0) diff --git a/craton/tests/unit/test_api.py b/craton/tests/unit/test_api.py index 41196c0..9e10466 100644 --- a/craton/tests/unit/test_api.py +++ b/craton/tests/unit/test_api.py @@ -1,4 +1,5 @@ import mock +import uuid from oslo_serialization import jsonutils @@ -9,6 +10,8 @@ from craton.db.sqlalchemy import api as dbapi from craton.tests import TestCase from craton.tests.unit import fake_resources +project_id1 = uuid.uuid4().hex + class APIV1Test(TestCase): def setUp(self): @@ -104,16 +107,16 @@ class APIV1CellsTest(APIV1Test): @mock.patch.object(dbapi, 'cells_create') def test_create_cell_with_valid_data(self, mock_cell): mock_cell.return_value = None - data = {'name': 'cell1', 'region_id': 1, 'project_id': 1} + data = {'name': 'cell1', 'region_id': 1, 'project_id': project_id1} resp = self.post('v1/cells', data=data) self.assertEqual(200, resp.status_code) @mock.patch.object(dbapi, 'cells_create') def test_create_cell_returns_cell_obj(self, mock_cell): return_value = {'name': 'cell1', 'region_id': 1, - 'project_id': 1, 'id': 1} + 'project_id': project_id1, 'id': 1} mock_cell.return_value = return_value - data = {'name': 'cell1', 'region_id': 1, 'project_id': 1} + data = {'name': 'cell1', 'region_id': 1, 'project_id': project_id1} resp = self.post('v1/cells', data=data) self.assertEqual(200, resp.status_code) self.assertEqual(return_value, resp.json) @@ -122,7 +125,7 @@ class APIV1CellsTest(APIV1Test): def test_create_cell_fails_with_invalid_data(self, mock_cell): mock_cell.return_value = None # data is missing required cell name - data = {'region_id': 1, 'project_id': 1} + data = {'region_id': 1, 'project_id': project_id1} resp = self.post('v1/cells', data=data) self.assertEqual(422, resp.status_code) @@ -196,15 +199,15 @@ class APIV1RegionsTest(APIV1Test): @mock.patch.object(dbapi, 'regions_create') def test_post_region_with_valid_data(self, mock_region): mock_region.return_value = None - data = {'name': 'region1', 'project_id': 1} + data = {'name': 'region1', 'project_id': project_id1} resp = self.post('v1/regions', data=data) self.assertEqual(200, resp.status_code) @mock.patch.object(dbapi, 'regions_create') def test_create_region_returns_region_obj(self, mock_region): - return_value = {'name': 'region1', 'project_id': 1, 'id': 1} + return_value = {'name': 'region1', 'project_id': project_id1, 'id': 1} mock_region.return_value = return_value - data = {'name': 'region1', 'project_id': 1} + data = {'name': 'region1', 'project_id': project_id1} resp = self.post('v1/regions', data=data) self.assertEqual(200, resp.status_code) self.assertEqual(return_value, resp.json) @@ -212,7 +215,7 @@ class APIV1RegionsTest(APIV1Test): @mock.patch.object(dbapi, 'regions_create') def test_post_region_with_invalid_data_fails(self, mock_region): mock_region.return_value = None - data = {'project_id': '1'} + data = {'project_id': project_id1} resp = self.post('v1/regions', data=data) self.assertEqual(422, resp.status_code) @@ -311,20 +314,21 @@ class APIV1HostsTest(APIV1Test): @mock.patch.object(dbapi, 'hosts_create') def test_create_host_with_valid_data(self, mock_host): mock_host.return_value = None - data = {'name': 'www.host1.com', 'region_id': 1, 'project_id': 1, - 'ip_address': '10.0.0.1', 'device_type': 'server', - 'active': True} + data = {'name': 'www.host1.com', 'region_id': 1, + 'project_id': project_id1, 'ip_address': '10.0.0.1', + 'device_type': 'server', 'active': True} resp = self.post('/v1/hosts', data=data) self.assertEqual(200, resp.status_code) @mock.patch.object(dbapi, 'hosts_create') def test_create_host_returns_host_obj(self, mock_host): return_value = {'name': 'www.host1.com', 'region_id': 1, - 'project_id': 1, 'ip_address': '10.0.0.1', 'id': 1, - 'device_type': 'server', 'active': True} + 'project_id': project_id1, 'ip_address': '10.0.0.1', + 'id': 1, 'device_type': 'server', 'active': True} mock_host.return_value = return_value - data = {'name': 'www.host1.com', 'region_id': 1, 'project_id': 1, - 'ip_address': '10.0.0.1', 'device_type': 'server'} + data = {'name': 'www.host1.com', 'region_id': 1, + 'project_id': project_id1, 'ip_address': '10.0.0.1', + 'device_type': 'server'} resp = self.post('v1/hosts', data=data) self.assertEqual(200, resp.status_code) self.assertEqual(return_value, resp.json) @@ -385,10 +389,10 @@ class APIV1UsersTest(APIV1Test): @mock.patch.object(dbapi, 'users_create') def test_create_users(self, mock_project, mock_user): mock_project.return_value = {'id': 1, 'name': 'project1'} - return_value = {'name': 'user1', 'project_id': 1, + return_value = {'name': 'user1', 'project_id': project_id1, 'is_admin': False, 'id': 1, 'api_key': 'xxxx'} mock_user.return_value = return_value - data = {'name': 'user1', 'project_id': 1, 'is_admin': False} + data = {'name': 'user1', 'project_id': project_id1, 'is_admin': False} resp = self.post('v1/users', data=data) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.json['id'], 1) @@ -432,8 +436,8 @@ class APIV1NetworksTest(APIV1Test): @mock.patch.object(dbapi, 'networks_create') def test_create_networks_with_valid_data(self, mock_network): mock_network.return_value = None - data = {'name': 'some network', 'region_id': 1, 'project_id': 1, - 'cidr': '10.10.1.0/24', 'gateway': '192.168.1.1', - 'netmask': '255.255.255.0'} + data = {'name': 'some network', 'region_id': 1, + 'project_id': project_id1, 'cidr': '10.10.1.0/24', + 'gateway': '192.168.1.1', 'netmask': '255.255.255.0'} resp = self.post('/v1/networks', data=data) self.assertEqual(200, resp.status_code) diff --git a/doc/source/dev/install.rst b/doc/source/dev/install.rst index ee7fc19..177e44f 100755 --- a/doc/source/dev/install.rst +++ b/doc/source/dev/install.rst @@ -160,11 +160,11 @@ Create Project and User * Modify the projects and users as following:: - # insert into projects (created_at, updated_at, name) values - (NOW(), NOW(), "osic"); + # 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(), 1, "demo", "demo", False); + values (NOW(), NOW(), "717e9a216e2d44e0bc848398563bda06", "demo", "demo", False); * Logout from the database server:: @@ -193,9 +193,12 @@ Create a Region * To create region, execute the following command:: - # curl -i "http://${MY_IP}:8080/v1/regions" -XPOST -d - '{"name": "DFW", "project_id": 1}' -H "Content-Type: application/json" - -H "X-Auth-Token: demo" -H "X-Auth-User: demo" -H "X-Auth-Project: 1" + # curl -i "http://${MY_IP}:8080/v1/regions" \ + -d '{"name": "DFW", "project_id": "717e9a216e2d44e0bc848398563bda06"}' \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: demo" \ + -H "X-Auth-User: demo" \ + -H "X-Auth-Project: 717e9a216e2d44e0bc848398563bda06" ------------------ Get created Region @@ -203,9 +206,11 @@ Get created Region * To get the created region, execute the following command:: - # curl -i "http://${MY_IP}:8080/v1/regions" -H "Content-Type: - application/json" -H "X-Auth-Token: demo" -H "X-Auth-User: - demo" -H "X-Auth-Project: 1" + # curl -i "http://${MY_IP}:8080/v1/regions" \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: demo" \ + -H "X-Auth-User: demo" \ + -H "X-Auth-Project: 717e9a216e2d44e0bc848398563bda06" -------------------------- Get all hosts for Region 1 @@ -213,9 +218,11 @@ Get all hosts for Region 1 * To get all hosts for region 1, execute the following command:: - # curl -i "http://${MY_IP}:8080/v1/hosts?region_id=1" - -H "Content-Type: application/json" -H "X-Auth-Token: demo" - -H "X-Auth-User: demo" -H "X-Auth-Project: 1" + # curl -i "http://${MY_IP}:8080/v1/hosts?region_id=1" \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: demo" \ + -H "X-Auth-User: demo" \ + -H "X-Auth-Project: 717e9a216e2d44e0bc848398563bda06" --------------------- Get a particular host @@ -223,6 +230,8 @@ Get a particular host * To get a particular host, execute the following command:: - # curl -i "http://${MY_IP}:8080/v1/hosts/33" -H - "Content-Type: application/json" -H "X-Auth-Token: demo" - -H "X-Auth-User: demo" -H "X-Auth-Project: 1" + # curl -i "http://${MY_IP}:8080/v1/hosts/33" \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: demo" \ + -H "X-Auth-User: demo" \ + -H "X-Auth-Project: 717e9a216e2d44e0bc848398563bda06" diff --git a/tools/docker_run.sh b/tools/docker_run.sh index 6345d02..95546e5 100755 --- a/tools/docker_run.sh +++ b/tools/docker_run.sh @@ -19,11 +19,15 @@ mysqladmin flush-privileges ############## /craton/bin/craton-dbsync --config-file=/craton/etc/craton-api-conf.sample upgrade +USERNAME="demo" +TOKEN="demo" +PROJECT="b9f10eca66ac4c279c139d01e65f96b4" + ################################### # Create initial project and user # ################################### -mysql -u root craton -e "INSERT into projects (created_at, updated_at, name) values (NOW(), NOW(), 'demo')" -mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_admin) values (NOW(), NOW(), 1, 'demo', 'demo', False)" +mysql -u root craton -e "INSERT into projects (created_at, updated_at, name, id) values (NOW(), NOW(), '$USERNAME', '$PROJECT')" +mysql -u root craton -e "INSERT into users (created_at, updated_at, project_id, username, api_key, is_admin) values (NOW(), NOW(), '$PROJECT', '$USERNAME', '$TOKEN', False)" ######################### # Start the API service # diff --git a/tools/generate_fake_data.py b/tools/generate_fake_data.py index 65f00aa..2544d9a 100644 --- a/tools/generate_fake_data.py +++ b/tools/generate_fake_data.py @@ -44,13 +44,13 @@ class Inventory(object): self.url = url self.auth_user = auth_user self.auth_key = auth_key - self.project_id = project_id or 1 + self.project_id = project_id self.region = None self.cell = None self.ip_addresses = self.generate_ip_addresses(16) self.headers = {"Content-Type": "application/json", - "X-Auth-Project": str(self.project_id), + "X-Auth-Project": self.project_id, "X-Auth-User": self.auth_user, "X-Auth-Token": self.auth_key} @@ -189,7 +189,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--url', help='Endpoint for Craton Service') parser.add_argument('--user', help='User id') - parser.add_argument('--project', type=int, help='Project id') + parser.add_argument('--project', help='Project id') parser.add_argument('--key', help='Auth Key for the sevice') args = parser.parse_args()