chef-config 17.10.29 → 18.0.169

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,143 +1,143 @@
1
- # Author:: Bryan McLellan <btm@loftninjas.org>
2
- # Copyright:: Copyright (c) Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require_relative "credentials"
19
- autoload :Train, "train"
20
- require_relative "../config"
21
- require "chef-utils/dist" unless defined?(ChefUtils::Dist)
22
-
23
- module ChefConfig
24
- module Mixin
25
- module TrainTransport
26
- include ChefConfig::Mixin::Credentials
27
-
28
- attr_accessor :logger
29
-
30
- def initialize(logger)
31
- @logger = logger
32
- end
33
-
34
- #
35
- # Returns a RFC099 credentials profile as a hash
36
- #
37
- def load_credentials(profile)
38
- # Tomlrb.load_file returns a hash with keys as strings
39
- credentials = parse_credentials_file
40
- if contains_split_fqdn?(credentials, profile)
41
- logger.warn("Credentials file #{credentials_file_path} contains target '#{profile}' as a Hash, expected a string.")
42
- logger.warn("Hostnames must be surrounded by single quotes, e.g. ['host.example.org']")
43
- end
44
-
45
- # host names must be specified in credentials file as ['foo.example.org'] with quotes
46
- if !credentials.nil? && !credentials[profile].nil?
47
- credentials[profile].transform_keys(&:to_sym) # return symbolized keys to match Train.options()
48
- else
49
- nil
50
- end
51
- end
52
-
53
- # Toml creates hashes when a key is separated by periods, e.g.
54
- # [host.example.org] => { host: { example: { org: {} } } }
55
- #
56
- # Returns true if the above example is true
57
- #
58
- # A hostname has to be specified as ['host.example.org']
59
- # This will be a common mistake so we should catch it
60
- #
61
- def contains_split_fqdn?(hash, fqdn)
62
- fqdn.split(".").reduce(hash) do |h, k|
63
- v = h[k]
64
- if Hash === v
65
- v
66
- else
67
- break false
68
- end
69
- end
70
- end
71
-
72
- # ChefConfig::Mixin::Credentials.credentials_file_path is designed around knife,
73
- # overriding it here.
74
- #
75
- # Credentials file preference:
76
- #
77
- # 1) target_mode.credentials_file
78
- # 2) /etc/chef/TARGET_MODE_HOST/credentials
79
- # 3) #credentials_file_path from parent ($HOME/.chef/credentials)
80
- #
81
- def credentials_file_path
82
- tm_config = config.target_mode
83
- profile = tm_config.host
84
-
85
- credentials_file =
86
- if tm_config.credentials_file && File.exist?(tm_config.credentials_file)
87
- tm_config.credentials_file
88
- elsif File.exist?(config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials"))
89
- config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials")
90
- else
91
- super
92
- end
93
-
94
- raise ArgumentError, "No credentials file found for target '#{profile}'" unless credentials_file
95
- raise ArgumentError, "Credentials file specified for target mode does not exist: '#{credentials_file}'" unless File.exist?(credentials_file)
96
-
97
- logger.debug("Loading credentials file '#{credentials_file}' for target '#{profile}'")
98
-
99
- credentials_file
100
- end
101
-
102
- def build_transport
103
- return nil unless config.target_mode?
104
-
105
- # TODO: Consider supporting parsing the protocol from a URI passed to `--target`
106
- #
107
- train_config = {}
108
-
109
- # Load the target_mode config context from config, and place any valid settings into the train configuration
110
- tm_config = config.target_mode
111
-
112
- # Load the credentials file, and place any valid settings into the train configuration
113
- credentials = load_credentials(tm_config.host)
114
-
115
- protocol = credentials[:transport_protocol] || tm_config.protocol
116
- train_config = tm_config.to_hash.select { |k| Train.options(protocol).key?(k) }
117
- logger.trace("Using target mode options from #{ChefUtils::Dist::Infra::PRODUCT} config file: #{train_config.keys.join(", ")}") if train_config
118
-
119
- if credentials
120
- valid_settings = credentials.select { |k| Train.options(protocol).key?(k) }
121
- valid_settings[:enable_password] = credentials[:enable_password] if credentials.key?(:enable_password)
122
- train_config.merge!(valid_settings)
123
- logger.trace("Using target mode options from credentials file: #{valid_settings.keys.join(", ")}") if valid_settings
124
- end
125
-
126
- train_config[:logger] = logger
127
-
128
- # Train handles connection retries for us
129
- Train.create(protocol, train_config)
130
- rescue SocketError => e # likely a dns failure, not caught by train
131
- e.message.replace "Error connecting to #{train_config[:target]} via #{protocol} - #{e.message}"
132
- raise e
133
- rescue Train::PluginLoadError
134
- logger.error("Invalid target mode protocol: #{protocol}")
135
- exit(1)
136
- end
137
-
138
- def config
139
- raise NotImplementedError
140
- end
141
- end
142
- end
143
- end
1
+ # Author:: Bryan McLellan <btm@loftninjas.org>
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require_relative "credentials"
19
+ autoload :Train, "train"
20
+ require_relative "../config"
21
+ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
22
+
23
+ module ChefConfig
24
+ module Mixin
25
+ module TrainTransport
26
+ include ChefConfig::Mixin::Credentials
27
+
28
+ attr_accessor :logger
29
+
30
+ def initialize(logger)
31
+ @logger = logger
32
+ end
33
+
34
+ #
35
+ # Returns a RFC099 credentials profile as a hash
36
+ #
37
+ def load_credentials(profile)
38
+ # Tomlrb.load_file returns a hash with keys as strings
39
+ credentials = parse_credentials_file
40
+ if contains_split_fqdn?(credentials, profile)
41
+ logger.warn("Credentials file #{credentials_file_path} contains target '#{profile}' as a Hash, expected a string.")
42
+ logger.warn("Hostnames must be surrounded by single quotes, e.g. ['host.example.org']")
43
+ end
44
+
45
+ # host names must be specified in credentials file as ['foo.example.org'] with quotes
46
+ if !credentials.nil? && !credentials[profile].nil?
47
+ credentials[profile].transform_keys(&:to_sym) # return symbolized keys to match Train.options()
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ # Toml creates hashes when a key is separated by periods, e.g.
54
+ # [host.example.org] => { host: { example: { org: {} } } }
55
+ #
56
+ # Returns true if the above example is true
57
+ #
58
+ # A hostname has to be specified as ['host.example.org']
59
+ # This will be a common mistake so we should catch it
60
+ #
61
+ def contains_split_fqdn?(hash, fqdn)
62
+ fqdn.split(".").reduce(hash) do |h, k|
63
+ v = h[k]
64
+ if Hash === v
65
+ v
66
+ else
67
+ break false
68
+ end
69
+ end
70
+ end
71
+
72
+ # ChefConfig::Mixin::Credentials.credentials_file_path is designed around knife,
73
+ # overriding it here.
74
+ #
75
+ # Credentials file preference:
76
+ #
77
+ # 1) target_mode.credentials_file
78
+ # 2) /etc/chef/TARGET_MODE_HOST/credentials
79
+ # 3) #credentials_file_path from parent ($HOME/.chef/credentials)
80
+ #
81
+ def credentials_file_path
82
+ tm_config = config.target_mode
83
+ profile = tm_config.host
84
+
85
+ credentials_file =
86
+ if tm_config.credentials_file && File.exist?(tm_config.credentials_file)
87
+ tm_config.credentials_file
88
+ elsif File.exist?(config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials"))
89
+ config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials")
90
+ else
91
+ super
92
+ end
93
+
94
+ raise ArgumentError, "No credentials file found for target '#{profile}'" unless credentials_file
95
+ raise ArgumentError, "Credentials file specified for target mode does not exist: '#{credentials_file}'" unless File.exist?(credentials_file)
96
+
97
+ logger.debug("Loading credentials file '#{credentials_file}' for target '#{profile}'")
98
+
99
+ credentials_file
100
+ end
101
+
102
+ def build_transport
103
+ return nil unless config.target_mode?
104
+
105
+ # TODO: Consider supporting parsing the protocol from a URI passed to `--target`
106
+ #
107
+ train_config = {}
108
+
109
+ # Load the target_mode config context from config, and place any valid settings into the train configuration
110
+ tm_config = config.target_mode
111
+
112
+ # Load the credentials file, and place any valid settings into the train configuration
113
+ credentials = load_credentials(tm_config.host)
114
+
115
+ protocol = credentials[:transport_protocol] || tm_config.protocol
116
+ train_config = tm_config.to_hash.select { |k| Train.options(protocol).key?(k) }
117
+ logger.trace("Using target mode options from #{ChefUtils::Dist::Infra::PRODUCT} config file: #{train_config.keys.join(", ")}") if train_config
118
+
119
+ if credentials
120
+ valid_settings = credentials.select { |k| Train.options(protocol).key?(k) }
121
+ valid_settings[:enable_password] = credentials[:enable_password] if credentials.key?(:enable_password)
122
+ train_config.merge!(valid_settings)
123
+ logger.trace("Using target mode options from credentials file: #{valid_settings.keys.join(", ")}") if valid_settings
124
+ end
125
+
126
+ train_config[:logger] = logger
127
+
128
+ # Train handles connection retries for us
129
+ Train.create(protocol, train_config)
130
+ rescue SocketError => e # likely a dns failure, not caught by train
131
+ e.message.replace "Error connecting to #{train_config[:target]} via #{protocol} - #{e.message}"
132
+ raise e
133
+ rescue Train::PluginLoadError
134
+ logger.error("Invalid target mode protocol: #{protocol}")
135
+ exit(1)
136
+ end
137
+
138
+ def config
139
+ raise NotImplementedError
140
+ end
141
+ end
142
+ end
143
+ end