foreman_acd 0.0.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +79 -26
  3. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +122 -0
  4. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +54 -0
  5. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +1 -2
  6. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +54 -0
  7. data/app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb +0 -0
  8. data/app/controllers/foreman_acd/app_definitions_controller.rb +36 -4
  9. data/app/controllers/foreman_acd/app_instances_controller.rb +24 -90
  10. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +23 -0
  11. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  13. data/app/controllers/foreman_acd/remote_execution_controller.rb +49 -0
  14. data/app/controllers/ui_acd_controller.rb +11 -4
  15. data/app/models/foreman_acd/ansible_playbook.rb +50 -0
  16. data/app/models/foreman_acd/app_definition.rb +2 -1
  17. data/app/models/foreman_acd/app_instance.rb +7 -0
  18. data/app/services/foreman_acd/app_configurator.rb +70 -0
  19. data/app/services/foreman_acd/app_deployer.rb +139 -0
  20. data/app/services/foreman_acd/inventory_creator.rb +67 -0
  21. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +21 -0
  22. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +3 -0
  23. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  24. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  25. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +3 -0
  26. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +3 -0
  27. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +3 -0
  28. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +3 -0
  29. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +3 -0
  30. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +3 -0
  31. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -0
  32. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +3 -0
  33. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +3 -0
  34. data/app/views/foreman_acd/app_definitions/_form.html.erb +25 -19
  35. data/app/views/foreman_acd/app_definitions/edit.html.erb +5 -0
  36. data/app/views/foreman_acd/app_definitions/import.html.erb +18 -0
  37. data/app/views/foreman_acd/app_definitions/index.html.erb +9 -5
  38. data/app/views/foreman_acd/app_instances/_form.html.erb +10 -8
  39. data/app/views/foreman_acd/app_instances/deploy.html.erb +19 -0
  40. data/app/views/foreman_acd/app_instances/index.html.erb +10 -5
  41. data/app/views/foreman_acd/app_instances/report.html.erb +19 -0
  42. data/app/views/templates/job/run_acd_ansible_playbook.erb +49 -0
  43. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  44. data/app/views/ui_acd/app.json.rabl +6 -2
  45. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  46. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  47. data/config/routes.rb +32 -1
  48. data/db/migrate/20190610202252_create_app_definitions.rb +1 -3
  49. data/db/migrate/20190625140305_create_app_instances.rb +1 -1
  50. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  51. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  52. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +5 -0
  53. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +5 -0
  54. data/db/seeds.d/75-job_templates.rb +8 -0
  55. data/lib/foreman_acd/engine.rb +3 -0
  56. data/lib/foreman_acd/plugin.rb +72 -4
  57. data/lib/foreman_acd/version.rb +1 -1
  58. data/package.json +1 -2
  59. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +376 -0
  60. data/webpack/components/ApplicationDefinition/ApplicationDefinition.scss +1 -0
  61. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +295 -0
  62. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +14 -0
  63. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  64. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +243 -0
  65. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +8 -0
  66. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  67. data/webpack/components/ApplicationDefinition/index.js +33 -0
  68. data/webpack/components/ApplicationInstance/ApplicationInstance.js +412 -0
  69. data/webpack/components/ApplicationInstance/ApplicationInstance.scss +11 -0
  70. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +239 -0
  71. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +14 -0
  72. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +295 -0
  73. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +9 -0
  74. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +49 -0
  75. data/webpack/components/ApplicationInstance/components/Service.js +30 -0
  76. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +37 -0
  77. data/webpack/components/ApplicationInstance/index.js +35 -0
  78. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +155 -0
  79. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +27 -0
  80. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +86 -0
  81. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +4 -0
  82. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +52 -0
  83. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +5 -0
  84. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +26 -0
  85. data/webpack/components/ApplicationInstanceReport/index.js +27 -0
  86. data/webpack/components/ParameterSelection/ParameterSelection.js +96 -183
  87. data/webpack/components/ParameterSelection/ParameterSelection.scss +9 -2
  88. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +72 -104
  89. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +14 -19
  90. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +3 -35
  91. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +100 -83
  92. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +3 -7
  93. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +12 -21
  94. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +1 -1
  95. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +3 -45
  96. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +20 -0
  97. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +22 -46
  98. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  99. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +40 -265
  100. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +11 -96
  101. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +3 -9
  102. data/webpack/components/ParameterSelection/index.js +6 -8
  103. data/webpack/components/common/AddTableEntry.js +30 -0
  104. data/webpack/components/common/DeleteTableEntry.js +39 -0
  105. data/webpack/components/common/EasyHeaderFormatter.js +18 -0
  106. data/webpack/components/common/ExtSelect.js +43 -0
  107. data/webpack/components/common/RailsData.js +27 -0
  108. data/webpack/components/common/__tests__/AddTableEntry.test.js +26 -0
  109. data/webpack/components/common/__tests__/DeleteTableEntry.test.js +29 -0
  110. data/webpack/components/common/__tests__/ExtSelect.test.js +38 -0
  111. data/webpack/components/common/__tests__/RailsData.test.js +16 -0
  112. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +35 -0
  113. data/webpack/components/common/__tests__/__snapshots__/AddTableEntry.test.js.snap +35 -0
  114. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +41 -0
  115. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +41 -0
  116. data/webpack/components/common/__tests__/__snapshots__/ExtSelect.test.js.snap +18 -0
  117. data/webpack/components/common/__tests__/__snapshots__/RailsData.test.js.snap +10 -0
  118. data/webpack/helper.js +20 -0
  119. data/webpack/index.js +6 -0
  120. data/webpack/reducer.js +43 -3
  121. metadata +87 -39
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ object @ansible_data
4
+ attribute :id
5
+ attribute :name
6
+ attribute :groups
@@ -4,6 +4,10 @@ child @app_data['app_definition'] => :app_definition do
4
4
  extends 'ui_acd/app_definition'
