-
Notifications
You must be signed in to change notification settings - Fork 900
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make MiqProductFeature seeding pluggable #18806
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ class MiqProductFeature < ApplicationRecord | |
ALL_TASKS_FEATURE = "miq_task_all_ui".freeze | ||
TENANT_ADMIN_FEATURE = "rbac_tenant".freeze | ||
|
||
include_concern "Seeding" | ||
|
||
acts_as_tree | ||
|
||
has_and_belongs_to_many :miq_user_roles, :join_table => :miq_roles_features | ||
|
@@ -18,8 +20,6 @@ class MiqProductFeature < ApplicationRecord | |
validates_presence_of :identifier | ||
validates_uniqueness_of :identifier | ||
|
||
FIXTURE_PATH = Rails.root.join(*["db", "fixtures", table_name]) | ||
|
||
DETAIL_ATTRS = [ | ||
:name, | ||
:description, | ||
|
@@ -62,10 +62,6 @@ def self.current_tenant_identifier(identifier) | |
tenant_identifier(identifier, User.current_tenant.id) if identifier && feature_details(identifier) && root_tenant_identifier?(identifier) | ||
end | ||
|
||
def self.feature_yaml(path = FIXTURE_PATH) | ||
"#{path}.yml".freeze | ||
end | ||
|
||
def self.feature_root | ||
features.keys.detect { |k| feature_parent(k).nil? } | ||
end | ||
|
@@ -148,29 +144,51 @@ def self.with_tenant_feature_root_features | |
where(:identifier => TENANT_FEATURE_ROOT_IDENTIFIERS) | ||
end | ||
|
||
def self.seed_tenant_miq_product_features | ||
result = with_tenant_feature_root_features.map.each do |tenant_miq_product_feature| | ||
Tenant.in_my_region.all.map { |tenant| tenant.build_miq_product_feature(tenant_miq_product_feature) } | ||
end.flatten | ||
def self.seed_single_tenant_miq_product_features(tenant) | ||
result = MiqProductFeature.with_tenant_feature_root_features.map do |miq_product_feature| | ||
{ | ||
:name => miq_product_feature.name, | ||
:description => miq_product_feature.description, | ||
:feature_type => 'admin', | ||
:hidden => false, | ||
:identifier => tenant_identifier(miq_product_feature.identifier, tenant.id), | ||
:tenant_id => tenant.id, | ||
:parent_id => miq_product_feature.id | ||
} | ||
end | ||
|
||
MiqProductFeature.invalidate_caches | ||
MiqProductFeature.create(result).map(&:identifier) | ||
end | ||
|
||
def self.seed_features(path = FIXTURE_PATH) | ||
fixture_yaml = feature_yaml(path) | ||
def self.seed_tenant_miq_product_features | ||
Tenant.in_my_region.all.flat_map { |t| seed_single_tenant_miq_product_features(t) } | ||
end | ||
|
||
features = all.to_a.index_by(&:identifier) | ||
seen = seed_from_hash(YAML.load_file(fixture_yaml), seen, nil, features) | ||
def self.seed_features | ||
transaction do | ||
features = all.index_by(&:identifier) | ||
|
||
root_feature = MiqProductFeature.find_by(:identifier => SUPER_ADMIN_FEATURE) | ||
Dir.glob(path.join("*.yml")).each do |fixture| | ||
seed_from_hash(YAML.load_file(fixture), seen, root_feature) | ||
root_file, other_files = seed_files | ||
|
||
seen = seed_from_hash(YAML.load_file(root_file), seen, nil, features) | ||
root_feature = find_by(:identifier => SUPER_ADMIN_FEATURE) | ||
|
||
other_files.each do |file| | ||
seed_from_array(YAML.load_file(file), seen, root_feature) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me say this to make sure I understand.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
end | ||
|
||
tenant_identifiers = seed_tenant_miq_product_features | ||
deletes = where.not(:identifier => seen.values.flatten + tenant_identifiers).destroy_all | ||
_log.info("Deleting product features: #{deletes.collect(&:identifier).inspect}") unless deletes.empty? | ||
seen | ||
end | ||
end | ||
|
||
tenant_identifiers = seed_tenant_miq_product_features | ||
deletes = where.not(:identifier => seen.values.flatten + tenant_identifiers).destroy_all | ||
_log.info("Deleting product features: #{deletes.collect(&:identifier).inspect}") unless deletes.empty? | ||
seen | ||
def self.seed_from_array(array, seen = nil, parent = nil, features = nil) | ||
Array.wrap(array).each do |hash| | ||
seed_from_hash(hash, seen, parent, features) | ||
end | ||
end | ||
|
||
def self.seed_from_hash(hash, seen = nil, parent = nil, features = nil) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
class MiqProductFeature < ApplicationRecord | ||
module Seeding | ||
extend ActiveSupport::Concern | ||
|
||
RELATIVE_FIXTURE_PATH = "db/fixtures/miq_product_features".freeze | ||
FIXTURE_PATH = Rails.root.join(RELATIVE_FIXTURE_PATH).freeze | ||
|
||
module ClassMethods | ||
def seed_files | ||
return seed_root_filename, seed_core_files + seed_plugin_files | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Fryguy If I'm reading correctly, this doesn't break the UI plugin work by @martinpovolny because they should still be picked up in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, this keeps @martinpovolny 's original "directory of feature yamls" in core, however that's not being used anywhere, so while we have it we may want to consider dropping it. On the plugin side though it could be useful to have separate yamls per feature in a dir, so I basically made plugins work like core. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, I'd like to see it dropped. Also it does not support any nesting if I remember correctly. Someone might me using it: https://documentation.commvault.com/commvault/v11_adminconsole/article?p=87519.htm and they should be provided with a way to migrate. What we need with this new way is documentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed, this return value feels strange to me, but I understand why it's done this way. Maybe in a future PR we can pull the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this idea, and definitely think we should do it in a followup. |
||
end | ||
|
||
private | ||
|
||
def seed_root_filename | ||
"#{FIXTURE_PATH}.yml" | ||
end | ||
|
||
def seed_core_files | ||
Dir.glob("#{FIXTURE_PATH}/*.y{,a}ml").sort | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate the sort on Dir.glob ❤️ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I basically always sort that method now, because of its unpredictability... I'm almost tempted to create a more_core_extensions method that enforces it :) |
||
end | ||
|
||
def seed_plugin_files | ||
Vmdb::Plugins.flat_map do |plugin| | ||
Dir.glob("#{plugin.root.join(RELATIVE_FIXTURE_PATH)}{.yml,.yaml,/*.yml,/*.yaml}").sort | ||
end | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, I didn't see this until now... I guess we were really worried about hardcoding "miq_product_features"... I can't believe I didn't see
table_name
before...