bolt 2.15.0 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -0
  3. data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -0
  5. data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +1 -0
  6. data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +1 -0
  7. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +1 -0
  8. data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +1 -0
  9. data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +1 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +1 -0
  11. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +1 -0
  12. data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
  13. data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +1 -0
  14. data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +1 -0
  15. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -0
  16. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +2 -1
  17. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -0
  18. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +2 -1
  19. data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +1 -0
  20. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
  21. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +1 -0
  22. data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +1 -0
  23. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
  24. data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +1 -0
  25. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
  26. data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +1 -0
  27. data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
  28. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
  29. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +2 -0
  30. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +1 -0
  31. data/bolt-modules/file/lib/puppet/functions/file/join.rb +2 -0
  32. data/bolt-modules/file/lib/puppet/functions/file/read.rb +2 -0
  33. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +2 -0
  34. data/bolt-modules/file/lib/puppet/functions/file/write.rb +2 -0
  35. data/bolt-modules/out/lib/puppet/functions/out/message.rb +2 -0
  36. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +1 -0
  37. data/bolt-modules/system/lib/puppet/functions/system/env.rb +2 -0
  38. data/lib/bolt/applicator.rb +2 -1
  39. data/lib/bolt/bolt_option_parser.rb +7 -7
  40. data/lib/bolt/cli.rb +3 -4
  41. data/lib/bolt/config.rb +14 -117
  42. data/lib/bolt/config/options.rb +321 -0
  43. data/lib/bolt/config/transport/base.rb +16 -16
  44. data/lib/bolt/config/transport/docker.rb +9 -23
  45. data/lib/bolt/config/transport/local.rb +6 -44
  46. data/lib/bolt/config/transport/options.rb +305 -0
  47. data/lib/bolt/config/transport/orch.rb +9 -18
  48. data/lib/bolt/config/transport/remote.rb +3 -6
  49. data/lib/bolt/config/transport/ssh.rb +55 -149
  50. data/lib/bolt/config/transport/winrm.rb +18 -47
  51. data/lib/bolt/inventory/group.rb +1 -1
  52. data/lib/bolt/inventory/inventory.rb +0 -14
  53. data/lib/bolt/inventory/target.rb +18 -5
  54. data/lib/bolt/pal.rb +3 -1
  55. data/lib/bolt/project.rb +21 -38
  56. data/lib/bolt/shell/bash.rb +9 -9
  57. data/lib/bolt/shell/powershell.rb +2 -1
  58. data/lib/bolt/transport/docker.rb +1 -1
  59. data/lib/bolt/version.rb +1 -1
  60. metadata +4 -2
@@ -7,24 +7,15 @@ module Bolt
7
7
  class Config
8
8
  module Transport
9
9
  class Orch < Base
10
- # NOTE: All transport configuration options should have a corresponding schema definition
11
- # in schemas/bolt-transport-definitions.json
12
- OPTIONS = {
13
- "cacert" => { type: String,
14
- desc: "The path to the CA certificate." },
15
- "host" => { type: String,
16
- desc: "Host name." },
17
- "job-poll-interval" => { type: Integer,
18
- desc: "Set interval to poll orchestrator for job status." },
19
- "job-poll-timeout" => { type: Integer,
20
- desc: "Set time to wait for orchestrator job status." },
21
- "service-url" => { type: String,
22
- desc: "The URL of the orchestrator API." },
23
- "task-environment" => { type: String,
24
- desc: "The environment the orchestrator loads task code from." },
25
- "token-file" => { type: String,
26
- desc: "The path to the token file." }
27
- }.freeze
10
+ OPTIONS = %w[
11
+ cacert
12
+ host
13
+ job-poll-interval
14
+ job-poll-timeout
15
+ service-url
16
+ task-environment
17
+ token-file
18
+ ].freeze
28
19
 
