Project

General

Profile

Download (6.46 KB) Statistics
| Branch: | Tag: | Revision:

hammer-cli-csv / lib / hammer_cli_csv / provisioning_templates.rb @ c06f1783

1
module HammerCLICsv
2
  class CsvCommand
3
    class ProvisioningTemplatesCommand < BaseCommand
4
      command_name 'provisioning-templates'
5
      desc         'import or export provisioning templates'
6

    
7
      option %w(--include-locked), :flag, 'Include locked templates (will fail if re-imported)',
8
                                   :attribute_name => :option_include_locked
9

    
10
      ORGANIZATIONS = 'Organizations'
11
      LOCATIONS = 'Locations'
12
      OPERATINGSYSTEMS = 'Operating Systems'
13
      ASSOCIATIONS = 'Host Group / Puppet Environment Combinations'
14
      KIND = 'Kind'
15
      TEMPLATE = 'Template'
16

    
17
      def export(csv)
18
        csv << [NAME, ORGANIZATIONS, LOCATIONS, OPERATINGSYSTEMS, ASSOCIATIONS, KIND, TEMPLATE]
19
        params = {
20
            :per_page => 999999
21
        }
22
        params['search'] =  "organization = \"#{option_organization}\"" if option_organization
23
        @api.resource(:config_templates).call(:index, params)['results'].each do |template_id|
24
          template = @api.resource(:config_templates).call(:show, {:id => template_id['id']})
25
          next if template['locked'] && !option_include_locked?
26
          name = template['name']
27
          kind = template['snippet'] ? 'snippet' : template['template_kind_name']
28
          organizations = export_column(template, 'organizations', 'name')
29
          locations = export_column(template, 'locations', 'name')
30
          operatingsystems = export_column(template, 'operatingsystems', 'fullname')
31
          # TODO: puppet environments for content views are not present in api
32
          # http://projects.theforeman.org/issues/10293
33
          associations = export_associations(template)
34
          unless name == 'Boot disk iPXE - generic host' || name == 'Boot disk iPXE - host'
35
            csv << [name, organizations, locations, operatingsystems, associations, kind, template['template']]
36
          end
37
        end
38
      end
39

    
40
      def import
41
        @existing = {}
42
        @api.resource(:config_templates).call(:index, {
43
            :per_page => 999999
44
        })['results'].each do |template|
45
          @existing[template['name']] = template['id'] if template
46
        end
47

    
48
        thread_import do |line|
49
          create_templates_from_csv(line)
50
        end
51
      end
52

    
53
      def create_templates_from_csv(line)
54
        organizations = collect_column(line[ORGANIZATIONS]) do |organization|
55
          foreman_organization(:name => organization)
56
        end
57
        if option_organization
58
          org_id = foreman_organization(:name => option_organization)
59
          return if org_id.nil? || !organizations.include?(org_id)
60
          organizations = [org_id]
61
        end
62
        locations = collect_column(line[LOCATIONS]) do |location|
63
          foreman_location(:name => location)
64
        end
65
        operatingsystems = collect_column(line[OPERATINGSYSTEMS]) do |operatingsystem|
66
          foreman_operatingsystem(:name => operatingsystem)
67
        end
68

    
69
        count(line[COUNT]).times do |number|
70
          name = namify(line[NAME], number)
71
          if !@existing.include? name
72
            print _("Creating provisioning template '%{name}'...") % {:name => name } if option_verbose?
73
            template_id = @api.resource(:config_templates).call(:create, {
74
                'config_template' => {
75
                  'name' => name,
76
                  'snippet' => line[KIND] == 'snippet',
77
                  'template_kind_id' => line[KIND] == 'snippet' ? nil : foreman_template_kind(:name => line[KIND]),
78
                  'operatingsystem_ids' => operatingsystems,
79
                  'location_ids' => locations,
80
                  'template' => line[TEMPLATE]
81
                }
82
            })['id']
83
          else
84
            print _("Updating provisioning template '%{name}'...") % {:name => name} if option_verbose?
85
            template_id = @api.resource(:config_templates).call(:update, {
86
                'id' => @existing[name],
87
                'config_template' => {
88
                  'name' => name,
89
                  'snippet' => line[KIND] == 'snippet',
90
                  'template_kind_id' => line[KIND] == 'snippet' ? nil : foreman_template_kind(:name => line[KIND]),
91
                  'operatingsystem_ids' => operatingsystems,
92
                  'location_ids' => locations,
93
                  'template' => line[TEMPLATE]
94
                }
95
            })['id']
96
          end
97
          @existing[name] = template_id
98

    
99
          # Update associated resources
100
          @template_organizations ||= {}
101
          organizations.each do |organization_id|
102
            if @template_organizations[organization_id].nil?
103
              @template_organizations[organization_id] = @api.resource(:organizations).call(:show, {
104
                  'id' => organization_id
105
              })['config_templates'].collect do |template|
106
                template['id']
107
              end
108
            end
109
            if !@template_organizations[organization_id].include? template_id
110
              @template_organizations[organization_id] << template_id
111
              @api.resource(:organizations).call(:update, {
112
                  'id' => organization_id,
113
                  'organization' => {
114
                      'config_template_ids' => @template_organizations[organization_id]
115
                  }
116
              })
117
            end
118
          end
119
          @template_locations ||= {}
120
          locations.each do |location_id|
121
            if @template_locations[location_id].nil?
122
              @template_locations[location_id] = @api.resource(:locations).call(:show, {
123
                  'id' => location_id
124
              })['config_templates'].collect do |template|
125
                template['id']
126
              end
127
            end
128
            if !@template_locations[location_id].include? template_id
129
              @template_locations[location_id] += [template_id]
130
              @api.resource(:locations).call(:update, {
131
                  'id' => location_id,
132
                  'location' => {
133
                      'config_template_ids' => @template_locations[location_id]
134
                  }
135
              })
136
            end
137
          end
138

    
139
          puts _('done') if option_verbose?
140
        end
141
      rescue RuntimeError => e
142
        raise "#{e}\n       #{line[NAME]}"
143
      end
144

    
145
      def export_associations(template)
146
        return '' unless template['template_combinations']
147
        values = CSV.generate do |column|
148
          column << template['template_combinations'].collect do |combo|
149
            "#{combo['hostgroup_name']}|#{combo['environment_name']}"
150
          end
151
        end
152
        values.delete!("\n")
153
      end
154
    end
155
  end
156
end