Browse Source

Add volume_connectors table to save connector information

This patch introduces a new "volume_connectors" table in order to save
the volume connector information of physical nodes. With this patch,
Ironic can put/get volume connector information to/from the database.

Co-Authored-By: Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com>
Co-Authored-By: Stephane Miller <stephane@alum.mit.edu>
Co-Authored-By: Julia Kreger <juliaashleykreger@gmail.com>
Change-Id: I8237ab671a04ac9b01c8bdb2936cf0a661b9b1de
Partial-Bug: 1526231
tags/7.0.0
Satoru Moriya 3 years ago
parent
commit
a82a0ceba1

+ 13
- 0
ironic/common/exception.py View File

@@ -157,6 +157,15 @@ class DuplicateName(Conflict):
157 157
     _msg_fmt = _("A node with name %(name)s already exists.")
158 158
 
159 159
 
160
+class VolumeConnectorAlreadyExists(Conflict):
161
+    _msg_fmt = _("A volume connector with UUID %(uuid)s already exists.")
162
+
163
+
164
+class VolumeConnectorTypeAndIdAlreadyExists(Conflict):
165
+    _msg_fmt = _("A volume connector with type %(type)s and connector ID "
166
+                 "%(connector_id)s already exists.")
167
+
168
+
160 169
 class InvalidUUID(Invalid):
161 170
     _msg_fmt = _("Expected a UUID but received %(uuid)s.")
162 171
 
@@ -302,6 +311,10 @@ class ChassisNotFound(NotFound):
302 311
     _msg_fmt = _("Chassis %(chassis)s could not be found.")
303 312
 
304 313
 
314
+class VolumeConnectorNotFound(NotFound):
315
+    _msg_fmt = _("Volume connector %(connector)s could not be found.")
316
+
317
+
305 318
 class NoDriversLoaded(IronicException):
306 319
     _msg_fmt = _("Conductor %(conductor)s cannot be started "
307 320
                  "because no drivers were loaded.")

+ 98
- 0
ironic/db/api.py View File

@@ -614,3 +614,101 @@ class Connection(object):
614 614
         :returns: Node object.
615 615
         :raises: NodeNotFound if none or several nodes are found.
616 616
         """
617
+
618
+    @abc.abstractmethod
619
+    def get_volume_connector_list(self, limit=None, marker=None,
620
+                                  sort_key=None, sort_dir=None):
621
+        """Return a list of volume connectors.
622
+
623
+        :param limit: Maximum number of volume connectors to return.
624
+        :param marker: The last item of the previous page; we return the next
625
+                       result set.
626
+        :param sort_key: Attribute by which results should be sorted.
627
+        :param sort_dir: Direction in which results should be sorted.
628
+                         (asc, desc)
629
+        :returns: A list of volume connectors.
630
+        :raises: InvalidParameterValue If sort_key does not exist.
631
+        """
632
+
633
+    @abc.abstractmethod
634
+    def get_volume_connector_by_id(self, id):
635
+        """Return a volume connector representation.
636
+
637
+        :param id: The ID of a volume connector.
638
+        :returns: A volume connector with the specified ID.
639
+        :raises: VolumeConnectorNotFound If a volume connector
640
+                 with the specified ID is not found.
641
+        """
642
+
643
+    @abc.abstractmethod
644
+    def get_volume_connector_by_uuid(self, connector_uuid):
645
+        """Return a volume connector representation.
646
+
647
+        :param connector_uuid: The UUID of a connector.
648
+        :returns: A volume connector with the specified UUID.
649
+        :raises: VolumeConnectorNotFound If a volume connector
650
+                 with the specified UUID is not found.
651
+        """
652
+
653
+    @abc.abstractmethod
654
+    def get_volume_connectors_by_node_id(self, node_id, limit=None,
655
+                                         marker=None, sort_key=None,
656
+                                         sort_dir=None):
657
+        """List all the volume connectors for a given node.
658
+
659
+        :param node_id: The integer node ID.
660
+        :param limit: Maximum number of volume connectors to return.
661
+        :param marker: The last item of the previous page; we return the next
662
+                       result set.
663
+        :param sort_key: Attribute by which results should be sorted
664
+        :param sort_dir: Direction in which results should be sorted
665
+                         (asc, desc)
666
+        :returns: A list of volume connectors.
667
+        :raises: InvalidParameterValue If sort_key does not exist.
668
+        """
669
+
670
+    @abc.abstractmethod
671
+    def create_volume_connector(self, connector_info):
672
+        """Create a new volume connector.
673
+
674
+        :param connector_info: Dictionary containing information about the
675
+                               connector. Example::
676
+
677
+                                   {
678
+                                       'uuid': '000000-..',
679
+                                       'type': 'wwnn',
680
+                                       'connector_id': '00:01:02:03:04:05:06',
681
+                                       'node_id': 2
682
+                                   }
683
+
684
+        :returns: A volume connector.
685
+        :raises: VolumeConnectorTypeAndIdAlreadyExists If a connector
686
+                 already exists with a matching type and connector_id.
687
+        :raises: VolumeConnectorAlreadyExists If a volume connector with
688
+                 the same UUID already exists.
689
+        """
690
+    @abc.abstractmethod
691
+    def update_volume_connector(self, ident, connector_info):
692
+        """Update properties of a volume connector.
693
+
694
+        :param ident: The UUID or integer ID of a volume connector.
695
+        :param connector_info: Dictionary containing the information about
696
+                               connector to update.
697
+        :returns: A volume connector.
698
+        :raises: VolumeConnectorTypeAndIdAlreadyExists If another
699
+                 connector already exists with a matching type and
700
+                 connector_id field.
701
+        :raises: VolumeConnectorNotFound If a volume connector
702
+                 with the specified ident does not exist.
703
+        :raises: InvalidParameterValue When a UUID is included in
704
+                 connector_info.
705
+        """
706
+
707
+    @abc.abstractmethod
708
+    def destroy_volume_connector(self, ident):
709
+        """Destroy a volume connector.
710
+
711
+        :param ident: The UUID or integer ID of a volume connector.
712
+        :raises: VolumeConnectorNotFound If a volume connector
713
+                 with the specified ident does not exist.
714
+        """

+ 48
- 0
ironic/db/sqlalchemy/alembic/versions/daa1ba02d98_add_volume_connectors_table.py View File

@@ -0,0 +1,48 @@
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
+"""Add volume_connectors table
14
+
15
+Revision ID: daa1ba02d98
16
+Revises: c14cef6dfedf
17
+Create Date: 2015-11-26 17:19:22.074989
18
+
19
+"""
20
+
21
+# revision identifiers, used by Alembic.
22
+revision = 'daa1ba02d98'
23
+down_revision = 'bcdd431ba0bf'
24
+
25
+from alembic import op
26
+import sqlalchemy as sa
27
+
28
+
29
+def upgrade():
30
+    op.create_table('volume_connectors',
31
+                    sa.Column('created_at', sa.DateTime(), nullable=True),
32
+                    sa.Column('updated_at', sa.DateTime(), nullable=True),
33
+                    sa.Column('id', sa.Integer(), nullable=False),
34
+                    sa.Column('uuid', sa.String(length=36), nullable=True),
35
+                    sa.Column('node_id', sa.Integer(), nullable=True),
36
+                    sa.Column('type', sa.String(length=32), nullable=True),
37
+                    sa.Column('connector_id', sa.String(length=255),
38
+                              nullable=True),
39
+                    sa.Column('extra', sa.Text(), nullable=True),
40
+                    sa.ForeignKeyConstraint(['node_id'], ['nodes.id'], ),
41
+                    sa.PrimaryKeyConstraint('id'),
42
+                    sa.UniqueConstraint('type', 'connector_id',
43
+                                        name='uniq_volumeconnectors0type0'
44
+                                             'connector_id'),
45
+                    sa.UniqueConstraint('uuid',
46
+                                        name='uniq_volumeconnectors0uuid'),
47
+                    mysql_charset='utf8',
48
+                    mysql_engine='InnoDB')

+ 81
- 0
ironic/db/sqlalchemy/api.py View File

@@ -382,6 +382,10 @@ class Connection(api.Connection):
382 382
             tag_query = model_query(models.NodeTag).filter_by(node_id=node_id)
383 383
             tag_query.delete()
384 384
 
385
+            volume_connector_query = model_query(
386
+                models.VolumeConnector).filter_by(node_id=node_id)
387
+            volume_connector_query.delete()
388
+
385 389
             query.delete()
386 390
 
387 391
     def update_node(self, node_id, values):
@@ -871,3 +875,80 @@ class Connection(api.Connection):
871 875
             raise exception.NodeNotFound(
872 876
                 _('Multiple nodes with port addresses %s were found')
873 877
                 % addresses)
878
+
879
+    def get_volume_connector_list(self, limit=None, marker=None,
880
+                                  sort_key=None, sort_dir=None):
881
+        return _paginate_query(models.VolumeConnector, limit, marker,
882
+                               sort_key, sort_dir)
883
+
884
+    def get_volume_connector_by_id(self, id):
885
+        query = model_query(models.VolumeConnector).filter_by(id=id)
886
+        try:
887
+            return query.one()
888
+        except NoResultFound:
889
+            raise exception.VolumeConnectorNotFound(connector=id)
890
+
891
+    def get_volume_connector_by_uuid(self, connector_uuid):
892
+        query = model_query(models.VolumeConnector).filter_by(
893
+            uuid=connector_uuid)
894
+        try:
895
+            return query.one()
896
+        except NoResultFound:
897
+            raise exception.VolumeConnectorNotFound(connector=connector_uuid)
898
+
899
+    def get_volume_connectors_by_node_id(self, node_id, limit=None,
900
+                                         marker=None, sort_key=None,
901
+                                         sort_dir=None):
902
+        query = model_query(models.VolumeConnector).filter_by(node_id=node_id)
903
+        return _paginate_query(models.VolumeConnector, limit, marker,
904
+                               sort_key, sort_dir, query)
905
+
906
+    def create_volume_connector(self, connector_info):
907
+        if 'uuid' not in connector_info:
908
+            connector_info['uuid'] = uuidutils.generate_uuid()
909
+
910
+        connector = models.VolumeConnector()
911
+        connector.update(connector_info)
912
+        with _session_for_write() as session:
913
+            try:
914
+                session.add(connector)
915
+                session.flush()
916
+            except db_exc.DBDuplicateEntry as exc:
917
+                if 'type' in exc.columns:
918
+                    raise exception.VolumeConnectorTypeAndIdAlreadyExists(
919
+                        type=connector_info['type'],
920
+                        connector_id=connector_info['connector_id'])
921
+                raise exception.VolumeConnectorAlreadyExists(
922
+                    uuid=connector_info['uuid'])
923
+            return connector
924
+
925
+    def update_volume_connector(self, ident, connector_info):
926
+        if 'uuid' in connector_info:
927
+            msg = _("Cannot overwrite UUID for an existing Volume Connector.")
928
+            raise exception.InvalidParameterValue(err=msg)
929
+
930
+        try:
931
+            with _session_for_write() as session:
932
+                query = model_query(models.VolumeConnector)
933
+                query = add_identity_filter(query, ident)
934
+                ref = query.one()
935
+                orig_type = ref['type']
936
+                orig_connector_id = ref['connector_id']
937
+                ref.update(connector_info)
938
+                session.flush()
939
+        except db_exc.DBDuplicateEntry:
940
+            raise exception.VolumeConnectorTypeAndIdAlreadyExists(
941
+                type=connector_info.get('type', orig_type),
942
+                connector_id=connector_info.get('connector_id',
943
+                                                orig_connector_id))
944
+        except NoResultFound:
945
+            raise exception.VolumeConnectorNotFound(connector=ident)
946
+        return ref
947
+
948
+    def destroy_volume_connector(self, ident):
949
+        with _session_for_write():
950
+            query = model_query(models.VolumeConnector)
951
+            query = add_identity_filter(query, ident)
952
+            count = query.delete()
953
+            if count == 0:
954
+                raise exception.VolumeConnectorNotFound(connector=ident)

+ 19
- 0
ironic/db/sqlalchemy/models.py View File

@@ -210,3 +210,22 @@ class NodeTag(Base):
210 210
         primaryjoin='and_(NodeTag.node_id == Node.id)',
211 211
         foreign_keys=node_id
212 212
     )
213
+
214
+
215
+class VolumeConnector(Base):
216
+    """Represents a volume connector of a bare metal node."""
217
+
218
+    __tablename__ = 'volume_connectors'
219
+    __table_args__ = (
220
+        schema.UniqueConstraint('uuid', name='uniq_volumeconnectors0uuid'),
221
+        schema.UniqueConstraint(
222
+            'type',
223
+            'connector_id',
224
+            name='uniq_volumeconnectors0type0connector_id'),
225
+        table_args())
226
+    id = Column(Integer, primary_key=True)
227
+    uuid = Column(String(36))
228
+    node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True)
229
+    type = Column(String(32))
230
+    connector_id = Column(String(255))
231
+    extra = Column(db_types.JsonEncodedDict)

+ 37
- 0
ironic/tests/unit/db/sqlalchemy/test_migrations.py View File

@@ -547,6 +547,43 @@ class MigrationCheckersMixin(object):
547 547
             self.assertIsInstance(getattr(nodes.c, name).type,
548 548
                                   sqlalchemy.types.String)
549 549
 
550
+    def _check_daa1ba02d98(self, engine, data):
551
+        connectors = db_utils.get_table(engine, 'volume_connectors')
552
+        col_names = [column.name for column in connectors.c]
553
+        expected_names = ['created_at', 'updated_at', 'id', 'uuid', 'node_id',
554
+                          'type', 'connector_id', 'extra']
555
+        self.assertEqual(sorted(expected_names), sorted(col_names))
556
+
557
+        self.assertIsInstance(connectors.c.created_at.type,
558
+                              sqlalchemy.types.DateTime)
559
+        self.assertIsInstance(connectors.c.updated_at.type,
560
+                              sqlalchemy.types.DateTime)
561
+        self.assertIsInstance(connectors.c.id.type,
562
+                              sqlalchemy.types.Integer)
563
+        self.assertIsInstance(connectors.c.uuid.type,
564
+                              sqlalchemy.types.String)
565
+        self.assertIsInstance(connectors.c.node_id.type,
566
+                              sqlalchemy.types.Integer)
567
+        self.assertIsInstance(connectors.c.type.type,
568
+                              sqlalchemy.types.String)
569
+        self.assertIsInstance(connectors.c.connector_id.type,
570
+                              sqlalchemy.types.String)
571
+        self.assertIsInstance(connectors.c.extra.type,
572
+                              sqlalchemy.types.TEXT)
573
+
574
+        typestring = 'a' * 32
575
+        connector_idstring = 'a' * 255
576
+        uuid = uuidutils.generate_uuid()
577
+        data = {'uuid': uuid, 'node_id': 1, 'type': typestring,
578
+                'connector_id': connector_idstring, 'extra': '{}'}
579
+        connectors.insert().execute(data)
580
+        connector = connectors.select(
581
+            connectors.c.uuid == uuid).execute().first()
582
+        self.assertEqual(typestring, connector['type'])
583
+        self.assertEqual(connector_idstring, connector['connector_id'])
584
+        self.assertEqual(1, connector['node_id'])
585
+        self.assertEqual('{}', connector['extra'])
586
+
550 587
     def test_upgrade_and_version(self):
551 588
         with patch_with_engine(self.engine):
552 589
             self.migration_api.upgrade('head')

+ 20
- 0
ironic/tests/unit/db/test_nodes.py View File

@@ -359,6 +359,26 @@ class DbNodeTestCase(base.DbTestCase):
359 359
         self.dbapi.destroy_node(node.uuid)
360 360
         self.assertFalse(self.dbapi.node_tag_exists(node.id, tag.tag))
361 361
 
362
+    def test_volume_connector_get_destroyed_after_destroying_a_node(self):
363
+        node = utils.create_test_node()
364
+
365
+        connector = utils.create_test_volume_connector(node_id=node.id)
366
+
367
+        self.dbapi.destroy_node(node.id)
368
+
369
+        self.assertRaises(exception.VolumeConnectorNotFound,
370
+                          self.dbapi.get_volume_connector_by_id, connector.id)
371
+
372
+    def test_volume_connector_get_destroyed_after_destroying_a_node_uuid(self):
373
+        node = utils.create_test_node()
374
+
375
+        connector = utils.create_test_volume_connector(node_id=node.id)
376
+
377
+        self.dbapi.destroy_node(node.uuid)
378
+
379
+        self.assertRaises(exception.VolumeConnectorNotFound,
380
+                          self.dbapi.get_volume_connector_by_id, connector.id)
381
+
362 382
     def test_update_node(self):
363 383
         node = utils.create_test_node()
364 384
 

+ 151
- 0
ironic/tests/unit/db/test_volume_connectors.py View File

@@ -0,0 +1,151 @@
1
+# Copyright 2015 Hitachi Data Systems
2
+#
3
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+#    not use this file except in compliance with the License. You may obtain
5
+#    a copy of the License at
6
+#
7
+#         http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+#    Unless required by applicable law or agreed to in writing, software
10
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+#    License for the specific language governing permissions and limitations
13
+#    under the License.
14
+
15
+"""Tests for manipulating VolumeConnectors via the DB API"""
16
+
17
+from oslo_utils import uuidutils
18
+import six
19
+
20
+from ironic.common import exception
21
+from ironic.tests.unit.db import base
22
+from ironic.tests.unit.db import utils as db_utils
23
+
24
+
25
+class DbVolumeConnectorTestCase(base.DbTestCase):
26
+
27
+    def setUp(self):
28
+        # This method creates a volume_connector for every test and
29
+        # replaces a test for creating a volume_connector.
30
+        super(DbVolumeConnectorTestCase, self).setUp()
31
+        self.node = db_utils.create_test_node()
32
+        self.connector = db_utils.create_test_volume_connector(
33
+            node_id=self.node.id, type='test',
34
+            connector_id='test-connector_id')
35
+
36
+    def test_create_volume_connector_duplicated_type_connector_id(self):
37
+        self.assertRaises(exception.VolumeConnectorTypeAndIdAlreadyExists,
38
+                          db_utils.create_test_volume_connector,
39
+                          uuid=uuidutils.generate_uuid(),
40
+                          node_id=self.node.id,
41
+                          type=self.connector.type,
42
+                          connector_id=self.connector.connector_id)
43
+
44
+    def test_create_volume_connector_duplicated_uuid(self):
45
+        self.assertRaises(exception.VolumeConnectorAlreadyExists,
46
+                          db_utils.create_test_volume_connector,
47
+                          uuid=self.connector.uuid,
48
+                          node_id=self.node.id,
49
+                          type='test',
50
+                          connector_id='test-connector_id-2')
51
+
52
+    def test_get_volume_connector_by_id(self):
53
+        res = self.dbapi.get_volume_connector_by_id(self.connector.id)
54
+        self.assertEqual(self.connector.type, res.type)
55
+        self.assertEqual(self.connector.connector_id, res.connector_id)
56
+        self.assertRaises(exception.VolumeConnectorNotFound,
57
+                          self.dbapi.get_volume_connector_by_id,
58
+                          -1)
59
+
60
+    def test_get_volume_connector_by_uuid(self):
61
+        res = self.dbapi.get_volume_connector_by_uuid(self.connector.uuid)
62
+        self.assertEqual(self.connector.id, res.id)
63
+        self.assertRaises(exception.VolumeConnectorNotFound,
64
+                          self.dbapi.get_volume_connector_by_uuid,
65
+                          -1)
66
+
67
+    def _connector_list_preparation(self):
68
+        uuids = [six.text_type(self.connector.uuid)]
69
+        for i in range(1, 6):
70
+            volume_connector = db_utils.create_test_volume_connector(
71
+                uuid=uuidutils.generate_uuid(),
72
+                type='iqn',
73
+                connector_id='iqn.test-%s' % i)
74
+            uuids.append(six.text_type(volume_connector.uuid))
75
+        return uuids
76
+
77
+    def test_get_volume_connector_list(self):
78
+        uuids = self._connector_list_preparation()
79
+        res = self.dbapi.get_volume_connector_list()
80
+        res_uuids = [r.uuid for r in res]
81
+        six.assertCountEqual(self, uuids, res_uuids)
82
+
83
+    def test_get_volume_connector_list_sorted(self):
84
+        uuids = self._connector_list_preparation()
85
+        res = self.dbapi.get_volume_connector_list(sort_key='uuid')
86
+        res_uuids = [r.uuid for r in res]
87
+        self.assertEqual(sorted(uuids), res_uuids)
88
+
89
+        self.assertRaises(exception.InvalidParameterValue,
90
+                          self.dbapi.get_volume_connector_list, sort_key='foo')
91
+
92
+    def test_get_volume_connectors_by_node_id(self):
93
+        res = self.dbapi.get_volume_connectors_by_node_id(self.node.id)
94
+        self.assertEqual(self.connector.type, res[0].type)
95
+        self.assertEqual(self.connector.connector_id, res[0].connector_id)
96
+
97
+    def test_get_volume_connectors_by_node_id_that_does_not_exist(self):
98
+        self.assertEqual([], self.dbapi.get_volume_connectors_by_node_id(99))
99
+
100
+    def test_update_volume_connector(self):
101
+        old_connector_id = self.connector.connector_id
102
+        new_connector_id = 'test-connector_id-2'
103
+
104
+        self.assertNotEqual(old_connector_id, new_connector_id)
105
+
106
+        res = self.dbapi.update_volume_connector(
107
+            self.connector.id,
108
+            {'connector_id': new_connector_id})
109
+        self.assertEqual(new_connector_id, res.connector_id)
110
+        res = self.dbapi.update_volume_connector(
111
+            self.connector.uuid,
112
+            {'connector_id': old_connector_id})
113
+        self.assertEqual(old_connector_id, res.connector_id)
114
+
115
+    def test_update_volume_connector_uuid(self):
116
+        self.assertRaises(exception.InvalidParameterValue,
117
+                          self.dbapi.update_volume_connector,
118
+                          self.connector.id,
119
+                          {'uuid': ''})
120
+
121
+    def test_update_volume_connector_fails_invalid_id(self):
122
+        self.assertRaises(exception.VolumeConnectorNotFound,
123
+                          self.dbapi.update_volume_connector,
124
+                          -1,
125
+                          {'node_id': ''})
126
+
127
+    def test_update_volume_connector_duplicated_type_connector_id(self):
128
+        type = self.connector.type
129
+        connector_id1 = self.connector.connector_id
130
+        connector_id2 = 'test-connector_id-2'
131
+        volume_connector2 = db_utils.create_test_volume_connector(
132
+            uuid=uuidutils.generate_uuid(),
133
+            node_id=self.node.id,
134
+            type=type,
135
+            connector_id=connector_id2)
136
+        self.assertRaises(exception.VolumeConnectorTypeAndIdAlreadyExists,
137
+                          self.dbapi.update_volume_connector,
138
+                          volume_connector2.id,
139
+                          {'connector_id': connector_id1})
140
+
141
+    def test_destroy_volume_connector(self):
142
+        self.dbapi.destroy_volume_connector(self.connector.id)
143
+        # Attempt to retrieve the volume to verify it is gone.
144
+        self.assertRaises(exception.VolumeConnectorNotFound,
145
+                          self.dbapi.get_volume_connector_by_id,
146
+                          self.connector.id)
147
+        # Ensure that the destroy_volume_connector returns the
148
+        # expected exception.
149
+        self.assertRaises(exception.VolumeConnectorNotFound,
150
+                          self.dbapi.destroy_volume_connector,
151
+                          self.connector.id)

+ 31
- 0
ironic/tests/unit/db/utils.py View File

@@ -315,6 +315,37 @@ def create_test_port(**kw):
315 315
     return dbapi.create_port(port)
316 316
 
317 317
 
318
+def get_test_volume_connector(**kw):
319
+    return {
320
+        'id': kw.get('id', 789),
321
+        'uuid': kw.get('uuid', '1be26c0b-03f2-4d2e-ae87-c02d7f33c781'),
322
+        'node_id': kw.get('node_id', 123),
323
+        'type': kw.get('type', 'iqn'),
324
+        'connector_id': kw.get('connector_id',
325
+                               'iqn.2012-06.com.example:initiator'),
326
+        'extra': kw.get('extra', {}),
327
+        'created_at': kw.get('created_at'),
328
+        'updated_at': kw.get('updated_at'),
329
+    }
330
+
331
+
332
+def create_test_volume_connector(**kw):
333
+    """Create test connector entry in DB and return VolumeConnector DB object.
334
+
335
+    Function to be used to create test VolumeConnector objects in the database.
336
+
337
+    :param kw: kwargs with overriding values for connector's attributes.
338
+    :returns: Test VolumeConnector DB object.
339
+
340
+    """
341
+    connector = get_test_volume_connector(**kw)
342
+    # Let DB generate ID if it isn't specified explicitly
343
+    if 'id' not in kw:
344
+        del connector['id']
345
+    dbapi = db_api.get_instance()
346
+    return dbapi.create_volume_connector(connector)
347
+
348
+
318 349
 def get_test_chassis(**kw):
319 350
     return {
320 351
         'id': kw.get('id', 42),

Loading…
Cancel
Save