29
20
  DEFAULTS = {
30
21
  "task-environment" => "production"
@@ -7,12 +7,9 @@ module Bolt
7
7
  class Config
8
8
  module Transport
9
9
  class Remote < Base
10
- # NOTE: All transport configuration options should have a corresponding schema definition
11
- # in schemas/bolt-transport-definitions.json
12
- OPTIONS = {
13
- "run-on" => { type: String,
14
- desc: "The proxy target that the task executes on." }
15
- }.freeze
10
+ OPTIONS = %w[
11
+ run-on
12
+ ].freeze
16
13
 
17
14
  DEFAULTS = {
18
15
  "run-on" => "localhost"
@@ -7,148 +7,68 @@ module Bolt
7
7
  class Config
8
8
  module Transport
9
9
  class SSH < Base
10
- LOGIN_SHELLS = %w[sh bash zsh dash ksh powershell].freeze
11
-
12
- # NOTE: All transport configuration options should have a corresponding schema definition
13
- # in schemas/bolt-transport-definitions.json
14
- OPTIONS = {
15
- "cleanup" => { type: TrueClass,
16
- external: true,
17
- desc: "Whether to clean up temporary files created on targets." },
18
- "connect-timeout" => { type: Integer,
19
- desc: "How long to wait when establishing connections." },
20
- "copy-command" => { external: true,
21
- desc: "Command to use when copying files using ssh-command. "\
22
- "Bolt runs `<copy-command> <src> <dest>`. **This option is "\
23
- "experimental.**" },
24
- "disconnect-timeout" => { type: Integer,
25
- desc: "How long to wait before force-closing a connection." },
26
- "encryption-algorithms" => { type: Array,
27
- desc: "List of encryption algorithms to use when establishing a "\
28
- "connection with a target. Supported algorithms are "\
29
- "defined by the Ruby net-ssh library and can be viewed "\
30
- "[here](https://github.com/net-ssh/net-ssh#supported-algorithms). "\
31
- "All supported, non-deprecated algorithms are available by default when "\
32
- "this option is not used. To reference all default algorithms "\
33
- "when using this option, add 'defaults' to the list of supported "\
34
- "algorithms." },
35
- "extensions" => { type: Array,
36
- desc: "List of file extensions that are accepted for scripts or tasks on "\
37
- "Windows. Scripts with these file extensions rely on the target's file "\
38
- "type association to run. For example, if Python is installed on the "\
39
- "system, a `.py` script runs with `python.exe`. The extensions `.ps1`, "\
40
- "`.rb`, and `.pp` are always allowed and run via hard-coded "\
41
- "executables." },
42
- "host" => { type: String,
43
- external: true,
44
- desc: "Host name." },
45
- "host-key-algorithms" => { type: Array,
46
- desc: "List of host key algorithms to use when establishing a connection "\
47
- "with a target. Supported algorithms are defined by the Ruby net-ssh "\
48
- "library "\
49
- "([docs](https://github.com/net-ssh/net-ssh#supported-algorithms)). "\
50
- "All supported, non-deprecated algorithms are available by default when "\
51
- "this option is not used. To reference all default algorithms "\
52
- "using this option, add 'defaults' to the list of supported "\
53
- "algorithms." },
54
- "host-key-check" => { type: TrueClass,
55
- external: true,
56
- desc: "Whether to perform host key validation when connecting." },
57
- "interpreters" => { type: Hash,
58
- external: true,
59
- desc: "A map of an extension name to the absolute path of an executable, "\
60
- "enabling you to override the shebang defined in a task executable. "\
61
- "The extension can optionally be specified with the `.` character "\
62
- "(`.py` and `py` both map to a task executable `task.py`) and the "\
63
- "extension is case sensitive. When a target's name is `localhost`, "\
64
- "Ruby tasks run with the Bolt Ruby interpreter by default." },
65
- "kex-algorithms" => { type: Array,
66
- desc: "List of key exchange algorithms to use when establishing a "\
67
- "connection to a target. Supported algorithms are defined by the "\
68
- "Ruby net-ssh library "\
69
- "([docs](https://github.com/net-ssh/net-ssh#supported-algorithms)). "\
70
- "All supported, non-deprecated algorithms are available by default when "\
71
- "this option is not used. To reference all default algorithms "\
72
- "using this option, add 'defaults' to the list of supported "\
73
- "algorithms." },
74
- "load-config" => { type: TrueClass,
75
- desc: "Whether to load system SSH configuration." },
76
- "login-shell" => { type: String,
77
- desc: "Which login shell Bolt should expect on the target. "\
78
- "Supported shells are #{LOGIN_SHELLS.join(', ')}. "\
79
- "**This option is experimental.**" },
80
- "mac-algorithms" => { type: Array,
81
- desc: "List of message authentication code algorithms to use when "\
82
- "establishing a connection to a target. Supported algorithms are "\
83
- "defined by the Ruby net-ssh library "\
84
- "([docs](https://github.com/net-ssh/net-ssh#supported-algorithms)). "\
85
- "All supported, non-deprecated algorithms are available by default when "\
86
- "this option is not used. To reference all default algorithms "\
87
- "using this option, add 'defaults' to the list of supported "\
88
- "algorithms." },
89
- "password" => { type: String,
90
- desc: "Login password." },
91
- "port" => { type: Integer,
92
- external: true,
93
- desc: "Connection port." },
94
- "private-key" => { external: true,
95
- desc: "Either the path to the private key file to use for authentication, or "\
96
- "a hash with the key `key-data` and the contents of the private key." },
97
- "proxyjump" => { type: String,
98
- desc: "A jump host to proxy connections through, and an optional user to "\
99
- "connect with." },
100
- "run-as" => { type: String,
101
- external: true,
102
- desc: "A different user to run commands as after login." },
103
- "run-as-command" => { type: Array,
104
- external: true,
105
- desc: "The command to elevate permissions. Bolt appends the user and command "\
106
- "strings to the configured `run-as-command` before running it on the "\
107
- "target. This command must not require an interactive password prompt, "\
108
- "and the `sudo-password` option is ignored when `run-as-command` is "\
109
- "specified. The `run-as-command` must be specified as an array." },
110
- "script-dir" => { type: String,
111
- external: true,
112
- desc: "The subdirectory of the tmpdir to use in place of a randomized "\
113
- "subdirectory for uploading and executing temporary files on the "\
114
- "target. It's expected that this directory already exists as a subdir "\
115
- "of tmpdir, which is either configured or defaults to `/tmp`." },
116
- "ssh-command" => { external: true,
117
- desc: "Command and flags to use when SSHing. This enables the external "\
118
- "SSH transport which shells out to the specified command. "\
119
- "**This option is experimental.**" },
120
- "sudo-executable" => { type: String,
121
- external: true,
122
- desc: "The executable to use when escalating to the configured `run-as` "\
123
- "user. This is useful when you want to escalate using the configured "\
124
- "`sudo-password`, since `run-as-command` does not use `sudo-password` "\
125
- "or support prompting. The command executed on the target is "\
126
- "`<sudo-executable> -S -u <user> -p custom_bolt_prompt <command>`. "\
127
- "**This option is experimental.**" },
128
- "sudo-password" => { type: String,
129
- external: true,
130
- desc: "Password to use when changing users via `run-as`." },
131
- "tmpdir" => { type: String,
132
- external: true,
133
- desc: "The directory to upload and execute temporary files on the target." },
134
- "tty" => { type: TrueClass,
135
- desc: "Request a pseudo tty for the session. This option is generally "\
136
- "only used in conjunction with the `run-as` option when the sudoers "\
137
- "policy requires a `tty`." },
138
- "user" => { type: String,
139
- external: true,
140
- desc: "Login user." }
141
- }.freeze
10
+ # Options available when using the net-ssh-based transport
11
+ OPTIONS = %w[
12
+ cleanup
13
+ connect-timeout
14
+ disconnect-timeout
15
+ encryption-algorithms
16
+ extensions
17
+ host
18
+ host-key-algorithms
19
+ host-key-check
20
+ interpreters
21
+ kex-algorithms
22
+ load-config
23
+ login-shell
24
+ mac-algorithms
25
+ password
26
+ port
27
+ private-key
28
+ proxyjump
29
+ script-dir
30
+ tmpdir
31
+ tty
32
+ user
33
+ ].concat(RUN_AS_OPTIONS).sort.freeze
34
+
35
+ # Options available when using the external ssh transport
36
+ EXTERNAL_OPTIONS = %w[
37
+ cleanup
38
+ copy-command
39
+ host
40
+ host-key-check
41
+ interpreters
42
+ port
43
+ private-key
44
+ script-dir
45
+ ssh-command
46
+ tmpdir
47
+ user
48
+ ].concat(RUN_AS_OPTIONS).sort.freeze
142
49
 
143
50
  DEFAULTS = {
144
51
  "cleanup" => true,
145
52
  "connect-timeout" => 10,
146
- "tty" => false,
147
- "load-config" => true,
148
53
  "disconnect-timeout" => 5,
149
- "login-shell" => 'bash'
54
+ "load-config" => true,
55
+ "login-shell" => 'bash',
56
+ "tty" => false
150
57
  }.freeze
151
58
 
59
+ # The set of options available for the ssh and external ssh transports overlap, so we
60
+ # need to check which transport is used before fully initializing, otherwise options
61
+ # may not be filtered correctly.
62
+ def initialize(data = {}, project = nil)
63
+ assert_hash_or_config(data)
64
+ @external = true if data['ssh-command']
65
+ super(data, project)
66
+ end
67
+
68
+ private def filter(unfiltered)
69
+ @external ? unfiltered.slice(*EXTERNAL_OPTIONS) : unfiltered.slice(*OPTIONS)
70
+ end
71
+
152
72
  private def validate
153
73
  super
154
74
 
@@ -201,20 +121,6 @@ module Bolt
201
121
  msg = 'Cannot use external SSH transport with load-config set to false'
202
122
  raise Bolt::ValidationError, msg
203
123
  end
204
-
205
- if (ssh_cmd = @config['ssh-command'])
206
- unless ssh_cmd.is_a?(String) || ssh_cmd.is_a?(Array)
207
- raise Bolt::ValidationError,
208
- "ssh-command must be a String or Array, received #{ssh_cmd.class} #{ssh_cmd.inspect}"
209
- end
210
- end
211
-
212
- if (copy_cmd = @config['copy-command'])
213
- unless copy_cmd.is_a?(String) || copy_cmd.is_a?(Array)
214
- raise Bolt::ValidationError,
215
- "copy-command must be a String or Array, received #{copy_cmd.class} #{copy_cmd.inspect}"
216
- end
217
- end
218
124
  end
219
125
  end
220
126
  end
@@ -7,53 +7,24 @@ module Bolt
7
7
  class Config
8
8
  module Transport
9
9
  class WinRM < Base
10
- # NOTE: All transport configuration options should have a corresponding schema definition
11
- # in schemas/bolt-transport-definitions.json
12
- OPTIONS = {
13
- "basic-auth-only" => { type: TrueClass,
14
- desc: "Force basic authentication. This option is only available when using SSL." },
15
- "cacert" => { type: String,
16
- desc: "The path to the CA certificate." },
17
- "cleanup" => { type: TrueClass,
18
- desc: "Whether to clean up temporary files created on targets." },
19
- "connect-timeout" => { type: Integer,
20
- desc: "How long Bolt should wait when establishing connections." },
21
- "extensions" => { type: Array,
22
- desc: "List of file extensions that are accepted for scripts or tasks. "\
23
- "Scripts with these file extensions rely on the target's file type "\
24
- "association to run. For example, if Python is installed on the system, "\
25
- "a `.py` script runs with `python.exe`. The extensions `.ps1`, `.rb`, and "\
26
- "`.pp` are always allowed and run via hard-coded executables." },
27
- "file-protocol" => { type: String,
28
- desc: "Which file transfer protocol to use. Either `winrm` or `smb`. Using `smb` is "\
29
- "recommended for large file transfers." },
30
- "host" => { type: String,
31
- desc: "Host name." },
32
- "interpreters" => { type: Hash,
33
- desc: "A map of an extension name to the absolute path of an executable, "\
34
- "enabling you to override the shebang defined in a task executable. The "\
35
- "extension can optionally be specified with the `.` character (`.py` and "\
36
- "`py` both map to a task executable `task.py`) and the extension is case "\
37
- "sensitive. When a target's name is `localhost`, Ruby tasks run with the "\
38
- "Bolt Ruby interpreter by default." },
39
- "password" => { type: String,
40
- desc: "Login password. **Required unless using Kerberos.**" },
41
- "port" => { type: Integer,
42
- desc: "Connection port." },
43
- "realm" => { type: String,
44
- desc: "Kerberos realm (Active Directory domain) to authenticate against." },
45
- "smb-port" => { type: Integer,
46
- desc: "With file-protocol set to smb, this is the port to establish a "\
47
- "connection on." },
48
- "ssl" => { type: TrueClass,
49
- desc: "When true, Bolt uses secure https connections for WinRM." },
50
- "ssl-verify" => { type: TrueClass,
51
- desc: "When true, verifies the targets certificate matches the cacert." },
52
- "tmpdir" => { type: String,
53
- desc: "The directory to upload and execute temporary files on the target." },
54
- "user" => { type: String,
55
- desc: "Login user. **Required unless using Kerberos.**" }
56
- }.freeze
10
+ OPTIONS = %w[
11
+ basic-auth-only
12
+ cacert
13
+ cleanup
14
+ connect-timeout
15
+ extensions
16
+ file-protocol
17
+ host
18
+ interpreters
19
+ password
20
+ port
21
+ realm
22
+ smb-port
23
+ ssl
24
+ ssl-verify
25
+ tmpdir
26
+ user
27
+ ].freeze
57
28
 
58
29
  DEFAULTS = {
59
30
  "basic-auth-only" => false,
@@ -16,7 +16,7 @@ module Bolt
16
16
  DATA_KEYS = %w[config facts vars features plugin_hooks].freeze
17
17
  TARGET_KEYS = DATA_KEYS + %w[name alias uri]
18
18
  GROUP_KEYS = DATA_KEYS + %w[name groups targets]
19
- CONFIG_KEYS = Bolt::Config::INVENTORY_CONFIG.keys
19
+ CONFIG_KEYS = Bolt::Config::INVENTORY_OPTIONS.keys
20
20
 
21
21
  def initialize(input, plugins)
22
22
  @logger = Logging.logger[self]
@@ -78,20 +78,6 @@ module Bolt
78
78
  target_array.first
79
79
  end
80
80
 
81
- def self.localhost_defaults(data)
82
- defaults = {
83
- 'config' => {
84
- 'transport' => 'local',
85
- 'local' => { 'interpreters' => { '.rb' => RbConfig.ruby } }
86
- },
87
- 'features' => ['puppet-agent']
88
- }
89
- data = Bolt::Util.deep_merge(defaults, data)
90
- # If features is an empty array deep_merge won't add the puppet-agent
91
- data['features'] += ['puppet-agent'] if data['features'].empty?
92
- data
93
- end
94
-
95
81
  #### PRIVATE ####
96
82
  def group_data_for(target_name)
97
83
  @groups.group_collect(target_name)
@@ -30,6 +30,10 @@ module Bolt
30
30
  @safe_name = @uri_obj.omit(:password).to_str.sub(%r{^//}, '')
31
31
  end
32
32
 
33
+ if @name == 'localhost'
34
+ target_data = localhost_defaults(target_data)
35
+ end
36
+
33
37
  @config = target_data['config'] || {}
34
38
  @vars = target_data['vars'] || {}
35
39
  @facts = target_data['facts'] || {}
@@ -45,6 +49,20 @@ module Bolt
45
49
  validate
46
50
  end
47
51
 
52
+ def localhost_defaults(data)
53
+ defaults = {
54
+ 'config' => {
55
+ 'transport' => 'local',
56
+ 'local' => { 'interpreters' => { '.rb' => RbConfig.ruby } }
57
+ },
58
+ 'features' => ['puppet-agent']
59
+ }
60
+ data = Bolt::Util.deep_merge(defaults, data)
61
+ # If features is an empty array deep_merge won't add the puppet-agent
62
+ data['features'] += ['puppet-agent'] if data['features'].empty?
63
+ data
64
+ end
65
+
48
66
  # rubocop:disable Naming/AccessorMethodName
49
67
  def set_resource(resource)
50
68
  if (existing_resource = resources[resource.reference])
@@ -218,11 +236,6 @@ module Bolt
218
236
  'target_alias' => []
219
237
  }
220
238
 
221
- # This should be handled by `get_targets`
222
- if @name == 'localhost'
223
- group_data = Bolt::Inventory::Inventory.localhost_defaults(group_data)
224
- end
225
-
226
239
  @group_cache = group_data
227
240
  end
228
241
 
@@ -137,7 +137,9 @@ module Bolt
137
137
  # TODO: If we always call this inside a bolt_executor we can remove this here
138
138
  setup
139
139
  r = Puppet::Pal.in_tmp_environment('bolt', modulepath: @modulepath, facts: {}) do |pal|
140
- Puppet.override(bolt_project: @project,
140
+ # Only load the project if it a) exists, b) has a name it can be loaded with
141
+ bolt_project = @project if @project&.name
142
+ Puppet.override(bolt_project: bolt_project,
141
143
  yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
142
144
  pal.with_script_compiler do |compiler|
143
145
  alias_types(compiler)
@@ -9,8 +9,10 @@ module Bolt
9
9
  BOLTDIR_NAME = 'Boltdir'
10
10
  PROJECT_SETTINGS = {
11
11
  "name" => "The name of the project",
12
- "plans" => "An array of plan names to whitelist. Whitelisted plans are included in `bolt plan show` output",
13
- "tasks" => "An array of task names to whitelist. Whitelisted plans are included in `bolt task show` output"
12
+ "plans" => "An array of plan names to show, if they exist in the project."\
13
+ "These plans are included in `bolt plan show` output",
14
+ "tasks" => "An array of task names to show, if they exist in the project."\
15
+ "These tasks are included in `bolt task show` output"
14
16
  }.freeze
15
17
 
16
18
  attr_reader :path, :data, :config_file, :inventory_file, :modulepath, :hiera_config,
@@ -67,17 +69,17 @@ module Bolt
67
69
  @resource_types = @path + '.resource_types'
68
70
  @type = type
69
71
 
70
- tc = Bolt::Config::INVENTORY_CONFIG.keys & raw_data.keys
72
+ tc = Bolt::Config::INVENTORY_OPTIONS.keys & raw_data.keys
71
73
  if tc.any?
72
74
  msg = "Transport configuration isn't supported in bolt-project.yaml. Ignoring keys #{tc}"
73
75
  @warnings << { msg: msg }
74
76
  end
75
77
 
76
- @data = raw_data.reject { |k, _| Bolt::Config::INVENTORY_CONFIG.keys.include?(k) }
78
+ @data = raw_data.reject { |k, _| Bolt::Config::INVENTORY_OPTIONS.include?(k) }
77
79
 
78
80
  # Once bolt.yaml deprecation is removed, this attribute should be removed
79
81
  # and replaced with .project_file in lib/bolt/config.rb
80
- @config_file = if (Bolt::Config::OPTIONS.keys & @data.keys).any?
82
+ @config_file = if (Bolt::Config::BOLT_OPTIONS & @data.keys).any?
81
83
  if (@path + 'bolt.yaml').file?
82
84
  msg = "bolt-project.yaml contains valid config keys, bolt.yaml will be ignored"
83
85
  @warnings << { msg: msg }
@@ -109,10 +111,7 @@ module Bolt
109
111
  end
110
112
 
111
113
  def name
112
- # If the project is in mymod/Boltdir/bolt-project.yaml, use mymod as the project name
113
- dirname = @path.basename.to_s == 'Boltdir' ? @path.parent.basename.to_s : @path.basename.to_s
114
- pname = @data['name'] || dirname
115
- pname.include?('-') ? pname.split('-', 2)[1] : pname
114
+ @data['name']
116
115
  end
117
116
 
118
117
  def tasks
@@ -123,36 +122,20 @@ module Bolt
123
122
  @data['plans']
124
123
  end
125
124
 
126
- def project_directory_name?(name)
127
- # it must match an installed project name according to forge validator
128
- name =~ /^[a-z][a-z0-9_]*$/
129
- end
130
-
131
- def project_namespaced_name?(name)
132
- # it must match the full project name according to forge validator
133
- name =~ /^[a-zA-Z0-9]+[-][a-z][a-z0-9_]*$/
134
- end
135
-
136
125
  def validate
137
- n = @data['name']
138
- if n && !project_directory_name?(n) && !project_namespaced_name?(n)
139
- raise Bolt::ValidationError, <<~ERROR_STRING
140
- Invalid project name '#{n}' in bolt-project.yaml; project names must match either:
141
- An installed project name (ex. projectname) matching the expression /^[a-z][a-z0-9_]*$/ -or-
142
- A namespaced project name (ex. author-projectname) matching the expression /^[a-zA-Z0-9]+[-][a-z][a-z0-9_]*$/
143
- ERROR_STRING
144
- elsif !project_directory_name?(name) && !project_namespaced_name?(name)
145
- raise Bolt::ValidationError, <<~ERROR_STRING
146
- Invalid project name '#{name}'; project names must match either:
147
- A project name (ex. projectname) matching the expression /^[a-z][a-z0-9_]*$/ -or-
148
- A namespaced project name (ex. author-projectname) matching the expression /^[a-zA-Z0-9]+[-][a-z][a-z0-9_]*$/
149
-
150
- Configure project name in <project_dir>/bolt-project.yaml
151
- ERROR_STRING
152
- # If the project name is the same as one of the built-in modules raise a warning
153
- elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
154
- raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
155
- "with a built-in Bolt module of the same name."
126
+ if name
127
+ name_regex = /^[a-z][a-z0-9_]*$/
128
+ if name !~ name_regex
129
+ raise Bolt::ValidationError, <<~ERROR_STRING
130
+ Invalid project name '#{name}' in bolt-project.yaml; project name must match #{name_regex.inspect}
131
+ ERROR_STRING
132
+ elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
133
+ raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
134
+ "with a built-in Bolt module of the same name."
135
+ end
136
+ else
137
+ message = "No project name is specified in bolt-project.yaml. Project-level content will not be available."
138
+ @warnings << { msg: message }
156
139
  end
157
140
 
158
141
  %w[tasks plans].each do |conf|