Skip to content
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

Add support for exporting and importing customization templates #17877

Merged

Conversation

branic
Copy link
Contributor

@branic branic commented Aug 17, 2018

These rake scripts and classes provide functionality for exporting/importing of the following ManageIQ object types:

  • Customization Templates

This PR uses the framework that was implemented for PRs #14126, #15256, #16717, and others to export/import other ManageIQ object types.

These scripts are based on the CFME RH Consulting Scripts and are used by Red Hat consultants to enable storing customizations in Git and maintaining customizations between environments (e.g. dev/qa/prod) for an SDLC lifecycle.

Links [Optional]

Steps for Testing/QA [Optional]

Exporting

  1. Create a directory for the exports
mkdir /tmp/customization_templates
  1. Export user defined customization templates
vmdb
bin/rake evm:export:customization_templates -- --directory /tmp/customization_templates

Importing

  1. Import all provision dialog yaml files in a directory
# vmdb
# bin/rake evm:import:customization_templates -- --source /tmp/customization_templates
  1. or Import specific customization template yaml file
# vmdb
# bin/rake evm:import:customization_templates -- --source /tmp/customization_templates/Test_customization_template.yaml

@branic
Copy link
Contributor Author

branic commented Aug 17, 2018

/cc @gtanzillo @gmcculloug

@branic branic force-pushed the export_import_customization_templates branch from 0691671 to 18e06ee Compare August 17, 2018 18:49
def validate_type(custom_template_type)
valid_types = CustomizationTemplate.descendants.collect(&:name)

valid_types.include?(custom_template_type) ? true : false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename method to valid_type?. Also, the include? method already returns true or false so no need for the ternary. This could be reduced to:

CustomizationTemplate.descendants.collect(&:name)include?(custom_template_type)

Bonus Friday method example (not worth it since it makes the method longer, but wanted to show the example for future reference):

def valid_type?(custom_template_type)
  klass = custom_template_type.safe_constantize
  return false unless klass

  klass < CustomizationTemplate
end

if pxe_image
{ :pxe_image_type => pxe_image.to_model_hash.reject { |key| EXCLUDE_ATTRS.include?(key) } }
else
{ :pxe_image_type => {} }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something you ran into? Looks like it is an invalid configuration so we are just exporting something we know will fail to import.

Is there a reason to export or should the code detect and skip these records during export?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to get around the issue that .to_model_hash outputs a key called :pxe_image_type_id and we need to convert that ID into the :name and provision_type from the PxeImageType that the ID is for so that the import can work between regions. The import script looks for a key called :pxe_image_type and coverts it into a valid PxeImageType object that is then used when finding the CustomiztionTemplate to update or creating a new CustomizationTemplate object.

Having the empty hash is there to support exporting the examples. The examples don't have a :pxe_image_type_id, but for the import to work I need to have the :pxe_image_type key so I just set it to an empty hash. The import script aborts with an error if the :pxe_image_type does not contain a key named :name.


private

def pxe_image(pxe_image)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest renaming to pxe_image_type_hash and pass pxe_image_type as the parameter.

ct_hash = Exports.exclude_attributes(customization_template.to_model_hash, EXCLUDE_ATTRS)
ct_hash.merge!(pxe_image(customization_template.pxe_image_type))

image_type_name = ct_hash[:pxe_image_type][:name] ? ct_hash[:pxe_image_type][:name] : "Examples"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: image_type_name = ct_hash.fetch_path(:pxe_image_type, :name) || "Examples"

end

def assert_test_ct_one_present(pit)
# pit = PxeImageType.find_by(:name => existing_pit_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't need this line 😄

let(:ct_desc) { "This template takes use of rootpassword defined in the UI" }
let(:existing_pit_name) { "RHEL-6" }
let(:new_pit_name) { "RHEL-7" }
let(:new_pit_pt) { "vm" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of a minor quibble but a lot of these are only pertinent for one context, so I think they should be moved into that context. For example like the first one I noticed update_file and ct_system_file are only used in one context each (as are a few others), so they could be moved down into them.

Arguably, since they only really pertain to the #import method, even the top ones like data_dir should be moved inside the describe "#import" do block, but since that's all this class is supposed to do anyway, I don't think it's that big of a deal to have ones that are used all over at this high level.


image_type_name = ct_hash[:pxe_image_type][:name] ? ct_hash[:pxe_image_type][:name] : "Examples"
filename = Exports.safe_filename("#{image_type_name}-#{ct_hash[:name]}", options[:keep_spaces])
File.write("#{export_dir}/#{filename}.yaml", ct_hash.to_yaml)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be timestamping these filenames at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so. In many (probably most) cases these scripts are being used to maintain the .yaml files in an SCM, Adding a timestamp to the filename would defeat the ability to see modifications over time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, none of the other export scripts add a timestamp to the filename.

@miq-bot
Copy link
Member

miq-bot commented Aug 17, 2018

Checked commits branic/manageiq@18e06ee~...28ab11a with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
5 files checked, 0 offenses detected
Everything looks fine. 🍪

Copy link
Member

@gmcculloug gmcculloug left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eclarizio PTAL

Copy link
Member

@eclarizio eclarizio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@gmcculloug gmcculloug merged commit ccb8a20 into ManageIQ:master Aug 20, 2018
@gmcculloug gmcculloug added this to the Sprint 93 Ending Aug 27, 2018 milestone Aug 20, 2018
@branic branic deleted the export_import_customization_templates branch August 20, 2018 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants