summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Verboso <fverboso@unime.it>2018-09-21 14:41:13 +0200
committerFabio Verboso <fverboso@unime.it>2018-09-21 14:41:13 +0200
commit3c351e80ced88a12f49beb45a593f8401122b85f (patch)
treee5d65f906d16def0abf92e943b9aa51de65cfe9f
parenta081c594b2532edaf9c4a963cacbb1de3951bd10 (diff)
"Boards in a fleet"
Now a board can join a fleet Change-Id: I5f553421929e72dd1871cce1783043e5e38865f1
Notes
Notes (review): Code-Review+2: Fabio Verboso <fverboso@unime.it> Workflow+1: Fabio Verboso <fverboso@unime.it> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Fri, 21 Sep 2018 13:11:02 +0000 Reviewed-on: https://review.openstack.org/604350 Project: openstack/iotronic Branch: refs/heads/master
-rw-r--r--iotronic/api/controllers/v1/board.py4
-rw-r--r--iotronic/api/controllers/v1/fleet.py85
-rw-r--r--iotronic/db/sqlalchemy/alembic/versions/9c5c34dfd9f1_add_boards_in_fleet.py24
-rw-r--r--iotronic/db/sqlalchemy/api.py2
-rw-r--r--iotronic/db/sqlalchemy/models.py1
-rw-r--r--iotronic/objects/board.py1
6 files changed, 72 insertions, 45 deletions
diff --git a/iotronic/api/controllers/v1/board.py b/iotronic/api/controllers/v1/board.py
index f479413..273e2be 100644
--- a/iotronic/api/controllers/v1/board.py
+++ b/iotronic/api/controllers/v1/board.py
@@ -30,7 +30,8 @@ from oslo_log import log as logging
30LOG = logging.getLogger(__name__) 30LOG = logging.getLogger(__name__)
31 31
32 32
33_DEFAULT_RETURN_FIELDS = ('name', 'code', 'status', 'uuid', 'session', 'type') 33_DEFAULT_RETURN_FIELDS = ('name', 'code', 'status', 'uuid', 'session', 'type',
34 'fleet')
34 35
35 36
36class Board(base.APIBase): 37class Board(base.APIBase):
@@ -45,6 +46,7 @@ class Board(base.APIBase):
45 owner = types.uuid 46 owner = types.uuid
46 session = wsme.wsattr(wtypes.text) 47 session = wsme.wsattr(wtypes.text)
47 project = types.uuid 48 project = types.uuid
49 fleet = types.uuid
48 mobile = types.boolean 50 mobile = types.boolean
49 links = wsme.wsattr([link.Link], readonly=True) 51 links = wsme.wsattr([link.Link], readonly=True)
50 location = wsme.wsattr([loc.Location]) 52 location = wsme.wsattr([loc.Location])
diff --git a/iotronic/api/controllers/v1/fleet.py b/iotronic/api/controllers/v1/fleet.py
index a36b291..9ae45df 100644
--- a/iotronic/api/controllers/v1/fleet.py
+++ b/iotronic/api/controllers/v1/fleet.py
@@ -13,6 +13,7 @@
13 13
14from iotronic.api.controllers import base 14from iotronic.api.controllers import base
15from iotronic.api.controllers import link 15from iotronic.api.controllers import link
16from iotronic.api.controllers.v1.board import BoardCollection
16from iotronic.api.controllers.v1 import collection 17from iotronic.api.controllers.v1 import collection
17from iotronic.api.controllers.v1 import types 18from iotronic.api.controllers.v1 import types
18from iotronic.api.controllers.v1 import utils as api_utils 19from iotronic.api.controllers.v1 import utils as api_utils
@@ -29,6 +30,9 @@ from wsme import types as wtypes
29_DEFAULT_RETURN_FIELDS = ( 30_DEFAULT_RETURN_FIELDS = (
30 'name', 'uuid', 'project', 'description', 'extra') 31 'name', 'uuid', 'project', 'description', 'extra')
31 32
33_DEFAULT_BOARDS_RETURN_FIELDS = ('name', 'code', 'status', 'uuid', 'session',
34 'type', 'fleet')
35
32 36
33class Fleet(base.APIBase): 37class Fleet(base.APIBase):
34 """API representation of a fleet. 38 """API representation of a fleet.
@@ -94,48 +98,16 @@ class FleetCollection(collection.Collection):
94 return collection 98 return collection
95 99
96 100
97class PublicFleetsController(rest.RestController): 101class FleetBoardsController(rest.RestController):
98 """REST controller for Public Fleets.""" 102 def __init__(self, fleet_ident):
99 103 self.fleet_ident = fleet_ident
100 invalid_sort_key_list = ['extra']
101
102 def _get_fleets_collection(self, marker, limit,
103 sort_key, sort_dir,
104 fields=None):
105
106 limit = api_utils.validate_limit(limit)
107 sort_dir = api_utils.validate_sort_dir(sort_dir)
108
109 marker_obj = None
110 if marker:
111 marker_obj = objects.Fleet.get_by_uuid(pecan.request.context,
112 marker)
113
114 if sort_key in self.invalid_sort_key_list:
115 raise exception.InvalidParameterValue(
116 ("The sort_key value %(key)s is an invalid field for "
117 "sorting") % {'key': sort_key})
118
119 filters = {}
120 filters['public'] = True
121
122 fleets = objects.Fleet.list(pecan.request.context, limit,
123 marker_obj,
124 sort_key=sort_key, sort_dir=sort_dir,
125 filters=filters)
126
127 parameters = {'sort_key': sort_key, 'sort_dir': sort_dir}
128
129 return FleetCollection.convert_with_links(fleets, limit,
130 fields=fields,
131 **parameters)
132 104
133 @expose.expose(FleetCollection, types.uuid, int, wtypes.text, 105 @expose.expose(BoardCollection, types.uuid, int, wtypes.text,
134 wtypes.text, types.listtype, types.boolean, types.boolean) 106 wtypes.text, types.listtype)
135 def get_all(self, marker=None, 107 def get_all(self, marker=None,
136 limit=None, sort_key='id', sort_dir='asc', 108 limit=None, sort_key='id', sort_dir='asc',
137 fields=None): 109 fields=None):
138 """Retrieve a list of fleets. 110 """Retrieve a list of boards.
139 111
140 :param marker: pagination marker for large data sets. 112 :param marker: pagination marker for large data sets.
141 :param limit: maximum number of resources to return in a single result. 113 :param limit: maximum number of resources to return in a single result.
@@ -148,19 +120,31 @@ class PublicFleetsController(rest.RestController):
148 of the resource to be returned. 120 of the resource to be returned.
149 """ 121 """
150 cdict = pecan.request.context.to_policy_values() 122 cdict = pecan.request.context.to_policy_values()
151 policy.authorize('iot:fleet:get', cdict, cdict) 123 policy.authorize('iot:board:get', cdict, cdict)
152 124
153 if fields is None: 125 if fields is None:
154 fields = _DEFAULT_RETURN_FIELDS 126 fields = _DEFAULT_BOARDS_RETURN_FIELDS
155 return self._get_fleets_collection(marker, 127
156 limit, sort_key, sort_dir, 128 filters = {}
157 fields=fields) 129 filters['fleet'] = self.fleet_ident
130
131 boards = objects.Board.list(pecan.request.context, limit, marker,
132 sort_key=sort_key, sort_dir=sort_dir,
133 filters=filters)
134
135 parameters = {'sort_key': sort_key, 'sort_dir': sort_dir}
136
137 return BoardCollection.convert_with_links(boards, limit,
138 fields=fields,
139 **parameters)
158 140
159 141
160class FleetsController(rest.RestController): 142class FleetsController(rest.RestController):
161 """REST controller for Fleets.""" 143 """REST controller for Fleets."""
162 144
163 public = PublicFleetsController() 145 _subcontroller_map = {
146 'boards': FleetBoardsController,
147 }
164 148
165 invalid_sort_key_list = ['extra', ] 149 invalid_sort_key_list = ['extra', ]
166 150
@@ -168,6 +152,19 @@ class FleetsController(rest.RestController):
168 'detail': ['GET'], 152 'detail': ['GET'],
169 } 153 }
170 154
155 @pecan.expose()
156 def _lookup(self, ident, *remainder):
157 try:
158 ident = types.uuid_or_name.validate(ident)
159 except exception.InvalidUuidOrName as e:
160 pecan.abort('400', e.args[0])
161 if not remainder:
162 return
163
164 subcontroller = self._subcontroller_map.get(remainder[0])
165 if subcontroller:
166 return subcontroller(fleet_ident=ident), remainder[1:]
167
171 def _get_fleets_collection(self, marker, limit, 168 def _get_fleets_collection(self, marker, limit,
172 sort_key, sort_dir, 169 sort_key, sort_dir,
173 fields=None): 170 fields=None):
diff --git a/iotronic/db/sqlalchemy/alembic/versions/9c5c34dfd9f1_add_boards_in_fleet.py b/iotronic/db/sqlalchemy/alembic/versions/9c5c34dfd9f1_add_boards_in_fleet.py
new file mode 100644
index 0000000..afa4f81
--- /dev/null
+++ b/iotronic/db/sqlalchemy/alembic/versions/9c5c34dfd9f1_add_boards_in_fleet.py
@@ -0,0 +1,24 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13
14# revision identifiers, used by Alembic.
15revision = '9c5c34dfd9f1'
16down_revision = '44e74b9170d1'
17
18from alembic import op
19
20
21def upgrade():
22 # ### commands auto generated by Alembic - please adjust! ###
23 op.create_foreign_key(None, 'boards', 'fleets', ['fleet'], ['uuid'])
24 # ### end Alembic commands ###
diff --git a/iotronic/db/sqlalchemy/api.py b/iotronic/db/sqlalchemy/api.py
index a9a96ca..068a71f 100644
--- a/iotronic/db/sqlalchemy/api.py
+++ b/iotronic/db/sqlalchemy/api.py
@@ -131,6 +131,8 @@ class Connection(api.Connection):
131 query = query.filter(models.Board.project == filters['project_id']) 131 query = query.filter(models.Board.project == filters['project_id'])
132 if 'status' in filters: 132 if 'status' in filters:
133 query = query.filter(models.Board.status == filters['status']) 133 query = query.filter(models.Board.status == filters['status'])
134 if 'fleet' in filters:
135 query = query.filter(models.Board.fleet == filters['fleet'])
134 136
135 return query 137 return query
136 138
diff --git a/iotronic/db/sqlalchemy/models.py b/iotronic/db/sqlalchemy/models.py
index 351d411..d585a12 100644
--- a/iotronic/db/sqlalchemy/models.py
+++ b/iotronic/db/sqlalchemy/models.py
@@ -154,6 +154,7 @@ class Board(Base):
154 agent = Column(String(255), nullable=True) 154 agent = Column(String(255), nullable=True)
155 owner = Column(String(36)) 155 owner = Column(String(36))
156 project = Column(String(36)) 156 project = Column(String(36))
157 fleet = Column(String(36), ForeignKey('fleets.uuid'), nullable=True)
157 mobile = Column(Boolean, default=False) 158 mobile = Column(Boolean, default=False)
158 config = Column(JSONEncodedDict) 159 config = Column(JSONEncodedDict)
159 extra = Column(JSONEncodedDict) 160 extra = Column(JSONEncodedDict)
diff --git a/iotronic/objects/board.py b/iotronic/objects/board.py
index 5d41065..fe0e6d2 100644
--- a/iotronic/objects/board.py
+++ b/iotronic/objects/board.py
@@ -39,6 +39,7 @@ class Board(base.IotronicObject):
39 'agent': obj_utils.str_or_none, 39 'agent': obj_utils.str_or_none,
40 'owner': obj_utils.str_or_none, 40 'owner': obj_utils.str_or_none,
41 'project': obj_utils.str_or_none, 41 'project': obj_utils.str_or_none,
42 'fleet': obj_utils.str_or_none,
42 'mobile': bool, 43 'mobile': bool,
43 'config': obj_utils.dict_or_none, 44 'config': obj_utils.dict_or_none,
44 'extra': obj_utils.dict_or_none, 45 'extra': obj_utils.dict_or_none,