Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Simon János
/
orchestrator
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
09e73a8e
authored
Dec 17, 2016
by
Simon János
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added new resource types; changed tests accordingly
parent
553e5137
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
104 additions
and
11 deletions
+104
-11
orchestrator/model/resources.py
+78
-8
tests/test_api.py
+26
-3
tests/test_model.py
+0
-0
No files found.
orchestrator/model/resources.py
View file @
09e73a8e
import
copy
import
json
import
json
import
uuid
import
uuid
from
socket
import
inet_aton
from
enum
import
Enum
from
enum
import
Enum
from
oslo_config
import
cfg
from
voluptuous
import
Schema
,
Invalid
,
MultipleInvalid
,
Any
,
ALLOW_EXTRA
,
PREVENT_EXTRA
,
re
,
Required
,
Optional
,
All
,
\
Range
from
voluptuous
import
Schema
,
Invalid
,
MultipleInvalid
,
Any
,
ALLOW_EXTRA
,
PREVENT_EXTRA
,
re
from
orchestrator.util.task_client
import
Tasks
class
Resource
(
object
):
class
Resource
(
object
):
...
@@ -23,7 +27,7 @@ class Resource(object):
...
@@ -23,7 +27,7 @@ class Resource(object):
@classmethod
@classmethod
def
__attributes_from_dict
(
cls
,
attributes
):
def
__attributes_from_dict
(
cls
,
attributes
):
cls
.
__validate_attributes
(
attributes
,
cls
.
__schema
(
extend
=
False
))
cls
.
__validate_attributes
(
attributes
,
cls
.
__schema
(
extend
=
False
))
attributes
=
copy
.
deepcopy
(
attributes
)
attributes
=
attributes
.
copy
(
)
attributes
[
'id'
]
=
attributes
.
get
(
'id'
,
Resource
.
__generate_random_id
())
attributes
[
'id'
]
=
attributes
.
get
(
'id'
,
Resource
.
__generate_random_id
())
attributes
[
'type'
]
=
ResourceType
.
validate
(
attributes
.
get
(
'type'
,
cls
))
attributes
[
'type'
]
=
ResourceType
.
validate
(
attributes
.
get
(
'type'
,
cls
))
return
attributes
return
attributes
...
@@ -37,17 +41,28 @@ class Resource(object):
...
@@ -37,17 +41,28 @@ class Resource(object):
@classmethod
@classmethod
def
__schema
(
cls
,
resource_type
=
None
,
extend
=
False
):
def
__schema
(
cls
,
resource_type
=
None
,
extend
=
False
):
schema
=
Schema
(
schema
=
{
'id'
:
cls
.
_
_
id_validator
,
'type'
:
ResourceType
.
validate
},
extra
=
ALLOW_EXTRA
)
schema
=
Schema
(
schema
=
{
'id'
:
cls
.
_id_validator
,
'type'
:
ResourceType
.
validate
},
extra
=
ALLOW_EXTRA
)
if
extend
:
if
extend
:
additional
=
resource_type
.
ADDITIONAL_SCHEMA
if
resource_type
else
cls
.
ADDITIONAL_SCHEMA
additional
=
resource_type
.
ADDITIONAL_SCHEMA
if
resource_type
else
cls
.
ADDITIONAL_SCHEMA
schema
=
schema
.
extend
(
additional
,
extra
=
PREVENT_EXTRA
)
schema
=
schema
.
extend
(
additional
,
extra
=
PREVENT_EXTRA
)
return
schema
return
schema
@staticmethod
@staticmethod
def
_
_
id_validator
(
resource_id
):
def
_id_validator
(
resource_id
):
if
not
re
.
compile
(
'^[a-zA-Z0-9_-]{2,42}$'
)
.
match
(
resource_id
):
if
not
re
.
compile
(
'^[a-zA-Z0-9_-]{2,42}$'
)
.
match
(
resource_id
):
raise
Invalid
(
"'
%
s' is invalid"
%
resource_id
)
raise
Invalid
(
"'
%
s' is invalid"
%
resource_id
)
@staticmethod
def
_mac_validator
(
mac
):
return
re
.
match
(
"[0-9a-f]{2}([-:])[0-9a-f]{2}(
\\
1[0-9a-f]{2}){4}$"
,
mac
.
lower
())
@staticmethod
def
_ip_validator
(
ip_address
):
try
:
return
inet_aton
(
ip_address
)
except
AttributeError
:
return
False
@property
@property
def
type
(
self
):
def
type
(
self
):
return
str
(
self
.
_attributes
[
'type'
])
return
str
(
self
.
_attributes
[
'type'
])
...
@@ -92,7 +107,10 @@ class Resource(object):
...
@@ -92,7 +107,10 @@ class Resource(object):
def
flatten
(
self
,
fqn
=
None
,
flat_leaves
=
True
):
def
flatten
(
self
,
fqn
=
None
,
flat_leaves
=
True
):
fqn
=
'
%
s.
%
s'
%
(
fqn
,
self
.
id
)
if
fqn
else
self
.
id
fqn
=
'
%
s.
%
s'
%
(
fqn
,
self
.
id
)
if
fqn
else
self
.
id
if
flat_leaves
:
if
flat_leaves
:
return
{
'
%
s.
%
s'
%
(
fqn
,
key
):
str
(
value
)
for
key
,
value
in
self
.
items
()}
leaves
=
{}
for
key
,
value
in
self
.
items
():
leaves
[
'
%
s.
%
s'
%
(
fqn
,
key
)]
=
str
(
value
)
if
isinstance
(
value
,
ResourceType
)
else
value
return
leaves
return
{
fqn
:
self
}
return
{
fqn
:
self
}
@staticmethod
@staticmethod
...
@@ -101,10 +119,13 @@ class Resource(object):
...
@@ -101,10 +119,13 @@ class Resource(object):
return
str
(
data
)
return
str
(
data
)
return
dict
(
data
)
return
dict
(
data
)
def
deploy
(
self
,
name
):
pass
class
ResourceGroup
(
Resource
):
class
ResourceGroup
(
Resource
):
ADDITIONAL_SCHEMA
=
{
ADDITIONAL_SCHEMA
=
{
'resources'
:
Any
(
list
,
set
,
tuple
)
Optional
(
'resources'
)
:
Any
(
list
,
set
,
tuple
)
}
}
def
__init__
(
self
,
*
_
,
**
__
):
def
__init__
(
self
,
*
_
,
**
__
):
...
@@ -162,7 +183,53 @@ class ResourceGroup(Resource):
...
@@ -162,7 +183,53 @@ class ResourceGroup(Resource):
class
Instance
(
Resource
):
class
Instance
(
Resource
):
ADDITIONAL_SCHEMA
=
{
ADDITIONAL_SCHEMA
=
{
'number_of_cores'
:
int
Required
(
'cpu_count'
):
int
,
Required
(
'memory'
):
int
}
def
deploy
(
self
,
name
):
args
=
{
'name'
:
name
,
'vcpu'
:
self
.
cpu_count
,
'memory_max'
:
self
.
memory
}
result
=
Tasks
.
send_task
(
'vmdriver.create'
,
args
=
[
args
])
return
result
class
Disk
(
Resource
):
ADDITIONAL_SCHEMA
=
{
Required
(
'size'
):
All
(
int
,
Range
(
min
=
1
)),
Optional
(
'base'
):
str
}
def
deploy
(
self
,
name
):
args
=
{
'dir'
:
cfg
.
CONF
.
storage
.
datastore_root
,
'name'
:
name
,
'format'
:
'qcow2'
,
'type'
:
'normal'
,
'size'
:
self
.
size
,
'base_name'
:
self
.
base
or
None
}
task_name
=
'storagedriver.snapshot'
if
self
.
base
else
'storagedriver.create'
result
=
Tasks
.
send_task
(
task_name
,
args
=
[
args
])
return
result
class
DiskAttachment
(
Resource
):
ADDITIONAL_SCHEMA
=
{
Required
(
'instance_id'
):
Resource
.
_id_validator
,
Required
(
'stack_id'
):
Resource
.
_id_validator
}
class
NetworkConnection
(
Resource
):
ADDITIONAL_SCHEMA
=
{
Required
(
'instance_id'
):
Resource
.
_id_validator
,
Required
(
'mac'
):
Resource
.
_mac_validator
,
Required
(
'vlan'
):
All
(
int
,
Range
(
min
=
1
,
max
=
4094
)),
Required
(
'ip_address'
):
Resource
.
_ip_validator
}
}
...
@@ -170,6 +237,9 @@ class ResourceType(Enum):
...
@@ -170,6 +237,9 @@ class ResourceType(Enum):
null
=
Resource
null
=
Resource
group
=
ResourceGroup
group
=
ResourceGroup
instance
=
Instance
instance
=
Instance
disk
=
Disk
attachment
=
DiskAttachment
connection
=
NetworkConnection
@classmethod
@classmethod
def
validate
(
cls
,
value
):
def
validate
(
cls
,
value
):
...
...
tests/test_api.py
View file @
09e73a8e
...
@@ -5,6 +5,10 @@ from falcon.testing import TestCase
...
@@ -5,6 +5,10 @@ from falcon.testing import TestCase
from
orchestrator.api
import
stacks
from
orchestrator.api
import
stacks
TEST_INSTANCE_ARGS
=
{
'cpu_count'
:
2
,
'memory'
:
256
*
1000
*
1000
}
class
StackTest
(
TestCase
):
class
StackTest
(
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -30,7 +34,9 @@ class StackTest(TestCase):
...
@@ -30,7 +34,9 @@ class StackTest(TestCase):
'resources'
:
[
'resources'
:
[
{
{
'id'
:
'instance-1'
,
'id'
:
'instance-1'
,
'type'
:
'instance'
'type'
:
'instance'
,
'cpu_count'
:
1
,
'memory'
:
100
},
},
{
{
'id'
:
'level-1'
,
'id'
:
'level-1'
,
...
@@ -38,11 +44,23 @@ class StackTest(TestCase):
...
@@ -38,11 +44,23 @@ class StackTest(TestCase):
'resources'
:
[
'resources'
:
[
{
{
'id'
:
'instance-2'
,
'id'
:
'instance-2'
,
'type'
:
'instance'
'type'
:
'instance'
,
'cpu_count'
:
2
,
'memory'
:
200
},
},
{
{
'id'
:
'instance-3'
,
'id'
:
'instance-3'
,
'type'
:
'instance'
'type'
:
'instance'
,
'cpu_count'
:
3
,
'memory'
:
300
},
{
'id'
:
'connection-1'
,
'type'
:
'connection'
,
'instance_id'
:
'instance-1'
,
'vlan'
:
42
,
'mac'
:
'aa:bb:cc:dd:ee:ff'
,
'ip_address'
:
'10.0.0.42'
}
}
]
]
}
}
...
@@ -96,6 +114,7 @@ class StackTest(TestCase):
...
@@ -96,6 +114,7 @@ class StackTest(TestCase):
resource_id
=
'new_resource'
resource_id
=
'new_resource'
group1
=
{
'id'
:
stack_id
,
'type'
:
'group'
,
'resources'
:
[]}
group1
=
{
'id'
:
stack_id
,
'type'
:
'group'
,
'resources'
:
[]}
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
.
update
(
TEST_INSTANCE_ARGS
)
group2
=
{
'id'
:
stack_id
,
'type'
:
'group'
,
'resources'
:
[
resource
]}
group2
=
{
'id'
:
stack_id
,
'type'
:
'group'
,
'resources'
:
[
resource
]}
expected_diff
=
{
expected_diff
=
{
'added'
:
{
'added'
:
{
...
@@ -117,6 +136,7 @@ class StackTest(TestCase):
...
@@ -117,6 +136,7 @@ class StackTest(TestCase):
# given
# given
resource_id
=
'some_resource'
resource_id
=
'some_resource'
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
.
update
(
TEST_INSTANCE_ARGS
)
# when
# when
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource
))
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource
))
...
@@ -132,7 +152,9 @@ class StackTest(TestCase):
...
@@ -132,7 +152,9 @@ class StackTest(TestCase):
def
test_stacks_api_get_list
(
self
):
def
test_stacks_api_get_list
(
self
):
# given
# given
resource1
=
{
'id'
:
'some_resource'
,
'type'
:
'instance'
}
resource1
=
{
'id'
:
'some_resource'
,
'type'
:
'instance'
}
resource1
.
update
(
TEST_INSTANCE_ARGS
)
resource2
=
{
'id'
:
'some_other_resource'
,
'type'
:
'instance'
}
resource2
=
{
'id'
:
'some_other_resource'
,
'type'
:
'instance'
}
resource2
.
update
(
TEST_INSTANCE_ARGS
)
# when
# when
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource1
))
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource1
))
...
@@ -148,6 +170,7 @@ class StackTest(TestCase):
...
@@ -148,6 +170,7 @@ class StackTest(TestCase):
# given
# given
resource_id
=
'some_resource'
resource_id
=
'some_resource'
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
=
{
'id'
:
resource_id
,
'type'
:
'instance'
}
resource
.
update
(
TEST_INSTANCE_ARGS
)
# when
# when
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource
))
self
.
simulate_post
(
'/stacks'
,
body
=
json
.
dumps
(
resource
))
...
...
tests/test_model.py
View file @
09e73a8e
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment