def get_plugins_node_roles(cls, cluster): result = {} core_roles = set(cluster.release.roles_metadata) for plugin_db in ClusterPlugin.get_enabled(cluster.id): plugin_roles = wrap_plugin(plugin_db).normalized_roles_metadata # we should check all possible cases of roles intersection # with core ones and those from other plugins # and afterwards show them in error message; # thus role names for which following checks # fails are accumulated in err_info variable err_roles = set( r for r in plugin_roles if r in core_roles or r in result ) if err_roles: raise errors.AlreadyExists( "Plugin (ID={0}) is unable to register the following " "node roles: {1}".format(plugin_db.id, ", ".join(sorted(err_roles))) ) # update info on processed roles in case of # success of all intersection checks result.update(plugin_roles) return result
def get_plugins_node_roles(cls, cluster): result = {} core_roles = set(cluster.release.roles_metadata) for plugin_db in ClusterPlugin.get_enabled(cluster.id): plugin_roles = wrap_plugin(plugin_db).normalized_roles_metadata # we should check all possible cases of roles intersection # with core ones and those from other plugins # and afterwards show them in error message; # thus role names for which following checks # fails are accumulated in err_info variable err_roles = set(r for r in plugin_roles if r in core_roles or r in result) if err_roles: raise errors.AlreadyExists( "Plugin (ID={0}) is unable to register the following " "node roles: {1}".format(plugin_db.id, ", ".join(sorted(err_roles)))) # update info on processed roles in case of # success of all intersection checks result.update(plugin_roles) return result
def process_cluster_attributes(cls, cluster, attributes): """Generate Cluster-Plugins relation based on attributes. Iterates through plugins attributes, creates or deletes Cluster <-> Plugins relation if plugin is enabled or disabled. :param cluster: A cluster instance :type cluster: nailgun.db.sqlalchemy.models.cluster.Cluster :param attributes: Cluster attributes :type attributes: dict """ from nailgun.objects import Release plugins = {} # Detach plugins data for k in list(attributes): if cls.is_plugin_data(attributes[k]): plugins[k] = attributes.pop(k)['metadata'] propagate_task_deploy = get_in( attributes, 'common', 'propagate_task_deploy', 'value') if propagate_task_deploy is not None: legacy_tasks_are_ignored = not propagate_task_deploy else: legacy_tasks_are_ignored = not get_in( cluster.attributes.editable, 'common', 'propagate_task_deploy', 'value') for container in six.itervalues(plugins): default = container.get('default', False) for attrs in container.get('versions', []): version_metadata = attrs.pop('metadata') plugin_id = version_metadata['plugin_id'] plugin = Plugin.get_by_uid(plugin_id) if not plugin: logger.warning( 'Plugin with id "%s" is not found, skip it', plugin_id) continue enabled = container['enabled'] \ and plugin_id == container['chosen_id'] if (enabled and Release.is_lcm_supported(cluster.release) and legacy_tasks_are_ignored and cls.contains_legacy_tasks( wrap_plugin(Plugin.get_by_uid(plugin.id)))): raise errors.InvalidData( 'Cannot enable plugin with legacy tasks unless ' 'propagate_task_deploy attribute is set. ' 'Ensure tasks.yaml is empty and all tasks ' 'has version >= 2.0.0.') ClusterPlugin.set_attributes( cluster.id, plugin.id, enabled=enabled, attrs=attrs if enabled or default else None )
def process_cluster_attributes(cls, cluster, attributes): """Generate Cluster-Plugins relation based on attributes. Iterates through plugins attributes, creates or deletes Cluster <-> Plugins relation if plugin is enabled or disabled. :param cluster: A cluster instance :type cluster: nailgun.db.sqlalchemy.models.cluster.Cluster :param attributes: Cluster attributes :type attributes: dict """ from nailgun.objects import Release plugins = {} # Detach plugins data for k in list(attributes): if cls.is_plugin_data(attributes[k]): plugins[k] = attributes.pop(k)['metadata'] propagate_task_deploy = get_in(attributes, 'common', 'propagate_task_deploy', 'value') if propagate_task_deploy is not None: legacy_tasks_are_ignored = not propagate_task_deploy else: legacy_tasks_are_ignored = not get_in( cluster.attributes.editable, 'common', 'propagate_task_deploy', 'value') for container in six.itervalues(plugins): default = container.get('default', False) for attrs in container.get('versions', []): version_metadata = attrs.pop('metadata') plugin_id = version_metadata['plugin_id'] plugin = Plugin.get_by_uid(plugin_id) if not plugin: logger.warning('Plugin with id "%s" is not found, skip it', plugin_id) continue enabled = container['enabled'] \ and plugin_id == container['chosen_id'] if (enabled and Release.is_lcm_supported(cluster.release) and legacy_tasks_are_ignored and cls.contains_legacy_tasks( wrap_plugin(Plugin.get_by_uid(plugin.id)))): raise errors.InvalidData( 'Cannot enable plugin with legacy tasks unless ' 'propagate_task_deploy attribute is set. ' 'Ensure tasks.yaml is empty and all tasks ' 'has version >= 2.0.0.') ClusterPlugin.set_attributes( cluster.id, plugin.id, enabled=enabled, attrs=attrs if enabled or default else None)
def get_plugins_attributes(cls, cluster, all_versions=False, default=False): """Gets attributes of all plugins connected with given cluster. :param cluster: A cluster instance :type cluster: nailgun.db.sqlalchemy.models.cluster.Cluster :param all_versions: True to get attributes of all versions of plugins :type all_versions: bool :param default: True to return a default plugins attributes (for UI) :type default: bool :return: Plugins attributes :rtype: dict """ plugins_attributes = {} for plugin in ClusterPlugin.get_connected_plugins_data(cluster.id): db_plugin = Plugin.get_by_uid(plugin.id) plugin_adapter = wrap_plugin(db_plugin) default_attrs = plugin_adapter.attributes_metadata if all_versions: container = plugins_attributes.setdefault(plugin.name, {}) enabled = plugin.enabled and not (all_versions and default) cls.create_common_metadata(plugin, container, enabled) container['metadata']['default'] = default versions = container['metadata'].setdefault('versions', []) if default: actual_attrs = copy.deepcopy(default_attrs) actual_attrs.setdefault('metadata', {}) else: actual_attrs = copy.deepcopy(plugin.attributes) actual_attrs['metadata'] = default_attrs.get( 'metadata', {}) actual_attrs['metadata']['contains_legacy_tasks'] = \ cls.contains_legacy_tasks(plugin_adapter) cls.fill_plugin_metadata(plugin, actual_attrs['metadata']) versions.append(actual_attrs) container['metadata'].setdefault('chosen_id', plugin.id) if enabled: container['metadata']['chosen_id'] = plugin.id elif plugin.enabled: container = plugins_attributes.setdefault(plugin.name, {}) cls.create_common_metadata(plugin, container) container['metadata'].update(default_attrs.get('metadata', {})) cls.fill_plugin_metadata(plugin, container['metadata']) container.update(plugin.attributes) return plugins_attributes
def _plugin_update(cls, plugin): """Update plugin metadata. :param plugin: A plugin instance :type plugin: plugin model """ try: plugin_adapter = wrap_plugin(plugin) metadata = plugin_adapter.get_metadata() Plugin.update(plugin, metadata) except Exception as e: logger.error("cannot update plugin {0} in DB. Reason: {1}".format( plugin.name, str(e)))
def get_plugins_attributes( cls, cluster, all_versions=False, default=False): """Gets attributes of all plugins connected with given cluster. :param cluster: A cluster instance :type cluster: nailgun.db.sqlalchemy.models.cluster.Cluster :param all_versions: True to get attributes of all versions of plugins :type all_versions: bool :param default: True to return a default plugins attributes (for UI) :type default: bool :return: Plugins attributes :rtype: dict """ plugins_attributes = {} for plugin in ClusterPlugin.get_connected_plugins_data(cluster.id): db_plugin = Plugin.get_by_uid(plugin.id) plugin_adapter = wrap_plugin(db_plugin) default_attrs = plugin_adapter.attributes_metadata if all_versions: container = plugins_attributes.setdefault(plugin.name, {}) enabled = plugin.enabled and not (all_versions and default) cls.create_common_metadata(plugin, container, enabled) container['metadata']['default'] = default versions = container['metadata'].setdefault('versions', []) if default: actual_attrs = copy.deepcopy(default_attrs) actual_attrs.setdefault('metadata', {}) else: actual_attrs = copy.deepcopy(plugin.attributes) actual_attrs['metadata'] = default_attrs.get('metadata', {}) actual_attrs['metadata']['contains_legacy_tasks'] = \ cls.contains_legacy_tasks(plugin_adapter) cls.fill_plugin_metadata(plugin, actual_attrs['metadata']) versions.append(actual_attrs) container['metadata'].setdefault('chosen_id', plugin.id) if enabled: container['metadata']['chosen_id'] = plugin.id elif plugin.enabled: container = plugins_attributes.setdefault(plugin.name, {}) cls.create_common_metadata(plugin, container) container['metadata'].update(default_attrs.get('metadata', {})) cls.fill_plugin_metadata(plugin, container['metadata']) container.update(plugin.attributes) return plugins_attributes
def _plugin_update(cls, plugin): """Update plugin metadata. :param plugin: A plugin instance :type plugin: plugin model """ try: plugin_adapter = wrap_plugin(plugin) metadata = plugin_adapter.get_metadata() Plugin.update(plugin, metadata) except errors.InvalidData: raise except Exception as e: logger.error("cannot update plugin {0} in DB. Reason: {1}" .format(plugin.name, str(e)))
def sync_plugins_metadata(cls, plugin_ids=None): """Sync metadata for plugins by given IDs. If there are no IDs, all newest plugins will be synced. :param plugin_ids: list of plugin IDs :type plugin_ids: list """ if plugin_ids: plugins = PluginCollection.get_by_uids(plugin_ids) else: plugins = PluginCollection.all() for plugin in plugins: plugin_adapter = wrap_plugin(plugin) metadata = plugin_adapter.get_metadata() Plugin.update(plugin, metadata)
def enable_plugins_by_components(cls, cluster): """Enable plugin by components. :param cluster: A cluster instance :type cluster: Cluster model """ cluster_components = set(cluster.components) plugin_ids = [p.id for p in PluginCollection.all_newest()] for plugin in ClusterPlugin.get_connected_plugins(cluster, plugin_ids): plugin_adapter = wrap_plugin(plugin) plugin_components = set( component['name'] for component in plugin_adapter.components_metadata) if cluster_components & plugin_components: ClusterPlugin.set_attributes(cluster.id, plugin.id, enabled=True)
def enable_plugins_by_components(cls, cluster): """Enable plugin by components. :param cluster: A cluster instance :type cluster: Cluster model """ cluster_components = set(cluster.components) plugin_ids = [p.id for p in PluginCollection.all_newest()] for plugin in ClusterPlugin.get_connected_plugins( cluster, plugin_ids): plugin_adapter = wrap_plugin(plugin) plugin_components = set( component['name'] for component in plugin_adapter.components_metadata) if cluster_components & plugin_components: ClusterPlugin.set_attributes( cluster.id, plugin.id, enabled=True)
def _install_or_update_or_delete_plugins(cls): """Sync plugins using FS and DB. If plugin: in DB and present on filesystem, it will be updated; in DB and not present on filesystem, it will be removed; not in DB, but present on filesystem, it will be installed """ installed_plugins = {} for plugin in PluginCollection.all(): plugin_adapter = wrap_plugin(plugin) installed_plugins[plugin_adapter.path_name] = plugin for plugin_dir in cls._list_plugins_on_fs(): if plugin_dir in installed_plugins: cls._plugin_update(installed_plugins.pop(plugin_dir)) else: cls._plugin_create(plugin_dir) for deleted_plugin in installed_plugins.values(): cls._plugin_delete(deleted_plugin)
def get_enabled_plugins(cls, cluster): return [ wrap_plugin(plugin) for plugin in ClusterPlugin.get_enabled(cluster.id) ]
def get_enabled_plugins(cls, cluster): return [wrap_plugin(plugin) for plugin in ClusterPlugin.get_enabled(cluster.id)]