foreman_acd 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +87 -0
  4. data/Rakefile +49 -0
  5. data/app/assets/javascripts/foreman_acd/acd_dummy.js +3 -0
  6. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +55 -0
  7. data/app/controllers/foreman_acd/api/v2/base_controller.rb +16 -0
  8. data/app/controllers/foreman_acd/app_definitions_controller.rb +53 -0
  9. data/app/controllers/foreman_acd/app_instances_controller.rb +158 -0
  10. data/app/controllers/foreman_acd/application_controller.rb +10 -0
  11. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +23 -0
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +23 -0
  13. data/app/controllers/ui_acd_controller.rb +30 -0
  14. data/app/models/foreman_acd/app_definition.rb +23 -0
  15. data/app/models/foreman_acd/app_instance.rb +21 -0
  16. data/app/views/foreman_acd/app_definitions/_form.html.erb +40 -0
  17. data/app/views/foreman_acd/app_definitions/edit.html.erb +11 -0
  18. data/app/views/foreman_acd/app_definitions/index.html.erb +27 -0
  19. data/app/views/foreman_acd/app_definitions/new.html.erb +10 -0
  20. data/app/views/foreman_acd/app_instances/_form.html.erb +46 -0
  21. data/app/views/foreman_acd/app_instances/edit.html.erb +11 -0
  22. data/app/views/foreman_acd/app_instances/index.html.erb +30 -0
  23. data/app/views/foreman_acd/app_instances/new.html.erb +11 -0
  24. data/app/views/ui_acd/app.json.rabl +9 -0
  25. data/app/views/ui_acd/app_definition.json.rabl +5 -0
  26. data/app/views/ui_acd/computeprofile.json.rabl +4 -0
  27. data/app/views/ui_acd/domain.json.rabl +4 -0
  28. data/app/views/ui_acd/environment.json.rabl +4 -0
  29. data/app/views/ui_acd/fdata.json.rabl +24 -0
  30. data/app/views/ui_acd/lifecycle_environment.json.rabl +4 -0
  31. data/app/views/ui_acd/ptable.json.rabl +4 -0
  32. data/config/routes.rb +24 -0
  33. data/db/migrate/20190610202252_create_app_definitions.rb +19 -0
  34. data/db/migrate/20190625140305_create_app_instances.rb +19 -0
  35. data/lib/foreman_acd/engine.rb +43 -0
  36. data/lib/foreman_acd/plugin.rb +80 -0
  37. data/lib/foreman_acd/version.rb +5 -0
  38. data/lib/foreman_acd.rb +7 -0
  39. data/lib/tasks/foreman_acd_tasks.rake +47 -0
  40. data/locale/Makefile +60 -0
  41. data/locale/en/foreman_acd.po +19 -0
  42. data/locale/foreman_acd.pot +19 -0
  43. data/locale/gemspec.rb +2 -0
  44. data/package.json +121 -0
  45. data/test/controllers/app_definitions_controller_test.rb +24 -0
  46. data/test/controllers/app_instances_controller_test.rb +24 -0
  47. data/test/controllers/ui_acd_controller_test.rb +26 -0
  48. data/test/factories/foreman_acd_factories.rb +17 -0
  49. data/test/models/app_definition_test.rb +11 -0
  50. data/test/models/app_instance_test.rb +8 -0
  51. data/test/test_plugin_helper.rb +8 -0
  52. data/webpack/__mocks__/foremanReact/components/common/forms/Select.js +2 -0
  53. data/webpack/components/ParameterSelection/ParameterSelection.js +468 -0
  54. data/webpack/components/ParameterSelection/ParameterSelection.scss +3 -0
  55. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +294 -0
  56. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +31 -0
  57. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +52 -0
  58. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +175 -0
  59. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +15 -0
  60. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +162 -0
  61. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +194 -0
  62. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +127 -0
  63. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +48 -0
  64. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +150 -0
  65. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +47 -0
  66. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +454 -0
  67. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +2265 -0
  68. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +209 -0
  69. data/webpack/components/ParameterSelection/index.js +39 -0
  70. data/webpack/index.js +8 -0
  71. data/webpack/reducer.js +7 -0
  72. data/webpack/test_setup.js +11 -0
  73. metadata +206 -0
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Foreman Application Centric Deployment
2
+
3
+ A plugin to bring an user self service portal and application centric deployment to Foreman.
4
+
5
+ # Description
6
+
7
+ The target of this plugin is, to deploy whole applications which include multiple hosts
8
+ and an Ansible Playbook / saltstack state to configure the application.
9
+
10
+ This plugin follows the idea of different user types working together.
11
+ The administrative user creates application definitions including multiple servers and
12
+ configuration management items (Ansible Playbook, saltstack state).
13
+ The user can create and deploy new application instances with an easy to use self service portal.
14
+
15
+ *Example Application Definition:*
16
+ To run a complex web application, a loadbalancer is required.
17
+ The loadbalancer routes the requests to 3 different web servers.
18
+ The web servers are using a database which is in high availability mode on 2 hosts.
19
+ => 6 hosts are required.
20
+
21
+ This plugin aims to setup all 6 hosts and to deploy the application.
22
+
23
+ # Current State
24
+ In the current state the plugin can be used to provide an easy to use self service user portal
25
+ to deploy new servers.
26
+
27
+ # Road Map
28
+ - Self service portal for single host deployments (current version)
29
+ - Add application deployment with single host requirements
30
+ - Add application deployment with multi host requirements
31
+
32
+ ## WARNING
33
+
34
+ This plugin is in development.
35
+ In the current state, a self service portal to deploy single servers can be created.
36
+
37
+ ## Installation
38
+
39
+ See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin)
40
+ for how to install Foreman plugins
41
+
42
+ ATM, Katello plugin need to exist, too.
43
+
44
+ ## Usage
45
+
46
+ Application Definition (Admin)
47
+ * Create an Application Definition (Configure -> Application Definition) first
48
+ * Select the Hostgroup you want to use.
49
+ * Specifiy the values, a user could overwrite.
50
+ (you can set a default value, if you want)
51
+
52
+ Application Instance (User)
53
+ * Create an Application Instance (Configure -> Application Instrane)
54
+ * Select the Application Definition which should be used
55
+ * Set the values.
56
+ Remember, all parameters need to have a value.
57
+ * Save the Application Instance
58
+ * To Deploy the host, select "Deploy" in the Action selection dropdown field
59
+ on the Application Instance index site
60
+
61
+ ## TODO
62
+
63
+ - Add ansible playbook / saltstack support to configure the application
64
+ - Multi-host support
65
+ - Add validation to the different parameter types
66
+
67
+ ## Contributing
68
+
69
+ Fork and send a Pull Request. Thanks!
70
+
71
+ ## Copyright
72
+
73
+ Copyright (c) 2019 ATIX AG
74
+
75
+ This program is free software: you can redistribute it and/or modify
76
+ it under the terms of the GNU General Public License as published by
77
+ the Free Software Foundation, either version 3 of the License, or
78
+ (at your option) any later version.
79
+
80
+ This program is distributed in the hope that it will be useful,
81
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
82
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83
+ GNU General Public License for more details.
84
+
85
+ You should have received a copy of the GNU General Public License
86
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
87
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require 'bundler/setup'
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+ begin
10
+ require 'rdoc/task'
11
+ rescue LoadError
12
+ require 'rdoc/rdoc'
13
+ require 'rake/rdoctask'
14
+ RDoc::Task = Rake::RDocTask
15
+ end
16
+
17
+ RDoc::Task.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'ForemanAppcendep'
20
+ rdoc.options << '--line-numbers'
21
+ rdoc.rdoc_files.include('README.rdoc')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rake/testtask'
30
+
31
+ Rake::TestTask.new(:test) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/**/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+ task :default => :test
39
+
40
+ begin
41
+ require 'rubocop/rake_task'
42
+ RuboCop::RakeTask.new
43
+ rescue StandardError => _e
44
+ puts 'Rubocop not loaded.'
45
+ end
46
+
47
+ task :default do
48
+ Rake::Task['rubocop'].execute
49
+ end
@@ -0,0 +1,3 @@
1
+ function acd_dummy_method() {
2
+ console.log("This file / function / method exists so that %foreman_precompile_plugin -s works during RPM build stage...");
3
+ }
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # API controller for App Definitions
7
+ class AppDefinitionsController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::ForemanAcd::Concerns::AppDefinitionParameters
9
+
10
+ before_action :find_resource, :except => [:index, :create]
11
+
12
+ api :GET, '/app_definitions/:id', N_('Show application definition')
13
+ param :id, :identifier, :required => true
14
+ def show; end
15
+
16
+ api :GET, '/app_definitions', N_('List application definitions')
17
+ param_group :search_and_pagination, ::Api::V2::BaseController
18
+ add_scoped_search_description_for(AppDefinition)
19
+ def index
20
+ @app_definitions = resource_scope_for_index
21
+ end
22
+
23
+ def_param_group :app_definition do
24
+ param :app_definition, Hash, :required => true, :action_aware => true do
25
+ param :name, String, :required => true
26
+ param :description, String, :required => true
27
+ param :hostgroup_id, :number, :required => true
28
+ param :parameters, String, :required => true
29
+ end
30
+ end
31
+
32
+ api :POST, '/app_definitions', N_('Create a application definition')
33
+ param_group :app_definition, :as => :create
34
+ def create
35
+ @app_definition = AppDefinition.new(app_definition_params)
36
+ process_response @app_definition.save
37
+ end
38
+
39
+ api :DELETE, '/app_definitions/:id', N_('Deletes application definition')
40
+ param :id, :identifier, :required => true
41
+ def destroy
42
+ process_response @app_definition.destroy
43
+ end
44
+
45
+ def controller_permission
46
+ 'app_definitions'
47
+ end
48
+
49
+ def resource_class
50
+ ForemanAcd::AppDefinition
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # Base Controller for all Acd API controllers
7
+ class BaseController < ::Api::V2::BaseController
8
+ resource_description do
9
+ resource_id 'foreman_acd'
10
+ api_version 'v2'
11
+ api_base_url '/acd/api'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Application Definition Controller
5
+ class AppDefinitionsController < ::ForemanAcd::ApplicationController
6
+ include Foreman::Controller::AutoCompleteSearch
7
+ include ::ForemanAcd::Concerns::AppDefinitionParameters
8
+
9
+ before_action :find_resource, :only => [:edit, :update, :destroy]
10
+
11
+ def index
12
+ @app_definitions = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
+ end
14
+
15
+ def read_hostgroups
16
+ @hostgroups = Hostgroup.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
17
+ end
18
+
19
+ def new
20
+ read_hostgroups
21
+ @app_definition = AppDefinition.new
22
+ end
23
+
24
+ def create
25
+ @app_definition = AppDefinition.new(app_definition_params)
26
+ if @app_definition.save
27
+ process_success
28
+ else
29
+ process_error
30
+ end
31
+ end
32
+
33
+ def edit
34
+ read_hostgroups
35
+ end
36
+
37
+ def update
38
+ if @app_definition.update(app_definition_params)
39
+ process_success
40
+ else
41
+ process_error
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ if @app_definition.destroy
47
+ process_success
48
+ else
49
+ process_error
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Application Instance Controller
5
+ class AppInstancesController < ::ForemanAcd::ApplicationController
6
+ include Foreman::Controller::AutoCompleteSearch
7
+ include ::ForemanAcd::Concerns::AppInstanceParameters
8
+
9
+ before_action :find_resource, :only => [:edit, :update, :destroy, :deploy]
10
+
11
+ def index
12
+ @app_instances = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
+ end
14
+
15
+ def read_applications
16
+ @applications = ForemanAcd::AppDefinition.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
17
+ end
18
+
19
+ def new
20
+ @app_instance = AppInstance.new
21
+ read_applications
22
+ end
23
+
24
+ def create
25
+ @app_instance = AppInstance.new(app_instance_params)
26
+ if @app_instance.save
27
+ process_success
28
+ else
29
+ process_error
30
+ end
31
+ end
32
+
33
+ def edit
34
+ read_applications
35
+ end
36
+
37
+ def update
38
+ if @app_instance.update(app_instance_params)
39
+ process_success
40
+ else
41
+ process_error
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ if @app_instance.destroy
47
+ process_success
48
+ else
49
+ process_error
50
+ end
51
+ end
52
+
53
+ def action_permission
54
+ case params[:action]
55
+ when 'deploy'
56
+ :deploy
57
+ else
58
+ super
59
+ end
60
+ end
61
+
62
+ def deploy
63
+ params = host_attributes(set_host_params)
64
+
65
+ # Print to log for debugging purposes
66
+ logger.info("Host creation parameters:\n#{params}\n")
67
+
68
+ @host = Host.new(params)
69
+ apply_compute_profile(@host)
70
+ @host.suggest_default_pxe_loader
71
+ @host.save
72
+ success _('Successfully initiated host creation')
73
+ rescue StandardError => e
74
+ logger.error("Failed to initiate host creation: #{e.backtrace.join($INPUT_RECORD_SEPARATOR)}")
75
+ ensure
76
+ redirect_to app_instances_path
77
+ end
78
+
79
+ private
80
+
81
+ # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
82
+ def apply_compute_profile(host)
83
+ host.apply_compute_profile(InterfaceMerge.new(:merge_compute_attributes => true))
84
+ host.apply_compute_profile(ComputeAttributeMerge.new)
85
+ end
86
+
87
+ # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
88
+ def host_attributes(params, host = nil)
89
+ return {} if params.nil?
90
+
91
+ params = params.deep_clone
92
+ if params[:interfaces_attributes]
93
+ # handle both hash and array styles of nested attributes
94
+ params[:interfaces_attributes] = params[:interfaces_attributes].values if params[:interfaces_attributes].is_a?(Hash) || params[:interfaces_attributes].is_a?(ActionController::Parameters)
95
+ # map interface types
96
+ params[:interfaces_attributes] = params[:interfaces_attributes].map do |nic_attr|
97
+ interface_attributes(nic_attr, :allow_nil_type => host.nil?)
98
+ end
99
+ end
100
+ params = host.apply_inherited_attributes(params) if host
101
+ params
102
+ end
103
+
104
+ # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
105
+ def interface_attributes(params, allow_nil_type: false)
106
+ params[:type] = InterfaceTypeMapper.map(params[:type]) if params.key?(:type) || allow_nil_type
107
+ params
108
+ end
109
+
110
+ def hardcoded_params
111
+ result = {}
112
+ result['managed'] = true
113
+ result['enabled'] = true
114
+ result['build'] = true
115
+ result['compute_attributes'] = { 'start' => '1' }
116
+ result['host_parameters_attributes'] = []
117
+ result
118
+ end
119
+
120
+ def set_host_params
121
+ result = hardcoded_params
122
+ result['hostgroup_id'] = @app_instance.app_definition.hostgroup_id
123
+ JSON.parse(@app_instance.parameters).each do |param|
124
+ case param['type']
125
+
126
+ when 'computeprofile'
127
+ result['compute_profile_id'] = param['value']
128
+
129
+ when 'domain'
130
+ result['domain_id'] = param['value']
131
+
132
+ when 'hostname'
133
+ result['name'] = param['value']
134
+
135
+ when 'hostparam'
136
+ result['host_parameters_attributes'].push(:name => param['name'], :value => param['value'])
137
+
138
+ when 'ip'
139
+ result['ip'] = param['value']
140
+
141
+ when 'lifecycleenv'
142
+ result['content_facet_attributes'] = { 'lifecycle_environment_id' => param['value'] }
143
+
144
+ when 'ptable'
145
+ result['ptable_id'] = param['value']
146
+
147
+ when 'puppetenv'
148
+ result['environment_id'] = param['value']
149
+
150
+ when 'password'
151
+ result['root_pass'] = param['value']
152
+
153
+ end
154
+ end
155
+ result
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Base controller for all controllers
5
+ class ApplicationController < ::ApplicationController
6
+ def resource_class
7
+ "ForemanAcd::#{controller_name.singularize.classify}".constantize
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Concerns
5
+ # Parameters for AppDefinitions
6
+ module AppDefinitionParameters
7
+ extend ActiveSupport::Concern
8
+
9
+ class_methods do
10
+ def app_definition_params_filter
11
+ Foreman::ParameterFilter.new(::ForemanAcd::AppDefinition).tap do |filter|
12
+ filter.permit(:name, :description, :hostgroup_id, :parameters)
13
+ end
14
+ end
15
+ end
16
+
17
+ def app_definition_params
18
+ param_name = parameter_filter_context.api? ? 'app_definition' : 'foreman_acd_app_definition'
19
+ self.class.app_definition_params_filter.filter_params(params, parameter_filter_context, param_name)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Concerns
5
+ # Parameters for AppInstances
6
+ module AppInstanceParameters
7
+ extend ActiveSupport::Concern
8
+
9
+ class_methods do
10
+ def app_instance_params_filter
11
+ Foreman::ParameterFilter.new(::ForemanAcd::AppInstance).tap do |filter|
12
+ filter.permit(:name, :app_definition_id, :description, :parameters)
13
+ end
14
+ end
15
+ end
16
+
17
+ def app_instance_params
18
+ param_name = parameter_filter_context.api? ? 'app_instance' : 'foreman_acd_app_instance'
19
+ self.class.app_instance_params_filter.filter_params(params, parameter_filter_context, param_name)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Controller to create JSON data to be used in react app
4
+ class UiAcdController < ::Api::V2::BaseController
5
+ def app
6
+ @app_data = {}
7
+ app_definition = ForemanAcd::AppDefinition.find(params[:id])
8
+ @app_data['app_definition'] = app_definition
9
+ @app_data['fdata'] = collect_fdata(app_definition.hostgroup_id)
10
+ end
11
+
12
+ def fdata
13
+ @fdata = collect_fdata(params['id'])
14
+ end
15
+
16
+ private
17
+
18
+ def collect_fdata(hostgroup_id)
19
+ hg = Hostgroup.find(hostgroup_id)
20
+ fdata = OpenStruct.new(
21
+ :environments => Environment.all,
22
+ :lifecycle_environments => Katello::KTEnvironment.all,
23
+ :domains => Domain.all,
24
+ :computeprofiles => ComputeProfile.all,
25
+ :hostgroup_id => hg.id,
26
+ :ptables => hg&.operatingsystem.ptables
27
+ )
28
+ fdata
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Application Definition
5
+ class AppDefinition < ApplicationRecord
6
+ include Authorizable
7
+ extend FriendlyId
8
+ friendly_id :name
9
+
10
+ validates :name, :presence => true, :uniqueness => true
11
+ belongs_to :hostgroup, :class_name => '::Hostgroup'
12
+ has_many :app_instances, :inverse_of => :app_definition, :dependent => :destroy
13
+ scoped_search :on => :name
14
+
15
+ def self.humanize_class_name(_name = nil)
16
+ _('App Definition')
17
+ end
18
+
19
+ def self.permission_name
20
+ 'app_definitions'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Application Instance
5
+ class AppInstance < ApplicationRecord
6
+ include Authorizable
7
+ extend FriendlyId
8
+ friendly_id :name
9
+ validates :name, :presence => true, :uniqueness => true
10
+ belongs_to :app_definition, :inverse_of => :app_instances
11
+ scoped_search :on => :name
12
+
13
+ def self.humanize_class_name(_name = nil)
14
+ _('App Instance')
15
+ end
16
+
17
+ def self.permission_name
18
+ 'app_instances'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ <%
2
+ json = {
3
+ "organization": current_organization,
4
+ "location": current_location,
5
+ "hostgroups": @hostgroups,
6
+ "loadForemanDataUrl": ui_acd_fdata_path("__id__")
7
+ }
8
+
9
+ if @app_definition.name.empty?
10
+ json["mode"] = "newDefinition"
11
+ else
12
+ json["mode"] = "editDefinition"
13
+ json["appDefinition"] = {
14
+ "id": @app_definition.id,
15
+ "name": @app_definition.name,
16
+ "hostgroup_id": @app_definition.hostgroup_id,
17
+ }
18
+ json["parameters"] = JSON.parse(@app_definition.parameters)
19
+ end
20
+
21
+ %>
22
+
23
+ <%= form_for @app_definition, :url => (@app_definition.new_record? ? app_definitions_path : app_definition_path(:id => @app_definition.id)) do |f| %>
24
+ <%= base_errors_for @app_definition %>
25
+ <ul class="nav nav-tabs" data-tabs="tabs">
26
+ <li class="active"><a href="#primary" data-toggle="tab"><%= _('Application Definitions') %></a></li>
27
+ </ul>
28
+
29
+ <div class="tab-content">
30
+ <div class="tab-pane active" id="primary">
31
+ <%= text_f f, :name %>
32
+ <%= text_f f, :description %>
33
+
34
+ <div id='param-selection'></div>
35
+ <%= mount_react_component('ParameterSelection', "#param-selection", json.to_json) %>
36
+ </div>
37
+ </div>
38
+
39
+ <%= submit_or_cancel f %>
40
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <% title(_('Edit Application Definition %s') % @app_definition) %>
2
+
3
+ <% content_for(:javascripts) do %>
4
+ <%= webpacked_plugins_js_for :foreman_acd %>
5
+ <% end %>
6
+ <% content_for(:stylesheets) do %>
7
+ <%= webpacked_plugins_css_for :foreman_acd %>
8
+ <% end %>
9
+
10
+ <%= render :partial => 'form' %>
11
+
@@ -0,0 +1,27 @@
1
+ <% title _('Application Definitions') %>
2
+
3
+ <% title_actions button_group(new_link(_('New Application Definition'))) %>
4
+
5
+ <table class="table table-bordered table-striped">
6
+ <tr>
7
+ <th><%= sort :name, :as => s_('AppDefinition|Name') %></th>
8
+ <th><%= _('Description') %></th>
9
+ <th><%= sort :hostgroup, :as => _('Host groups'), :default => 'DESC' %></th>
10
+ <th></th>
11
+ </tr>
12
+ <% for app_definition in @app_definitions %>
13
+ <tr>
14
+ <td><%=link_to_if_authorized h(app_definition.name), hash_for_edit_app_definition_path(:id => app_definition).merge(:auth_object => app_definition, :authorizer => authorizer) %></td>
15
+ <td><%= app_definition.description %></td>
16
+ <td><%= app_definition.hostgroup %></td>
17
+ <td>
18
+ <%= action_buttons(display_delete_if_authorized(hash_for_app_definition_path(:id => app_definition).merge(:auth_object => app_definition, :authorizer => authorizer),
19
+ :data => { 'confirm': _('Delete %s?') % app_definition.name })) %>
20
+ </td>
21
+ </tr>
22
+ <% end %>
23
+ </table>
24
+
25
+ <%= page_entries_info @app_definitions %>
26
+ <%= will_paginate @app_definitions %>
27
+
@@ -0,0 +1,10 @@
1
+ <% title _('New Application Definition') %>
2
+
3
+ <% content_for(:javascripts) do %>
4
+ <%= webpacked_plugins_js_for :foreman_acd %>
5
+ <% end %>
6
+ <% content_for(:stylesheets) do %>
7
+ <%= webpacked_plugins_css_for :foreman_acd %>
8
+ <% end %>
9
+
10
+ <%= render :partial => 'form' %>