5
5
  end
6
6
 
7
- child @app_data['fdata'] => :fdata do
8
- extends 'ui_acd/fdata'
7
+ child @app_data['foreman_data'] => :foreman_data do
8
+ extends 'ui_acd/foreman_data'
9
+ end
10
+
11
+ child @app_data['ansible_data'] => :ansible_data do
12
+ extends 'ui_acd/ansible_data'
9
13
  end
@@ -2,4 +2,4 @@
2
2
 
3
3
  object @app_definition
4
4
 
5
- attributes :id, :name, :description, :hostgroup_id, :parameters, :created_at, :updated_at
5
+ attributes :id, :name, :description, :services, :ansible_vars_all, :created_at, :updated_at
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- object @fdata
3
+ object @foreman_data
4
4
  attribute :hostgroup_id
5
5
 
6
6
  child :environments => :environments do
@@ -2,10 +2,26 @@
2
2
 
3
3
  Rails.application.routes.draw do
4
4
  scope :acd, :path => '/acd' do
5
+ resources :ansible_playbooks, :controller => 'foreman_acd/ansible_playbooks' do
6
+ collection do
7
+ get 'auto_complete_search'
8
+ end
9
+
10
+ member do
11
+ get 'import_vars'
12
+ end
13
+
14
+ end
5
15
  resources :app_definitions, :controller => 'foreman_acd/app_definitions' do
6
16
  collection do
7
17
  get 'auto_complete_search'
18
+ get 'import'
8
19
  end
20
+
21
+ member do
22
+ get 'export'
23
+ end
24
+
9
25
  end
10
26
 
11
27
  resources :app_instances, :controller => 'foreman_acd/app_instances' do
@@ -15,10 +31,25 @@ Rails.application.routes.draw do
15
31
 
16
32
  member do
17
33
  post 'deploy'
34
+ get 'report'
18
35
  end
19
36
  end
20
37
 
38
+ match '/remote_execution', :controller => 'foreman_acd/remote_execution', :action => 'create', :via => [:post]
39
+
21
40
  get 'ui_acd_app/:id', :to => 'ui_acd#app', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_app
