chef-rundeck 1.0.1 → 2.0.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.
- checksums.yaml +7 -0
- data/bin/chef-rundeck +18 -5
- data/lib/chef-rundeck.rb +108 -22
- data/spec/chef-rundeck_spec.rb +17 -0
- metadata +21 -37
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ce7ece53bc0c72a4fe221d30e8babef9077dacf
|
4
|
+
data.tar.gz: 98f8966b2cda5a2eeb852333e7c409af35c6bfbb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: adb94d82eab00bc70ee9c8ae0a9a21c269f4cd27a27cc4620c66e85777760ca39862e5d89b20b59465beca6255ea6a058d727d4845939ab6c18e0ebf68f07943
|
7
|
+
data.tar.gz: f522ced6479217a1ff953757f80dae46241bc9cfad96b3b923babd4dddb05c14c558ae66a917ab715d9a3f0eb2717a445bc876d5c6a8db2d4c4ff7fb08e5a6fd
|
data/bin/chef-rundeck
CHANGED
@@ -35,10 +35,10 @@ class ChefRundeckCLI
|
|
35
35
|
:description => "The client.pem to sign requests"
|
36
36
|
|
37
37
|
option :config_file,
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
:short => "-c CONFIG",
|
39
|
+
:long => "--config CONFIG",
|
40
|
+
:default => '/etc/chef/client.rb',
|
41
|
+
:description => "The Chef configuration file to use, default /etc/chef/client.rb"
|
42
42
|
|
43
43
|
option :username,
|
44
44
|
:short => "-u USERNAME",
|
@@ -52,6 +52,18 @@ class ChefRundeckCLI
|
|
52
52
|
:description => "The base URL of the Chef Web UI",
|
53
53
|
:default => "https://manage.opscode.com"
|
54
54
|
|
55
|
+
option :project_config,
|
56
|
+
:short => "-f PROJECT_CONFIG",
|
57
|
+
:long => "--project-config PROJECT_CONFIG",
|
58
|
+
:description => "JSON project configuration file, default /etc/chef/rundeck.json",
|
59
|
+
:default => "/etc/chef/rundeck.json"
|
60
|
+
|
61
|
+
option :host,
|
62
|
+
:short => "-o HOST",
|
63
|
+
:long => "--host HOST",
|
64
|
+
:description => "Listen on HOST (default: localhost)",
|
65
|
+
:default => "localhost"
|
66
|
+
|
55
67
|
option :port,
|
56
68
|
:short => "-p PORT",
|
57
69
|
:long => "--port PORT",
|
@@ -73,6 +85,7 @@ ChefRundeck.username = cli.config[:username]
|
|
73
85
|
ChefRundeck.web_ui_url = cli.config[:web_ui_url]
|
74
86
|
ChefRundeck.api_url = cli.config[:api_url]
|
75
87
|
ChefRundeck.client_key = cli.config[:client_key]
|
88
|
+
ChefRundeck.project_config = cli.config[:project_config]
|
76
89
|
ChefRundeck.configure
|
77
90
|
|
78
91
|
begin
|
@@ -84,5 +97,5 @@ rescue Exception => e
|
|
84
97
|
puts "== Error writing pid file #{pid}!"
|
85
98
|
end
|
86
99
|
|
87
|
-
ChefRundeck.run! :
|
100
|
+
ChefRundeck.run! :bind => cli.config[:host], :port => cli.config[:port]
|
88
101
|
|
data/lib/chef-rundeck.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
#
|
2
2
|
# Copyright 2010, Opscode, Inc.
|
3
|
-
#
|
3
|
+
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
# you may not use this file except in compliance with the License.
|
6
6
|
# You may obtain a copy of the License at
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Unless required by applicable law or agreed to in writing, software
|
11
11
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -20,6 +20,15 @@ require 'chef/node'
|
|
20
20
|
require 'chef/mixin/xml_escape'
|
21
21
|
require 'chef/rest'
|
22
22
|
|
23
|
+
REQUIRED_ATTRS = [ :kernel, :fqdn, :platform, :platform_version ]
|
24
|
+
|
25
|
+
class MissingAttribute < StandardError
|
26
|
+
attr_reader :name
|
27
|
+
def initialize(name)
|
28
|
+
@name = name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
23
32
|
class ChefRundeck < Sinatra::Base
|
24
33
|
|
25
34
|
include Chef::Mixin::XMLEscape
|
@@ -27,9 +36,10 @@ class ChefRundeck < Sinatra::Base
|
|
27
36
|
class << self
|
28
37
|
attr_accessor :config_file
|
29
38
|
attr_accessor :username
|
30
|
-
attr_accessor :api_url
|
31
39
|
attr_accessor :web_ui_url
|
40
|
+
attr_accessor :api_url
|
32
41
|
attr_accessor :client_key
|
42
|
+
attr_accessor :project_config
|
33
43
|
|
34
44
|
def configure
|
35
45
|
Chef::Config.from_file(ChefRundeck.config_file)
|
@@ -42,36 +52,112 @@ class ChefRundeck < Sinatra::Base
|
|
42
52
|
unless ChefRundeck.client_key
|
43
53
|
ChefRundeck.client_key = Chef::Config[:client_key]
|
44
54
|
end
|
55
|
+
|
56
|
+
if (File.exists?(ChefRundeck.project_config)) then
|
57
|
+
Chef::Log.info("Using JSON project file #{ChefRundeck.project_config}")
|
58
|
+
projects = File.open(ChefRundeck.project_config, "r") { |f| JSON.parse(f.read) }
|
59
|
+
projects.keys.each do | project |
|
60
|
+
get "/#{project}" do
|
61
|
+
content_type 'text/xml'
|
62
|
+
Chef::Log.info("Loading nodes for /#{project}")
|
63
|
+
response = build_project projects[project]['pattern'], projects[project]['username'], (projects[project]['hostname'].nil? ? "fqdn" : projects[project]['hostname']), projects[project]['attributes']
|
64
|
+
response
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
get '/' do
|
70
|
+
content_type 'text/xml'
|
71
|
+
Chef::Log.info("Loading all nodes for /")
|
72
|
+
response = build_project
|
73
|
+
response
|
74
|
+
end
|
45
75
|
end
|
46
76
|
end
|
47
77
|
|
48
|
-
|
49
|
-
|
50
|
-
response
|
51
|
-
|
52
|
-
|
78
|
+
def build_project (pattern="*:*", username=ChefRundeck.username, hostname="fqdn", custom_attributes=nil)
|
79
|
+
response = '<?xml version="1.0" encoding="UTF-8"?>'
|
80
|
+
response << '<!DOCTYPE project PUBLIC "-//DTO Labs Inc.//DTD Resources Document 1.0//EN" "project.dtd">'
|
81
|
+
response << '<project>'
|
82
|
+
|
83
|
+
q = Chef::Search::Query.new
|
84
|
+
q.search("node",pattern) do |node|
|
53
85
|
|
54
|
-
|
55
|
-
|
86
|
+
begin
|
87
|
+
if node_is_valid? node
|
88
|
+
response << build_node(node, username, hostname, custom_attributes)
|
89
|
+
else
|
90
|
+
Chef::Log.warn("invalid node element: #{node.inspect}")
|
91
|
+
end
|
92
|
+
rescue Exception => e
|
93
|
+
Chef::Log.error("=== could not generate xml for Node: #{node.name} - #{e.message}")
|
94
|
+
Chef::Log.debug(e.backtrace.join('\n'))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
response << "</project>"
|
99
|
+
Chef::Log.debug(response)
|
100
|
+
|
101
|
+
return response
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_node (node, username, hostname, custom_attributes)
|
56
106
|
#--
|
57
107
|
# Certain features in Rundeck require the osFamily value to be set to 'unix' to work appropriately. - SRK
|
58
108
|
#++
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
109
|
+
data = ''
|
110
|
+
os_family = node[:kernel][:os] =~ /winnt|windows/i ? 'winnt' : 'unix'
|
111
|
+
nodeexec = node[:kernel][:os] =~ /winnt|windows/i ? "node-executor=\"overthere-winrm\"" : ''
|
112
|
+
data << <<-EOH
|
113
|
+
<node name="#{xml_escape(node[:fqdn])}" #{nodeexec}
|
114
|
+
type="Node"
|
115
|
+
description="#{xml_escape(node.name)}"
|
64
116
|
osArch="#{xml_escape(node[:kernel][:machine])}"
|
65
117
|
osFamily="#{xml_escape(os_family)}"
|
66
118
|
osName="#{xml_escape(node[:platform])}"
|
67
119
|
osVersion="#{xml_escape(node[:platform_version])}"
|
68
|
-
tags="#{xml_escape(
|
69
|
-
|
70
|
-
|
71
|
-
|
120
|
+
tags="#{xml_escape(node.run_list.roles.concat(node.run_list.recipes).join(',') + ',' + node.chef_environment)}"
|
121
|
+
roles="#{xml_escape(node.run_list.roles.join(','))}"
|
122
|
+
recipes="#{xml_escape(node.run_list.recipes.join(','))}"
|
123
|
+
environment="#{xml_escape(node.chef_environment)}"
|
124
|
+
username="#{xml_escape(username)}"
|
125
|
+
hostname="#{xml_escape(node[hostname])}"
|
126
|
+
editUrl="#{xml_escape(ChefRundeck.web_ui_url)}/nodes/#{xml_escape(node.name)}/edit" #{custom_attributes.nil? ? '/': ''}>
|
127
|
+
EOH
|
128
|
+
if !custom_attributes.nil? then
|
129
|
+
custom_attributes.each do |attr|
|
130
|
+
attr_name = attr
|
131
|
+
attr_value = get_custom_attr(node, attr.split('.'))
|
132
|
+
data << <<-EOH
|
133
|
+
<attribute name="#{attr_name}"><![CDATA[#{attr_value}]]></attribute>
|
72
134
|
EOH
|
135
|
+
end
|
136
|
+
data << "</node>"
|
137
|
+
end
|
138
|
+
|
139
|
+
return data
|
140
|
+
end
|
141
|
+
|
142
|
+
def get_custom_attr (obj, params)
|
143
|
+
value = obj
|
144
|
+
Chef::Log.debug("loading custom attributes for node: #{obj} with #{params}")
|
145
|
+
params.each do |p|
|
146
|
+
value = value[p.to_sym]
|
147
|
+
if value.nil? then
|
148
|
+
break
|
73
149
|
end
|
74
|
-
response << "</project>"
|
75
|
-
response
|
76
150
|
end
|
151
|
+
return value.nil? ? "" : value.to_s
|
152
|
+
end
|
153
|
+
|
154
|
+
def node_is_valid?(node)
|
155
|
+
node[:fqdn] and
|
156
|
+
node.name and
|
157
|
+
node[:kernel] and
|
158
|
+
node[:kernel][:machine] and
|
159
|
+
node[:kernel][:os] and
|
160
|
+
node[:platform] and
|
161
|
+
node[:platform_version] and
|
162
|
+
node.chef_environment
|
77
163
|
end
|
data/spec/chef-rundeck_spec.rb
CHANGED
@@ -7,6 +7,7 @@ describe 'ChefRundeck' do
|
|
7
7
|
ChefRundeck.config_file = "#{ENV['TRAVIS_BUILD_DIR']}/spec/support/client.rb"
|
8
8
|
ChefRundeck.username = ENV['USER']
|
9
9
|
ChefRundeck.web_ui_url = 'https://manage.opscode.com'
|
10
|
+
ChefRundeck.project_config = "#{ENV['TRAVIS_BUILD_DIR']}/spec/support/chef-rundeck.json"
|
10
11
|
ChefRundeck.configure
|
11
12
|
end
|
12
13
|
it 'fetch to root should return 200' do
|
@@ -17,4 +18,20 @@ describe 'ChefRundeck' do
|
|
17
18
|
get '/'
|
18
19
|
Nokogiri::XML(last_response.body).document.should be_true
|
19
20
|
end
|
21
|
+
it 'fetched document should be node1 only' do
|
22
|
+
get '/node1_systems'
|
23
|
+
last_response.should be_ok
|
24
|
+
Nokogiri::XML(last_response.body).xpath("//project/node[@name='node1.chefrundeck.local']").length().should == 1
|
25
|
+
Nokogiri::XML(last_response.body).xpath("//project/node[@name='node2.chefrundeck.local']").length().should == 0
|
26
|
+
end
|
27
|
+
it 'fetched document should be node2 only' do
|
28
|
+
get '/node2_systems'
|
29
|
+
last_response.should be_ok
|
30
|
+
Nokogiri::XML(last_response.body).xpath("//project/node[@name='node1.chefrundeck.local']").length().should == 0
|
31
|
+
Nokogiri::XML(last_response.body).xpath("//project/node[@name='node2.chefrundeck.local']").length().should == 1
|
32
|
+
end
|
33
|
+
it 'check custom attributes on node2 only' do
|
34
|
+
get '/node2_systems'
|
35
|
+
Nokogiri::XML(last_response.body).xpath("//project/node[@name='node2.chefrundeck.local']/attribute").length().should == 2
|
36
|
+
end
|
20
37
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-rundeck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam Jacob
|
@@ -16,113 +15,99 @@ dependencies:
|
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: sinatra
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
|
-
- -
|
19
|
+
- - ~>
|
22
20
|
- !ruby/object:Gem::Version
|
23
21
|
version: '0'
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
|
-
- -
|
26
|
+
- - ~>
|
30
27
|
- !ruby/object:Gem::Version
|
31
28
|
version: '0'
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: chef
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
|
-
- -
|
33
|
+
- - ~>
|
38
34
|
- !ruby/object:Gem::Version
|
39
35
|
version: '0'
|
40
36
|
type: :runtime
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
|
-
- -
|
40
|
+
- - ~>
|
46
41
|
- !ruby/object:Gem::Version
|
47
42
|
version: '0'
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
44
|
name: mixlib-cli
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
|
-
- -
|
47
|
+
- - ~>
|
54
48
|
- !ruby/object:Gem::Version
|
55
49
|
version: '0'
|
56
50
|
type: :runtime
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
53
|
requirements:
|
61
|
-
- -
|
54
|
+
- - ~>
|
62
55
|
- !ruby/object:Gem::Version
|
63
56
|
version: '0'
|
64
57
|
- !ruby/object:Gem::Dependency
|
65
58
|
name: rspec
|
66
59
|
requirement: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
60
|
requirements:
|
69
|
-
- -
|
61
|
+
- - ~>
|
70
62
|
- !ruby/object:Gem::Version
|
71
63
|
version: 1.2.9
|
72
64
|
type: :development
|
73
65
|
prerelease: false
|
74
66
|
version_requirements: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
67
|
requirements:
|
77
|
-
- -
|
68
|
+
- - ~>
|
78
69
|
- !ruby/object:Gem::Version
|
79
70
|
version: 1.2.9
|
80
71
|
- !ruby/object:Gem::Dependency
|
81
72
|
name: yard
|
82
73
|
requirement: !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
74
|
requirements:
|
85
|
-
- -
|
75
|
+
- - ~>
|
86
76
|
- !ruby/object:Gem::Version
|
87
77
|
version: '0'
|
88
78
|
type: :development
|
89
79
|
prerelease: false
|
90
80
|
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
81
|
requirements:
|
93
|
-
- -
|
82
|
+
- - ~>
|
94
83
|
- !ruby/object:Gem::Version
|
95
84
|
version: '0'
|
96
85
|
- !ruby/object:Gem::Dependency
|
97
86
|
name: rack-test
|
98
87
|
requirement: !ruby/object:Gem::Requirement
|
99
|
-
none: false
|
100
88
|
requirements:
|
101
|
-
- -
|
89
|
+
- - ~>
|
102
90
|
- !ruby/object:Gem::Version
|
103
91
|
version: '0'
|
104
92
|
type: :development
|
105
93
|
prerelease: false
|
106
94
|
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
95
|
requirements:
|
109
|
-
- -
|
96
|
+
- - ~>
|
110
97
|
- !ruby/object:Gem::Version
|
111
98
|
version: '0'
|
112
99
|
- !ruby/object:Gem::Dependency
|
113
100
|
name: nokogiri
|
114
101
|
requirement: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
102
|
requirements:
|
117
|
-
- -
|
103
|
+
- - ~>
|
118
104
|
- !ruby/object:Gem::Version
|
119
105
|
version: '0'
|
120
106
|
type: :development
|
121
107
|
prerelease: false
|
122
108
|
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
109
|
requirements:
|
125
|
-
- -
|
110
|
+
- - ~>
|
126
111
|
- !ruby/object:Gem::Version
|
127
112
|
version: '0'
|
128
113
|
description: Provides a resource endpoint for RunDeck from a Chef Server
|
@@ -145,28 +130,27 @@ files:
|
|
145
130
|
- spec/spec.opts
|
146
131
|
- spec/spec_helper.rb
|
147
132
|
homepage: http://github.com/oswaldlabs/chef-rundeck
|
148
|
-
licenses:
|
133
|
+
licenses:
|
134
|
+
- Apache License 2.0 (Apache-2.0)
|
135
|
+
metadata: {}
|
149
136
|
post_install_message:
|
150
137
|
rdoc_options: []
|
151
138
|
require_paths:
|
152
139
|
- lib
|
153
140
|
required_ruby_version: !ruby/object:Gem::Requirement
|
154
|
-
none: false
|
155
141
|
requirements:
|
156
|
-
- -
|
142
|
+
- - '>='
|
157
143
|
- !ruby/object:Gem::Version
|
158
144
|
version: '0'
|
159
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
-
none: false
|
161
146
|
requirements:
|
162
|
-
- -
|
147
|
+
- - '>='
|
163
148
|
- !ruby/object:Gem::Version
|
164
149
|
version: '0'
|
165
150
|
requirements: []
|
166
151
|
rubyforge_project:
|
167
|
-
rubygems_version:
|
152
|
+
rubygems_version: 2.2.2
|
168
153
|
signing_key:
|
169
154
|
specification_version: 3
|
170
155
|
summary: Integrates Chef with RunDeck
|
171
156
|
test_files: []
|
172
|
-
has_rdoc:
|