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,46 @@
|
|
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
|
+
|
24
|
+
Overview
|
25
|
+
--------
|
26
|
+
|
27
|
+
Runs a server for the get-NextAction cmdlet's named pipe which serves out the next action from a text file.
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
Debugging from Visual Studio
|
32
|
+
----------------------------
|
33
|
+
VS 2008 C# projects appear not to allow variable substitution in debug command
|
34
|
+
lines (as has been allowed previously by C++ projects). This is likely to
|
35
|
+
improve in future, but in the meantime hardcode the .dll path (which gets
|
36
|
+
saved in your personal "ChefNodeCmdlet.csproj.user" file and is never checked
|
37
|
+
into source control).
|
38
|
+
|
39
|
+
See ChefNodeCmdlet\ReadMe.txt for details of debugging the client piece of get-NextAction (from a separate IDE instance).
|
40
|
+
|
41
|
+
Example:
|
42
|
+
|
43
|
+
Choose "Start project" for "Start Action"
|
44
|
+
|
45
|
+
Command line arguments:
|
46
|
+
-pn next_action_testing -na c:\temp\next-action.txt
|
@@ -0,0 +1,68 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
3
|
+
<PropertyGroup>
|
4
|
+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
5
|
+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
6
|
+
<ProductVersion>9.0.30729</ProductVersion>
|
7
|
+
<SchemaVersion>2.0</SchemaVersion>
|
8
|
+
<ProjectGuid>{9AF14C55-5808-4335-9BAA-74BD8DE5205B}</ProjectGuid>
|
9
|
+
<OutputType>Exe</OutputType>
|
10
|
+
<AppDesignerFolder>Properties</AppDesignerFolder>
|
11
|
+
<RootNamespace>TestNextActionCmdlet</RootNamespace>
|
12
|
+
<AssemblyName>TestNextActionCmdlet</AssemblyName>
|
13
|
+
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
14
|
+
<FileAlignment>512</FileAlignment>
|
15
|
+
</PropertyGroup>
|
16
|
+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
17
|
+
<DebugSymbols>true</DebugSymbols>
|
18
|
+
<DebugType>full</DebugType>
|
19
|
+
<Optimize>false</Optimize>
|
20
|
+
<OutputPath>$(SolutionDir)\$(Configuration)</OutputPath>
|
21
|
+
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
22
|
+
<ErrorReport>prompt</ErrorReport>
|
23
|
+
<WarningLevel>4</WarningLevel>
|
24
|
+
</PropertyGroup>
|
25
|
+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
26
|
+
<DebugType>pdbonly</DebugType>
|
27
|
+
<Optimize>true</Optimize>
|
28
|
+
<OutputPath>$(SolutionDir)\$(Configuration)</OutputPath>
|
29
|
+
<DefineConstants>TRACE</DefineConstants>
|
30
|
+
<ErrorReport>prompt</ErrorReport>
|
31
|
+
<WarningLevel>4</WarningLevel>
|
32
|
+
</PropertyGroup>
|
33
|
+
<ItemGroup>
|
34
|
+
<Reference Include="System" />
|
35
|
+
<Reference Include="System.Core">
|
36
|
+
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
37
|
+
</Reference>
|
38
|
+
<Reference Include="System.Xml.Linq">
|
39
|
+
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
40
|
+
</Reference>
|
41
|
+
<Reference Include="System.Data.DataSetExtensions">
|
42
|
+
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
43
|
+
</Reference>
|
44
|
+
<Reference Include="System.Data" />
|
45
|
+
<Reference Include="System.Xml" />
|
46
|
+
</ItemGroup>
|
47
|
+
<ItemGroup>
|
48
|
+
<Compile Include="Program.cs" />
|
49
|
+
<Compile Include="Properties\AssemblyInfo.cs" />
|
50
|
+
</ItemGroup>
|
51
|
+
<ItemGroup>
|
52
|
+
<ProjectReference Include="..\ChefNodeCmdlet\ChefNodeCmdlet.csproj">
|
53
|
+
<Project>{F421745A-3ADE-473A-83DE-C7A3DF1B9557}</Project>
|
54
|
+
<Name>ChefNodeCmdlet</Name>
|
55
|
+
</ProjectReference>
|
56
|
+
</ItemGroup>
|
57
|
+
<ItemGroup>
|
58
|
+
<Content Include="ReadMe.txt" />
|
59
|
+
</ItemGroup>
|
60
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
61
|
+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
62
|
+
Other similar extension points exist, see Microsoft.Common.targets.
|
63
|
+
<Target Name="BeforeBuild">
|
64
|
+
</Target>
|
65
|
+
<Target Name="AfterBuild">
|
66
|
+
</Target>
|
67
|
+
-->
|
68
|
+
</Project>
|
Binary file
|
@@ -0,0 +1,463 @@
|
|
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
|
+
require 'rubygems'
|
23
|
+
require File.normalize_path(File.join(File.dirname(__FILE__), 'pipe_server'))
|
24
|
+
require 'json'
|
25
|
+
require 'set'
|
26
|
+
|
27
|
+
module RightScale
|
28
|
+
|
29
|
+
module Windows
|
30
|
+
|
31
|
+
# Provides a server for a named pipe connection which serves data from a
|
32
|
+
# node structure organized as a hierarchy of hashes to privitives, arrays
|
33
|
+
# and subhashes. complex types can also appear but will be served out as
|
34
|
+
# hashes without type. caution should be used not to use complex types which
|
35
|
+
# have circular references.
|
36
|
+
class ChefNodeServer
|
37
|
+
|
38
|
+
include RightSupport::Ruby::EasySingleton
|
39
|
+
|
40
|
+
CHEF_NODE_PIPE_NAME = 'chef_node_D1D6B540-5125-4c00-8ABF-412417774DD5'
|
41
|
+
COMMAND_KEY = "Command"
|
42
|
+
PATH_KEY = "Path"
|
43
|
+
NODE_VALUE_KEY = "NodeValue"
|
44
|
+
|
45
|
+
attr_reader :node
|
46
|
+
attr_accessor :current_resource
|
47
|
+
attr_accessor :new_resource
|
48
|
+
|
49
|
+
# Starts the pipe server by creating an asynchronous named pipe. Returns
|
50
|
+
# control to the caller after adding the pipe to the event machine.
|
51
|
+
#
|
52
|
+
# === Parameters
|
53
|
+
# options[:node](Node):: Chef node, required
|
54
|
+
#
|
55
|
+
# === Return
|
56
|
+
# true:: If server was successfully started
|
57
|
+
# false:: Otherwise
|
58
|
+
def start(options)
|
59
|
+
return true if @pipe_eventable # Idempotent
|
60
|
+
|
61
|
+
Log.debug("[ChefNodeServer] - Starting")
|
62
|
+
@node = options[:node] || {}
|
63
|
+
@pipe_eventable = nil
|
64
|
+
@current_resource = nil
|
65
|
+
@new_resource = nil
|
66
|
+
|
67
|
+
flags = ::Win32::Pipe::ACCESS_DUPLEX | ::Win32::Pipe::OVERLAPPED
|
68
|
+
pipe = PipeServer.new(CHEF_NODE_PIPE_NAME, 0, flags)
|
69
|
+
res = true
|
70
|
+
begin
|
71
|
+
options = {:target => self,
|
72
|
+
:request_handler => :request_handler,
|
73
|
+
:pipe => pipe}
|
74
|
+
@pipe_eventable = EM.watch(pipe, PipeServerHandler, options)
|
75
|
+
@pipe_eventable.notify_readable = true
|
76
|
+
rescue Exception => e
|
77
|
+
pipe.close rescue nil
|
78
|
+
res = false
|
79
|
+
end
|
80
|
+
Log.debug("[ChefNodeServer] - Started = #{res}")
|
81
|
+
res
|
82
|
+
end
|
83
|
+
|
84
|
+
# Stops the pipe server by detaching the eventable from the event machine.
|
85
|
+
#
|
86
|
+
# === Return
|
87
|
+
# true:: Always return true
|
88
|
+
def stop
|
89
|
+
Log.debug("[ChefNodeServer] - Stopping - need to stop = #{!@pipe_eventable.nil?}")
|
90
|
+
@pipe_eventable.force_detach if @pipe_eventable
|
91
|
+
@pipe_eventable = nil
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
# Handler for data node requests. Expects complete requests and responses
|
96
|
+
# to appear serialized as JSON on individual lines (i.e. delimited by
|
97
|
+
# newlines). note that JSON text escapes newline characters within string
|
98
|
+
# values and normally only includes whitespace for human-readability.
|
99
|
+
def request_handler(request_data)
|
100
|
+
# assume request_data is a single line with a possible newline trailing.
|
101
|
+
request = JSON.load(request_data.chomp)
|
102
|
+
if request.has_key?(COMMAND_KEY)
|
103
|
+
handler = REQUEST_HANDLERS[request[COMMAND_KEY]]
|
104
|
+
Log.debug("handler = #{handler}")
|
105
|
+
return self.send(handler, request) if handler
|
106
|
+
end
|
107
|
+
raise "Invalid request"
|
108
|
+
rescue Exception => e
|
109
|
+
return JSON.dump( { :Error => "#{e.class}: #{e.message}", :Detail => e.backtrace.join("\n") } ) + "\n"
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
REQUEST_HANDLERS = {"GetChefNodeRequest" => :handle_get_chef_node_request,
|
115
|
+
"SetChefNodeRequest" => :handle_set_chef_node_request,
|
116
|
+
"GetCurrentResourceRequest" => :handle_get_current_resource_request,
|
117
|
+
"SetCurrentResourceRequest" => :handle_set_current_resource_request,
|
118
|
+
"GetNewResourceRequest" => :handle_get_new_resource_request,
|
119
|
+
"SetNewResourceRequest" => :handle_set_new_resource_request }
|
120
|
+
|
121
|
+
# exception for a circular reference in node structure.
|
122
|
+
class CircularReferenceException < StandardError
|
123
|
+
def initialize(message)
|
124
|
+
super(message)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# exception for an invalid path.
|
129
|
+
class InvalidPathException < StandardError
|
130
|
+
def initialize(message)
|
131
|
+
super(message)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Handles a Get-ChefNode request by finding the node matching the path,
|
136
|
+
# normalizing and then JSONing the data out.
|
137
|
+
#
|
138
|
+
# === Parameters
|
139
|
+
# request(Hash):: hash containing the following parameters:
|
140
|
+
#
|
141
|
+
# PATH_KEY(Array):: array of path elements
|
142
|
+
#
|
143
|
+
# === Returns
|
144
|
+
# response(String):: JSON structure containing found value or error
|
145
|
+
def handle_get_chef_node_request(request)
|
146
|
+
return handle_get_from_hash_request(request, @node)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Handles a Set-ChefNode request by attempting to build the hash hierarchy
|
150
|
+
# to the requested path depth and the inserting the given value.
|
151
|
+
#
|
152
|
+
# === Parameters
|
153
|
+
# request(Hash):: hash containing the following parameters:
|
154
|
+
#
|
155
|
+
# PATH_KEY(Array):: array of path elements
|
156
|
+
#
|
157
|
+
# NODE_VALUE_KEY(Object):: node value to set
|
158
|
+
#
|
159
|
+
# === Returns
|
160
|
+
# response(String):: JSON structure containing acknowledgement or error
|
161
|
+
def handle_set_chef_node_request(request)
|
162
|
+
handle_set_into_hash_request(request, @node)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Handles a Get-CurrentResource request.
|
166
|
+
#
|
167
|
+
# === Parameters
|
168
|
+
# request(Hash):: hash containing the following parameters:
|
169
|
+
#
|
170
|
+
# === Returns
|
171
|
+
# response(String):: JSON structure containing current resource or error
|
172
|
+
def handle_get_current_resource_request(request)
|
173
|
+
return handle_get_resource_request(request, @current_resource)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Handles a Set-CurrentResource request.
|
177
|
+
#
|
178
|
+
# === Parameters
|
179
|
+
# request(Hash):: hash containing the following parameters:
|
180
|
+
#
|
181
|
+
# === Returns
|
182
|
+
# response(String):: empty JSON structure or error.
|
183
|
+
def handle_set_current_resource_request(request)
|
184
|
+
return handle_set_resource_request(request, @current_resource)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Handles a Get-NewResource request.
|
188
|
+
#
|
189
|
+
# === Parameters
|
190
|
+
# request(Hash):: hash containing the following parameters:
|
191
|
+
#
|
192
|
+
# PATH_KEY(Array):: array of path elements
|
193
|
+
#
|
194
|
+
# === Returns
|
195
|
+
# response(String):: JSON structure containing new resource or error
|
196
|
+
def handle_get_new_resource_request(request)
|
197
|
+
handle_get_resource_request(request, @new_resource)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Handles a Set-NewResource request.
|
201
|
+
#
|
202
|
+
# === Parameters
|
203
|
+
# request(Hash):: hash containing no additional parameters.
|
204
|
+
#
|
205
|
+
# PATH_KEY(Array):: array of path elements
|
206
|
+
#
|
207
|
+
# NODE_VALUE_KEY(Object):: node value to set
|
208
|
+
#
|
209
|
+
# === Returns
|
210
|
+
# response(String):: empty JSON structure or error.
|
211
|
+
def handle_set_new_resource_request(request)
|
212
|
+
return handle_set_resource_request(request, @new_resource)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Handles a get from hash request by normalizing and then JSONing
|
216
|
+
# the current resource, if any.
|
217
|
+
#
|
218
|
+
# === Parameters
|
219
|
+
# request(Hash):: hash containing no additional parameters.
|
220
|
+
#
|
221
|
+
# hash(Hash):: a hash or hash-like object containing data to query.
|
222
|
+
#
|
223
|
+
# === Returns
|
224
|
+
# response(String):: JSON structure containing current resource or error
|
225
|
+
def handle_get_from_hash_request(request, hash)
|
226
|
+
raise "Missing required Path parameter" unless path = request[PATH_KEY]
|
227
|
+
node_value = get_node_value_from_hash(path, hash) rescue nil
|
228
|
+
node_value = normalize_node_value(node_value)
|
229
|
+
return JSON.dump( { :Path => path, :NodeValue => node_value } )
|
230
|
+
end
|
231
|
+
|
232
|
+
# Handles a set into hash request.
|
233
|
+
#
|
234
|
+
# === Parameters
|
235
|
+
# request(Hash):: hash containing no additional parameters.
|
236
|
+
#
|
237
|
+
# hash(Hash):: a hash or hash-like object containing data to query.
|
238
|
+
#
|
239
|
+
# === Returns
|
240
|
+
# response(String):: JSON structure containing current resource or error
|
241
|
+
def handle_set_into_hash_request(request, hash)
|
242
|
+
raise "Missing required Path parameter" unless path = request[PATH_KEY]
|
243
|
+
raise "Missing required NodeValue parameter" unless request.has_key?(NODE_VALUE_KEY) # value can be nil
|
244
|
+
node_value = request[NODE_VALUE_KEY]
|
245
|
+
set_node_value_into_hash(path, hash, node_value)
|
246
|
+
return JSON.dump( { :Path => path } )
|
247
|
+
end
|
248
|
+
|
249
|
+
# Handles a get resource request by normalizing and then JSONing
|
250
|
+
# the current resource, if any.
|
251
|
+
#
|
252
|
+
# === Parameters
|
253
|
+
# request(Hash):: hash containing no additional parameters.
|
254
|
+
#
|
255
|
+
# resource(Object):: resource for response.
|
256
|
+
#
|
257
|
+
# === Returns
|
258
|
+
# response(String):: JSON structure containing current resource or error
|
259
|
+
def handle_get_resource_request(request, resource)
|
260
|
+
# note that Chef::Resource and subclasses support :to_hash which will
|
261
|
+
# give us the interesting instance variables.
|
262
|
+
if resource && resource.respond_to?(:to_hash)
|
263
|
+
resource = resource.to_hash
|
264
|
+
resource = Mash.new(resource) unless resource.kind_of?(Mash)
|
265
|
+
end
|
266
|
+
return handle_get_from_hash_request(request, resource)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Handles a set resource request by attempting to set member variables or
|
270
|
+
# set hash pairs depending on type.
|
271
|
+
#
|
272
|
+
# === Parameters
|
273
|
+
# request(Hash):: hash containing the following parameters:
|
274
|
+
#
|
275
|
+
# resource(Object):: resource object to modify by request.
|
276
|
+
#
|
277
|
+
# === Returns
|
278
|
+
# response(String):: JSON structure containing acknowledgement or error
|
279
|
+
def handle_set_resource_request(request, resource)
|
280
|
+
# resource may or may not support hash insertion, but we can reuse the
|
281
|
+
# generic code which parses parameters and inserts into a new hash.
|
282
|
+
hash = {}
|
283
|
+
result = handle_set_into_hash_request(request, hash)
|
284
|
+
|
285
|
+
# note that Chef::Resource and subclasses support :to_hash no :from_hash
|
286
|
+
# and so have to set instance variables by mutator. we also want to
|
287
|
+
# support hash types which will likely support both :has_key? and
|
288
|
+
# :to_hash so check for :has_key? first.
|
289
|
+
if resource.respond_to?(:has_key?)
|
290
|
+
hash.each do |key, value|
|
291
|
+
# note it is non-trivial here to determine if keys are supposed to
|
292
|
+
# be tokens or strings, so always use Mash-like objects for such
|
293
|
+
# resources.
|
294
|
+
resource[key] = value
|
295
|
+
end
|
296
|
+
elsif resource.respond_to?(:to_hash)
|
297
|
+
# set any instance variables by public mutator (which may fail due
|
298
|
+
# to validation, etc.).
|
299
|
+
hash.each do |key, value|
|
300
|
+
# Chef resources normally implement validating accessor/mutator
|
301
|
+
# single methods which take either nil for get or the value to
|
302
|
+
# set, but also check the name= method for completeness.
|
303
|
+
name_equals_sym = (key + "=").to_sym
|
304
|
+
if resource.respond_to?(name_equals_sym)
|
305
|
+
Log.debug("calling resource.#{name_equals_sym} #{value.inspect[0,64]}") if Log.debug?
|
306
|
+
resource.send(name_equals_sym, value)
|
307
|
+
else
|
308
|
+
Log.debug("calling resource.#{key} #{value.inspect[0,64]}") if Log.debug?
|
309
|
+
|
310
|
+
resource.send(key.to_sym, value)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
else
|
314
|
+
raise "Resource of type #{resource.class} cannot be modified."
|
315
|
+
end
|
316
|
+
|
317
|
+
return result
|
318
|
+
end
|
319
|
+
|
320
|
+
# Queries the node value given by path from the node for this server.
|
321
|
+
#
|
322
|
+
# === Parameters
|
323
|
+
# path(Array):: array containing path elements.
|
324
|
+
#
|
325
|
+
# hash(Hash):: hash or hash-like object to query.
|
326
|
+
#
|
327
|
+
# === Returns
|
328
|
+
# node_value(Object):: node value from path or nil
|
329
|
+
def get_node_value_from_hash(path, hash)
|
330
|
+
# special case for the empty path element
|
331
|
+
return hash if (1 == path.length && path[0].to_s.length == 0)
|
332
|
+
|
333
|
+
node_by_path = node_by_path_statement(path)
|
334
|
+
result = instance_eval node_by_path
|
335
|
+
Log.debug("#{node_by_path} = #{result.inspect[0,64]}") if Log.debug?
|
336
|
+
return result
|
337
|
+
end
|
338
|
+
|
339
|
+
# Inserts the node value given by path into the node for this server,
|
340
|
+
# replacing any existing value.
|
341
|
+
#
|
342
|
+
# === Parameters
|
343
|
+
# path(Array):: array containing path elements.
|
344
|
+
#
|
345
|
+
# hash(Hash):: hash or hash-like object to query.
|
346
|
+
#
|
347
|
+
# node_value(Object):: value to insert.
|
348
|
+
#
|
349
|
+
# === Return
|
350
|
+
# true:: Always return true
|
351
|
+
def set_node_value_into_hash(path, hash, node_value)
|
352
|
+
# build up hash structure incrementally to avoid forcing the caller to
|
353
|
+
# explicitly insert all of the hashes described by the path.
|
354
|
+
raise InvalidPathException, "Cannot set the root node" if (path.empty? || path[0].empty?)
|
355
|
+
parent_path = []
|
356
|
+
path[0..-2].each do |element|
|
357
|
+
raise InvalidPathException, "At least one path element was empty" if element.empty?
|
358
|
+
parent_path << element
|
359
|
+
parent_node = get_node_value_from_hash(parent_path, hash)
|
360
|
+
if parent_node.nil? || false == parent_node.respond_to?(:has_key?)
|
361
|
+
node_by_path = node_by_path_statement(parent_path)
|
362
|
+
instance_eval "#{node_by_path} = {}"
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# insert node value.
|
367
|
+
node_by_path = node_by_path_statement(path)
|
368
|
+
instance_eval "#{node_by_path} = node_value"
|
369
|
+
|
370
|
+
true
|
371
|
+
end
|
372
|
+
|
373
|
+
# Generates an evaluatable statement for querying Chef node by path.
|
374
|
+
#
|
375
|
+
# === Parameters
|
376
|
+
# path(Array):: array containing path elements.
|
377
|
+
def node_by_path_statement(path)
|
378
|
+
return "hash[\"#{path.join('"]["')}\"]"
|
379
|
+
end
|
380
|
+
|
381
|
+
# Nnormalizes the given node value to produce simple containers, hashes
|
382
|
+
# and primitives for JSON serialization. Also detects circular references.
|
383
|
+
#
|
384
|
+
# === Parameters
|
385
|
+
# node_value(Object):: value to normalize
|
386
|
+
#
|
387
|
+
# node_value_set(Set):: set used for circular reference detection.
|
388
|
+
#
|
389
|
+
# === Returns
|
390
|
+
# normal_value(Object):: normalized value
|
391
|
+
def normalize_node_value(node_value)
|
392
|
+
normalize_node_value3(node_value, [], Set.new)
|
393
|
+
end
|
394
|
+
|
395
|
+
# Recursively normalizes the given node value to produce simple
|
396
|
+
# containers, hashes and primitives for JSON serialization. Also detects
|
397
|
+
# circular references.
|
398
|
+
#
|
399
|
+
# === Parameters
|
400
|
+
# node_value(Object):: value to normalize
|
401
|
+
#
|
402
|
+
# depth(Array):: current depth of hash keys or empty
|
403
|
+
#
|
404
|
+
# node_value_set(Set):: set used for circular reference detection.
|
405
|
+
#
|
406
|
+
# === Returns
|
407
|
+
# normal_value(Object):: normalized value
|
408
|
+
def normalize_node_value3(node_value, depth, node_value_set)
|
409
|
+
return nil if node_value.nil?
|
410
|
+
case node_value
|
411
|
+
when FalseClass, TrueClass, Numeric, String
|
412
|
+
# primitives can appear repeatedly but are not a circular reference.
|
413
|
+
return node_value
|
414
|
+
when Array
|
415
|
+
# arrays can contain circular references.
|
416
|
+
if node_value_set.add?(node_value.object_id)
|
417
|
+
result = []
|
418
|
+
node_value.each { |array_value| result << normalize_node_value3(array_value, depth, node_value_set) }
|
419
|
+
return result
|
420
|
+
else
|
421
|
+
raise CircularReferenceException, "Circular reference detected at depth = #{depth.join(', ')}"
|
422
|
+
end
|
423
|
+
when Chef::Node
|
424
|
+
# the Chef root node is a special case because we don't want to return
|
425
|
+
# the entire node in a JSON stream. only return the root keys.
|
426
|
+
result = []
|
427
|
+
node_value.each { |key, value| result << key.to_s }
|
428
|
+
return result
|
429
|
+
else
|
430
|
+
# note that the root node (i.e. Chef::Node) does not respond to
|
431
|
+
# has_key? but otherwise behaves like a hash.
|
432
|
+
if node_value.respond_to?(:has_key?) || node_value.kind_of?(Chef::Node)
|
433
|
+
# hashes can contain circular references.
|
434
|
+
if node_value_set.add?(node_value.object_id)
|
435
|
+
result = {}
|
436
|
+
node_value.each do |key, value|
|
437
|
+
depth.push key
|
438
|
+
begin
|
439
|
+
# recursion.
|
440
|
+
result[key.to_s] = normalize_node_value3(value, depth, node_value_set)
|
441
|
+
ensure
|
442
|
+
depth.pop
|
443
|
+
end
|
444
|
+
end
|
445
|
+
return result
|
446
|
+
else
|
447
|
+
Log.debug("Handling circular reference for hash by responding with key set at depth = #{depth.join(', ')}")
|
448
|
+
result = []
|
449
|
+
node_value.each { |key, value| result << key.to_s }
|
450
|
+
return result
|
451
|
+
end
|
452
|
+
else
|
453
|
+
# currently ignoring complex types except for converting them to
|
454
|
+
# string value.
|
455
|
+
return node_value.to_s
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
end
|
462
|
+
|
463
|
+
end
|