22
- get 'ui_acd_fdata/:id', :to => 'ui_acd#fdata', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_fdata
41
+ get 'ui_acd_foreman_data/:id', :to => 'ui_acd#foreman_data', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_foreman_data
42
+ get 'ui_acd_ansible_data/:id', :to => 'ui_acd#ansible_data', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_ansible_data
43
+
44
+ scope :api, :path => '/api', :defaults => { :format => 'json' } do
45
+ scope '(:apiv)', :defaults => { :apiv => 'v2' },
46
+ :apiv => /v1|v2/, :constraints => ApiConstraints.new(:version => 2) do
47
+ constraints(:id => /[\w\.-]+/) do
48
+ resources :app_definitions, :only => [:show, :index], :controller => 'foreman_acd/api/v2/app_definitions', :as => :acd_api_v2_app_definitions
49
+ resources :app_instances, :only => [:show, :index], :controller => 'foreman_acd/api/v2/app_instances', :as => :api_v2_foreman_acd_app_instances
50
+ resources :ansible_playbooks, :only => [:show, :index], :controller => 'foreman_acd/api/v2/ansible_playbooks', :as => :api_v2_foreman_acd_ansible_playbooks
51
+ end
52
+ end
53
+ end
23
54
  end
24
55
  end
@@ -6,11 +6,9 @@ class CreateAppDefinitions < ActiveRecord::Migration[5.2]
6
6
  create_table :app_definitions do |t|
7
7
  t.string :name, :default => '', :null => false, :limit => 255, :unique => true
8
8
  t.text :description
9
- t.column :hostgroup_id, :integer
10
- t.text :parameters
9
+ t.text :services
11
10
  t.timestamps :null => true
12
11
  end
13
- add_foreign_key :app_definitions, :hostgroups
14
12
  end
15
13
 
16
14
  def down
@@ -7,7 +7,7 @@ class CreateAppInstances < ActiveRecord::Migration[5.2]
7
7
  t.string :name, :default => '', :null => false, :limit => 255, :unique => true
8
8
  t.column :app_definition_id, :integer, :null => false
9
9
  t.text :description
10
- t.text :parameters
10
+ t.text :hosts
11
11
  t.timestamps :null => true
12
12
  end
13
13
  add_foreign_key :app_instances, :app_definitions
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adding acd ansible playbooks db table
4
+ class CreateAnsiblePlaybooks < ActiveRecord::Migration[5.2]
5
+ def up
6
+ create_table :acd_ansible_playbooks do |t|
7
+ t.string :name, :default => '', :null => false, :limit => 255, :unique => true
8
+ t.text :description
9
+ t.string :scm_type
10
+ t.string :path
11
+ t.string :playfile
12
+ t.text :vars
13
+ t.timestamps :null => true
14
+ end
15
+ end
16
+
17
+ def down
18
+ drop_table :acd_ansible_playbooks
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adding acd ansible playbooks db table
4
+ class AddAnsiblePlaybookId < ActiveRecord::Migration[5.2]
5
+ def up
6
+ add_column :app_definitions, :acd_ansible_playbook_id, :integer
7
+ add_foreign_key "app_definitions", "acd_ansible_playbooks", :name => "app_definitions_acd_ansible_playbooks_id_fk"
8
+ end
9
+
10
+ def down
11
+ remove_foreign_key 'app_definitions', :name => 'app_definitions_acd_ansible_playbooks_id_fk'
12
+ remove_column :app_definitions, :acd_ansible_playbook_id
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class AddAnsibleVarsAllToAppDefinitions < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :app_definitions, :ansible_vars_all, :text
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddAnsibleVarsAllToAppInstances < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :app_instances, :ansible_vars_all, :text
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ User.as_anonymous_admin do
2
+ JobTemplate.without_auditing do
3
+ Dir[File.join("#{ForemanAcd::Engine.root}/app/views/templates/**/*.erb")].each do |template|
4
+ sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
5
+ JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
6
+ end
7
+ end
8
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'foreman_remote_execution'
4
+
3
5
  module ForemanAcd
4
6
  # This engine connects ForemanAcd with Foreman core
5
7
  class Engine < ::Rails::Engine
@@ -12,6 +14,7 @@ module ForemanAcd
12
14
  config.autoload_paths += Dir["#{config.root}/app/overrides"]
13
15
  config.autoload_paths += Dir["#{config.root}/app/services"]
14
16
  config.autoload_paths += Dir["#{config.root}/app/lib"]
17
+ config.autoload_paths += Dir["#{config.root}/lib"]
15
18
 
16
19
  # Add any db migrations
17
20
  initializer 'foreman_acd.load_app_instance_data' do |app|
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Foreman::Plugin.register :foreman_acd do
4
- requires_foreman '>= 1.19'
4
+ requires_foreman '>= 2.1'
5
5
 
6
6
  apipie_documented_controllers ["#{ForemanAcd::Engine.root}/app/controllers/foreman_acd/api/v2/*.rb"]
7
7
 
8
8
  # Menus
9
9
  divider :top_menu, :parent => :configure_menu, :caption => 'Applications'
10
+ menu :top_menu, :ansible_playbooks,
11
+ :url_hash => { :controller => :'foreman_acd/ansible_playbooks', :action => :index },
12
+ :caption => 'Ansible Playbooks',
13
+ :parent => :configure_menu
14
+
10
15
  menu :top_menu, :app_definitions,
11
16
  :url_hash => { :controller => :'foreman_acd/app_definitions', :action => :index },
12
17
  :caption => 'App Definitions',
@@ -19,6 +24,31 @@ Foreman::Plugin.register :foreman_acd do
19
24
 
20
25
  # Add permissions
21
26
  security_block :foreman_acd do
27
+ permission :create_ansible_playbooks,
28
+ { :'foreman_acd/ansible_playbooks' => [:new, :create],
29
+ :'foreman_acd/api/v2/ansible_playbooks' => [:create] },
30
+ :resource_type => 'ForemanAcd::AnsiblePlaybook'
31
+
32
+ permission :view_ansible_playbooks,
33
+ { :'foreman_acd/ansible_playbooks' => [:index, :show, :auto_complete_search],
34
+ :'foreman_acd/api/v2/ansible_playbooks' => [:index, :show] },
35
+ :resource_type => 'ForemanAcd::AnsiblePlaybook'
36
+
37
+ permission :edit_ansible_playbooks,
38
+ { :'foreman_acd/ansible_playbooks' => [:update, :edit],
39
+ :'foreman_acd/api/v2/ansible_playbooks' => [:update] },
40
+ :resource_type => 'ForemanAcd::AnsiblePlaybook'
41
+
42
+ permission :destroy_ansible_playbooks,
43
+ { :'foreman_acd/ansible_playbooks' => [:destroy],
44
+ :'foreman_acd/api/v2/ansible_playbooks' => [:destroy] },
45
+ :resource_type => 'ForemanAcd::AnsiblePlaybook'
46
+
47
+ permission :import_vars_ansible_playbooks,
48
+ { :'foreman_acd/ansible_playbooks' => [:import_vars],
49
+ :'foreman_acd/api/v2/ansible_playbooks' => [:import_vars] },
50
+ :resource_type => 'ForemanAcd::AnsiblePlaybook'
51
+
22
52
  permission :create_app_definitions,
23
53
  { :'foreman_acd/app_definitions' => [:new, :create],
24
54
  :'foreman_acd/api/v2/app_definitions' => [:create] },
@@ -39,6 +69,16 @@ Foreman::Plugin.register :foreman_acd do
39
69
  :'foreman_acd/api/v2/app_definitions' => [:destroy] },
40
70
  :resource_type => 'ForemanAcd::AppDefinition'
41
71
 
72
+ permission :export_app_definitions,
73
+ { :'foreman_acd/app_definitions' => [:export],
74
+ :'foreman_acd/api/v2/app_definitions' => [:export] },
75
+ :resource_type => 'ForemanAcd::AppDefinition'
76
+
77
+ permission :import_app_definitions,
78
+ { :'foreman_acd/app_definitions' => [:import],
79
+ :'foreman_acd/api/v2/app_definitions' => [:import] },
80
+ :resource_type => 'ForemanAcd::AppDefinition'
81
+
42
82
  permission :create_app_instances,
43
83
  { :'foreman_acd/app_instances' => [:new, :create],
44
84
  :'foreman_acd/api/v2/app_instances' => [:create] },
@@ -63,18 +103,46 @@ Foreman::Plugin.register :foreman_acd do
63
103
  { :'foreman_acd/app_instances' => [:deploy],
64
104
  :'foreman_acd/api/v2/app_instances' => [:deploy] },
65
105
  :resource_type => 'ForemanAcd::AppInstance'
106
+
107
+ permission :configure_app_instances,
108
+ { :'foreman_acd/app_instances' => [:configure],
109
+ :'foreman_acd/api/v2/app_instances' => [:configure] },
110
+ :resource_type => 'ForemanAcd::AppInstance'
111
+
112
+ permission :report_app_instances,
113
+ { :'foreman_acd/app_instances' => [:report],
114
+ :'foreman_acd/api/v2/app_instances' => [:report] },
115
+ :resource_type => 'ForemanAcd::AppInstance'
66
116
  end
67
117
 
68
118
  # Manager Role
69
- role 'Application Centric Deployment Manager', [:create_app_definitions,
119
+ role 'Application Centric Deployment Manager', [:create_ansible_playbooks,
120
+ :view_ansible_playbooks,
121
+ :edit_ansible_playbooks,
122
+ :destroy_ansible_playbooks,
123
+ :import_vars_ansible_playbooks,
124
+ :create_app_definitions,
70
125
  :view_app_definitions,
71
126
  :edit_app_definitions,
72
- :destroy_app_definitions]
127
+ :destroy_app_definitions,
128
+ :export_app_definitions,
129
+ :import_app_definitions]
73
130
 
74
131
  # User Role
75
132
  role 'Application Centric Deployment User', [:create_app_instances,
76
133
  :view_app_instances,
77
134
  :edit_app_instances,
78
135
  :destroy_app_instances,
79
- :deploy_app_instances]
136
+ :deploy_app_instances,
137
+ :configure_app_instances,
138
+ :report_app_instances]
139
+
140
+ RemoteExecutionFeature.register(
141
+ :run_acd_ansible_playbook,
142
+ N_('Run playbook for ACD'),
143
+ {
144
+ :description => N_('Run an Ansible playbook to configure ACD application'),
145
+ :provided_inputs => %w[application_name playbook_name playbook_path inventory_path]
146
+ }
147
+ )
80
148
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ForemanAcd
4
- VERSION = '0.0.4'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_acd",
3
- "version": "0.0.4",
3
+ "version": "0.3.0",
4
4
  "description": "foreman application centric deployment",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -31,7 +31,6 @@
31
31
  "eslint-plugin-react": "^7.4.0",
32
32
  "identity-obj-proxy": "^3.0.0",
33
33
  "lodash": "^4.17.11",
34
- "patternfly-react": "^2.31.0",
35
34
  "jest": "^23.6.0",
36
35
  "jest-cli": "^23.6.0",
37
36
  "jest-prop-type-error": "^1.1.0",
@@ -0,0 +1,376 @@
1
+ import $ from 'jquery';
2
+ import React, { useState } from 'react'
3
+ import PropTypes from 'prop-types';
4
+ import {
5
+ Icon,
6
+ Button,
7
+ } from 'patternfly-react';
8
+ import * as resolve from 'table-resolver';
9
+ import ForemanModal from 'foremanReact/components/ForemanModal';
10
+ import Select from 'foremanReact/components/common/forms/Select';
11
+ import ParameterSelection from '../ParameterSelection';
12
+ import AddTableEntry from '../common/AddTableEntry';
13
+ import DeleteTableEntry from '../common/DeleteTableEntry';
14
+ import RailsData from '../common/RailsData';
15
+ import EasyHeaderFormatter from '../common/EasyHeaderFormatter';
16
+ import AnsiblePlaybookSelector from './components/AnsiblePlaybookSelector';
17
+
18
+ import {
19
+ Table,
20
+ FormControl,
21
+ inlineEditFormatterFactory,
22
+ } from 'patternfly-react';
23
+
24
+ import {
25
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
26
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
27
+ } from '../ParameterSelection/ParameterSelectionConstants';
28
+
29
+ class ApplicationDefinition extends React.Component {
30
+
31
+ constructor(props) {
32
+ super(props);
33
+ }
34
+
35
+ isEditing({rowData}) {
36
+ return (rowData.backup !== undefined);
37
+ }
38
+
39
+ createAnsibleGroupObject(ansibleGroups, withAll=false) {
40
+ const ansibleGroupObj = {};
41
+
42
+ const ansibleGroupArray = Object.keys(ansibleGroups);
43
+ ansibleGroupArray.forEach(e => (ansibleGroupObj[e] = e));
44
+
45
+ if ((withAll === false) && (ansibleGroupObj.hasOwnProperty('all'))) {
46
+ delete ansibleGroupObj.all;
47
+ }
48
+
49
+ return ansibleGroupObj;
50
+ }
51
+
52
+ componentDidMount() {
53
+ const {
54
+ data: { mode, ansiblePlaybook, ansibleDataUrl, services, ansibleVarsAll, hostgroups },
55
+ initApplicationDefinition,
56
+ addApplicationDefinitionService,
57
+ deleteApplicationDefinitionService,
58
+ activateEditApplicationDefinitionService,
59
+ changeEditApplicationDefinitionService,
60
+ openForemanParameterSelectionModal,
61
+ openAnsibleParameterSelectionModal,
62
+ loadAnsibleData,
63
+ } = this.props;
64
+
65
+ const inlineEditButtonsFormatter = inlineEditFormatterFactory({
66
+ isEditing: additionalData => this.props.editMode,
67
+ renderValue: (value, additionalData) => (
68
+ <td style={{ padding: '2px' }}>
69
+ <Button
70
+ bsStyle="default"
71
+ onClick={() => activateEditApplicationDefinitionService(additionalData)}
72
+ >
73
+ <Icon type="pf" name="edit" title="edit entry" />
74
+ </Button>
75
+ &nbsp;
76
+ <Button
77
+ bsStyle="default"
78
+ onClick={() => openForemanParameterSelectionModal(additionalData)}
79
+ >
80
+ <Icon type="pf" name="settings" title="change parameters" />
81
+ </Button>
82
+ &nbsp;
83
+ <Button
84
+ bsStyle="default"
85
+ onClick={() => openAnsibleParameterSelectionModal(additionalData)}
86
+ >
87
+ <span title="change ansible variables">A</span>
88
+ </Button>
89
+ <DeleteTableEntry
90
+ hidden={false}
91
+ disabled={false}
92
+ onDeleteTableEntry={deleteApplicationDefinitionService}
93
+ additionalData={additionalData}
94
+ />
95
+ </td>
96
+ ),
97
+ renderEdit: (value, additionalData) => (
98
+ <td style={{ padding: '2px' }}>
99
+ <Button bsStyle="default" disabled>
100
+ <Icon type="pf" name="edit" />
101
+ </Button>
102
+ &nbsp;
103
+ <Button bsStyle="default" disabled>
104
+ <Icon type="pf" name="settings" />
105
+ </Button>
106
+ &nbsp;
107
+ <Button
108
+ bsStyle="default" disabled>
109
+ <span>A</span>
110
+ </Button>
111
+ <DeleteTableEntry
112
+ hidden={false}
113
+ disabled={true}
114
+ onDeleteTableEntry={deleteApplicationDefinitionService}
115
+ additionalData={additionalData}
116
+ />
117
+ </td>
118
+ )
119
+ });
120
+ this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
121
+
122
+ this.headerFormatter = EasyHeaderFormatter;
123
+
124
+ const inlineEditFormatterImpl = {
125
+ renderValue: (value, additionalData) => (
126
+ <td>
127
+ <span className="static">{value}</span>
128
+ </td>
129
+ ),
130
+ renderEditText: (value, additionalData, subtype='text') => (
131
+ <td className="editing">
132
+ <FormControl
133
+ type={subtype}
134
+ defaultValue={value}
135
+ onBlur={e => changeEditApplicationDefinitionService(e.target.value, additionalData) }
136
+ />
137
+ </td>
138
+ ),
139
+ renderEditSelect: (value, additionalData, options) => (
140
+ <td className="editing">
141
+ <Select
142
+ value={value.toString()}
143
+ onChange={e => changeEditApplicationDefinitionService(e.target.value, additionalData) }
144
+ options={options}
145
+ allowClear
146
+ key="key"
147
+ />
148
+ </td>
149
+ )
150
+ };
151
+
152
+ const inlineEditFormatter = inlineEditFormatterFactory({
153
+ isEditing: additionalData => this.isEditing(additionalData),
154
+ renderValue: (value, additionalData) => {
155
+ let prettyValue = value;
156
+ if (additionalData.property == 'hostgroup') {
157
+ prettyValue = hostgroups[value];
158
+ }
159
+ else if (additionalData.property == 'ansibleGroup') {
160
+ const ag = this.createAnsibleGroupObject(this.props.ansiblePlaybook.groups);
161
+ prettyValue = ag[value];
162
+ }
163
+ return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
164
+ },
165
+ renderEdit: (value, additionalData) => {
166
+ if (additionalData.property == 'hostgroup') {
167
+ if (additionalData.rowData.newEntry === true) {
168
+ return inlineEditFormatterImpl.renderEditSelect(value, additionalData, hostgroups);
169
+ }
170
+ return inlineEditFormatterImpl.renderValue(hostgroups[value], additionalData)
171
+ }
172
+ else if (additionalData.property == 'ansibleGroup') {
173
+ const ag = this.createAnsibleGroupObject(this.props.ansiblePlaybook.groups);
174
+
175
+ if (additionalData.rowData.newEntry === true) {
176
+ return inlineEditFormatterImpl.renderEditSelect(value, additionalData, ag);
177
+ }
178
+ return inlineEditFormatterImpl.renderValue(ag[value], additionalData);
179
+ }
180
+ return inlineEditFormatterImpl.renderEditText(value, additionalData);
181
+ }
182
+ });
183
+ this.inlineEditFormatter = inlineEditFormatter;
184
+
185
+ initApplicationDefinition(
186
+ ansiblePlaybook,
187
+ services,
188
+ ansibleVarsAll,
189
+ this.headerFormatter,
190
+ this.inlineEditFormatter,
191
+ this.inlineEditButtonsFormatter,
192
+ );
193
+ };
194
+
195
+ render() {
196
+ const {
197
+ data: { organization, location, mode, ansiblePlaybooks, foremanDataUrl, ansibleDataUrl },
198
+ ansiblePlaybook,
199
+ services,
200
+ columns,
201
+ addApplicationDefinitionService,
202
+ confirmEditApplicationDefinitionService,
203
+ cancelEditApplicationDefinitionService,
204
+ closeForemanParameterSelectionModal,
205
+ openAnsibleParameterSelectionModal,
206
+ closeAnsibleParameterSelectionModal,
207
+ ParameterSelectionModal,
208
+ loadAnsibleData,
209
+ } = this.props;
210
+
211
+ return (
212
+ <span>
213
+ <div>
214
+ <AnsiblePlaybookSelector
215
+ label="Ansible Playbook"
216
+ editable={ mode == 'newDefinition' }
217
+ viewText={ ansiblePlaybook.name }
218
+ options={ ansiblePlaybooks }
219
+ onChange={ loadAnsibleData }
220
+ selectValue={ ansiblePlaybook.id.toString() }
221
+ additionalData={{url: ansibleDataUrl }}
222
+ />
223
+ </div>
224
+ <div className="form-group">
225
+ <AddTableEntry
226
+ hidden={ false }
227
+ disabled={ this.props.editMode }
228
+ onAddTableEntry={ addApplicationDefinitionService }
229
+ />
230
+ <Table.PfProvider
231
+ striped
232
+ bordered
233
+ hover
234
+ dataTable
235
+ inlineEdit
236
+ columns={columns}
237
+ components={{
238
+ body: {
239
+ row: Table.InlineEditRow,
240
+ cell: cellProps => cellProps.children
241
+ }
242
+ }}
243
+ >
244
+ <Table.Header headerRows={resolve.headerRows({ columns })} />
245
+ <Table.Body
246
+ rows={services}
247
+ rowKey="id"
248
+ onRow={(rowData, { rowIndex }) => ({
249
+ role: 'row',
250
+ isEditing: () => this.isEditing({ rowData }),
251
+ onCancel: () => cancelEditApplicationDefinitionService({ rowData, rowIndex }),
252
+ onConfirm: () => confirmEditApplicationDefinitionService({ rowData, rowIndex }),
253
+ last: rowIndex === services.length - 1
254
+ })}
255
+ />
256
+ </Table.PfProvider>
257
+ <AddTableEntry
258
+ hidden={ false }
259
+ disabled={ this.props.editMode }
260
+ onAddTableEntry={ addApplicationDefinitionService }
261
+ />
262
+ <span style={{ marginLeft: 30 }}>
263
+ Ansible group vars 'all':
264
+ <Button
265
+ style={{ marginLeft: 10 }}
266
+ bsStyle="default"
267
+ disabled={ this.props.editMode }
268
+ onClick={() => openAnsibleParameterSelectionModal({
269
+ isAllGroup: true
270
+ })}
271
+ >
272
+ <span title="change ansible variables for 'all'">A</span>
273
+ </Button>
274
+ </span>
275
+ </div>
276
+ <div>
277
+ <ForemanModal
278
+ id="AppDefinitionForemanParamSelection"
279
+ dialogClassName="param_selection_modal"
280
+ title="Foreman Parameter definition for Application Definition"
281
+ >
282
+ <ForemanModal.Header closeButton={false}>
283
+ Parameter definition
284
+ </ForemanModal.Header>
285
+ {this.props.parametersData ? (
286
+ <ParameterSelection
287
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN }
288
+ location={ location }
289
+ organization={ organization }
290
+ paramDataUrl= { foremanDataUrl }
291
+ data={ this.props.parametersData }
292
+ />
293
+ ) : (<span>Empty</span>)
294
+ }
295
+ <ForemanModal.Footer>
296
+ <div>
297
+ <Button bsStyle="primary" onClick={() => closeForemanParameterSelectionModal({ mode: 'save' })}>Save</Button>
298
+ <Button bsStyle="default" onClick={() => closeForemanParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
299
+ </div>
300
+ </ForemanModal.Footer>
301
+ </ForemanModal>
302
+ </div>
303
+ <div>
304
+ <ForemanModal
305
+ id="AppDefinitionAnsibleParamSelection"
306
+ dialogClassName="param_selection_modal"
307
+ title="Ansible variables for Application Definition"
308
+ >
309
+ <ForemanModal.Header closeButton={false}>
310
+ Parameter definition
311
+ </ForemanModal.Header>
312
+ {this.props.parametersData ? (
313
+ <ParameterSelection
314
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE }
315
+ location={ location }
316
+ organization={ organization }
317
+ data={ this.props.parametersData }
318
+ />
319
+ ) : (<span>Empty</span>)
320
+ }
321
+ <ForemanModal.Footer>
322
+ <div>
323
+ <Button bsStyle="primary" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'save' })}>Save</Button>
324
+ <Button bsStyle="default" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
325
+ </div>
326
+ </ForemanModal.Footer>
327
+ </ForemanModal>
328
+ </div>
329
+ <RailsData
330
+ key='applications_definition'
331
+ view='app_definition'
332
+ parameter='services'
333
+ value={JSON.stringify(this.props.services)}
334
+ />
335
+ <RailsData
336
+ key='applications_definition'
337
+ view='app_definition'
338
+ parameter='ansible_vars_all'
339
+ value={JSON.stringify(this.props.ansibleVarsAll)}
340
+ />
341
+ </span>
342
+ )};
343
+ }
344
+
345
+ ApplicationDefinition.defaultProps = {
346
+ error: {},
347
+ editMode: false,
348
+ ansiblePlaybook: { "id": '', "name": '' },
349
+ services: [],
350
+ ansibleVarsAll: [],
351
+ parametersData: {},
352
+ columns: [],
353
+ editParamsOfRowId: null,
354
+ }
355
+
356
+ ApplicationDefinition.propTypes = {
357
+ initApplicationDefinition: PropTypes.func,
358
+ editMode: PropTypes.bool.isRequired,
359
+ ansiblePlaybook: PropTypes.object,
360
+ services: PropTypes.array,
361
+ ansibleVarsAll: PropTypes.array,
362
+ columns: PropTypes.array,
363
+ addApplicationDefinitionService: PropTypes.func,
364
+ deleteApplicationDefinitionService: PropTypes.func,
365
+ activateEditApplicationDefinitionService: PropTypes.func,
366
+ confirmEditApplicationDefinitionService: PropTypes.func,
367
+ cancelEditApplicationDefinitionService: PropTypes.func,
368
+ changeEditApplicationDefinitionService: PropTypes.func,
369
+ openForemanParameterSelectionModal: PropTypes.func,
370
+ closeForemanParameterSelectionModal: PropTypes.func,
371
+ openAnsibleParameterSelectionModal: PropTypes.func,
372
+ closeAnsibleParameterSelectionModal: PropTypes.func,
373
+ parametersData: PropTypes.object,
374
+ };
375
+
376
+ export default ApplicationDefinition;