hybrid_platforms_conductor 33.8.3 → 33.9.2

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/bin/nodes_to_deploy +19 -9
  4. data/docs/config_dsl.md +10 -4
  5. data/lib/hybrid_platforms_conductor/deployer.rb +7 -1
  6. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +1 -1
  7. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +94 -2
  8. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +4 -18
  9. data/lib/hybrid_platforms_conductor/platform_handler.rb +17 -7
  10. data/lib/hybrid_platforms_conductor/platforms_handler.rb +9 -7
  11. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  12. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +44 -0
  13. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +9 -4
  14. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +53 -0
  15. data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +43 -13
  16. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +75 -0
  17. data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +4 -2
  18. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +2 -1
  19. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/metadata.rb +13 -0
  20. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/31_unknown_recipe_include.rb +2 -0
  21. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/32_unknown_cookbook_include.rb +2 -0
  22. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/33_unknown_include.rb +3 -0
  23. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/34_known_include.rb +1 -0
  24. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/35_unparsable_include.rb +7 -0
  25. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_1.rb +1 -0
  26. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_2.rb +1 -0
  27. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_3.rb +1 -0
  28. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_4.rb +1 -0
  29. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_1.rb +1 -0
  30. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_2.rb +1 -0
  31. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node31.json +10 -0
  32. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node32.json +10 -0
  33. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node33.json +10 -0
  34. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node34.json +10 -0
  35. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node35.json +10 -0
  36. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_31.rb +4 -0
  37. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_32.rb +4 -0
  38. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_33.rb +4 -0
  39. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_34.rb +4 -0
  40. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_35.rb +4 -0
  41. data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +2 -2
  42. data/spec/hybrid_platforms_conductor_test.rb +1 -0
  43. metadata +24 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80a9228f00ac63d2ddf325f1fd4faeab83af8d7bbf73c43ff46d4632883462a4
4
- data.tar.gz: 225b174fb0107a743e4daeda8a65148b8ce7d0ea81fb0862066a3626e60b7571
3
+ metadata.gz: 2a6b91bf179fa45f605d1b08d8c21cced9547c0588139b1998fca01a19f75abe
4
+ data.tar.gz: 5372e49247ba48adf64eed5a9fe3cc5aff5b2e82be8bc834a2283f815cc4c928
5
5
  SHA512:
6
- metadata.gz: cc3c6a8c0a245a1929481f2e5482fdc3b9100dc24dab7a98bfbc026a294a8ef88b359060608cafb5c9937197ad89fc39630e3b56265888f5c913be9435960a3b
7
- data.tar.gz: c82665286ed8c6783b02640e4122eb08d555c0d04fecbc49a688194caf828144f63f243824e28be8a120f41a331cd5194497b9ede07630d9347e8888383187b9
6
+ metadata.gz: a1d886444be942a74153cb834e450b8062356959aaca508e10186bcb444f63295f8fc198b3e49f94babbbb7b6315bed146c1a29c21ab23d9112de94971e18d11
7
+ data.tar.gz: 31640de82a155dc42128926683fe7ded34039bad1cb639ff6bb8d4571f7f01a191f2103ea6a01c3de60322dc67015e92c833a0e8597b10bb3d6030e10199a864
data/CHANGELOG.md CHANGED
@@ -1,3 +1,51 @@
1
+ # [v33.9.2](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.9.1...v33.9.2) (2021-09-01 17:46:34)
2
+
3
+ ## Global changes
4
+ ### Patches
5
+
6
+ * [[Fix(nodes_to_deploy)] [#112] Support UTF-8 encoding from log files](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/26a7bd2fd53d387bd972b5e1b60cac9be6541ce5)
7
+
8
+ ## Changes for nodes_to_deploy
9
+ ### Patches
10
+
11
+ * [[Fix(nodes_to_deploy)] [#112] Support UTF-8 encoding from log files](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/26a7bd2fd53d387bd972b5e1b60cac9be6541ce5)
12
+
13
+ # [v33.9.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.9.0...v33.9.1) (2021-09-01 16:59:59)
14
+
15
+ ## Global changes
16
+ ### Patches
17
+
18
+ * [[Fix(nodes_to_deploy)] [#110] Make sure unknown platforms are taken into account when detecting nodes to be deployed](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/c1b8312c5d473a1c5d044f6cda3ad9bed2b3ca61)
19
+
20
+ ## Changes for nodes_to_deploy
21
+ ### Patches
22
+
23
+ * [[Fix(nodes_to_deploy)] [#110] Make sure unknown platforms are taken into account when detecting nodes to be deployed](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/c1b8312c5d473a1c5d044f6cda3ad9bed2b3ca61)
24
+
25
+ # [v33.9.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.4...v33.9.0) (2021-08-24 13:15:44)
26
+
27
+ ## Global changes
28
+ ### Patches
29
+
30
+ * [[Feature(platform_handler)] [#102] Add the name option when declaring platforms to set the platform name](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/13ada7687f08b3f970521320e2b26ea42d9a6d7f)
31
+
32
+ ## Changes for platform_handler
33
+ ### Features
34
+
35
+ * [[Feature(platform_handler)] [#102] Add the name option when declaring platforms to set the platform name](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/13ada7687f08b3f970521320e2b26ea42d9a6d7f)
36
+
37
+ # [v33.8.4](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.3...v33.8.4) (2021-08-20 15:45:41)
38
+
39
+ ## Global changes
40
+ ### Patches
41
+
42
+ * [[Fix(platform_handler_serverless_chef)] [#99] Make sure dynamic or unparsable cookbook/recipe names are considered using metadata for recipes dependencies](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d7feb24881f04cd3f31bc1e41712dfc4cfe715f)
43
+
44
+ ## Changes for platform_handler_serverless_chef
45
+ ### Patches
46
+
47
+ * [[Fix(platform_handler_serverless_chef)] [#99] Make sure dynamic or unparsable cookbook/recipe names are considered using metadata for recipes dependencies](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d7feb24881f04cd3f31bc1e41712dfc4cfe715f)
48
+
1
49
  # [v33.8.3](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.2...v33.8.3) (2021-08-16 14:18:52)
2
50
 
3
51
  ## Global changes
data/bin/nodes_to_deploy CHANGED
@@ -17,6 +17,7 @@ executable = HybridPlatformsConductor::Executable.new(deploy_options: false) do
17
17
  end
18
18
  end
19
19
  nodes_handler = executable.nodes_handler
20
+ platforms_handler = executable.platforms_handler
20
21
  deployer = executable.deployer
21
22
 
22
23
  executable.parse_options!
@@ -72,20 +73,29 @@ unless ignore_deploy_info
72
73
  commit_id = node_deploy_info[:deployment_info]["commit_id_#{repo_idx}".to_sym]
73
74
  impacted_nodes = cache_impacted_nodes.dig(repo_name, commit_id)
74
75
  if impacted_nodes.nil?
75
- begin
76
- impacted_nodes, _single_impacted_nodes, _impacted_services, _impact_global = nodes_handler.impacted_nodes_from_git_diff(
77
- repo_name,
78
- from_commit: commit_id,
79
- to_commit: 'master'
80
- )
81
- rescue HybridPlatformsConductor::NodesHandler::GitError
82
- # Consider the node was deployed with a non-release branch commit (as it is missing)
76
+ if platforms_handler.platform(repo_name)
77
+ begin
78
+ impacted_nodes, _single_impacted_nodes, _impacted_services, _impact_global = nodes_handler.impacted_nodes_from_git_diff(
79
+ repo_name,
80
+ from_commit: commit_id,
81
+ to_commit: 'master'
82
+ )
83
+ rescue HybridPlatformsConductor::NodesHandler::GitError
84
+ # Consider the node was deployed with a non-release branch commit (as it is missing)
85
+ # So we have to make sure we deploy it again
86
+ executable.log_warn "[ #{node} ] - Unknown commit ID from deployment logs: #{repo_name} / #{commit_id}."
87
+ impacted_nodes = :unknown
88
+ end
89
+ else
90
+ # Consider the node was deployed with an obdsolete platform (as it is unknown)
83
91
  # So we have to make sure we deploy it again
84
- impacted_nodes = [node]
92
+ executable.log_warn "[ #{node} ] - Unknown platform from deployment logs: #{repo_name}."
93
+ impacted_nodes = :unknown
85
94
  end
86
95
  cache_impacted_nodes[repo_name] = {} unless cache_impacted_nodes.key?(repo_name)
87
96
  cache_impacted_nodes[repo_name][commit_id] = impacted_nodes
88
97
  end
98
+ impacted_nodes = [node] if impacted_nodes == :unknown
89
99
  if impacted_nodes.include?(node)
90
100
  executable.log_debug "[ #{node} ] - Diffs on #{repo_name} between #{commit_id} and master are impacting this node."
91
101
  node_impacted = true
data/docs/config_dsl.md CHANGED
@@ -28,19 +28,25 @@ This DSL can also be completed by plugins. Check [the plugins documentations](pl
28
28
  Declare a new platform of type `<platform_type>`, providing either a local path to it (using `path: '/path/to/files'`) or a git repository to it (using `git: 'git_url'`). The possible platform types are the names of the [`platform_handler` plugins](plugins.md#platform_handler).
29
29
 
30
30
  Git branches can also be specified using `branch: 'branch_name'`.
31
+
32
+ The name of the platform (as used for example by the [`for_nodes`](#for_nodes) DSL) defaults to the base name of the directory in case of a local path, or the base name of the first remote in case of a git repository. It can be enforced to a given name using `name: 'platform_name'` (useful to avoid name conflicts and keep consistency with the rest of your configuration among the team).
33
+
31
34
  An optional code block taking the local repository path as parameter can also be specified to add configuration that is specific to this platform.
32
35
 
33
36
  Examples:
34
37
  ```ruby
35
- # Declare a platform of type Chef, located in a distant git repository
38
+ # Declare a platform of type Chef, located in a distant git repository (its name will be my-chef-repo)
36
39
  chef_platform git: 'https://my-git.domain.com/project/my-chef-repo.git'
37
40
 
38
- # Declare a platform located in a local path
39
- chef_platform path: '/path/to/my-chef-repo'
41
+ # Declare a platform located in a local path (its name will be my-other-chef-repo)
42
+ chef_platform path: '/path/to/my-other-chef-repo'
43
+
44
+ # Declare a platform located in a local path and forces its name (its name will be my-platform)
45
+ chef_platform path: '/path/to/my-repo', name: 'my-platform'
40
46
 
41
47
  # Declare a platform from a git branch, and apply some configuration to it
42
48
  chef_platform(
43
- git: 'https://my-git.domain.com/project/my-chef-repo.git',
49
+ git: 'https://my-git.domain.com/project/devops-chef-repo.git',
44
50
  branch: 'my-branch'
45
51
  ) do |path|
46
52
  # Here path will be a local path containing a checkout of the branch my-branch of the git repo.
@@ -475,9 +475,15 @@ module HybridPlatformsConductor
475
475
  progress_name: 'Read deployment logs'
476
476
  )
477
477
  nodes.map do |node|
478
+ exit_code, stdout, stderr = read_actions_results[node] || [nil, nil, nil]
478
479
  [
479
480
  node,
480
- @log_plugins[log_plugins_for(node).first].logs_for(node, *(read_actions_results[node] || [nil, nil, nil]))
481
+ @log_plugins[log_plugins_for(node).first].logs_for(
482
+ node,
483
+ exit_code,
484
+ stdout&.force_encoding(Encoding::UTF_8),
485
+ stderr&.force_encoding(Encoding::UTF_8)
486
+ )
481
487
  ]
482
488
  end.to_h
483
489
  end
@@ -26,7 +26,7 @@ module HybridPlatformsConductor
26
26
  # Parameters::
27
27
  # * *source* (String): File to parse
28
28
  def parse(source)
29
- instance_eval(File.read(source))
29
+ instance_eval(File.read(source), source)
30
30
  end
31
31
 
32
32
  # Intercept all missing methods
@@ -105,8 +105,59 @@ module HybridPlatformsConductor
105
105
  recipe_content = File.read("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/recipes/#{recipe}.rb")
106
106
  # Check for include_recipe
107
107
  used_recipes = recipe_content.
108
- scan(/include_recipe\s+["'](\w+(::\w+)?)["']/).
109
- map { |(recipe_def, _sub_grp)| @platform.decode_recipe(recipe_def) }
108
+ scan(/include_recipe(\((.+)\)|\s+(.+)|\((.*))$/).
109
+ map do |(_match, match_1, match_2, match_3)|
110
+ case match_1 || match_2 || match_3
111
+ when /^["']([^:'"]+(::[^'"]+)?)["']$/
112
+ # The recipe definition is given in a String
113
+ used_cookbook, used_recipe = Regexp.last_match(1).split('::')
114
+ used_recipe = 'default' if used_recipe.nil?
115
+ if used_cookbook =~ /^\w+$/
116
+ # Find the cookbook it belongs to
117
+ used_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{used_cookbook}") }
118
+ if used_recipe =~ /^\w+$/
119
+ # Check that the recipe exists if we know the cookbook dir
120
+ raise "Unknown recipe #{used_cookbook}::#{used_recipe} from cookbook #{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}." if !used_cookbook_dir.nil? && !File.exist?("#{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}/recipes/#{used_recipe}.rb")
121
+
122
+ [
123
+ [used_cookbook_dir, used_cookbook.to_sym, used_recipe.to_sym]
124
+ ]
125
+ elsif used_cookbook_dir
126
+ # We are dealing with a dynamically named recipe.
127
+ # Return all recipes of the cookbook if we know the cookbook dir
128
+ Dir.glob("#{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}/recipes/*.rb").map do |used_recipe_file_path|
129
+ [
130
+ used_cookbook_dir,
131
+ used_cookbook.to_sym,
132
+ File.basename(used_recipe_file_path, '.rb').to_sym
133
+ ]
134
+ end
135
+ else
136
+ # We are dealing with a dynamically named recipe.
137
+ # We have no cookbook dir - certainly comes from the supermarket.
138
+ []
139
+ end
140
+ elsif used_recipe =~ /^\w+$/
141
+ # We are dealing with a dynamically named cookbook, but the recipe name is known.
142
+ # Look for this recipe in all cookbooks that are part of the metadata.
143
+ dependent_cookbooks(cookbook_dir, cookbook).map do |dependent_cookbook|
144
+ dependent_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{dependent_cookbook}") }
145
+ if !dependent_cookbook_dir.nil? && File.exist?("#{@platform.repository_path}/#{dependent_cookbook_dir}/#{dependent_cookbook}/recipes/#{used_recipe}.rb")
146
+ # Found a matching recipe name
147
+ [dependent_cookbook_dir, dependent_cookbook, used_recipe.to_sym]
148
+ end
149
+ end.compact
150
+ else
151
+ # We are dealing with cynamically named cookbooks and recipes.
152
+ # Consider we depend on all recipes of our dependent cookbooks.
153
+ all_dependent_recipes(cookbook_dir, cookbook)
154
+ end
155
+ else
156
+ # The recipe definition is much more complex, so treat it as unparsable and consider we depnd on all recipes of our dependent cookbooks from metadata.
157
+ all_dependent_recipes(cookbook_dir, cookbook)
158
+ end
159
+ end.
160
+ flatten(1)
110
161
  # Check for some helpers we know include some recipes
111
162
  @config.known_helpers_including_recipes.each do |helper_name, used_recipes_by_helper|
112
163
  if recipe_content =~ Regexp.new(/(\W|^)#{Regexp.escape(helper_name)}(\W|$)/)
@@ -222,6 +273,47 @@ module HybridPlatformsConductor
222
273
  end
223
274
  end
224
275
 
276
+ # Get the list of dependent cookbooks from a cookbook's metadata
277
+ #
278
+ # Parameters::
279
+ # * *cookbook_dir* (String): The cookbook directory
280
+ # * *cookbook* (Symbol): The cookbook name
281
+ # Result::
282
+ # * Array<Symbol>: List of dependent cookbooks
283
+ def dependent_cookbooks(cookbook_dir, cookbook)
284
+ # Read the metadata file
285
+ dsl_parser = DslParser.new
286
+ dsl_parser.parse("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/metadata.rb")
287
+ dsl_parser.
288
+ calls.
289
+ map { |call_info| call_info[:method] == :depends ? call_info[:args].first.to_sym : nil }.
290
+ compact
291
+ end
292
+
293
+ # Get all recipes from all cookbooks that are a metadata dependency from a given cookbook.
294
+ #
295
+ # Parameters::
296
+ # * *cookbook_dir* (String): The cookbook directory
297
+ # * *cookbook* (Symbol): The cookbook name
298
+ # Result::
299
+ # * Array< [String, Symbol, Symbol] >: List of tuples [cookbook_dir, cookbook, recipe] used by this recipe
300
+ def all_dependent_recipes(cookbook_dir, cookbook)
301
+ dependent_cookbooks(cookbook_dir, cookbook).map do |dependent_cookbook|
302
+ dependent_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{dependent_cookbook}") }
303
+ if dependent_cookbook_dir.nil?
304
+ nil
305
+ else
306
+ Dir.glob("#{@platform.repository_path}/#{dependent_cookbook_dir}/#{dependent_cookbook}/recipes/*.rb").map do |used_recipe_file_path|
307
+ [
308
+ dependent_cookbook_dir,
309
+ dependent_cookbook,
310
+ File.basename(used_recipe_file_path, '.rb').to_sym
311
+ ]
312
+ end
313
+ end
314
+ end.compact.flatten(1)
315
+ end
316
+
225
317
  end
226
318
 
227
319
  end
@@ -47,24 +47,10 @@ module HybridPlatformsConductor
47
47
  end
48
48
  extend_config_dsl_with MyDSLExtension, :init_serverless_chef
49
49
 
50
- # Constructor
51
- #
52
- # Parameters::
53
- # * *platform_type* (Symbol): Platform type
54
- # * *repository_path* (String): Repository path
55
- # * *logger* (Logger): Logger to be used [default: Logger.new(STDOUT)]
56
- # * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
57
- # * *config* (Config): Config to be used. [default: Config.new]
58
- # * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
59
- def initialize(
60
- platform_type,
61
- repository_path,
62
- logger: Logger.new($stdout),
63
- logger_stderr: Logger.new($stderr),
64
- config: Config.new,
65
- cmd_runner: CmdRunner.new
66
- )
67
- super
50
+ # Initialize a new instance of this platform handler.
51
+ # [API] - This method is optional.
52
+ # [API] - @cmd_runner is accessible.
53
+ def init
68
54
  # Mutex for getting the full recipes tree
69
55
  @recipes_tree_mutex = Mutex.new
70
56
  end
@@ -17,13 +17,13 @@ module HybridPlatformsConductor
17
17
  # Make sure we define automatically a helper for such a platform
18
18
  mixin = Module.new
19
19
  platform_type = subclass.name.split('::').last.gsub(/([a-z\d])([A-Z\d])/, '\1_\2').downcase.to_sym
20
- mixin.define_method("#{platform_type}_platform".to_sym) do |path: nil, git: nil, branch: 'master', &platform_config_code|
20
+ mixin.define_method("#{platform_type}_platform".to_sym) do |path: nil, git: nil, branch: 'master', name: nil, &platform_config_code|
21
21
  repository_path =
22
22
  if !path.nil?
23
23
  path
24
24
  elsif !git.nil?
25
25
  # Clone in a local repository
26
- local_repository_path = "#{@git_platforms_dir}/#{File.basename(git)[0..-File.extname(git).size - 1]}"
26
+ local_repository_path = "#{@git_platforms_dir}/#{name.nil? ? File.basename(git)[0..-File.extname(git).size - 1] : name}"
27
27
  unless File.exist?(local_repository_path)
28
28
  branch = "refs/heads/#{branch}" unless branch.include?('/')
29
29
  local_ref = "refs/remotes/origin/#{branch.split('/').last}"
@@ -37,8 +37,10 @@ module HybridPlatformsConductor
37
37
  else
38
38
  raise 'The platform has to be defined with either a path or a git URL'
39
39
  end
40
- @platform_dirs[platform_type] = [] unless @platform_dirs.key?(platform_type)
41
- @platform_dirs[platform_type] << repository_path
40
+ @platforms_info[platform_type] = {} unless @platforms_info.key?(platform_type)
41
+ raise "Platform repository path #{repository_path} is declared several times." if @platforms_info.values.any? { |known_platforms_info| known_platforms_info.key?(repository_path) }
42
+
43
+ @platforms_info[platform_type][repository_path] = name.nil? ? {} : { name: name }
42
44
  platform_config_code&.call(repository_path)
43
45
  end
44
46
  # Register this new mixin in the Config DSL
@@ -66,18 +68,21 @@ module HybridPlatformsConductor
66
68
  # * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
67
69
  # * *config* (Config): Config to be used. [default: Config.new]
68
70
  # * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
71
+ # * *name* (String or nil): Platform name, or nil for defaults (based on path or git remote) [default: nil]
69
72
  def initialize(
70
73
  platform_type,
71
74
  repository_path,
72
75
  logger: Logger.new($stdout),
73
76
  logger_stderr: Logger.new($stderr),
74
77
  config: Config.new,
75
- cmd_runner: CmdRunner.new
78
+ cmd_runner: CmdRunner.new,
79
+ name: nil
76
80
  )
77
81
  super(logger: logger, logger_stderr: logger_stderr, config: config)
78
82
  @platform_type = platform_type
79
83
  @repository_path = repository_path
80
84
  @cmd_runner = cmd_runner
85
+ @name = name
81
86
  init if respond_to?(:init)
82
87
  end
83
88
 
@@ -142,7 +147,12 @@ module HybridPlatformsConductor
142
147
  git_status = git.status
143
148
  git_commit = git.log.first
144
149
  {
145
- repo_name: git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, ''),
150
+ repo_name:
151
+ if @name.nil?
152
+ git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, '')
153
+ else
154
+ @name
155
+ end,
146
156
  commit: {
147
157
  id: git_commit.sha,
148
158
  ref: git_commit.name,
@@ -162,7 +172,7 @@ module HybridPlatformsConductor
162
172
  }
163
173
  else
164
174
  {
165
- repo_name: File.basename(@repository_path)
175
+ repo_name: @name.nil? ? File.basename(@repository_path) : @name
166
176
  }
167
177
  end
168
178
  end
@@ -9,13 +9,14 @@ module HybridPlatformsConductor
9
9
  # Add some config DSL
10
10
  module ConfigDSLExtension
11
11
 
12
- # List of platforms repository directories, per platform type
13
- # Hash<Symbol, Array<String> >
14
- attr_reader :platform_dirs
12
+ # List of platforms repository directories and their associated info, per platform type
13
+ # Hash<Symbol, Hash<String, Hash<Symbol,Object> > >
14
+ # Hash<platform_type, Hash<repository_path, Hash<Symbol,Object> > >
15
+ attr_reader :platforms_info
15
16
 
16
17
  # Mixin initializer
17
18
  def init_platforms_handler
18
- @platform_dirs = {}
19
+ @platforms_info = {}
19
20
  # Directory in which platforms are cloned
20
21
  @git_platforms_dir = "#{@hybrid_platforms_dir}/cloned_platforms"
21
22
  end
@@ -46,15 +47,16 @@ module HybridPlatformsConductor
46
47
  # Hash<Symbol, Array<PlatformHandler> >
47
48
  @platform_handlers = {}
48
49
  # Read all platforms from the config
49
- @config.platform_dirs.each do |platform_type, repositories|
50
- repositories.each do |repository_path|
50
+ @config.platforms_info.each do |platform_type, repositories_info|
51
+ repositories_info.each do |repository_path, repository_info|
51
52
  platform_handler = @platform_types[platform_type].new(
52
53
  platform_type,
53
54
  repository_path,
54
55
  logger: @logger,
55
56
  logger_stderr: @logger_stderr,
56
57
  config: @config,
57
- cmd_runner: @cmd_runner
58
+ cmd_runner: @cmd_runner,
59
+ name: repository_info[:name]
58
60
  )
59
61
  # Check that this platform has unique name
60
62
  raise "Platform name #{platform_handler.name} is declared several times." if @platform_handlers.values.flatten.any? { |known_platform| known_platform.name == platform_handler.name }
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '33.8.3'
3
+ VERSION = '33.9.2'
4
4
 
5
5
  end
@@ -196,6 +196,50 @@ describe HybridPlatformsConductor::Deployer do
196
196
  end
197
197
  end
198
198
 
199
+ it 'gets deployment info from log plugins returning UTF-8 characters' do
200
+ with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }) do
201
+ HybridPlatformsConductorTest::TestLogPlugin.mocked_logs = {
202
+ 'node' => {
203
+ deployment_info: { user: 'test_user' },
204
+ exit_status: 666,
205
+ services: %w[unknown],
206
+ stderr: 'stderrの展開テストログ',
207
+ stdout: 'stdoutの展開テストログ'
208
+ }
209
+ }
210
+ expect_actions_executor_runs [
211
+ # Expect the actions to get log files
212
+ proc do |actions_per_nodes|
213
+ expect(actions_per_nodes).to eq('node' => [{ bash: 'echo Read logs for node' }])
214
+ # Simulate the fact that data returned by the ssh system calls can contain UTF-8 chars, but is perceived as binary
215
+ { 'node' => [42, 'ログファイルはstdoutを読み取ります'.force_encoding('BINARY'), 'ログファイルはstderrを読み取ります'.force_encoding('BINARY')] }
216
+ end
217
+ ]
218
+ expect(test_deployer.deployment_info_from('node')).to eq(
219
+ 'node' => {
220
+ deployment_info: { user: 'test_user' },
221
+ exit_status: 666,
222
+ services: %w[unknown],
223
+ stderr: 'stderrの展開テストログ',
224
+ stdout: 'stdoutの展開テストログ'
225
+ }
226
+ )
227
+ expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
228
+ {
229
+ method: :actions_to_read_logs,
230
+ node: 'node'
231
+ },
232
+ {
233
+ method: :logs_for,
234
+ node: 'node',
235
+ exit_status: 42,
236
+ stdout: 'ログファイルはstdoutを読み取ります',
237
+ stderr: 'ログファイルはstderrを読み取ります'
238
+ }
239
+ ]
240
+ end
241
+ end
242
+
199
243
  it 'gets deployment info from log plugins not having actions_to_read_logs' do
200
244
  with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }, additional_config: 'send_logs_to :test_log_no_read') do
201
245
  expect(test_deployer.deployment_info_from('node')).to eq(
@@ -15,6 +15,10 @@ describe HybridPlatformsConductor::NodesHandler do
15
15
  },
16
16
  'platform2' => {
17
17
  nodes: { 'node4' => {}, 'node5' => { services: %w[service3 service1] }, 'node6' => {} }
18
+ },
19
+ 'platform3' => {
20
+ nodes: { 'node7' => {} },
21
+ name: 'other_platform'
18
22
  }
19
23
  },
20
24
  &block
@@ -24,12 +28,13 @@ describe HybridPlatformsConductor::NodesHandler do
24
28
  # List all tests of nodes selectors, and the corresponding nodes list they should be resolved into
25
29
  {
26
30
  [] => [],
27
- [{ all: true }] => %w[node1 node2 node3 node4 node5 node6],
31
+ [{ all: true }] => %w[node1 node2 node3 node4 node5 node6 node7],
28
32
  'node1' => %w[node1],
29
33
  '/node[12]/' => %w[node1 node2],
30
34
  [{ list: 'nodeslist1' }] => %w[node1 node3],
31
35
  [{ list: 'nodeslist2' }] => %w[node1 node2],
32
36
  [{ platform: 'platform2' }] => %w[node4 node5 node6],
37
+ [{ platform: 'other_platform' }] => %w[node7],
33
38
  [{ service: 'service1' }] => %w[node2 node5],
34
39
  ['/node[12]/', { service: 'service1' }] => %w[node1 node2 node5],
35
40
  [{ git_diff: { platform: 'platform2' } }] => %w[node4 node5 node6]
@@ -45,13 +50,13 @@ describe HybridPlatformsConductor::NodesHandler do
45
50
 
46
51
  it 'fails when selecting unknown nodes' do
47
52
  with_test_platform_for_nodes do
48
- expect { test_nodes_handler.select_nodes('node1', 'node7') }.to raise_error(RuntimeError, 'Unknown nodes: node7')
53
+ expect { test_nodes_handler.select_nodes('node1', 'unknown_node') }.to raise_error(RuntimeError, 'Unknown nodes: unknown_node')
49
54
  end
50
55
  end
51
56
 
52
57
  it 'ignore unknown nodes when asked' do
53
58
  with_test_platform_for_nodes do
54
- expect(test_nodes_handler.select_nodes(%w[node1 node7], ignore_unknowns: true).sort).to eq %w[node1 node7].sort
59
+ expect(test_nodes_handler.select_nodes(%w[node1 unknown_node], ignore_unknowns: true).sort).to eq %w[node1 unknown_node].sort
55
60
  end
56
61
  end
57
62
 
@@ -105,7 +110,7 @@ describe HybridPlatformsConductor::NodesHandler do
105
110
 
106
111
  it 'considers all nodes for en empty nodes selector stack' do
107
112
  with_test_platform_for_nodes do
108
- expect(test_nodes_handler.select_from_nodes_selector_stack([]).sort).to eq %w[node1 node2 node3 node4 node5 node6].sort
113
+ expect(test_nodes_handler.select_from_nodes_selector_stack([]).sort).to eq %w[node1 node2 node3 node4 node5 node6 node7].sort
109
114
  end
110
115
  end
111
116
 
@@ -235,6 +235,59 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
235
235
  end
236
236
  end
237
237
 
238
+ it 'returns impacted service due to a usage of another cookbook\'s recipe using parenthesis' do
239
+ with_serverless_chef_platforms('recipes') do |platform, repository|
240
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EO_RECIPE)
241
+ include_recipe('test_cookbook_2::other_recipe')
242
+ EO_RECIPE
243
+ expect(platform.impacts_from('cookbooks/test_cookbook_2/recipes/other_recipe.rb' => {})).to eq [
244
+ [],
245
+ %w[test_policy_1],
246
+ false
247
+ ]
248
+ end
249
+ end
250
+
251
+ it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic recipe name' do
252
+ with_serverless_chef_platforms('recipes') do |platform|
253
+ expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_1.rb' => {})).to eq [
254
+ [],
255
+ %w[test_policy_31 test_policy_33 test_policy_35],
256
+ false
257
+ ]
258
+ end
259
+ end
260
+
261
+ it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic cookbook name' do
262
+ with_serverless_chef_platforms('recipes') do |platform|
263
+ expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_2.rb' => {})).to eq [
264
+ [],
265
+ %w[test_policy_31 test_policy_32 test_policy_33 test_policy_35],
266
+ false
267
+ ]
268
+ end
269
+ end
270
+
271
+ it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic cookbook and recipe names' do
272
+ with_serverless_chef_platforms('recipes') do |platform|
273
+ expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_3.rb' => {})).to eq [
274
+ [],
275
+ %w[test_policy_31 test_policy_33 test_policy_35],
276
+ false
277
+ ]
278
+ end
279
+ end
280
+
281
+ it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic or unparsable cookbook and recipe names, using metadata' do
282
+ with_serverless_chef_platforms('recipes') do |platform|
283
+ expect(platform.impacts_from('cookbooks/test_cookbook_5/recipes/recipe_1.rb' => {})).to eq [
284
+ [],
285
+ %w[test_policy_33 test_policy_35],
286
+ false
287
+ ]
288
+ end
289
+ end
290
+
238
291
  it 'ignores cookbooks from cookbook paths that are not configured' do
239
292
  with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
240
293
  File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EO_RECIPE)
@@ -2,22 +2,22 @@ describe HybridPlatformsConductor::PlatformsHandler do
2
2
 
3
3
  context 'when checking config specific DSL' do
4
4
 
5
- it 'returns platform directories along with platform types' do
5
+ it 'returns platforms info' do
6
6
  with_test_platforms(
7
7
  {
8
8
  'platform1' => { platform_type: :test },
9
9
  'platform2' => { platform_type: :test_2 },
10
- 'platform3' => { platform_type: :test }
10
+ 'platform3' => { platform_type: :test, name: 'other_platform' }
11
11
  }
12
12
  ) do |repositories|
13
- expect(test_config.platform_dirs.keys.sort).to eq %i[test test_2].sort
14
- expect(test_config.platform_dirs[:test].sort).to eq [
15
- repositories['platform1'],
16
- repositories['platform3']
17
- ].sort
18
- expect(test_config.platform_dirs[:test_2].sort).to eq [
19
- repositories['platform2']
20
- ].sort
13
+ expect(test_config.platforms_info.keys.sort).to eq %i[test test_2].sort
14
+ expect(test_config.platforms_info[:test]).to eq(
15
+ repositories['platform1'] => {},
16
+ repositories['platform3'] => { name: 'other_platform' }
17
+ )
18
+ expect(test_config.platforms_info[:test_2]).to eq(
19
+ repositories['platform2'] => {}
20
+ )
21
21
  end
22
22
  end
23
23
 
@@ -55,27 +55,57 @@ describe HybridPlatformsConductor::PlatformsHandler do
55
55
  {
56
56
  'platform1' => { platform_type: :test },
57
57
  'platform2' => { platform_type: :test_2 },
58
- 'platform3' => { platform_type: :test }
58
+ 'platform3' => { platform_type: :test, name: 'other_platform' }
59
59
  }
60
60
  ) do
61
- expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2 platform3].sort
61
+ expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2 other_platform].sort
62
62
  end
63
63
  end
64
64
 
65
65
  it 'fails if several platforms share the same name' do
66
66
  with_repository('platform1') do |repository|
67
+ FileUtils.mkdir_p "#{repository}/platform1"
67
68
  with_test_platforms(
68
69
  {
69
70
  'platform1' => { platform_type: :test },
70
71
  'platform2' => { platform_type: :test_2 }
71
72
  },
72
- additional_config: "test_2_platform path: \'#{repository}\'"
73
+ additional_config: "test_2_platform path: \'#{repository}/platform1\'"
73
74
  ) do
74
75
  expect { test_platforms_handler.known_platforms }.to raise_error 'Platform name platform1 is declared several times.'
75
76
  end
76
77
  end
77
78
  end
78
79
 
80
+ it 'fails if several platforms share the same path' do
81
+ with_repository('platform1') do |repository|
82
+ with_test_platforms(
83
+ {
84
+ 'platform1' => { platform_type: :test },
85
+ 'platform2' => { platform_type: :test_2 }
86
+ },
87
+ additional_config: "test_2_platform path: \'#{repository}\', name: 'other_platform'"
88
+ ) do
89
+ expect { test_platforms_handler.known_platforms }.to raise_error "Platform repository path #{repository} is declared several times."
90
+ end
91
+ end
92
+ end
93
+
94
+ it 'can differentiate several platforms sharing the same path ending but with different explicit names' do
95
+ with_repository('platform1') do |repository|
96
+ FileUtils.mkdir_p "#{repository}/platform1"
97
+ with_test_platforms(
98
+ {
99
+ 'platform1' => { platform_type: :test },
100
+ 'platform2' => { platform_type: :test_2 }
101
+ },
102
+ additional_config: "test_platform path: \'#{repository}/platform1\', name: 'other_platform'"
103
+ ) do
104
+ expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2 other_platform].sort
105
+ end
106
+ end
107
+ end
108
+
79
109
  it 'returns defined platforms filtered by platform type' do
80
110
  with_test_platforms(
81
111
  {
@@ -190,6 +190,81 @@ describe 'nodes_to_deploy executable' do
190
190
  end
191
191
  end
192
192
 
193
+ it 'considers nodes having the same invalid commit ids in their logs to be deployed' do
194
+ with_test_platform_for_nodes_to_deploy do
195
+ expect(test_deployer).to receive(:deployment_info_from).with(%w[node1 node2]).and_return(
196
+ 'node1' => {
197
+ services: %w[service1],
198
+ deployment_info: {
199
+ repo_name_0: 'platform',
200
+ commit_id_0: 'abcdef1',
201
+ exit_status: 0
202
+ },
203
+ exit_status: 0,
204
+ stdout: '',
205
+ stderr: ''
206
+ },
207
+ 'node2' => {
208
+ services: %w[service2],
209
+ deployment_info: {
210
+ repo_name_0: 'platform',
211
+ commit_id_0: 'abcdef1',
212
+ exit_status: 0
213
+ },
214
+ exit_status: 0,
215
+ stdout: '',
216
+ stderr: ''
217
+ }
218
+ )
219
+ expect(test_nodes_handler).to receive(:impacted_nodes_from_git_diff).with('platform', from_commit: 'abcdef1', to_commit: 'master') do
220
+ raise HybridPlatformsConductor::NodesHandler::GitError, 'Mocked git error due to an invalid commit id'
221
+ end
222
+ exit_code, stdout = run 'nodes_to_deploy'
223
+ expect(exit_code).to eq 0
224
+ expect(stdout).to eq <<~EO_STDOUT
225
+ ===== Nodes to deploy =====
226
+ node1
227
+ node2
228
+ EO_STDOUT
229
+ end
230
+ end
231
+
232
+ it 'considers nodes having unknown platforms in their logs to be deployed' do
233
+ with_test_platform_for_nodes_to_deploy do
234
+ expect(test_deployer).to receive(:deployment_info_from).with(%w[node1 node2]).and_return(
235
+ 'node1' => {
236
+ services: %w[service1],
237
+ deployment_info: {
238
+ repo_name_0: 'unknown_platform',
239
+ commit_id_0: 'abcdef1',
240
+ exit_status: 0
241
+ },
242
+ exit_status: 0,
243
+ stdout: '',
244
+ stderr: ''
245
+ },
246
+ 'node2' => {
247
+ services: %w[service2],
248
+ deployment_info: {
249
+ repo_name_0: 'platform',
250
+ commit_id_0: 'abcdef2',
251
+ exit_status: 0
252
+ },
253
+ exit_status: 0,
254
+ stdout: '',
255
+ stderr: ''
256
+ }
257
+ )
258
+ expect(test_nodes_handler).to receive(:impacted_nodes_from_git_diff).with('platform', from_commit: 'abcdef2', to_commit: 'master').and_return [%w[], [], [], false]
259
+ exit_code, stdout = run 'nodes_to_deploy'
260
+ expect(exit_code).to eq 0
261
+ expect(stdout).to eq <<~EO_STDOUT
262
+ ===== Nodes to deploy =====
263
+ node1
264
+ EO_STDOUT
265
+ end
266
+ end
267
+
193
268
  it 'ignores impacts if asked' do
194
269
  with_test_platform_for_nodes_to_deploy do
195
270
  exit_code, stdout = run 'nodes_to_deploy', '--ignore-deployed-info'
@@ -73,7 +73,9 @@ module HybridPlatformsConductorTest
73
73
  # Clean-up at the end.
74
74
  #
75
75
  # Parameters::
76
- # * *platforms_info* (Hash<String,Object>): Platforms info for the test platform
76
+ # * *platforms_info* (Hash<String,Object>): Platforms info for the test platform:
77
+ # * *platform_type* (Symbol): Name of the platform handler plugin for this platform
78
+ # * *name* (String): Optional name to give the platform [optional]
77
79
  # * *as_git* (Boolean): Do we initialize those repositories as Git repositories? [default: false]
78
80
  # * *additional_config* (String): Additional config to be added [default: '']
79
81
  # * Proc: Code called with the environment ready
@@ -86,7 +88,7 @@ module HybridPlatformsConductorTest
86
88
  repositories.map do |platform, dir|
87
89
  platform_type = platforms_info[platform].key?(:platform_type) ? platforms_info[platform][:platform_type] : :test
88
90
  platform_types << platform_type unless platform_types.include?(platform_type)
89
- "#{platform_type}_platform path: '#{dir}'"
91
+ "#{platform_type}_platform path: '#{dir}'#{platforms_info[platform].key?(:name) ? ", name: '#{platforms_info[platform][:name]}'" : ''}"
90
92
  end.join("\n") + "\n#{additional_config}"
91
93
  ) do
92
94
  register_platform_handlers(platform_types.map do |platform_type|
@@ -200,10 +200,11 @@ module HybridPlatformsConductorTest
200
200
  # Result::
201
201
  # * Hash<Symbol, Object>: Platform info (check TestPlatformHandler#platforms_info to know about properties)
202
202
  def platform_info
203
+ _repo_base_name, found_platform_info = HybridPlatformsConductorTest::PlatformHandlerPlugins::Test.platforms_info.find { |search_repo_base_name, search_platform_info| (search_platform_info[:name] || search_repo_base_name) == name }
203
204
  {
204
205
  nodes: {},
205
206
  nodes_lists: {}
206
- }.merge(HybridPlatformsConductorTest::PlatformHandlerPlugins::Test.platforms_info[name])
207
+ }.merge(found_platform_info)
207
208
  end
208
209
 
209
210
  # Return the node info of a given node
@@ -0,0 +1,13 @@
1
+ name 'test_cookbook_3'
2
+ maintainer 'Muriel Salvan'
3
+ maintainer_email 'muriel@x-aeon.com'
4
+ supports 'debian'
5
+ chef_version '>= 14.8'
6
+ source_url 'https://x-aeon.com'
7
+ issues_url 'https://x-aeon.com'
8
+ license 'BSD'
9
+ description 'Installs/Configures test_cookbook_3'
10
+ long_description ''
11
+ version '0.1.0'
12
+ depends 'test_cookbook_4'
13
+ depends 'test_cookbook_5'
@@ -0,0 +1,2 @@
1
+ recipe_name = 'recipe_1'
2
+ include_recipe "test_cookbook_4::#{recipe_name}"
@@ -0,0 +1,2 @@
1
+ cookbook_name = 'test_cookbook_4'
2
+ include_recipe "#{cookbook_name}::recipe_2"
@@ -0,0 +1,3 @@
1
+ cookbook_name = 'test_cookbook_4'
2
+ recipe_name = 'recipe_3'
3
+ include_recipe "#{cookbook_name}::#{recipe_name}"
@@ -0,0 +1,7 @@
1
+ cookbook_name = ENV['cookbook_name']
2
+ recipe_name = ENV['recipe_name']
3
+ # rubocop:disable Style/StringConcatenation
4
+ include_recipe(
5
+ cookbook_name + '::' + recipe_name
6
+ )
7
+ # rubocop:enable Style/StringConcatenation
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "node31",
3
+ "normal": {
4
+ "description": "Node 31",
5
+ "image": "debian_9",
6
+ "private_ips": ["172.16.0.31"]
7
+ },
8
+ "policy_name": "test_policy_31",
9
+ "policy_group": "test_group"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "node32",
3
+ "normal": {
4
+ "description": "Node 32",
5
+ "image": "debian_9",
6
+ "private_ips": ["172.16.0.32"]
7
+ },
8
+ "policy_name": "test_policy_32",
9
+ "policy_group": "test_group"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "node33",
3
+ "normal": {
4
+ "description": "Node 33",
5
+ "image": "debian_9",
6
+ "private_ips": ["172.16.0.33"]
7
+ },
8
+ "policy_name": "test_policy_33",
9
+ "policy_group": "test_group"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "node34",
3
+ "normal": {
4
+ "description": "Node 34",
5
+ "image": "debian_9",
6
+ "private_ips": ["172.16.0.34"]
7
+ },
8
+ "policy_name": "test_policy_34",
9
+ "policy_group": "test_group"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "node35",
3
+ "normal": {
4
+ "description": "Node 35",
5
+ "image": "debian_9",
6
+ "private_ips": ["172.16.0.35"]
7
+ },
8
+ "policy_name": "test_policy_35",
9
+ "policy_group": "test_group"
10
+ }
@@ -0,0 +1,4 @@
1
+ name File.basename(__FILE__, '.rb')
2
+ default_source :supermarket
3
+ default_source :chef_repo, '..'
4
+ run_list 'recipe[test_cookbook_3::31_unknown_recipe_include]'
@@ -0,0 +1,4 @@
1
+ name File.basename(__FILE__, '.rb')
2
+ default_source :supermarket
3
+ default_source :chef_repo, '..'
4
+ run_list 'recipe[test_cookbook_3::32_unknown_cookbook_include]'
@@ -0,0 +1,4 @@
1
+ name File.basename(__FILE__, '.rb')
2
+ default_source :supermarket
3
+ default_source :chef_repo, '..'
4
+ run_list 'recipe[test_cookbook_3::33_unknown_include]'
@@ -0,0 +1,4 @@
1
+ name File.basename(__FILE__, '.rb')
2
+ default_source :supermarket
3
+ default_source :chef_repo, '..'
4
+ run_list 'recipe[test_cookbook_3::34_known_include]'
@@ -0,0 +1,4 @@
1
+ name File.basename(__FILE__, '.rb')
2
+ default_source :supermarket
3
+ default_source :chef_repo, '..'
4
+ run_list 'recipe[test_cookbook_3::35_unparsable_include]'
@@ -5,7 +5,7 @@ module HybridPlatformsConductorTest
5
5
 
6
6
  class << self
7
7
 
8
- attr_accessor :calls
8
+ attr_accessor(*%i[calls mocked_logs])
9
9
 
10
10
  end
11
11
 
@@ -89,7 +89,7 @@ module HybridPlatformsConductorTest
89
89
  stdout: stdout,
90
90
  stderr: stderr
91
91
  }
92
- {
92
+ TestLogPlugin.mocked_logs[node] || {
93
93
  services: %w[unknown],
94
94
  deployment_info: {
95
95
  user: 'test_user'
@@ -145,6 +145,7 @@ module HybridPlatformsConductorTest
145
145
  HybridPlatformsConductorTest::TestPlugins::NodeCheck.only_on_nodes = nil
146
146
  HybridPlatformsConductorTest::TestPlugins::SeveralChecks.runs = []
147
147
  HybridPlatformsConductorTest::TestLogPlugin.calls = []
148
+ HybridPlatformsConductorTest::TestLogPlugin.mocked_logs = {}
148
149
  HybridPlatformsConductorTest::TestLogNoReadPlugin.calls = []
149
150
  HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls = []
150
151
  HybridPlatformsConductorTest::TestSecretsReaderPlugin.deployer = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hybrid_platforms_conductor
3
3
  version: !ruby/object:Gem::Version
4
- version: 33.8.3
4
+ version: 33.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-16 00:00:00.000000000 Z
11
+ date: 2021-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: range_operators
@@ -1003,10 +1003,32 @@ files:
1003
1003
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb
1004
1004
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/other_recipe.rb
1005
1005
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/resources/my_resource.rb
1006
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/metadata.rb
1007
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/31_unknown_recipe_include.rb
1008
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/32_unknown_cookbook_include.rb
1009
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/33_unknown_include.rb
1010
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/34_known_include.rb
1011
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/35_unparsable_include.rb
1012
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_1.rb
1013
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_2.rb
1014
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_3.rb
1015
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_4.rb
1016
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_1.rb
1017
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_2.rb
1006
1018
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node1.json
1007
1019
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node2.json
1020
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node31.json
1021
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node32.json
1022
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node33.json
1023
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node34.json
1024
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node35.json
1008
1025
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_1.rb
1009
1026
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_2.rb
1027
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_31.rb
1028
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_32.rb
1029
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_33.rb
1030
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_34.rb
1031
+ - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_35.rb
1010
1032
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/config.rb
1011
1033
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/cookbooks/test_cookbook_1/recipes/default.rb
1012
1034
  - spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node1.json