right_link 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/actors/agent_manager.rb +88 -0
- data/actors/instance_scheduler.rb +321 -0
- data/actors/instance_services.rb +64 -0
- data/actors/instance_setup.rb +567 -0
- data/bin/cloud +25 -0
- data/bin/cook_runner +44 -0
- data/bin/deploy +120 -0
- data/bin/enroll +385 -0
- data/bin/rad +32 -0
- data/bin/rchk +29 -0
- data/bin/rnac +39 -0
- data/bin/rs_connect +33 -0
- data/bin/rs_log_level +31 -0
- data/bin/rs_ohai +28 -0
- data/bin/rs_reenroll +31 -0
- data/bin/rs_run_recipe +34 -0
- data/bin/rs_run_right_script +34 -0
- data/bin/rs_shutdown +33 -0
- data/bin/rs_tag +33 -0
- data/bin/rs_thunk +33 -0
- data/bin/rstat +31 -0
- data/bin/system +16 -0
- data/ext/Rakefile +18 -0
- data/init/config.yml +5 -0
- data/init/init.rb +79 -0
- data/lib/chef/ohai_setup.rb +51 -0
- data/lib/chef/plugins/cloud.rb +91 -0
- data/lib/chef/plugins/cloudstack.rb +23 -0
- data/lib/chef/plugins/ec2.rb +23 -0
- data/lib/chef/plugins/linux/block_device2.rb +24 -0
- data/lib/chef/plugins/rackspace.rb +23 -0
- data/lib/chef/plugins/rightscale.rb +125 -0
- data/lib/chef/plugins/windows/network.rb +114 -0
- data/lib/chef/plugins.rb +74 -0
- data/lib/chef/providers/dns_dnsmadeeasy_provider.rb +81 -0
- data/lib/chef/providers/dns_resource.rb +100 -0
- data/lib/chef/providers/executable_schedule_provider.rb +70 -0
- data/lib/chef/providers/executable_schedule_resource.rb +144 -0
- data/lib/chef/providers/remote_recipe_provider.rb +86 -0
- data/lib/chef/providers/remote_recipe_resource.rb +101 -0
- data/lib/chef/providers/right_link_tag_provider.rb +73 -0
- data/lib/chef/providers/right_link_tag_resource.rb +59 -0
- data/lib/chef/providers/right_script_provider.rb +190 -0
- data/lib/chef/providers/right_script_resource.rb +113 -0
- data/lib/chef/providers/rs_shutdown_provider.rb +75 -0
- data/lib/chef/providers/rs_shutdown_resource.rb +55 -0
- data/lib/chef/providers/server_collection_provider.rb +66 -0
- data/lib/chef/providers/server_collection_resource.rb +93 -0
- data/lib/chef/providers/windows/powershell_provider.rb +151 -0
- data/lib/chef/providers/windows/powershell_resource.rb +111 -0
- data/lib/chef/providers/windows/unsupported_provider.rb +51 -0
- data/lib/chef/right_providers.rb +55 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.csproj +104 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.dll-Help.xml +141 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Exceptions.cs +182 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionCommand.cs +178 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionRequest.cs +67 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionResponse.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueCommandBase.cs +142 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueRequestBase.cs +64 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueResponseBase.cs +69 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/JsonTransport.cs +110 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeClient.cs +158 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeServer.cs +142 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolConstants.cs +55 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolUtilities.cs +77 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ReadMe.txt +53 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeResponse.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceResponse.cs +40 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceResponse.cs +40 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueCommandBase.cs +293 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueRequestBase.cs +75 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueResponseBase.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Transport.cs +91 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet.sln +35 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Program.cs +374 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/TestChefNodeCmdlet.csproj +65 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Program.cs +136 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Properties/AssemblyInfo.cs +36 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/ReadMe.txt +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/TestNextActionCmdlet.csproj +68 -0
- data/lib/chef/windows/bin/Newtonsoft.Json.dll +0 -0
- data/lib/chef/windows/chef_node_server.rb +463 -0
- data/lib/chef/windows/dynamic_powershell_provider.rb +296 -0
- data/lib/chef/windows/pipe_server.rb +283 -0
- data/lib/chef/windows/powershell_host.rb +285 -0
- data/lib/chef/windows/powershell_pipe_server.rb +136 -0
- data/lib/chef/windows/powershell_provider_base.rb +92 -0
- data/lib/chef/windows/scripts/run_loop.ps1 +105 -0
- data/lib/clouds/cloud.rb +557 -0
- data/lib/clouds/cloud_factory.rb +250 -0
- data/lib/clouds/cloud_utilities.rb +244 -0
- data/lib/clouds/clouds/azure.rb +106 -0
- data/lib/clouds/clouds/cloudstack.rb +114 -0
- data/lib/clouds/clouds/ec2.rb +113 -0
- data/lib/clouds/clouds/eucalyptus.rb +46 -0
- data/lib/clouds/clouds/google.rb +102 -0
- data/lib/clouds/clouds/none.rb +76 -0
- data/lib/clouds/clouds/openstack.rb +30 -0
- data/lib/clouds/clouds/rackspace-ng.rb +54 -0
- data/lib/clouds/clouds/rackspace.rb +78 -0
- data/lib/clouds/clouds/softlayer.rb +91 -0
- data/lib/clouds/metadata_formatter.rb +108 -0
- data/lib/clouds/metadata_provider.rb +128 -0
- data/lib/clouds/metadata_source.rb +87 -0
- data/lib/clouds/metadata_sources/certificate_metadata_source.rb +207 -0
- data/lib/clouds/metadata_sources/config_drive_metadata_source.rb +129 -0
- data/lib/clouds/metadata_sources/file_metadata_source.rb +74 -0
- data/lib/clouds/metadata_sources/http_metadata_source.rb +277 -0
- data/lib/clouds/metadata_sources/selective_metadata_source.rb +122 -0
- data/lib/clouds/metadata_tree_climber.rb +144 -0
- data/lib/clouds/metadata_writer.rb +155 -0
- data/lib/clouds/metadata_writers/dictionary_metadata_writer.rb +72 -0
- data/lib/clouds/metadata_writers/ruby_metadata_writer.rb +76 -0
- data/lib/clouds/metadata_writers/shell_metadata_writer.rb +121 -0
- data/lib/clouds/register_clouds.rb +34 -0
- data/lib/clouds.rb +32 -0
- data/lib/gem_dependencies.rb +83 -0
- data/lib/git_hooks/commit-msg.rb +7 -0
- data/lib/instance/agent_config.rb +168 -0
- data/lib/instance/agent_watcher.rb +233 -0
- data/lib/instance/audit_cook_stub.rb +104 -0
- data/lib/instance/audit_proxy.rb +247 -0
- data/lib/instance/bundle_queue.rb +104 -0
- data/lib/instance/cook/agent_connection.rb +109 -0
- data/lib/instance/cook/audit_logger.rb +165 -0
- data/lib/instance/cook/audit_stub.rb +142 -0
- data/lib/instance/cook/ca-bundle.crt +2794 -0
- data/lib/instance/cook/chef_state.rb +211 -0
- data/lib/instance/cook/cook.rb +306 -0
- data/lib/instance/cook/cook_state.rb +298 -0
- data/lib/instance/cook/cookbook_path_mapping.rb +66 -0
- data/lib/instance/cook/cookbook_repo_retriever.rb +190 -0
- data/lib/instance/cook/executable_sequence.rb +765 -0
- data/lib/instance/cook/external_parameter_gatherer.rb +190 -0
- data/lib/instance/cook/repose_downloader.rb +349 -0
- data/lib/instance/cook/shutdown_request_proxy.rb +121 -0
- data/lib/instance/cook.rb +41 -0
- data/lib/instance/downloader.rb +208 -0
- data/lib/instance/duplicable.rb +67 -0
- data/lib/instance/exceptions.rb +49 -0
- data/lib/instance/executable_sequence_proxy.rb +278 -0
- data/lib/instance/instance_commands.rb +577 -0
- data/lib/instance/instance_state.rb +633 -0
- data/lib/instance/json_utilities.rb +102 -0
- data/lib/instance/login_manager.rb +533 -0
- data/lib/instance/login_user_manager.rb +522 -0
- data/lib/instance/message_encoder.rb +118 -0
- data/lib/instance/multi_thread_bundle_queue.rb +232 -0
- data/lib/instance/operation_context.rb +60 -0
- data/lib/instance/options_bag.rb +65 -0
- data/lib/instance/payload_formatter.rb +46 -0
- data/lib/instance/policy.rb +53 -0
- data/lib/instance/policy_audit.rb +100 -0
- data/lib/instance/policy_manager.rb +146 -0
- data/lib/instance/reenroll_manager.rb +104 -0
- data/lib/instance/right_scripts_cookbook.rb +181 -0
- data/lib/instance/shutdown_request.rb +221 -0
- data/lib/instance/single_thread_bundle_queue.rb +189 -0
- data/lib/instance/volume_management.rb +450 -0
- data/lib/instance.rb +50 -0
- data/lib/repo_conf_generators/apt_conf_generators.rb +106 -0
- data/lib/repo_conf_generators/gem_conf_generators.rb +80 -0
- data/lib/repo_conf_generators/rightscale_conf_generators.rb +254 -0
- data/lib/repo_conf_generators/rightscale_key.pub +17 -0
- data/lib/repo_conf_generators/yum_conf_generators.rb +225 -0
- data/lib/repo_conf_generators.rb +30 -0
- data/lib/run_shell.rb +28 -0
- data/scripts/agent_checker.rb +571 -0
- data/scripts/agent_controller.rb +247 -0
- data/scripts/agent_deployer.rb +148 -0
- data/scripts/bundle_runner.rb +336 -0
- data/scripts/cloud_controller.rb +176 -0
- data/scripts/log_level_manager.rb +142 -0
- data/scripts/ohai_runner.rb +33 -0
- data/scripts/reenroller.rb +193 -0
- data/scripts/server_importer.rb +293 -0
- data/scripts/shutdown_client.rb +183 -0
- data/scripts/system_configurator.rb +367 -0
- data/scripts/tagger.rb +381 -0
- data/scripts/thunker.rb +356 -0
- metadata +418 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
CONFIG_DRIVE_MOUNTPOINT = File.join(RightScale::Platform.filesystem.spool_dir, name.to_s) if ::RightScale::Platform.linux?
|
24
|
+
CONFIG_DRIVE_MOUNTPOINT = File.join(ENV['ProgramW6432'], 'RightScale', 'Mount', 'Softlayer').gsub('/', '\\') if ::RightScale::Platform.windows?
|
25
|
+
|
26
|
+
# dependencies.
|
27
|
+
metadata_source 'metadata_sources/config_drive_metadata_source'
|
28
|
+
metadata_writers 'metadata_writers/dictionary_metadata_writer',
|
29
|
+
'metadata_writers/ruby_metadata_writer',
|
30
|
+
'metadata_writers/shell_metadata_writer'
|
31
|
+
|
32
|
+
abbreviation :sl
|
33
|
+
|
34
|
+
# Parses softlayer user metadata into a hash.
|
35
|
+
#
|
36
|
+
# === Parameters
|
37
|
+
# tree_climber(MetadataTreeClimber):: tree climber
|
38
|
+
# data(String):: raw data
|
39
|
+
#
|
40
|
+
# === Return
|
41
|
+
# result(Hash):: Hash-like leaf value
|
42
|
+
def create_user_metadata_leaf(tree_climber, data)
|
43
|
+
result = tree_climber.create_branch
|
44
|
+
# REVIEW: This can (and will) raise an exception if the data is malformed or empty. I was putting it in a
|
45
|
+
# begin/rescue/end block, but there doesn't appear to be a logger in scope to report the problem and exit gracefully.
|
46
|
+
#
|
47
|
+
# Also, is it appropriate to be parsing JSON here? Is a specific tree_climber for json more appropriate?
|
48
|
+
#
|
49
|
+
# REVIEWER:
|
50
|
+
# (1) added an in-scope logger (it was always available as option(:logger)) for RightLink v5.8+
|
51
|
+
# (2) catching and logging an exception here is reasonable; added it.
|
52
|
+
# (3) as far as subclassing goes, the cloud definition methodology allows for overriding a few
|
53
|
+
# methods in the existing code base instead of having to create a custom class hierarchy for each
|
54
|
+
# cloud. either approach is supported, but the override philosophy used here seems simpler
|
55
|
+
# (especially for new cloud providers who haven't seen much ruby up till now).
|
56
|
+
parsed_data = nil
|
57
|
+
begin
|
58
|
+
parsed_data = JSON.parse(data.strip)
|
59
|
+
rescue Exception => e
|
60
|
+
logger.error("#{e.class}: #{e.message}")
|
61
|
+
end
|
62
|
+
::RightScale::CloudUtilities.split_metadata(parsed_data[0], '&', result) unless !parsed_data || parsed_data.length == 0
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
# defaults.
|
67
|
+
default_option([:user_metadata, :metadata_tree_climber, :create_leaf_override], method(:create_user_metadata_leaf))
|
68
|
+
default_option([:metadata_source, :user_metadata_source_file_path], File.join(CONFIG_DRIVE_MOUNTPOINT, 'meta.js'))
|
69
|
+
|
70
|
+
default_option([:metadata_source, :config_drive_uuid], "681B-8C5D")
|
71
|
+
default_option([:metadata_source, :config_drive_filesystem], ::RightScale::Platform.windows? ? 'FAT' : 'vfat')
|
72
|
+
default_option([:metadata_source, :config_drive_label], 'METADATA')
|
73
|
+
default_option([:metadata_source, :config_drive_mountpoint], CONFIG_DRIVE_MOUNTPOINT)
|
74
|
+
|
75
|
+
# Updates the given node with cloud metadata details.
|
76
|
+
#
|
77
|
+
# === Return
|
78
|
+
# always true
|
79
|
+
def update_details
|
80
|
+
details = {}
|
81
|
+
if ohai = @options[:ohai_node]
|
82
|
+
if platform.windows?
|
83
|
+
details[:public_ip] = ::RightScale::CloudUtilities.ip_for_windows_interface(ohai, 'Local Area Connection 2')
|
84
|
+
details[:private_ip] = ::RightScale::CloudUtilities.ip_for_windows_interface(ohai, 'Local Area Connection')
|
85
|
+
else
|
86
|
+
details[:public_ip] = ::RightScale::CloudUtilities.ip_for_interface(ohai, :eth1)
|
87
|
+
details[:private_ip] = ::RightScale::CloudUtilities.ip_for_interface(ohai, :eth0)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
return details
|
91
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010-2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightScale
|
24
|
+
|
25
|
+
# Abstracts a formatter which maps one kind of metadata output to another.
|
26
|
+
class MetadataFormatter
|
27
|
+
|
28
|
+
# RS_ is reserved for use by RightScale and should be avoided by users
|
29
|
+
# passing non-RightScale metadata to instances.
|
30
|
+
RS_METADATA_PREFIX = 'RS_'
|
31
|
+
|
32
|
+
attr_accessor :formatted_path_prefix, :format_metadata_override
|
33
|
+
|
34
|
+
# Initializer.
|
35
|
+
#
|
36
|
+
# === Parameters
|
37
|
+
# options[:formatted_path_prefix](String):: default prefix for formatted metadata keys
|
38
|
+
# options[:format_metadata_override](Proc(formatter, metadata):: format_metadata override or nil
|
39
|
+
def initialize(options = {})
|
40
|
+
# options
|
41
|
+
@formatted_path_prefix = options[:formatted_path_prefix] || RS_METADATA_PREFIX
|
42
|
+
|
43
|
+
# overrides
|
44
|
+
@format_metadata_override = options[:format_metadata_override]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Formats metadata such that any hierarchical details flattened into simple
|
48
|
+
# key names.
|
49
|
+
#
|
50
|
+
# === Parameters
|
51
|
+
# tree_metadata(Hash):: tree of raw metadata
|
52
|
+
#
|
53
|
+
# === Returns
|
54
|
+
# flat_metadata(Hash):: flattened metadata
|
55
|
+
def format_metadata(metadata)
|
56
|
+
return @format_metadata_override.call(self, metadata) if @format_metadata_override
|
57
|
+
return recursive_flatten_metadata(metadata)
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
# Recursively flattens metadata.
|
63
|
+
#
|
64
|
+
# === Parameters
|
65
|
+
# tree_metadata(Hash):: metadata to flatten
|
66
|
+
# flat_metadata(Hash):: flattened metadata or {}
|
67
|
+
# metadata_path(Array):: array of metadata path elements or []
|
68
|
+
# path_index(int):: path array index to update or 0
|
69
|
+
#
|
70
|
+
# === Returns
|
71
|
+
# flat_metadata(Hash):: flattened metadata
|
72
|
+
def recursive_flatten_metadata(tree_metadata, flat_metadata = {}, metadata_path = [], path_index = 0)
|
73
|
+
unless tree_metadata.empty?
|
74
|
+
tree_metadata.each do |key, value|
|
75
|
+
metadata_path[path_index] = key
|
76
|
+
if value.respond_to?(:has_key?)
|
77
|
+
recursive_flatten_metadata(value, flat_metadata, metadata_path, path_index + 1)
|
78
|
+
else
|
79
|
+
flat_path = flatten_metadata_path(metadata_path)
|
80
|
+
flat_metadata[flat_path] = value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
metadata_path.pop
|
84
|
+
raise "Unexpected path" unless metadata_path.size == path_index
|
85
|
+
end
|
86
|
+
return flat_metadata
|
87
|
+
end
|
88
|
+
|
89
|
+
# Flattens a sequence of metadata keys into a simple key string
|
90
|
+
# distinguishing the path to a value stored at some depth in a tree of
|
91
|
+
# metadata.
|
92
|
+
#
|
93
|
+
# === Parameters
|
94
|
+
# metadata_path(Array):: array of metadata path elements
|
95
|
+
#
|
96
|
+
# === Returns
|
97
|
+
# flat_path(String):: flattened path
|
98
|
+
def flatten_metadata_path(metadata_path)
|
99
|
+
flat_path = metadata_path.join('_').gsub(/[\W,\/]/, '_').upcase
|
100
|
+
if @formatted_path_prefix && !(flat_path.start_with?(RS_METADATA_PREFIX) || flat_path.start_with?(@formatted_path_prefix))
|
101
|
+
return @formatted_path_prefix + flat_path
|
102
|
+
end
|
103
|
+
return flat_path
|
104
|
+
end
|
105
|
+
|
106
|
+
end # MetadataFormatter
|
107
|
+
|
108
|
+
end # RightScale
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require File.normalize_path(File.join(File.dirname(__FILE__), 'metadata_provider'))
|
24
|
+
|
25
|
+
module RightScale
|
26
|
+
|
27
|
+
# Abstracts a metadata provider which implements recursive tree building and
|
28
|
+
# relies on an external fetcher object
|
29
|
+
class MetadataProvider
|
30
|
+
|
31
|
+
attr_accessor :metadata_source, :metadata_tree_climber, :raw_metadata_writer
|
32
|
+
|
33
|
+
def initialize(options = {})
|
34
|
+
@metadata_source = options[:metadata_source]
|
35
|
+
@metadata_tree_climber = options[:metadata_tree_climber]
|
36
|
+
@raw_metadata_writer = options[:raw_metadata_writer]
|
37
|
+
@build_metadata_override = options[:build_metadata_override]
|
38
|
+
@query_override = options[:query_override]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Queries cloud-specific instance metadata in an implementation-specific
|
42
|
+
# manner. The resulting tree of metadata is built using the given Hash-like
|
43
|
+
# class.
|
44
|
+
#
|
45
|
+
# === Return
|
46
|
+
# tree_metadata(Hash|String):: tree of metadata or leaf value or nil
|
47
|
+
# depending on options
|
48
|
+
#
|
49
|
+
# === Raises
|
50
|
+
# RightScale::MetadataSource::QueryFailed:: on failure to query metadata
|
51
|
+
def build_metadata
|
52
|
+
return @build_metadata_override.call(self) if @build_metadata_override
|
53
|
+
@root_path = @metadata_tree_climber.root_path
|
54
|
+
recursive_build_metadata(@root_path)
|
55
|
+
ensure
|
56
|
+
@root_path = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
# Queries the given path for metadata using the responder. The metadata is
|
62
|
+
# then (recursively) processed according to the tree surgeon's analysis and
|
63
|
+
# the metadata tree (or else flat data) is filled and returned.
|
64
|
+
#
|
65
|
+
# === Parameters
|
66
|
+
# path(String):: path to metadata
|
67
|
+
#
|
68
|
+
# === Return
|
69
|
+
# tree_metadata(Hash|String):: tree of metadata or raw value depending on
|
70
|
+
# options
|
71
|
+
def recursive_build_metadata(path)
|
72
|
+
# query
|
73
|
+
query_result = query(path)
|
74
|
+
|
75
|
+
# climb, if arboreal
|
76
|
+
if @metadata_tree_climber.has_children?(path, query_result)
|
77
|
+
metadata = @metadata_tree_climber.create_branch
|
78
|
+
child_names = @metadata_tree_climber.child_names(path, query_result)
|
79
|
+
child_names.each do |child_name|
|
80
|
+
if key = @metadata_tree_climber.branch_key(child_name)
|
81
|
+
branch_path = @metadata_source.append_branch_name(path, child_name)
|
82
|
+
metadata[key] = recursive_build_metadata(branch_path)
|
83
|
+
elsif key = @metadata_tree_climber.leaf_key(child_name)
|
84
|
+
leaf_path = @metadata_source.append_leaf_name(path, child_name)
|
85
|
+
query_result = @metadata_source.query(leaf_path)
|
86
|
+
write_raw_leaf_query_result(leaf_path, query_result)
|
87
|
+
metadata[key] = @metadata_tree_climber.create_leaf(leaf_path, query_result)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
return metadata
|
91
|
+
end
|
92
|
+
|
93
|
+
# the only leaf.
|
94
|
+
write_raw_leaf_query_result(path, query_result)
|
95
|
+
return @metadata_tree_climber.create_leaf(path, query_result)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Executes a query on the source using the given path.
|
99
|
+
#
|
100
|
+
# === Parameters
|
101
|
+
# path(String):: path to metadata
|
102
|
+
#
|
103
|
+
# === Return
|
104
|
+
# result(Object):: any kind of metadata
|
105
|
+
def query(path)
|
106
|
+
return @query_override.call(self, path) if @query_override
|
107
|
+
return @metadata_source.query(path)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Writes raw responses to query writer, if given
|
111
|
+
#
|
112
|
+
# === Parameters
|
113
|
+
# path(String):: path to metadata
|
114
|
+
# query_result(String):: raw query result
|
115
|
+
#
|
116
|
+
# === Return
|
117
|
+
# always true
|
118
|
+
def write_raw_leaf_query_result(path, query_result)
|
119
|
+
if @raw_metadata_writer
|
120
|
+
subpath = (path.length > @root_path.length) ? path[@root_path.length..-1] : nil
|
121
|
+
@raw_metadata_writer.write(query_result, subpath)
|
122
|
+
end
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightScale
|
24
|
+
|
25
|
+
# Interface for a metadata source.
|
26
|
+
class MetadataSource
|
27
|
+
|
28
|
+
# exceptions.
|
29
|
+
class QueryFailed < Exception; end
|
30
|
+
|
31
|
+
attr_reader :logger
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
raise ArgumentError, "options[:logger] is required" unless @logger = options[:logger]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Appends a branch name to the given path.
|
38
|
+
#
|
39
|
+
# === Parameters
|
40
|
+
# path(String):: metadata path
|
41
|
+
# branch_name(String):: branch name to append
|
42
|
+
#
|
43
|
+
# === Return
|
44
|
+
# result(String):: updated path
|
45
|
+
def append_branch_name(path, branch_name)
|
46
|
+
# remove anything after equals.
|
47
|
+
branch_name = branch_name.gsub(/\=.*$/, '')
|
48
|
+
branch_name = "#{branch_name}/" unless '/' == branch_name[-1..-1]
|
49
|
+
return append_leaf_name(path, branch_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Appends a leaf name to the given path.
|
53
|
+
#
|
54
|
+
# === Parameters
|
55
|
+
# path(String):: metadata path
|
56
|
+
# leaf_name(String):: leaf name to append
|
57
|
+
#
|
58
|
+
# === Return
|
59
|
+
# result(String):: updated path
|
60
|
+
def append_leaf_name(path, leaf_name)
|
61
|
+
path = "#{path}/" unless '/' == path[-1..-1]
|
62
|
+
return "#{path}#{URI.escape(leaf_name)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Queries for metadata using the given path.
|
66
|
+
#
|
67
|
+
# === Parameters
|
68
|
+
# path(String):: metadata path
|
69
|
+
#
|
70
|
+
# === Return
|
71
|
+
# metadata(String):: query result or empty
|
72
|
+
#
|
73
|
+
# === Raises
|
74
|
+
# QueryFailed:: on any failure to query
|
75
|
+
def query(path)
|
76
|
+
raise NotImplementedError
|
77
|
+
end
|
78
|
+
|
79
|
+
# Releases any resources used to query metadata. Must be called before
|
80
|
+
# releasing source.
|
81
|
+
def finish
|
82
|
+
raise NotImplementedError
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'tmpdir'
|
24
|
+
require 'openssl'
|
25
|
+
require 'base64'
|
26
|
+
|
27
|
+
module RightScale
|
28
|
+
|
29
|
+
module MetadataSources
|
30
|
+
|
31
|
+
# Provides metadata by reading a dictionary file on disk.
|
32
|
+
class CertificateMetadataSource < MetadataSource
|
33
|
+
|
34
|
+
# definitions for querying kinds of metadata by a simple path.
|
35
|
+
DEFAULT_CLOUD_METADATA_ROOT_PATH = "cloud_metadata"
|
36
|
+
DEFAULT_USER_METADATA_ROOT_PATH = "user_metadata"
|
37
|
+
|
38
|
+
attr_accessor :cloud_metadata_cert_store, :cloud_metadata_cert_issuer
|
39
|
+
attr_accessor :user_metadata_cert_store, :user_metadata_cert_issuer
|
40
|
+
|
41
|
+
def initialize(options)
|
42
|
+
super(options)
|
43
|
+
raise ArgumentError.new("options[:cloud_metadata_root_path] is required") unless @cloud_metadata_root_path = options[:cloud_metadata_root_path]
|
44
|
+
raise ArgumentError.new("options[:user_metadata_root_path] is required") unless @user_metadata_root_path = options[:user_metadata_root_path]
|
45
|
+
|
46
|
+
@cloud_metadata_cert_store = options[:cloud_metadata_cert_store]
|
47
|
+
@cloud_metadata_cert_issuer = options[:cloud_metadata_cert_issuer]
|
48
|
+
|
49
|
+
@user_metadata_cert_store = options[:user_metadata_cert_store]
|
50
|
+
@user_metadata_cert_issuer = options[:user_metadata_cert_issuer]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Queries for metadata using the given path.
|
54
|
+
#
|
55
|
+
# === Parameters
|
56
|
+
# path(String):: metadata path
|
57
|
+
#
|
58
|
+
# === Return
|
59
|
+
# metadata(String):: query result or empty
|
60
|
+
#
|
61
|
+
# === Raises
|
62
|
+
# QueryFailed:: on any failure to query
|
63
|
+
def query(path)
|
64
|
+
result = ""
|
65
|
+
if path == @cloud_metadata_root_path
|
66
|
+
result = read_cert(@cloud_metadata_cert_store, @cloud_metadata_cert_issuer) if @cloud_metadata_cert_store && @cloud_metadata_cert_issuer
|
67
|
+
elsif path == @user_metadata_root_path
|
68
|
+
result = read_cert(@user_metadata_cert_store, @user_metadata_cert_issuer) if @user_metadata_cert_store && @user_metadata_cert_issuer
|
69
|
+
else
|
70
|
+
raise QueryFailed.new("Unknown path: #{path}")
|
71
|
+
end
|
72
|
+
result
|
73
|
+
rescue QueryFailed
|
74
|
+
raise
|
75
|
+
rescue Exception => e
|
76
|
+
raise QueryFailed.new(e.message)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Nothing to do.
|
80
|
+
def finish
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
def read_cert(cert_store, cert_issuer)
|
87
|
+
if ::RightScale::Platform.windows?
|
88
|
+
read_cert_windows(cert_store, cert_issuer)
|
89
|
+
else
|
90
|
+
read_cert_linux(cert_store, cert_issuer)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def read_cert_linux(cert_store, cert_issuer)
|
95
|
+
begin
|
96
|
+
data = File.read(cert_store)
|
97
|
+
cert = OpenSSL::X509::Certificate.new(data)
|
98
|
+
|
99
|
+
certificate_issuer = cert.issuer.to_s.split("/").sort
|
100
|
+
certificate_issuer.shift
|
101
|
+
raise QueryFailed.new("Certificate issuer does not match.") unless certificate_issuer == cert_issuer.split(", ").sort
|
102
|
+
raise QueryFailed.new("Unexpected certificate subject format: #{cert.subject.to_s}") unless cert.subject.to_s[1..3] == "CN="
|
103
|
+
|
104
|
+
result = Base64.decode64(cert.subject.to_s[4..-1].gsub('x0A',''))
|
105
|
+
rescue Exception => e
|
106
|
+
raise QueryFailed.new("Failed to retrieve metadata from cert given as \"#{cert_issuer}\" under \"#{cert_store}\"")
|
107
|
+
end
|
108
|
+
|
109
|
+
return result
|
110
|
+
end
|
111
|
+
|
112
|
+
READ_CERT_POWERSHELL_SCRIPT = <<EOF
|
113
|
+
# stop and fail script when a command fails.
|
114
|
+
$ErrorActionPreference = "Stop"
|
115
|
+
|
116
|
+
try
|
117
|
+
{
|
118
|
+
# requires Win2008+
|
119
|
+
if ([Int32]::Parse((Get-WmiObject Win32_OperatingSystem).Version.split('.')[0]) -lt 6)
|
120
|
+
{
|
121
|
+
throw "This version of Windows is not supported."
|
122
|
+
}
|
123
|
+
|
124
|
+
# check arguments.
|
125
|
+
if ($args.length -lt 3)
|
126
|
+
{
|
127
|
+
write-output "Usage: read_cert <cert store> <cert issuer> <output file>"
|
128
|
+
exit 101
|
129
|
+
}
|
130
|
+
$CERT_STORE = $args[0]
|
131
|
+
$CERT_ISSUER = $args[1]
|
132
|
+
$OUTPUT_FILE_PATH = $args[2]
|
133
|
+
|
134
|
+
# normalizes a Distinguished Name (DN) to ensure that parts appear in a consistent order in
|
135
|
+
# the DN string for comparison purposes. in Active Directory, DN parts are strictly ordered
|
136
|
+
# to make a full path to an object but other use cases (cert issuer, etc.) may not be as strict.
|
137
|
+
function NormalizeDN($dn)
|
138
|
+
{
|
139
|
+
[string]::join(',', ($dn.split(',') | foreach-object { $_.trim() } | sort-object))
|
140
|
+
}
|
141
|
+
|
142
|
+
# attempt to cert given by issuer (distinguished name) in the given cert store. select the most
|
143
|
+
# recently issued cert matching the given issuer by sorting certs in descending 'not before'
|
144
|
+
# order (i.e. last issued) and selecting first in the sorted array.
|
145
|
+
$compare = NormalizeDN($CERT_ISSUER)
|
146
|
+
$certs = @() + (get-item "$CERT_STORE\\*" | where-object { $compare -eq (NormalizeDN($_.issuer)) } | sort-object -Property notbefore -Descending)
|
147
|
+
$cert = $certs[0]
|
148
|
+
if ($NULL -eq $cert)
|
149
|
+
{
|
150
|
+
throw "Unable to find certificate matching ""$CERT_ISSUER"" under ""$CERT_STORE""."
|
151
|
+
}
|
152
|
+
|
153
|
+
# assumes that metadata is encoded in base-64 binary as .subject field of cert
|
154
|
+
# in form 'CN=<base-64 metadata string>'. if we don't match this pattern,
|
155
|
+
# then just bail out.
|
156
|
+
$encodedMetadata = $cert.subject
|
157
|
+
if (-not ($encodedMetadata.startsWith('CN=')))
|
158
|
+
{
|
159
|
+
throw "Unexpected cert subject format ""$encodedMetadata"""
|
160
|
+
}
|
161
|
+
# note that the base-64 string may or may not have double-quotes around it.
|
162
|
+
# not sure how double-quotes get inserted into the middle of the CN= phrase
|
163
|
+
# on Linux side (and not in Windows test), but life is a mystery.
|
164
|
+
$encodedMetadata = ($encodedMetadata.substring(3, $encodedMetadata.length - 3)).trim('"')
|
165
|
+
$decodedMetadata = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encodedMetadata)))
|
166
|
+
$decodedMetadata | Out-File -Encoding ASCII $OUTPUT_FILE_PATH
|
167
|
+
}
|
168
|
+
catch
|
169
|
+
{
|
170
|
+
$ErrorActionPreference = "Continue"
|
171
|
+
write-error $_
|
172
|
+
exit 100
|
173
|
+
}
|
174
|
+
|
175
|
+
exit 0
|
176
|
+
EOF
|
177
|
+
|
178
|
+
def read_cert_windows(cert_store, cert_issuer)
|
179
|
+
result = ''
|
180
|
+
Dir.mktmpdir do |dir|
|
181
|
+
script_file_path = ::File.normalize_path(::File.join(dir, 'read_cert.ps1'))
|
182
|
+
output_file_path = ::File.normalize_path(::File.join(dir, 'output.txt'))
|
183
|
+
::File.open(script_file_path, "w") { |f| f.write READ_CERT_POWERSHELL_SCRIPT }
|
184
|
+
cmd = ::RightScale::Platform.shell.format_shell_command(script_file_path, cert_store, cert_issuer, output_file_path)
|
185
|
+
result = `#{cmd}`
|
186
|
+
if $?.success?
|
187
|
+
if ::File.file?(output_file_path)
|
188
|
+
result = ::File.read(output_file_path)
|
189
|
+
else
|
190
|
+
result = result.to_s.strip
|
191
|
+
result = "No data was read from cert given as \"#{cert_issuer}\" under \"#{cert_store}\"." if result.empty?
|
192
|
+
raise QueryFailed.new(result)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
result = result.to_s.strip
|
196
|
+
result = "Failed to retrieve metadata from cert given as \"#{cert_issuer}\" under \"#{cert_store}\"." if result.empty?
|
197
|
+
raise QueryFailed.new(result)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
return result
|
201
|
+
end
|
202
|
+
|
203
|
+
end # CertificateMetadataSource
|
204
|
+
|
205
|
+
end # MetadataSources
|
206
|
+
|
207
|
+
end # RightScale
|