chef-rundeck 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: