lita-puppet 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +16 -0
- data/Rakefile +1 -1
- data/lib/lita/handlers/puppet.rb +41 -14
- data/lib/utils/lita_puppet/puppetdb.rb +41 -12
- data/lita-puppet.gemspec +1 -1
- data/locales/en.yml +10 -0
- data/spec/lita/handlers/puppet_spec.rb +72 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1b3f7b216de57ce1507c62606049abe09c4a6d7
|
4
|
+
data.tar.gz: bf814b1efdb2b666499d4df0149fe28bbbeff81d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b01deb2674c47f115759323cae6093828d2aa9d5c727068c3f97edd1e83b69957d4c029682cf07ddaf6a3dc2b6ca8399d9c592a9ca1b64cb2cadc631ff28ed3
|
7
|
+
data.tar.gz: 40617d283ae66ef75a502f68ebcced9c35e126b5227e3057b96f62f92f972b2d557569463729199a5b7fe8d5f4f2b6f37a50dcc407e2d6581c9da6768396ace8
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -94,3 +94,19 @@ This is also available as:
|
|
94
94
|
pp class nodes <class>
|
95
95
|
|
96
96
|
Where `<class>` is a class name as it shows up in the catalog. Usually something like Role::Foo_bar
|
97
|
+
|
98
|
+
#### Query PuppetDB for the fact value of a given node
|
99
|
+
`puppet fact <certname> <fact>`
|
100
|
+
|
101
|
+
This is also available as:
|
102
|
+
|
103
|
+
`pp fact <certname> <fact>`
|
104
|
+
|
105
|
+
#### Query PuppetDB for some basic info about a node
|
106
|
+
`puppet <certname> info`
|
107
|
+
|
108
|
+
This is also available as:
|
109
|
+
|
110
|
+
`pp <certname> info`
|
111
|
+
|
112
|
+
This queries the [PuppetDB nodes endpoint](https://docs.puppet.com/puppetdb/4.4/api/query/v4/nodes.html)
|
data/Rakefile
CHANGED
data/lib/lita/handlers/puppet.rb
CHANGED
@@ -40,6 +40,20 @@ module Lita
|
|
40
40
|
help: { t('help.nodes_with_class.syntax') => t('help.nodes_with_class.desc') }
|
41
41
|
)
|
42
42
|
|
43
|
+
route(
|
44
|
+
/(puppet|pp)\s+(fact)\s+(\S+)\s+(\S+)/i,
|
45
|
+
:node_facts,
|
46
|
+
command: true,
|
47
|
+
help: { t('help.node_facts.syntax') => t('help.node_facts.desc') }
|
48
|
+
)
|
49
|
+
|
50
|
+
route(
|
51
|
+
/(puppet|pp)\s+(\S+)\s+(info)/i,
|
52
|
+
:nodes_info,
|
53
|
+
command: true,
|
54
|
+
help: { t('help.nodes_info.syntax') => t('help.nodes_info.desc') }
|
55
|
+
)
|
56
|
+
|
43
57
|
route(
|
44
58
|
/(puppet|pp)\s+(r10k|deploy)(\s+(\S+)(\s+(\S+))?)?/i,
|
45
59
|
:r10k_deploy,
|
@@ -92,16 +106,10 @@ module Lita
|
|
92
106
|
def node_profiles(response)
|
93
107
|
host = response.matches[0][2]
|
94
108
|
what = response.matches[0][1]
|
95
|
-
url = config.puppetdb_url
|
96
|
-
|
97
|
-
unless url
|
98
|
-
response.reply(t('replies.node_profiles.notconf'))
|
99
|
-
return false
|
100
|
-
end
|
101
109
|
|
102
110
|
response.reply_with_mention(t('replies.node_profiles.working'))
|
103
111
|
|
104
|
-
profiles = node_roles_and_profiles(
|
112
|
+
profiles = node_roles_and_profiles(what, host)
|
105
113
|
|
106
114
|
if profiles.is_a? String
|
107
115
|
fail_message response, t('replies.node_profiles.failure', error: profiles)
|
@@ -116,16 +124,10 @@ module Lita
|
|
116
124
|
|
117
125
|
def nodes_with_class(response)
|
118
126
|
puppet_class = response.matches[0][3]
|
119
|
-
url = config.puppetdb_url
|
120
|
-
|
121
|
-
unless url
|
122
|
-
response.reply(t('replies.nodes_with_class.notconf'))
|
123
|
-
return false
|
124
|
-
end
|
125
127
|
|
126
128
|
response.reply_with_mention(t('replies.nodes_with_class.working'))
|
127
129
|
|
128
|
-
puppet_classes = class_nodes(
|
130
|
+
puppet_classes = class_nodes(class_camel(puppet_class))
|
129
131
|
if puppet_classes.empty?
|
130
132
|
fail_message response, t('replies.nodes_with_class.failure', pclass: puppet_class)
|
131
133
|
else
|
@@ -137,6 +139,31 @@ module Lita
|
|
137
139
|
end
|
138
140
|
end
|
139
141
|
|
142
|
+
def node_facts(response)
|
143
|
+
host = response.matches[0][2]
|
144
|
+
fact = response.matches[0][3]
|
145
|
+
result = query_fact(host, fact)
|
146
|
+
if result.nil?
|
147
|
+
response.reply_with_mention(
|
148
|
+
t('replies.node_facts.error', host: host)
|
149
|
+
)
|
150
|
+
else
|
151
|
+
response.reply result
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def nodes_info(response)
|
156
|
+
host = response.matches[0][1]
|
157
|
+
result = node_info(host)
|
158
|
+
if result.nil?
|
159
|
+
response.reply_with_mention(
|
160
|
+
t('replies.nodes_info.error', host: host)
|
161
|
+
)
|
162
|
+
else
|
163
|
+
response.reply result
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
140
167
|
# rubocop:disable Metrics/AbcSize
|
141
168
|
def r10k_deploy(response)
|
142
169
|
environment = response.matches[0][3]
|
@@ -2,16 +2,19 @@ module Utils
|
|
2
2
|
module LitaPuppet
|
3
3
|
# Utility methods for working with PuppetDB
|
4
4
|
module PuppetDB
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
def db_connect
|
6
|
+
::PuppetDB::Client.new({
|
7
|
+
server: config.puppetdb_url,
|
8
|
+
pem: {
|
9
|
+
'key' => config.puppetdb_key,
|
10
|
+
'cert' => config.puppetdb_cert,
|
11
|
+
'ca_file' => config.puppetdb_ca_cert
|
12
|
+
}
|
13
|
+
}, config.puppetdb_api_vers)
|
14
|
+
end
|
15
|
+
|
16
|
+
def class_nodes(classname)
|
17
|
+
q = db_connect.request(
|
15
18
|
'resources',
|
16
19
|
[
|
17
20
|
:and,
|
@@ -23,11 +26,37 @@ module Utils
|
|
23
26
|
q.data.map { |node| node['certname'] }
|
24
27
|
end
|
25
28
|
|
29
|
+
def query_fact(node, fact)
|
30
|
+
q = db_connect.request(
|
31
|
+
"facts/#{fact}",
|
32
|
+
[:'=', 'certname', node]
|
33
|
+
)
|
34
|
+
begin
|
35
|
+
raise 'invalid query' if q.data.empty?
|
36
|
+
q.data.last['value']
|
37
|
+
rescue
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def node_info(node)
|
43
|
+
q = db_connect.request(
|
44
|
+
'nodes',
|
45
|
+
[:'=', 'certname', node]
|
46
|
+
)
|
47
|
+
begin
|
48
|
+
raise 'invalid node' if q.data.empty?
|
49
|
+
q.data.last.to_yaml
|
50
|
+
rescue
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
26
55
|
# rubocop:disable AbcSize
|
27
|
-
def node_roles_and_profiles(
|
56
|
+
def node_roles_and_profiles(what, nodename)
|
28
57
|
# TODO: validate url and nodename
|
29
58
|
::PuppetDB::Client.new({
|
30
|
-
server:
|
59
|
+
server: config.puppetdb_url,
|
31
60
|
pem: {
|
32
61
|
'key' => config.puppetdb_key,
|
33
62
|
'cert' => config.puppetdb_cert,
|
data/lita-puppet.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'lita-puppet'
|
3
|
-
spec.version = '2.
|
3
|
+
spec.version = '2.1.0'
|
4
4
|
spec.authors = ['Daniel Schaaff', 'Jonathan Gnagy'].sort
|
5
5
|
spec.email = ['jgnagy@knuedge.com']
|
6
6
|
spec.description = 'Some basic Puppet interactions for Lita'
|
data/locales/en.yml
CHANGED
@@ -15,6 +15,12 @@ en:
|
|
15
15
|
nodes_with_class:
|
16
16
|
syntax: puppet class nodes <class>
|
17
17
|
desc: Query PuppetDB to get a list of all nodes containing a class.
|
18
|
+
node_facts:
|
19
|
+
syntax: puppet fact <certname> <factname>
|
20
|
+
desc: Query PuppetDB for facts of a given node
|
21
|
+
nodes_info:
|
22
|
+
syntax: puppet <certname> info
|
23
|
+
desc: returns basic info about a node from puppetdb
|
18
24
|
r10k_deploy:
|
19
25
|
syntax: puppet r10k [env [module]]
|
20
26
|
desc: Deploy the latest puppet code on the puppet master via r10k, optionally specifying an environment, and possibly a module.
|
@@ -37,6 +43,10 @@ en:
|
|
37
43
|
working: "let me see what I can find in PuppetDB for you."
|
38
44
|
failure: "There are no nodes with %{pclass} class, are you sure it's a valid class?"
|
39
45
|
success: "Here are all the nodes with class %{pclass}:"
|
46
|
+
node_facts:
|
47
|
+
error: "that didn't work, are you sure %{host} is a valid certname?"
|
48
|
+
nodes_info:
|
49
|
+
error: "that didn't work, are you sure %{host} is a valid certname?"
|
40
50
|
r10k_deploy:
|
41
51
|
working: "I'll get right on that. Give me a moment and I'll let you know how it went."
|
42
52
|
failure: "your r10k run didn't seem to work. Here's what went wrong:"
|
@@ -16,6 +16,18 @@ describe Lita::Handlers::Puppet, lita_handler: true do
|
|
16
16
|
instance_double('::PuppetDB::Client', request: puppetdb_nodes)
|
17
17
|
end
|
18
18
|
|
19
|
+
let(:fact_request) do
|
20
|
+
instance_double('::PuppetDB::Client', request: puppetdb_fact_result)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:info_request) do
|
24
|
+
instance_double('::PuppetDB::Client', request: puppetdb_host_info)
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:bad_request) do
|
28
|
+
instance_double('::PuppetDB::Client', request: puppetdb_nil_data)
|
29
|
+
end
|
30
|
+
|
19
31
|
let(:puppetdb_nodes) do
|
20
32
|
double(
|
21
33
|
data: [
|
@@ -25,6 +37,35 @@ describe Lita::Handlers::Puppet, lita_handler: true do
|
|
25
37
|
)
|
26
38
|
end
|
27
39
|
|
40
|
+
let(:puppetdb_nil_data) do
|
41
|
+
double(
|
42
|
+
data: [
|
43
|
+
]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
let(:puppetdb_host_info) do
|
47
|
+
double(
|
48
|
+
data: [
|
49
|
+
{ 'deactivated' => nil,
|
50
|
+
'latest_report_hash' => '693feed',
|
51
|
+
'facts_environment' => 'production' }
|
52
|
+
]
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:puppetdb_fact_result) do
|
57
|
+
double(
|
58
|
+
data: [
|
59
|
+
{
|
60
|
+
'certname' => 'foo.example.com',
|
61
|
+
'name' => 'operatingsystem',
|
62
|
+
'value' => 'Darwin',
|
63
|
+
'environment' => 'production'
|
64
|
+
}
|
65
|
+
]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
28
69
|
let(:rye_box) do
|
29
70
|
box = instance_double(
|
30
71
|
'Rye::Box',
|
@@ -48,6 +89,8 @@ describe Lita::Handlers::Puppet, lita_handler: true do
|
|
48
89
|
is_expected.to route_command('puppet class nodes foo').to(:nodes_with_class)
|
49
90
|
is_expected.to route_command('puppet r10k')
|
50
91
|
.with_authorization_for(:puppet_admins).to(:r10k_deploy)
|
92
|
+
is_expected.to route_command('puppet fact node foo').to(:node_facts)
|
93
|
+
is_expected.to route_command('puppet node info').to(:nodes_info)
|
51
94
|
end
|
52
95
|
|
53
96
|
describe('#cert_clean') do
|
@@ -95,6 +138,35 @@ describe Lita::Handlers::Puppet, lita_handler: true do
|
|
95
138
|
end
|
96
139
|
end
|
97
140
|
|
141
|
+
describe('#node_facts') do
|
142
|
+
it 'should return error msg for invalid certname' do
|
143
|
+
allow(::PuppetDB::Client).to receive(:new).and_return(bad_request)
|
144
|
+
send_command('puppet fact foo.example.com operatingsystem')
|
145
|
+
expect(replies.last)
|
146
|
+
.to eq("that didn't work, are you sure foo.example.com is a valid certname?")
|
147
|
+
end
|
148
|
+
it 'should return error msg for invalid certname' do
|
149
|
+
allow(::PuppetDB::Client).to receive(:new).and_return(fact_request)
|
150
|
+
send_command('puppet fact foo.example.com operatingsystem')
|
151
|
+
expect(replies.last).to eq('Darwin')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe('#nodes_info') do
|
156
|
+
it 'should return error msg for invalid certname' do
|
157
|
+
allow(::PuppetDB::Client).to receive(:new).and_return(bad_request)
|
158
|
+
send_command('puppet foo.example.com info')
|
159
|
+
expect(replies.last)
|
160
|
+
.to eq("that didn't work, are you sure foo.example.com is a valid certname?")
|
161
|
+
end
|
162
|
+
it 'should return the node info' do
|
163
|
+
allow(::PuppetDB::Client).to receive(:new).and_return(info_request)
|
164
|
+
send_command('puppet foo.example.com info')
|
165
|
+
expect(replies.last)
|
166
|
+
.to eq("---\ndeactivated: \nlatest_report_hash: 693feed\nfacts_environment: production\n")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
98
170
|
describe('#r10k_deploy') do
|
99
171
|
before do
|
100
172
|
robot.auth.add_user_to_group!(lita_user, :puppet_admins)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Schaaff
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: lita
|
@@ -225,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
225
|
version: '0'
|
226
226
|
requirements: []
|
227
227
|
rubyforge_project:
|
228
|
-
rubygems_version: 2.4.
|
228
|
+
rubygems_version: 2.4.5
|
229
229
|
signing_key:
|
230
230
|
specification_version: 4
|
231
231
|
summary: Allow the Lita bot to handle requests for puppet tasks
|