hybrid_platforms_conductor 32.13.2 → 32.16.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +8 -1
  4. data/bin/get_impacted_nodes +1 -1
  5. data/bin/setup +6 -1
  6. data/docs/plugins.md +1 -0
  7. data/docs/plugins/platform_handler/serverless_chef.md +111 -0
  8. data/lib/hybrid_platforms_conductor/cmd_runner.rb +13 -1
  9. data/lib/hybrid_platforms_conductor/connector.rb +4 -2
  10. data/lib/hybrid_platforms_conductor/deployer.rb +2 -1
  11. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +1 -1
  12. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +535 -0
  13. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +51 -0
  14. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +232 -0
  15. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +1 -0
  16. data/lib/hybrid_platforms_conductor/nodes_handler.rb +9 -5
  17. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  18. data/spec/hybrid_platforms_conductor_test.rb +3 -0
  19. data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +7 -0
  20. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +23 -0
  21. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +11 -0
  22. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +17 -0
  23. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +94 -0
  24. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +317 -0
  25. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +65 -0
  26. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +292 -0
  27. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +272 -0
  28. data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +1 -1
  29. data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +53 -0
  30. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/chef_versions.yml +3 -0
  31. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +14 -0
  32. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/policyfiles/test_policy.rb +3 -0
  33. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/chef_versions.yml +3 -0
  34. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/data_bags/my_bag/my_item.json +4 -0
  35. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +14 -0
  36. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/policyfiles/test_policy.rb +3 -0
  37. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/chef_versions.yml +3 -0
  38. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/after_run.rb +1 -0
  39. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/before_run.rb +1 -0
  40. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/nodes/node.json +10 -0
  41. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/policyfiles/test_policy.rb +3 -0
  42. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
  43. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +4 -0
  44. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb +1 -0
  45. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
  46. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
  47. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node1.json +10 -0
  48. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node2.json +10 -0
  49. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_1.rb +4 -0
  50. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_2.rb +4 -0
  51. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/config.rb +1 -0
  52. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
  53. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node1.json +10 -0
  54. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node2.json +10 -0
  55. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +4 -0
  56. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/default.rb +1 -0
  57. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
  58. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
  59. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_1.rb +4 -0
  60. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_2.rb +4 -0
  61. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/chef_versions.yml +3 -0
  62. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/local.json +10 -0
  63. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node1.json +10 -0
  64. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node2.json +10 -0
  65. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_1.rb +3 -0
  66. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_2.rb +3 -0
  67. metadata +192 -143
@@ -0,0 +1,51 @@
1
+ module HybridPlatformsConductor
2
+
3
+ module HpcPlugins
4
+
5
+ module PlatformHandler
6
+
7
+ class ServerlessChef < HybridPlatformsConductor::PlatformHandler
8
+
9
+ # Small class that can get a Ruby DSL file and return all DSL calls that have been made to it
10
+ class DslParser
11
+
12
+ # List of calls made by parsing the source file
13
+ # Array
14
+ attr_reader :calls
15
+
16
+ # Constructor
17
+ #
18
+ # Parameters::
19
+ # * *calls* (Array): List of calls to complement [default = []]
20
+ def initialize(calls = [])
21
+ @calls = calls
22
+ end
23
+
24
+ # Parse a file and get all its DSL calls
25
+ #
26
+ # Parameters::
27
+ # * *source* (String): File to parse
28
+ def parse(source)
29
+ instance_eval(File.read(source))
30
+ end
31
+
32
+ def method_missing(method_name, *args, &block)
33
+ sub_calls = []
34
+ @calls << {
35
+ method: method_name,
36
+ args: args,
37
+ block: block,
38
+ calls_on_result: sub_calls
39
+ }
40
+ DslParser.new(sub_calls)
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,232 @@
1
+ require 'hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser'
2
+
3
+ module HybridPlatformsConductor
4
+
5
+ module HpcPlugins
6
+
7
+ module PlatformHandler
8
+
9
+ class ServerlessChef < HybridPlatformsConductor::PlatformHandler
10
+
11
+ # Build the recipes tree from a ServerlessChef platform
12
+ class RecipesTreeBuilder
13
+
14
+ # Constructor
15
+ #
16
+ # Parameters::
17
+ # * *config* (Config): Configuration that can be used to tune tree building
18
+ # * *platform* (ServerlessChef): Platform for which we build the recipes tree
19
+ def initialize(config, platform)
20
+ @config = config
21
+ @platform = platform
22
+ end
23
+
24
+ # Get the whole tree of recipes
25
+ #
26
+ # Result::
27
+ # * The tree of recipes:
28
+ # Hash< Symbol, Hash< Symbol, Hash<Symbol,Object> >
29
+ # Hash< cookbook, Hash< recipe, recipe_info >
30
+ # Each recipe info has the following attributes:
31
+ # * *included_recipes* (Array< [String or nil, Symbol, Symbol] >): List of [cookbook_dir, cookbook, recipe] included by this recipe
32
+ # * *used_by_policies* (Array<String>): List of policies that include (recursively) this recipe
33
+ # * *used_templates* (Array<String>): List of template sources used by this recipe
34
+ # * *used_files* (Array<String>): List of cookbook files used by this recipe
35
+ # * *used_cookbooks* (Array<Symbol>): List of additional used cookbooks (for example for resources)
36
+ def full_recipes_tree
37
+ @recipes_tree = {}
38
+ @platform.deployable_services.each do |service|
39
+ @platform.policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
40
+ add_recipe_in_tree(cookbook_dir, cookbook, recipe)
41
+ end
42
+ end
43
+ @platform.deployable_services.each do |service|
44
+ @platform.policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
45
+ mark_recipe_used_by_policy(cookbook, recipe, service)
46
+ end
47
+ end
48
+ @recipes_tree
49
+ end
50
+
51
+ private
52
+
53
+ # Fill the tree with a recipe and all its dependencies
54
+ #
55
+ # Parameters::
56
+ # * *cookbook_dir* (String): The cookbook directory, or nil if unknown
57
+ # * *cookbook* (Symbol): The cookbook name
58
+ # * *recipe* (Symbol): The recipe name
59
+ def add_recipe_in_tree(cookbook_dir, cookbook, recipe)
60
+ @recipes_tree[cookbook] = {} unless @recipes_tree.key?(cookbook)
61
+ unless @recipes_tree[cookbook].key?(recipe)
62
+ recipe_info =
63
+ if cookbook_dir.nil?
64
+ # This recipe comes from an external cookbook, we won't get into it.
65
+ {
66
+ included_recipes: [],
67
+ used_templates: [],
68
+ used_files: [],
69
+ used_cookbooks: []
70
+ }
71
+ else
72
+ recipe_usage(cookbook_dir, cookbook, recipe)
73
+ end
74
+ @recipes_tree[cookbook][recipe] = recipe_info.merge(
75
+ used_by_policies: []
76
+ )
77
+ recipe_info[:included_recipes].each do |(sub_cookbook_dir, sub_cookbook, sub_recipe)|
78
+ add_recipe_in_tree(sub_cookbook_dir, sub_cookbook, sub_recipe)
79
+ end
80
+ end
81
+ end
82
+
83
+ # Get some info on a given recipe.
84
+ # Parses for:
85
+ # * include_recipe.
86
+ # * source of template and cookbook_file.
87
+ # * Any library helper we know use some recipes.
88
+ # * Any resource we have defined in other cookbooks.
89
+ # * Any library method we have defined in other cookbooks.
90
+ #
91
+ # Parameters::
92
+ # * *cookbook_dir* (String): The cookbook directory
93
+ # * *cookbook* (Symbol): The cookbook name
94
+ # * *recipe* (Symbol): The recipe name
95
+ # Result::
96
+ # * Hash<Symbol,Object>: A structure describing the recipe:
97
+ # * *included_recipes* (Array< [String, Symbol, Symbol] >): List of tuples [cookbook_dir, cookbook, recipe] used by this recipe
98
+ # * *used_templates* (Array<String>): List of template sources used by this recipe
99
+ # * *used_files* (Array<String>): List of cookbook files used by this recipe
100
+ # * *used_cookbooks* (Array<String>): List of additional cookbooks used by this recipe
101
+ def recipe_usage(cookbook_dir, cookbook, recipe)
102
+ recipe_content = File.read("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/recipes/#{recipe}.rb")
103
+ # Check for include_recipe
104
+ used_recipes = recipe_content.
105
+ scan(/include_recipe\s+["'](\w+(::\w+)?)["']/).
106
+ map { |(recipe_def, _sub_grp)| @platform.decode_recipe(recipe_def) }
107
+ # Check for some helpers we know include some recipes
108
+ @config.known_helpers_including_recipes.each do |helper_name, used_recipes_by_helper|
109
+ if recipe_content =~ Regexp.new(/(\W|^)#{Regexp.escape(helper_name)}(\W|$)/)
110
+ used_recipes.concat(used_recipes_by_helper.map { |recipe_def| @platform.decode_recipe(recipe_def) })
111
+ used_recipes.uniq!
112
+ end
113
+ end
114
+ sources = []
115
+ recipe_content.
116
+ scan(/source\s+(["'])(.+?)\1/).
117
+ each do |(_sub_grp, source)|
118
+ sources << source unless source =~ /^https?:\/\//
119
+ end
120
+ erb_sources = sources.select { |source| File.extname(source).downcase == '.erb' }
121
+ non_erb_sources = sources - erb_sources
122
+ erb_sources.concat(recipe_content.scan(/template:?\s+(["'])(.+?)\1/).map { |(_sub_grp, source)| source })
123
+ # Check for known resources and library methods
124
+ used_cookbooks = []
125
+ known_resources.each do |cookbook, methods|
126
+ used_cookbooks << cookbook if methods.any? { |method_name| recipe_content.include?(method_name) }
127
+ end
128
+ known_library_methods.each do |cookbook, methods|
129
+ used_cookbooks << cookbook if methods.any? { |method_name| recipe_content.include?(method_name) }
130
+ end
131
+ {
132
+ included_recipes: used_recipes,
133
+ used_templates: erb_sources,
134
+ used_files: non_erb_sources,
135
+ used_cookbooks: used_cookbooks.uniq
136
+ }
137
+ end
138
+
139
+ # Get the user defined resources, per cookbook.
140
+ # Keep a memory cache of it.
141
+ #
142
+ # Result::
143
+ # * Hash< Symbol, Array<String> >: List of resource names (as useable methods), per cookbook
144
+ def known_resources
145
+ unless defined?(@known_resources)
146
+ @known_resources = {}
147
+ for_each_cookbook do |cookbook, cookbook_dir|
148
+ if File.exist?("#{cookbook_dir}/resources")
149
+ @known_resources[cookbook] = Dir.glob("#{cookbook_dir}/resources/*.rb").map do |resource_file|
150
+ "#{cookbook}_#{File.basename(resource_file, '.rb')}"
151
+ end
152
+ end
153
+ end
154
+ end
155
+ @known_resources
156
+ end
157
+
158
+ # Get the list of library methods we know we have to ignore from the parsing
159
+ # Array<String>
160
+ INVALID_LIBRARY_METHODS = [
161
+ 'initialize'
162
+ ]
163
+
164
+ # Get the user defined library methods, per cookbook.
165
+ # Keep a memory cache of it.
166
+ #
167
+ # Result::
168
+ # * Hash< Symbol, Array<String> >: List of library method names, per cookbook
169
+ def known_library_methods
170
+ unless defined?(@known_library_methods)
171
+ @known_library_methods = {}
172
+ for_each_cookbook do |cookbook, cookbook_dir|
173
+ if File.exist?("#{cookbook_dir}/libraries")
174
+ found_methods = Dir.glob("#{cookbook_dir}/libraries/*.rb").
175
+ map { |lib_file| File.read(lib_file).scan(/\bdef\s+(\w+)\b/).map { |(method_name)| method_name } }.
176
+ flatten - INVALID_LIBRARY_METHODS
177
+ @known_library_methods[cookbook] = found_methods unless found_methods.empty?
178
+ end
179
+ end
180
+ end
181
+ @known_library_methods
182
+ end
183
+
184
+ # Iterate over all cookbooks
185
+ #
186
+ # Parameters::
187
+ # * Proc: Code called for each cookbook:
188
+ # * Parameters::
189
+ # * *cookbook* (Symbol): Cookbook name
190
+ # * *cookbook_dir* (String): Cookbook directory
191
+ def for_each_cookbook
192
+ @platform.known_cookbook_paths.each do |cookbook_path|
193
+ cookbooks_in(cookbook_path).each do |cookbook, cookbook_dir|
194
+ yield cookbook, cookbook_dir
195
+ end
196
+ end
197
+ end
198
+
199
+ # Get the list of cookbooks of a given cookbook type
200
+ #
201
+ # Parameters::
202
+ # * *cookbook_type* (String): The cookbook type (like site-cookbook)
203
+ # Result::
204
+ # * Hash<Symbol, String>: List of cookbook directories, per cookbook name
205
+ def cookbooks_in(cookbook_type)
206
+ Hash[Dir.glob("#{@platform.repository_path}/#{cookbook_type}/*").map { |dir| [File.basename(dir).to_sym, dir] }.sort]
207
+ end
208
+
209
+ # Mark a recipe (and its included recipes) as used by a policy
210
+ #
211
+ # Parameters::
212
+ # * *cookbook* (Symbol): The cookbook
213
+ # * *recipe* (Symbol): The recipe
214
+ # * *used_by_policy* (String): The policy using this recipe
215
+ def mark_recipe_used_by_policy(cookbook, recipe, used_by_policy)
216
+ unless @recipes_tree[cookbook][recipe][:used_by_policies].include?(used_by_policy)
217
+ @recipes_tree[cookbook][recipe][:used_by_policies] << used_by_policy
218
+ @recipes_tree[cookbook][recipe][:included_recipes].each do |(_sub_cookbook_dir, sub_cookbook, sub_recipe)|
219
+ mark_recipe_used_by_policy(sub_cookbook, sub_recipe, used_by_policy)
220
+ end
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+ end
227
+
228
+ end
229
+
230
+ end
231
+
232
+ end
@@ -73,6 +73,7 @@ module HybridPlatformsConductor
73
73
  end
74
74
  end
75
75
  cmds = <<~EOS
76
+ set -e
76
77
  #{
77
78
  case image
78
79
  when :centos_7
@@ -269,12 +269,16 @@ module HybridPlatformsConductor
269
269
  #
270
270
  # Parameters::
271
271
  # * *node* (String): Node
272
- # * *property* (Symbol): The property name
272
+ # * *property* (Symbol or nil): The property name, or nil for all [default=nil]
273
273
  # Result::
274
- # * Object or nil: The node's metadata value for this property, or nil if none
275
- def metadata_of(node, property)
276
- prefetch_metadata_of([node], property) unless @metadata.key?(node) && @metadata[node].key?(property)
277
- @metadata[node][property]
274
+ # * Object or nil: The node's metadata value for this property, or nil if none, or a Hash of metadata if property was nil
275
+ def metadata_of(node, property = nil)
276
+ if property.nil?
277
+ @metadata[node] || {}
278
+ else
279
+ prefetch_metadata_of([node], property) unless @metadata.key?(node) && @metadata[node].key?(property)
280
+ @metadata[node][property]
281
+ end
278
282
  end
279
283
 
280
284
  # Override a metadata property for a given node
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '32.13.2'
3
+ VERSION = '32.16.0'
4
4
 
5
5
  end
@@ -35,6 +35,7 @@ require 'hybrid_platforms_conductor_test/helpers/platforms_handler_helpers'
35
35
  require 'hybrid_platforms_conductor_test/helpers/plugins_helpers'
36
36
  require 'hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers'
37
37
  require 'hybrid_platforms_conductor_test/helpers/reports_handler_helpers'
38
+ require 'hybrid_platforms_conductor_test/helpers/serverless_chef_helpers'
38
39
  require 'hybrid_platforms_conductor_test/helpers/services_handler_helpers'
39
40
  require 'hybrid_platforms_conductor_test/helpers/tests_runner_helpers'
40
41
  require 'hybrid_platforms_conductor_test/platform_handler_plugins/test'
@@ -69,6 +70,7 @@ module HybridPlatformsConductorTest
69
70
  include PluginsHelpers
70
71
  include ProvisionerProxmoxHelpers
71
72
  include ReportsHandlerHelpers
73
+ include ServerlessChefHelpers
72
74
  include ServicesHandlerHelpers
73
75
  include TestsRunnerHelpers
74
76
 
@@ -95,6 +97,7 @@ module HybridPlatformsConductorTest
95
97
  ENV.delete 'hpc_domain_for_thycotic'
96
98
  ENV.delete 'hpc_certificates'
97
99
  ENV.delete 'hpc_interactive'
100
+ ENV.delete 'hpc_test_cookbooks_path'
98
101
  # Set the necessary Hybrid Platforms Conductor environment variables
99
102
  ENV['hpc_ssh_user'] = 'test_user'
100
103
  HybridPlatformsConductor::ServicesHandler.packaged_deployments.clear
@@ -13,6 +13,13 @@ describe HybridPlatformsConductor::CmdRunner do
13
13
  end
14
14
  end
15
15
 
16
+ it 'runs a simple bash command and forces usage of bash' do
17
+ with_repository do |repository|
18
+ # Use set -o pipefail that does not work in /bin/sh
19
+ expect(test_cmd_runner.run_cmd "set -o pipefail ; echo TestStderr 1>&2 ; echo TestStdout", force_bash: true).to eq [0, "TestStdout\n", "TestStderr\n"]
20
+ end
21
+ end
22
+
16
23
  it 'runs a simple bash command and logs stdout and stderr to a file' do
17
24
  with_repository do |repository|
18
25
  test_cmd_runner.run_cmd "echo TestStderr 1>&2 ; sleep 1 ; echo TestStdout", log_to_file: "#{repository}/test_file"
@@ -84,6 +84,29 @@ describe HybridPlatformsConductor::Deployer do
84
84
  end
85
85
  end
86
86
 
87
+ it 'gives a new test instance ready to be used in place of the node without local node' do
88
+ with_test_platform(
89
+ {
90
+ nodes: {
91
+ 'node1' => { meta: { local_node: true } },
92
+ 'node2' => { meta: { local_node: true } }
93
+ }
94
+ }
95
+ ) do |repository|
96
+ register_plugins(:provisioner, { test_provisioner: HybridPlatformsConductorTest::TestProvisioner })
97
+ File.write("#{test_config.hybrid_platforms_dir}/dummy_secrets.json", '{}')
98
+ HybridPlatformsConductorTest::TestProvisioner.mocked_states = %i[created created running exited]
99
+ HybridPlatformsConductorTest::TestProvisioner.mocked_ip = '172.17.0.1'
100
+ expect(Socket).to receive(:tcp).with('172.17.0.1', 22, { connect_timeout: 1 }) do |&block|
101
+ block.call
102
+ end
103
+ test_deployer.with_test_provisioned_instance(:test_provisioner, 'node1', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
104
+ expect(sub_test_deployer.instance_eval { @nodes_handler.get_local_node_of('node1') }).to eq false
105
+ expect(sub_test_deployer.instance_eval { @nodes_handler.get_local_node_of('node2') }).to eq true
106
+ end
107
+ end
108
+ end
109
+
87
110
  it 'gives a new test instance ready to be used in place of the node without sudo specificities' do
88
111
  with_test_platform(
89
112
  {
@@ -38,6 +38,17 @@ describe HybridPlatformsConductor::NodesHandler do
38
38
  end
39
39
  end
40
40
 
41
+ it 'returns nodes currently known metadata using generic method' do
42
+ with_cmdb_test_platform do
43
+ test_nodes_handler.metadata_of('node1', :upcase)
44
+ test_nodes_handler.get_double_of('node1')
45
+ expect(test_nodes_handler.metadata_of('node1')).to eq(
46
+ double: 'node1node1',
47
+ upcase: 'NODE1'
48
+ )
49
+ end
50
+ end
51
+
41
52
  it 'returns nodes metadata using dynamic method several times (as the method is created dynamically)' do
42
53
  with_cmdb_test_platform do
43
54
  3.times { expect(test_nodes_handler.get_upcase_of('node1')).to eq 'NODE1' }
@@ -0,0 +1,17 @@
1
+ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
2
+
3
+ context 'checking config DSL' do
4
+
5
+ it 'defines helpers that include recipes' do
6
+ with_repository do |repository|
7
+ with_platforms('helpers_including_recipes(my_helper: [\'cookbook1::recipe1\', \'cookbook2\'])') do
8
+ expect(test_config.known_helpers_including_recipes).to eq(
9
+ my_helper: %w[cookbook1::recipe1 cookbook2]
10
+ )
11
+ end
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,94 @@
1
+ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
2
+
3
+ context 'checking how deployment output is parsed' do
4
+
5
+ it 'parses a deployment output properly' do
6
+ with_serverless_chef_platforms('empty') do |platform|
7
+ stdout = <<~EOS
8
+ Starting Chef Client, version 14.14.29
9
+ resolving cookbooks for run list: ["policy_xae_websql::xae"]
10
+ Synchronizing Cookbooks:
11
+ - policy_xae_websql (0.1.0)
12
+ - chef-ruby (0.1.2)
13
+ - nginx (10.1.0)
14
+ Installing Cookbook Gems:
15
+ Compiling Cookbooks...
16
+ Recipe: site_debian::default
17
+ * apt_update[apt update] action update
18
+ - force update new lists of packages
19
+ * directory[/etc/apt/apt.conf.d] action create (up to date)
20
+ * file[/etc/apt/apt.conf.d/15update-stamp] action create_if_missing (up to date)
21
+ * execute[apt-get -q update] action run
22
+ - execute ["apt-get", "-q", "update"]
23
+
24
+ Converging 145 resources
25
+ Recipe: policy_xae_websql::api
26
+ * site_artifactory_dpkg_package[xaecalcite] action install
27
+ * remote_file[/opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb] action create
28
+ - create new file /opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb
29
+ - update content in file /opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb from none to 39b0ca
30
+ (file sizes exceed 10000000 bytes, diff output suppressed)
31
+ * dpkg_package[xaecalcite] action install
32
+ - install version 0.2.4-1 of package xaecalcite
33
+
34
+ * service[/var/lib/xaecalcite/xaecalcite.service] action enable (skipped due to not_if)
35
+
36
+ Running handlers:
37
+ Running handlers complete
38
+ Chef Client finished, 16/300 resources updated in 27 seconds
39
+ EOS
40
+ expect(platform.parse_deploy_output(stdout, '')). to eq [
41
+ {
42
+ action: 'update',
43
+ diffs: "force update new lists of packages\n",
44
+ name: 'apt_update[apt update]',
45
+ status: :changed
46
+ },
47
+ {
48
+ action: 'create (up to date)',
49
+ name: 'directory[/etc/apt/apt.conf.d]',
50
+ status: :identical
51
+ },
52
+ {
53
+ action: 'create_if_missing (up to date)',
54
+ name: 'file[/etc/apt/apt.conf.d/15update-stamp]',
55
+ status: :identical
56
+ },
57
+ {
58
+ action: 'run',
59
+ diffs: "execute [\"apt-get\", \"-q\", \"update\"]\n",
60
+ name: 'execute[apt-get -q update]',
61
+ status: :changed
62
+ },
63
+ {
64
+ action: 'install',
65
+ name: 'site_artifactory_dpkg_package[xaecalcite]',
66
+ status: :identical
67
+ },
68
+ {
69
+ action: 'create',
70
+ diffs: <<~EOS,
71
+ create new file /opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb
72
+ update content in file /opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb from none to 39b0ca
73
+ EOS
74
+ name: 'remote_file[/opt/chef_cache/xaecalcite_0.2.4-1_amd64.deb]',
75
+ status: :changed
76
+ },
77
+ {
78
+ action: 'install',
79
+ diffs: "install version 0.2.4-1 of package xaecalcite\n",
80
+ name: 'dpkg_package[xaecalcite]',
81
+ status: :changed
82
+ },
83
+ {
84
+ action: 'enable (skipped due to not_if)',
85
+ name: 'service[/var/lib/xaecalcite/xaecalcite.service]',
86
+ status: :identical
87
+ }
88
+ ]
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end