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
This commit is contained in:
parent
cf6137ca7f
commit
096c6450e8
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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'},
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue