r10k 3.9.3 → 3.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec_tests.yml +1 -1
  3. data/.travis.yml +0 -10
  4. data/CHANGELOG.mkd +33 -0
  5. data/README.mkd +6 -0
  6. data/doc/dynamic-environments/configuration.mkd +25 -0
  7. data/doc/dynamic-environments/usage.mkd +26 -0
  8. data/doc/puppetfile.mkd +18 -5
  9. data/integration/Rakefile +3 -1
  10. data/integration/tests/basic_functionality/basic_deployment.rb +176 -0
  11. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +3 -9
  12. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +21 -25
  13. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
  14. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
  15. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
  16. data/lib/r10k/action/base.rb +1 -1
  17. data/lib/r10k/action/deploy/deploy_helpers.rb +4 -0
  18. data/lib/r10k/action/deploy/display.rb +1 -1
  19. data/lib/r10k/action/deploy/environment.rb +22 -9
  20. data/lib/r10k/action/deploy/module.rb +41 -11
  21. data/lib/r10k/action/puppetfile/check.rb +7 -5
  22. data/lib/r10k/action/puppetfile/install.rb +22 -16
  23. data/lib/r10k/action/puppetfile/purge.rb +12 -9
  24. data/lib/r10k/action/runner.rb +45 -10
  25. data/lib/r10k/action/visitor.rb +3 -0
  26. data/lib/r10k/cli/deploy.rb +5 -0
  27. data/lib/r10k/cli/puppetfile.rb +0 -1
  28. data/lib/r10k/content_synchronizer.rb +16 -4
  29. data/lib/r10k/environment/base.rb +64 -11
  30. data/lib/r10k/environment/with_modules.rb +6 -10
  31. data/lib/r10k/git/cache.rb +1 -1
  32. data/lib/r10k/git/rugged/credentials.rb +77 -0
  33. data/lib/r10k/git/stateful_repository.rb +8 -0
  34. data/lib/r10k/git.rb +3 -0
  35. data/lib/r10k/initializers.rb +4 -0
  36. data/lib/r10k/module/base.rb +42 -1
  37. data/lib/r10k/module/definition.rb +64 -0
  38. data/lib/r10k/module/forge.rb +16 -3
  39. data/lib/r10k/module/git.rb +23 -1
  40. data/lib/r10k/module/local.rb +6 -3
  41. data/lib/r10k/module/svn.rb +11 -0
  42. data/lib/r10k/module.rb +20 -2
  43. data/lib/r10k/module_loader/puppetfile/dsl.rb +42 -0
  44. data/lib/r10k/module_loader/puppetfile.rb +276 -0
  45. data/lib/r10k/puppetfile.rb +82 -160
  46. data/lib/r10k/settings/definition.rb +1 -1
  47. data/lib/r10k/settings.rb +58 -2
  48. data/lib/r10k/source/base.rb +10 -0
  49. data/lib/r10k/source/git.rb +5 -0
  50. data/lib/r10k/source/svn.rb +4 -0
  51. data/lib/r10k/util/purgeable.rb +74 -8
  52. data/lib/r10k/util/setopts.rb +2 -0
  53. data/lib/r10k/util/subprocess.rb +1 -0
  54. data/lib/r10k/version.rb +1 -1
  55. data/locales/r10k.pot +165 -65
  56. data/r10k.gemspec +2 -0
  57. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +4 -0
  58. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +3 -0
  59. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +8 -0
  60. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +10 -0
  61. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +10 -0
  62. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_subdir_2/ignored_1 +0 -0
  63. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  64. data/spec/r10k-mocks/mock_env.rb +3 -0
  65. data/spec/r10k-mocks/mock_source.rb +7 -3
  66. data/spec/unit/action/deploy/environment_spec.rb +105 -30
  67. data/spec/unit/action/deploy/module_spec.rb +232 -42
  68. data/spec/unit/action/puppetfile/check_spec.rb +17 -5
  69. data/spec/unit/action/puppetfile/install_spec.rb +42 -36
  70. data/spec/unit/action/puppetfile/purge_spec.rb +15 -17
  71. data/spec/unit/action/runner_spec.rb +122 -26
  72. data/spec/unit/environment/base_spec.rb +30 -17
  73. data/spec/unit/environment/git_spec.rb +2 -2
  74. data/spec/unit/environment/svn_spec.rb +4 -3
  75. data/spec/unit/environment/with_modules_spec.rb +2 -1
  76. data/spec/unit/git/cache_spec.rb +14 -0
  77. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  78. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  79. data/spec/unit/module/base_spec.rb +54 -8
  80. data/spec/unit/module/forge_spec.rb +59 -5
  81. data/spec/unit/module/git_spec.rb +67 -9
  82. data/spec/unit/module/svn_spec.rb +35 -5
  83. data/spec/unit/module_loader/puppetfile_spec.rb +405 -0
  84. data/spec/unit/module_spec.rb +12 -1
  85. data/spec/unit/puppetfile_spec.rb +125 -189
  86. data/spec/unit/settings_spec.rb +47 -2
  87. data/spec/unit/util/purgeable_spec.rb +38 -6
  88. metadata +29 -3
data/lib/r10k/settings.rb CHANGED
@@ -42,6 +42,22 @@ module R10K
42
42
  Only used by the 'rugged' Git provider."
43
43
  }),
44
44
 
45
+ Definition.new(:github_app_id, {
46
+ :desc => "The Github App id for Git SSL remotes.
47
+ Only used by the 'rugged' Git provider."
48
+ }),
49
+
50
+ Definition.new(:github_app_key, {
51
+ :desc => "The Github App private key for Git SSL remotes.
52
+ Only used by the 'rugged' Git provider."
53
+ }),
54
+
55
+ Definition.new(:github_app_ttl, {
56
+ :desc => "The ttl expiration for SSL tokens.
57
+ Only used by the 'rugged' Git provider.",
58
+ :default => "120",
59
+ }),
60
+
45
61
  URIDefinition.new(:proxy, {
46
62
  :desc => "An optional proxy server to use when interacting with Git sources via HTTP(S).",
47
63
  :default => :inherit,
@@ -65,6 +81,24 @@ module R10K
65
81
  :default => :inherit
66
82
  }),
67
83
 
84
+ Definition.new(:github_app_id, {
85
+ :desc => "The Github App id for Git SSL remotes.
86
+ Only used by the 'rugged' Git provider.",
87
+ :default => :inherit
88
+ }),
89
+
90
+ Definition.new(:github_app_key, {
91
+ :desc => "The Github App private key for Git SSL remotes.
92
+ Only used by the 'rugged' Git provider.",
93
+ :default => :inherit
94
+ }),
95
+
96
+ Definition.new(:github_app_ttl, {
97
+ :desc => "The ttl expiration for Git SSL tokens.
98
+ Only used by the 'rugged' Git provider.",
99
+ :default => :inherit
100
+ }),
101
+
68
102
  URIDefinition.new(:proxy, {
69
103
  :desc => "An optional proxy server to use when interacting with Git sources via HTTP(S).",
70
104
  :default => :inherit,
@@ -92,6 +126,20 @@ module R10K
92
126
  URIDefinition.new(:baseurl, {
93
127
  :desc => "The URL to the Puppet Forge to use for downloading modules."
94
128
  }),
129
+
130
+ Definition.new(:authorization_token, {
131
+ :desc => "The token for Puppet Forge authorization. Leave blank for unauthorized or license-based connections."
132
+ }),
133
+
134
+ Definition.new(:allow_puppetfile_override, {
135
+ :desc => "Whether to use `forge` declarations in the Puppetfile as an override of `baseurl`.",
136
+ :default => false,
137
+ :validate => lambda do |value|
138
+ unless !!value == value
139
+ raise ArgumentError, "`allow_puppetfile_override` can only be a boolean value, not '#{value}'"
140
+ end
141
+ end
142
+ })
95
143
  ])
96
144
  end
97
145
 
@@ -158,7 +206,15 @@ module R10K
158
206
  end
159
207
  end
160
208
  }),
161
- ])
209
+ Definition.new(:exclude_spec, {
210
+ :desc => "Whether or not to deploy the spec dir of a module. Defaults to false.",
211
+ :default => false,
212
+ :validate => lambda do |value|
213
+ unless !!value == value
214
+ raise ArgumentError, "`exclude_spec` can only be a boolean value, not '#{value}'"
215
+ end
216
+ end
217
+ })])
162
218
  end
163
219
 
164
220
  def self.global_settings
@@ -177,7 +233,7 @@ module R10K
177
233
  }),
178
234
 
179
235
  Definition.new(:postrun, {
180
- :desc => "The command r10k should run after deploying environments.",
236
+ :desc => "The command r10k should run after deploying environments or modules.",
181
237
  :validate => lambda do |value|
182
238
  if !value.is_a?(Array)
183
239
  raise ArgumentError, "The postrun setting should be an array of strings, not a #{value.class}"
@@ -63,6 +63,16 @@ class R10K::Source::Base
63
63
 
64
64
  end
65
65
 
66
+ # Perform actions to reload environments after the `preload!`. Similar
67
+ # to preload!, and likely to include network queries and rerunning
68
+ # environment generation.
69
+ #
70
+ # @api public
71
+ # @abstract
72
+ # @return [void]
73
+ def reload!
74
+ end
75
+
66
76
  # Enumerate the environments associated with this SVN source.
67
77
  #
68
78
  # @api public
@@ -93,6 +93,11 @@ class R10K::Source::Git < R10K::Source::Base
93
93
  end
94
94
  end
95
95
 
96
+ def reload!
97
+ @cache.sync!
98
+ @environments = generate_environments()
99
+ end
100
+
96
101
  def generate_environments
97
102
  envs = []
98
103
  branch_names.each do |bn|
@@ -65,6 +65,10 @@ class R10K::Source::SVN < R10K::Source::Base
65
65
  @ignore_branch_prefixes = options[:ignore_branch_prefixes]
66
66
  end
67
67
 
68
+ def reload!
69
+ @environments = generate_environments()
70
+ end
71
+
68
72
  # Enumerate the environments associated with this SVN source.
69
73
  #
70
74
  # @return [Array<R10K::Environment::SVN>] An array of environments created
@@ -1,3 +1,5 @@
1
+ require 'r10k/logging'
2
+
1
3
  require 'fileutils'
2
4
 
3
5
  module R10K
@@ -9,6 +11,14 @@ module R10K
9
11
  # {#desired_contents}
10
12
  module Purgeable
11
13
 
14
+ include R10K::Logging
15
+
16
+ HIDDEN_FILE = /\.[^.]+/
17
+
18
+ FN_MATCH_OPTS = File::FNM_PATHNAME | File::FNM_DOTMATCH
19
+
20
+ # @deprecated
21
+ #
12
22
  # @!method logger
13
23
  # @abstract Including classes must provide a logger method
14
24
  # @return [Log4r::Logger]
@@ -38,23 +48,79 @@ module R10K
38
48
  end
39
49
  end
40
50
 
51
+ # @deprecated Unused helper function
52
+ #
41
53
  # @return [Array<String>] Directory contents that are expected but not present
42
54
  def pending_contents(recurse)
43
55
  desired_contents - current_contents(recurse)
44
56
  end
45
57
 
58
+ def matches?(test, path)
59
+ if test == path
60
+ true
61
+ elsif File.fnmatch?(test, path, FN_MATCH_OPTS)
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ # A method to collect potentially purgeable content without searching into
69
+ # ignored directories when recursively searching.
70
+ #
71
+ # @param dir [String, Pathname] The directory to search for purgeable content
72
+ # @param exclusion_gobs [Array<String>] A list of file paths or File globs
73
+ # to exclude from recursion (These are generated by the classes that
74
+ # mix this module into them and are typically programatically generated)
75
+ # @param allowed_gobs [Array<String>] A list of file paths or File globs to exclude
76
+ # from recursion (These are passed in by the caller of purge! and typically
77
+ # are user supplied configuration values)
78
+ # @param desireds_not_to_recurse_into [Array<String>] A list of file paths not to
79
+ # recurse into. These are programatically generated, these exist to maintain
80
+ # backwards compatibility with previous implementations that used File.globs
81
+ # for "recursion", ie "**/{*,.[^.]*}" which would not recurse into dot directories.
82
+ # @param recurse [Boolean] Whether or not to recurse into child directories that do
83
+ # not match other filters.
84
+ #
85
+ # @return [Array<String>] Contents which may be purged.
86
+ def potentially_purgeable(dir, exclusion_globs, allowed_globs, desireds_not_to_recurse_into, recurse)
87
+ children = Pathname.new(dir).children.reject do |path|
88
+ path = path.to_s
89
+
90
+ if exclusion_match = exclusion_globs.find { |exclusion| matches?(exclusion, path) }
91
+ logger.debug2 _("Not purging %{path} due to internal exclusion match: %{exclusion_match}") % {path: path, exclusion_match: exclusion_match}
92
+ elsif allowlist_match = allowed_globs.find { |allowed| matches?(allowed, path) }
93
+ logger.debug _("Not purging %{path} due to whitelist match: %{allowlist_match}") % {path: path, allowlist_match: allowlist_match}
94
+ else
95
+ desired_match = desireds_not_to_recurse_into.grep(path).first
96
+ end
97
+
98
+ !!exclusion_match || !!allowlist_match || !!desired_match
99
+ end
100
+
101
+ children.flat_map do |child|
102
+ if File.directory?(child) && recurse
103
+ potentially_purgeable(child, exclusion_globs, allowed_globs, desireds_not_to_recurse_into, recurse)
104
+ else
105
+ child.to_s
106
+ end
107
+ end
108
+ end
109
+
46
110
  # @return [Array<String>] Directory contents that are present but not expected
47
111
  def stale_contents(recurse, exclusions, whitelist)
48
- fn_match_opts = File::FNM_PATHNAME | File::FNM_DOTMATCH
112
+ dirs = self.managed_directories
113
+ desireds = self.desired_contents
114
+ hidden_desireds, regular_desireds = desireds.partition do |desired|
115
+ HIDDEN_FILE.match(File.basename(desired))
116
+ end
49
117
 
50
- (current_contents(recurse) - desired_contents).reject do |item|
51
- if exclusion_match = exclusions.find { |ex_item| (ex_item == item) || File.fnmatch?(ex_item, item, fn_match_opts) }
52
- logger.debug2 _("Not purging %{item} due to internal exclusion match: %{exclusion_match}") % {item: item, exclusion_match: exclusion_match}
53
- elsif whitelist_match = whitelist.find { |wl_item| (wl_item == item) || File.fnmatch?(wl_item, item, fn_match_opts) }
54
- logger.debug _("Not purging %{item} due to whitelist match: %{whitelist_match}") % {item: item, whitelist_match: whitelist_match}
55
- end
118
+ initial_purgelist = dirs.flat_map do |dir|
119
+ potentially_purgeable(dir, exclusions, whitelist, hidden_desireds, recurse)
120
+ end
56
121
 
57
- !!exclusion_match || !!whitelist_match
122
+ initial_purgelist.reject do |path|
123
+ regular_desireds.any? { |desired| matches?(desired, path) }
58
124
  end
59
125
  end
60
126
 
@@ -1,3 +1,5 @@
1
+ require 'r10k/logging'
2
+
1
3
  module R10K
2
4
  module Util
3
5
 
@@ -1,3 +1,4 @@
1
+ require 'r10k/logging'
1
2
  require 'r10k/util/platform'
2
3
 
3
4
  module R10K
data/lib/r10k/version.rb CHANGED
@@ -2,5 +2,5 @@ module R10K
2
2
  # When updating to a new major (X) or minor (Y) version, include `#major` or
3
3
  # `#minor` (respectively) in your commit message to trigger the appropriate
4
4
  # release. Otherwise, a new patch (Z) version will be released.
5
- VERSION = '3.9.3'
5
+ VERSION = '3.12.1'
6
6
  end