Fuel UI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
4.4KB

  1. # Copyright 2015 Mirantis, Inc.
  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. from nailgun import consts
  15. from nailgun.db import db
  16. from nailgun.db.sqlalchemy import models
  17. from nailgun import errors
  18. from nailgun.objects import NailgunCollection
  19. from nailgun.objects import NailgunObject
  20. from nailgun.objects.serializers.openstack_config \
  21. import OpenstackConfigSerializer
  22. class OpenstackConfig(NailgunObject):
  23. model = models.OpenstackConfig
  24. serializer = OpenstackConfigSerializer
  25. @classmethod
  26. def create(cls, data):
  27. data['config_type'] = cls._get_config_type(data)
  28. data['is_active'] = True
  29. filters = data.copy()
  30. filters.pop('configuration')
  31. config = OpenstackConfigCollection.filter_by(None, **filters).first()
  32. if config:
  33. cls.disable(config)
  34. return super(OpenstackConfig, cls).create(data)
  35. @classmethod
  36. def disable(cls, instance):
  37. """Disables configuration.
  38. It is required to track history of previous configurations.
  39. This why disable operation doesn't remove a record from the database,
  40. it sets `is_active` property to False.
  41. """
  42. if not instance.is_active:
  43. raise errors.CannotUpdate(
  44. "Configuration '{0}' has been already disabled.".format(
  45. instance.id))
  46. instance.is_active = False
  47. db().flush()
  48. @classmethod
  49. def _get_config_type(cls, data):
  50. if data.get('node_id'):
  51. return consts.OPENSTACK_CONFIG_TYPES.node
  52. if data.get('node_role'):
  53. return consts.OPENSTACK_CONFIG_TYPES.role
  54. return consts.OPENSTACK_CONFIG_TYPES.cluster
  55. @classmethod
  56. def disable_by_nodes(cls, nodes):
  57. """Disactivate all active configurations for specified nodes."""
  58. node_ids = [n.id for n in nodes]
  59. (db().query(cls.model)
  60. .filter_by(
  61. config_type=consts.OPENSTACK_CONFIG_TYPES.node,
  62. is_active=True)
  63. .filter(models.OpenstackConfig.node_id.in_(node_ids))
  64. .update({models.OpenstackConfig.is_active: False},
  65. synchronize_session=False))
  66. class OpenstackConfigCollection(NailgunCollection):
  67. single = OpenstackConfig
  68. @classmethod
  69. def create(cls, data):
  70. configs = []
  71. # If node_ids list is passed, separate OpenstackConfig object
  72. # should be created for each node. For global config (cluster scope or
  73. # specific role scope) single config record is created
  74. # with node_id=None.
  75. node_ids = data.pop('node_ids', [None])
  76. for node_id in node_ids:
  77. config_data = dict(data, node_id=node_id)
  78. configs.append(cls.single.create(config_data))
  79. return configs
  80. @classmethod
  81. def find_configs_for_nodes(cls, cluster, nodes):
  82. """Returns list of configurations that should be applied.
  83. Returns list of configurations for specified nodes that will be
  84. applied. List is sorted by the config_type and node_role fields.
  85. """
  86. configs_query = cls.filter_by(
  87. None, cluster_id=cluster.id, is_active=True)
  88. configs_query = configs_query.order_by(cls.single.model.created_at)
  89. node_ids = set(n.id for n in nodes)
  90. node_roles = set()
  91. for node in nodes:
  92. node_roles.update(node.roles)
  93. configs = []
  94. for config in configs_query:
  95. if config.config_type == consts.OPENSTACK_CONFIG_TYPES.cluster:
  96. configs.append(config)
  97. elif (config.config_type == consts.OPENSTACK_CONFIG_TYPES.node and
  98. config.node_id in node_ids):
  99. configs.append(config)
  100. elif (config.config_type ==
  101. consts.OPENSTACK_CONFIG_TYPES.role and
  102. config.node_role in node_roles):
  103. configs.append(config)
  104. return configs