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 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
- :short => "-c CONFIG",
39
- :long => "--config CONFIG",
40
- :default => 'config.rb',
41
- :description => "The Chef configuration file to use"
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! :host => 'localhost', :port => cli.config[:port]
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
- get '/' do
49
- content_type 'text/xml'
50
- response = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE project PUBLIC "-//DTO Labs Inc.//DTD Resources Document 1.0//EN" "project.dtd"><project>'
51
- rest = Chef::REST.new(ChefRundeck.api_url, ChefRundeck.username, ChefRundeck.client_key)
52
- nodes = rest.get_rest("/nodes/")
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
- nodes.keys.each do |node_name|
55
- node = rest.get_rest("/nodes/#{node_name}")
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
- os_family = node[:kernel][:os] =~ /windows/i ? 'windows' : 'unix'
60
- response << <<-EOH
61
- <node name="#{xml_escape(node[:fqdn])}"
62
- type="Node"
63
- description="#{xml_escape(node_name)}"
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([node.chef_environment, node[:tags].join(','), node.run_list.roles.join(',')].join(','))}"
69
- username="#{xml_escape(ChefRundeck.username)}"
70
- hostname="#{xml_escape(node[:fqdn])}"
71
- editUrl="#{xml_escape(ChefRundeck.web_ui_url)}/nodes/#{xml_escape(node_name)}/edit"/>
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
@@ -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: 1.0.1
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: 1.8.25
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: