chef-rundeck2 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +8 -9
- data/.rubocop.yml +10 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -14
- data/Gemfile.lock +42 -34
- data/README.md +6 -5
- data/Rakefile +1 -1
- data/chef-rundeck2.gemspec +5 -6
- data/config/auth.json +7 -1
- data/config/config.json +7 -6
- data/config/state.json +65 -8
- data/lib/chef-rundeck/api.rb +49 -22
- data/lib/chef-rundeck/auth.rb +3 -2
- data/lib/chef-rundeck/chef.rb +67 -18
- data/lib/chef-rundeck/cli.rb +18 -9
- data/lib/chef-rundeck/config.rb +4 -1
- data/lib/chef-rundeck/state.rb +11 -5
- data/lib/chef-rundeck/util.rb +1 -1
- data/lib/chef-rundeck/version.rb +1 -1
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bc4d88bb86e8290eaf930b45370d42d3167203e
|
4
|
+
data.tar.gz: 612d1d682acd97e2218a9d3046fff628860cb70a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66e21d91b0d9ac9d1705d108ed4e3e1f505be153e41df172ab74ac64b262e32a854cfce86dc31cc8e80f63822a4e0006ea9fd1b353c561bb211e7eb5d4a9cedb
|
7
|
+
data.tar.gz: 9495409f2e3069cad561688108fd26deeb956f520f37a7856bd7dcb3c43c6b5cfbccb933beac3d651533f78af5df2354ec5c0c3745ae206978d26e33a353a670
|
data/.gitlab-ci.yml
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
before_script:
|
2
2
|
- ruby -v
|
3
3
|
- which ruby
|
4
|
-
- gem install bundler --no-
|
4
|
+
- gem install bundler --no-document
|
5
5
|
- bundle install --jobs $(nproc) --path vendor/bundle
|
6
6
|
|
7
|
-
test:Ruby 2.
|
8
|
-
image: ruby:2.
|
7
|
+
test:Ruby 2.4:
|
8
|
+
image: ruby:2.4
|
9
9
|
cache:
|
10
|
-
group: ruby_2.2
|
11
10
|
paths:
|
12
11
|
- .bundle
|
13
12
|
- vendor/bundle
|
@@ -18,20 +17,20 @@ test:Ruby 2.2:
|
|
18
17
|
except:
|
19
18
|
- tags
|
20
19
|
|
21
|
-
release:Ruby 2.
|
22
|
-
image: ruby:2.
|
20
|
+
release:Ruby 2.4:
|
21
|
+
image: ruby:2.4
|
23
22
|
cache:
|
24
|
-
group: ruby_2.2
|
25
23
|
paths:
|
26
24
|
- .bundle
|
27
25
|
- vendor/bundle
|
28
26
|
script:
|
29
27
|
- bundle exec rubocop
|
30
|
-
-
|
28
|
+
- gem install dpl --no-document
|
29
|
+
- dpl --provider=rubygems --api-key=$RUBYGEMS_API_KEY
|
31
30
|
artifacts:
|
32
31
|
name: "chef-rundeck2-$CI_BUILD_REF_NAME"
|
33
32
|
paths:
|
34
|
-
-
|
33
|
+
- ./*.gem
|
35
34
|
tags:
|
36
35
|
- ruby
|
37
36
|
only:
|
data/.rubocop.yml
CHANGED
@@ -7,6 +7,15 @@ Style/WordArray:
|
|
7
7
|
Style/FileName:
|
8
8
|
Enabled: false
|
9
9
|
|
10
|
+
Style/EmptyLineAfterMagicComment:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/PercentLiteralDelimiters:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Metrics/BlockLength:
|
17
|
+
Enabled: false
|
18
|
+
|
10
19
|
AllCops:
|
11
20
|
Include:
|
12
|
-
- lib/
|
21
|
+
- lib/
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Chef-RunDeck2 Changelog
|
2
|
+
=========================
|
3
|
+
This file is used to list changes made in each version of the `chef-rundeck2` gem.
|
4
|
+
|
5
|
+
v0.1.3 (2017-04-26)
|
6
|
+
-------------------
|
7
|
+
### Enhancements
|
8
|
+
- Allow customizing hostname:port value via Chef node attributes, API query params and project config file
|
9
|
+
- Sort Recipes & Tags
|
10
|
+
- Remove Recipes from Tags
|
11
|
+
|
12
|
+
v0.1.2 (2016-11-11)
|
13
|
+
-------------------
|
14
|
+
### Enhancements
|
15
|
+
- Security: Hide the config endpoint except in development mode
|
16
|
+
|
17
|
+
### Bugs Fixed
|
18
|
+
- Should automatically pick up the JSON config if developing locally and it is inside `config/config.json`
|
19
|
+
|
20
|
+
v0.1.1 (2016-06-09)
|
21
|
+
-------------------
|
22
|
+
- Initial Release
|
data/Gemfile
CHANGED
@@ -1,15 +1,2 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'chef-api' # => Chef API Interaction
|
4
|
-
# => gem 'hashie' # => Data Structure
|
5
|
-
# => gem 'logify' # => Logging
|
6
|
-
gem 'mixlib-cli' # => Option Parsing
|
7
|
-
gem 'rack-cache' # => Cache Responses
|
8
|
-
gem 'sinatra' # => Web Server
|
9
|
-
gem 'sinatra-contrib' # => For namespaces
|
10
|
-
|
11
|
-
group :development do
|
12
|
-
gem 'rake'
|
13
|
-
gem 'rspec'
|
14
|
-
gem 'rubocop'
|
15
|
-
end
|
2
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,51 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
chef-rundeck2 (0.1.3)
|
5
|
+
chef-api (~> 0.7)
|
6
|
+
mixlib-cli (~> 1.7)
|
7
|
+
rack-cache (~> 1.6)
|
8
|
+
sinatra (~> 1.4)
|
9
|
+
sinatra-contrib (~> 1.4)
|
10
|
+
|
1
11
|
GEM
|
2
12
|
remote: https://rubygems.org/
|
3
13
|
specs:
|
4
14
|
ast (2.3.0)
|
5
|
-
backports (3.
|
6
|
-
chef-api (0.
|
15
|
+
backports (3.7.0)
|
16
|
+
chef-api (0.7.0)
|
7
17
|
logify (~> 0.1)
|
8
18
|
mime-types
|
9
|
-
diff-lcs (1.
|
19
|
+
diff-lcs (1.3)
|
10
20
|
logify (0.2.0)
|
11
21
|
mime-types (3.1)
|
12
22
|
mime-types-data (~> 3.2015)
|
13
23
|
mime-types-data (3.2016.0521)
|
14
|
-
mixlib-cli (1.
|
24
|
+
mixlib-cli (1.7.0)
|
15
25
|
multi_json (1.12.1)
|
16
|
-
parser (2.
|
26
|
+
parser (2.4.0.0)
|
17
27
|
ast (~> 2.2)
|
18
28
|
powerpack (0.1.1)
|
19
|
-
rack (1.6.
|
20
|
-
rack-cache (1.
|
29
|
+
rack (1.6.5)
|
30
|
+
rack-cache (1.7.0)
|
21
31
|
rack (>= 0.4)
|
22
32
|
rack-protection (1.5.3)
|
23
33
|
rack
|
24
34
|
rack-test (0.6.3)
|
25
35
|
rack (>= 1.0)
|
26
|
-
rainbow (2.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
rspec-
|
31
|
-
rspec-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
rainbow (2.2.2)
|
37
|
+
rake
|
38
|
+
rake (10.5.0)
|
39
|
+
rspec (3.5.0)
|
40
|
+
rspec-core (~> 3.5.0)
|
41
|
+
rspec-expectations (~> 3.5.0)
|
42
|
+
rspec-mocks (~> 3.5.0)
|
43
|
+
rspec-core (3.5.4)
|
44
|
+
rspec-support (~> 3.5.0)
|
45
|
+
rspec-expectations (3.5.0)
|
35
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
-
rspec-support (~> 3.
|
37
|
-
rspec-mocks (3.
|
47
|
+
rspec-support (~> 3.5.0)
|
48
|
+
rspec-mocks (3.5.0)
|
38
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
-
rspec-support (~> 3.
|
40
|
-
rspec-support (3.
|
41
|
-
rubocop (0.
|
42
|
-
parser (>= 2.3.1
|
50
|
+
rspec-support (~> 3.5.0)
|
51
|
+
rspec-support (3.5.0)
|
52
|
+
rubocop (0.48.1)
|
53
|
+
parser (>= 2.3.3.1, < 3.0)
|
43
54
|
powerpack (~> 0.1)
|
44
55
|
rainbow (>= 1.99.1, < 3.0)
|
45
56
|
ruby-progressbar (~> 1.7)
|
46
57
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
47
58
|
ruby-progressbar (1.8.1)
|
48
|
-
sinatra (1.4.
|
59
|
+
sinatra (1.4.8)
|
49
60
|
rack (~> 1.5)
|
50
61
|
rack-protection (~> 1.4)
|
51
62
|
tilt (>= 1.3, < 3)
|
@@ -56,21 +67,18 @@ GEM
|
|
56
67
|
rack-test
|
57
68
|
sinatra (~> 1.4.0)
|
58
69
|
tilt (>= 1.3, < 3)
|
59
|
-
tilt (2.0.
|
60
|
-
unicode-display_width (1.
|
70
|
+
tilt (2.0.7)
|
71
|
+
unicode-display_width (1.2.1)
|
61
72
|
|
62
73
|
PLATFORMS
|
63
74
|
ruby
|
64
75
|
|
65
76
|
DEPENDENCIES
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
rubocop
|
72
|
-
sinatra
|
73
|
-
sinatra-contrib
|
77
|
+
bundler (~> 1.12)
|
78
|
+
chef-rundeck2!
|
79
|
+
rake (~> 10.0)
|
80
|
+
rspec (~> 3.0)
|
81
|
+
rubocop (~> 0.48)
|
74
82
|
|
75
83
|
BUNDLED WITH
|
76
|
-
1.
|
84
|
+
1.14.6
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Chef-RunDeck
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
2
|
+
* Chef Resource Provider for RunDeck utilizing the `RESOURCE-JSON` format
|
3
|
+
* RunDeck Options Provider for State of Provisioning
|
4
|
+
* Proxy to Chef Server for Client/Node Object Deletion
|
6
5
|
|
7
6
|
## Background
|
8
7
|
This project started out to act as a proxy for administrative Chef Server interactions, namely client/node deletion.
|
@@ -21,6 +20,8 @@ This gem also serves as a RunDeck options provider, delivering node search resul
|
|
21
20
|
* Query parameters will overrule project-specific configuration.
|
22
21
|
* You don't have to pass in a user, granting the ability to set that sort of configuration in the RunDeck project configuration.
|
23
22
|
|
23
|
+
* Chef node attributes `rd_hostname`, `rd_ssh_port`, `rd_winrm_port`, or `rd_username` will override values set elsewhere.
|
24
|
+
|
24
25
|
## State Functions
|
25
26
|
* Display the State - GET - http://localhost:9125/chef/v1/state
|
26
27
|
* List the Node's for a User - GET - http://localhost:9125/chef/v1/list/${USERNAME}
|
@@ -58,7 +59,7 @@ This leans on `rack-cache` to serve as a caching mechanism. The objective here
|
|
58
59
|
## Credits
|
59
60
|
This Gem leans heavily on Seth Vargo's `ChefAPI` gem. I also took many ideas from his Gem to build this one, as I've never written anything like this before. Thank you, Seth, for both the `ChefAPI` gem and for your consistent high quality contributions to the DevOps community.
|
60
61
|
|
61
|
-
Also, thank you to Adam Jacob for initially developing the `chef-rundeck` gem which served as a baseline for building the
|
62
|
+
Also, thank you to Adam Jacob for initially developing the `chef-rundeck` gem which served as a baseline for building the Resource Provider portion of this one. Thanks for Chef, you've greatly reduce the amount of chaos in my work life!
|
62
63
|
|
63
64
|
|
64
65
|
## Installation
|
data/Rakefile
CHANGED
data/chef-rundeck2.gemspec
CHANGED
@@ -11,14 +11,13 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.authors = ['Brian Dwyer']
|
12
12
|
spec.email = ['bdwyer@IEEE.org']
|
13
13
|
|
14
|
-
spec.summary = %
|
15
|
-
# => spec.description = %q(TODO: Write a longer description or delete this line.)
|
14
|
+
spec.summary = %w(Chef Options Provider for RunDeck with Extras)
|
16
15
|
spec.homepage = 'https://github.com/bdwyertech/chef-rundeck2'
|
17
16
|
spec.license = 'MIT'
|
18
17
|
|
19
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
20
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
21
|
-
if spec.respond_to?(:metadata)
|
20
|
+
if spec.respond_to?(:metadata) # rubocop: disable GuardClause
|
22
21
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
23
22
|
else
|
24
23
|
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
@@ -30,8 +29,8 @@ Gem::Specification.new do |spec|
|
|
30
29
|
spec.require_paths = ['lib']
|
31
30
|
|
32
31
|
# => Dependencies
|
33
|
-
spec.add_runtime_dependency 'chef-api', '~> 0.
|
34
|
-
spec.add_runtime_dependency 'mixlib-cli', '~> 1.
|
32
|
+
spec.add_runtime_dependency 'chef-api', '~> 0.7'
|
33
|
+
spec.add_runtime_dependency 'mixlib-cli', '~> 1.7'
|
35
34
|
spec.add_runtime_dependency 'rack-cache', '~> 1.6'
|
36
35
|
spec.add_runtime_dependency 'sinatra', '~> 1.4'
|
37
36
|
spec.add_runtime_dependency 'sinatra-contrib', '~> 1.4'
|
@@ -40,5 +39,5 @@ Gem::Specification.new do |spec|
|
|
40
39
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
41
40
|
spec.add_development_dependency 'rake', '~> 10.0'
|
42
41
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
43
|
-
spec.add_development_dependency 'rubocop'
|
42
|
+
spec.add_development_dependency 'rubocop', '~> 0.48'
|
44
43
|
end
|
data/config/auth.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"bdwyer": {
|
3
|
-
"auth_key": "
|
3
|
+
"auth_key": "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f",
|
4
4
|
"roles": [
|
5
5
|
"admin"
|
6
6
|
]
|
@@ -9,5 +9,11 @@
|
|
9
9
|
"roles": [
|
10
10
|
"alpha"
|
11
11
|
]
|
12
|
+
},
|
13
|
+
"vagrant": {
|
14
|
+
"roles": [
|
15
|
+
"alpha",
|
16
|
+
"test"
|
17
|
+
]
|
12
18
|
}
|
13
19
|
}
|
data/config/config.json
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
{
|
2
2
|
"cache_timeout": 30,
|
3
|
-
"
|
4
|
-
"
|
5
|
-
"
|
3
|
+
"authh_file": "/tmp/auth.json",
|
4
|
+
"statee_file": "/tmp/state.json",
|
5
|
+
"bind": "0.0.0.0",
|
6
|
+
"auth_only": true,
|
6
7
|
"port": 9125,
|
7
8
|
"environment": "production",
|
8
|
-
"chef_api_endpoint": "https://chef.
|
9
|
+
"chef_api_endpoint": "https://chef.lendio.com/organizations/lendio",
|
9
10
|
"chef_api_client": "rundeck-chef-client",
|
10
|
-
"chef_api_client_key": "~/.chef/
|
11
|
+
"chef_api_client_key": "~/.chef/CHEF_LENDIO/rundeck-chef-client.pem",
|
11
12
|
"chef_api_admin": "bdwyertech",
|
12
|
-
"chef_api_admin_key": "~/.chef/
|
13
|
+
"chef_api_admin_key": "~/.chef/CHEF_LENDIO/bdwyer.pem"
|
13
14
|
}
|
data/config/state.json
CHANGED
@@ -1,8 +1,49 @@
|
|
1
1
|
[
|
2
2
|
{
|
3
|
-
"name": "
|
4
|
-
"created": "2016-
|
5
|
-
"creator": "bdweezy"
|
3
|
+
"name": "alpha-test2",
|
4
|
+
"created": "2016-06-08T13:01:57-04:00",
|
5
|
+
"creator": "bdweezy",
|
6
|
+
"type": "test"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"name": "alpha-testing",
|
10
|
+
"created": "2016-06-08T13:01:57-04:00",
|
11
|
+
"creator": "bdweezy",
|
12
|
+
"type": "alpha",
|
13
|
+
"last_modified": [
|
14
|
+
"2016-06-18T20:16:11-04:00 - bdweezy",
|
15
|
+
"2016-06-18T13:08:56-04:00 - tinkle",
|
16
|
+
"2016-06-18T12:11:31-04:00 - tinkle",
|
17
|
+
"2016-06-18T12:11:30-04:00 - tinkle",
|
18
|
+
"2016-06-18T12:11:30-04:00 - tinkle",
|
19
|
+
"2016-06-18T12:11:30-04:00 - tinkle"
|
20
|
+
]
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"name": "alpha-testingg",
|
24
|
+
"created": "2016-06-18T20:27:45-04:00",
|
25
|
+
"creator": "bdweezy",
|
26
|
+
"type": "alpha"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"name": "alpha-testinggg",
|
30
|
+
"created": "2016-06-18T20:27:54-04:00",
|
31
|
+
"creator": "bdweezy",
|
32
|
+
"type": "alpha",
|
33
|
+
"protected": true
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"name": "alpha-testingggg",
|
37
|
+
"created": "2016-06-18T20:31:49-04:00",
|
38
|
+
"creator": "bdweezy",
|
39
|
+
"type": "alpha",
|
40
|
+
"protected": true
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"name": "alpha-testinggggg",
|
44
|
+
"created": "2016-06-18T20:31:56-04:00",
|
45
|
+
"creator": "bdweezy",
|
46
|
+
"type": "alpha"
|
6
47
|
},
|
7
48
|
{
|
8
49
|
"name": "alpha-vagrant",
|
@@ -11,12 +52,28 @@
|
|
11
52
|
},
|
12
53
|
{
|
13
54
|
"name": "BD-MBPro.local",
|
14
|
-
"created": "2016-
|
15
|
-
"creator": "bdweezy"
|
55
|
+
"created": "2016-06-04T13:53:33-04:00",
|
56
|
+
"creator": "bdweezy",
|
57
|
+
"last_modified": [
|
58
|
+
"2016-06-08T11:15:10-04:00 - bdweezy",
|
59
|
+
"2016-06-08T11:15:09-04:00 - bdweezy",
|
60
|
+
"2016-06-08T11:15:09-04:00 - bdweezy",
|
61
|
+
"2016-06-08T11:15:09-04:00 - bdweezy",
|
62
|
+
"2016-06-08T11:15:08-04:00 - bdweezy",
|
63
|
+
"2016-06-08T11:15:07-04:00 - bdweezy"
|
64
|
+
]
|
16
65
|
},
|
17
66
|
{
|
18
|
-
"name": "
|
19
|
-
"created": "2016-
|
20
|
-
"creator": "
|
67
|
+
"name": "Dave-Node",
|
68
|
+
"created": "2016-06-02T12:18:38-04:00",
|
69
|
+
"creator": "DAVE!!!",
|
70
|
+
"last_modified": [
|
71
|
+
"2016-06-02T12:19:09-04:00 - DAVE!!!",
|
72
|
+
"2016-06-02T12:19:09-04:00 - DAVE!!!",
|
73
|
+
"2016-06-02T12:19:09-04:00 - DAVE!!!",
|
74
|
+
"2016-06-02T12:19:09-04:00 - DAVE!!!",
|
75
|
+
"2016-06-02T12:19:09-04:00 - DAVE!!!",
|
76
|
+
"2016-06-02T12:19:08-04:00 - DAVE!!!"
|
77
|
+
]
|
21
78
|
}
|
22
79
|
]
|
data/lib/chef-rundeck/api.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# rubocop: disable LineLength
|
3
3
|
#
|
4
4
|
# Gem Name:: chef-rundeck
|
5
|
-
#
|
5
|
+
# Class:: API
|
6
6
|
#
|
7
7
|
# Copyright (C) 2016 Brian Dwyer - Intelligent Digital Services
|
8
8
|
#
|
@@ -53,25 +53,27 @@ module ChefRunDeck
|
|
53
53
|
########################
|
54
54
|
|
55
55
|
# => Current Configuration & Healthcheck Endpoint
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
56
|
+
if development?
|
57
|
+
get '/config' do
|
58
|
+
content_type 'application/json'
|
59
|
+
JSON.pretty_generate(
|
60
|
+
[
|
61
|
+
ChefRunDeck.inspect + ' is up and running!',
|
62
|
+
'Author: ' + Config.author,
|
63
|
+
'Environment: ' + Config.environment.to_s,
|
64
|
+
'Root: ' + Config.root.to_s,
|
65
|
+
'Config File: ' + (Config.config_file if File.exist?(Config.config_file)).to_s,
|
66
|
+
'Auth File: ' + (Config.auth_file if File.exist?(Config.auth_file)).to_s,
|
67
|
+
'State File: ' + (Config.state_file if File.exist?(Config.state_file)).to_s,
|
68
|
+
{ State: State.state.map { |n| n[:name] } },
|
69
|
+
'Params: ' + params.inspect,
|
70
|
+
'Cache Timeout: ' + Config.cache_timeout.to_s,
|
71
|
+
'BRIAN IS COOooooooL',
|
72
|
+
{ AppConfig: Config.options },
|
73
|
+
{ 'Sinatra Info' => env }
|
74
|
+
].compact
|
75
|
+
)
|
76
|
+
end
|
75
77
|
end
|
76
78
|
|
77
79
|
get '/state' do
|
@@ -124,9 +126,9 @@ module ChefRunDeck
|
|
124
126
|
# => Admins can see all Nodes
|
125
127
|
return State.state.map { |n| n[:name] }.to_json if Auth.admin?
|
126
128
|
# => Determine Role Admin Nodes
|
127
|
-
admin = State.state.select { |n| n[:type] && Auth.auth['roles'].any? { |r| r.to_s.casecmp(n[:type].to_s)
|
129
|
+
admin = State.state.select { |n| n[:type] && Auth.auth['roles'].any? { |r| r.to_s.casecmp(n[:type].to_s).zero? } }.map { |n| n[:name] }
|
128
130
|
# => Find User-Created Nodes
|
129
|
-
created = State.state.select { |n| n[:creator].casecmp(user)
|
131
|
+
created = State.state.select { |n| n[:creator].casecmp(user).zero? }.map { |n| n[:name] }
|
130
132
|
# => Return the Nodes
|
131
133
|
(admin + created).uniq.to_json
|
132
134
|
end
|
@@ -186,10 +188,35 @@ module ChefRunDeck
|
|
186
188
|
|
187
189
|
# => Add Node to the State
|
188
190
|
post '/add/:node/:user' do |node, user|
|
191
|
+
# => Check If Exists and Authorized
|
192
|
+
if State.state.any? { |n| n[:name] == node }
|
193
|
+
unless Auth.admin? || Auth.creator?(node) || Auth.role_admin?(Chef.run_list(node))
|
194
|
+
status 401
|
195
|
+
return 'Unauthorized'.to_json
|
196
|
+
end
|
197
|
+
end
|
198
|
+
# => Add the Node
|
189
199
|
status 200
|
190
200
|
State.add_state(node, user, params).to_json
|
191
201
|
end
|
192
202
|
|
203
|
+
# => Check If Authorized for a Node
|
204
|
+
post '/auth/:node' do |node|
|
205
|
+
if State.state.any? { |n| n[:name] == node }
|
206
|
+
# => Check Authorization
|
207
|
+
if Auth.admin? || Auth.creator?(node) || Auth.role_admin?(Chef.run_list(node))
|
208
|
+
status 200
|
209
|
+
return 'OK. Authorization Successful'.to_json
|
210
|
+
else
|
211
|
+
status 401
|
212
|
+
return 'Unauthorized'.to_json
|
213
|
+
end
|
214
|
+
else
|
215
|
+
status 200
|
216
|
+
return "OK. #{node} not found in State".to_json
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
193
220
|
# => Delete Node from the Chef Server
|
194
221
|
post '/delete/:node' do |node|
|
195
222
|
unless State.state.any? { |n| n[:name] == node }
|
data/lib/chef-rundeck/auth.rb
CHANGED
@@ -44,7 +44,7 @@ module ChefRunDeck
|
|
44
44
|
|
45
45
|
def admin?
|
46
46
|
# => Check if a User is an Administrator
|
47
|
-
auth['roles'].any? { |x| x.casecmp('admin')
|
47
|
+
auth['roles'].any? { |x| x.casecmp('admin').zero? }
|
48
48
|
end
|
49
49
|
|
50
50
|
def creator?(node)
|
@@ -52,7 +52,7 @@ module ChefRunDeck
|
|
52
52
|
existing = State.find_state(node)
|
53
53
|
return false unless existing
|
54
54
|
# => Check if Auth User was the Node-State Creator
|
55
|
-
existing[:creator].to_s.casecmp(Config.query_params['auth_user'].to_s)
|
55
|
+
existing[:creator].to_s.casecmp(Config.query_params['auth_user'].to_s).zero?
|
56
56
|
end
|
57
57
|
|
58
58
|
# => Validate the User's Authentication Key ## TODO: Use this, passthrough from a RunDeck Option Field
|
@@ -72,6 +72,7 @@ module ChefRunDeck
|
|
72
72
|
# => Role-Based Administration
|
73
73
|
def role_admin?(run_list = nil)
|
74
74
|
return false unless run_list.is_a?(Array)
|
75
|
+
# => This will Authorize Anyone if the RunList is Empty or the Chef Node does not exist!!!
|
75
76
|
run_list.empty? || auth['roles'].any? { |role| run_list.any? { |r| r =~ /role\[#{role}\]/i } }
|
76
77
|
end
|
77
78
|
end
|
data/lib/chef-rundeck/chef.rb
CHANGED
@@ -83,22 +83,20 @@ module ChefRunDeck
|
|
83
83
|
#
|
84
84
|
# => Try to Parse Project-Specific Settings
|
85
85
|
#
|
86
|
-
def
|
86
|
+
private def project
|
87
|
+
projectname = Config.query_params['project']
|
88
|
+
return {} unless projectname
|
87
89
|
settings = Util.parse_json_config(Config.projects_file, false)
|
88
|
-
return {} unless settings && settings[
|
89
|
-
settings[
|
90
|
+
return {} unless settings && settings[projectname]
|
91
|
+
settings[projectname]
|
90
92
|
end
|
91
93
|
|
92
94
|
#
|
93
95
|
# => Construct Query-Specific Configuration
|
94
96
|
#
|
95
|
-
def transient_settings
|
96
|
-
# => Initialize any Project-Specific Settings
|
97
|
-
project = project_settings(Config.query_params['project'])
|
98
|
-
|
97
|
+
private def transient_settings
|
99
98
|
# => Build the Configuration
|
100
99
|
cfg = {}
|
101
|
-
cfg[:username] = Config.query_params['username'] || project['username'] || Config.rd_node_username
|
102
100
|
cfg[:pattern] = Config.query_params['pattern'] || project['pattern'] || '*:*'
|
103
101
|
cfg[:extras] = Util.serialize_csv(Config.query_params['extras']) || project['extras']
|
104
102
|
|
@@ -109,7 +107,7 @@ module ChefRunDeck
|
|
109
107
|
#
|
110
108
|
# => Base Search Filter Definition
|
111
109
|
#
|
112
|
-
def default_search_filter
|
110
|
+
private def default_search_filter
|
113
111
|
{
|
114
112
|
name: ['name'],
|
115
113
|
kernel_machine: ['kernel', 'machine'],
|
@@ -122,7 +120,11 @@ module ChefRunDeck
|
|
122
120
|
platform: ['platform'],
|
123
121
|
platform_version: ['platform_version'],
|
124
122
|
tags: ['tags'],
|
125
|
-
hostname: ['hostname']
|
123
|
+
hostname: ['hostname'],
|
124
|
+
rd_hostname: ['rd_hostname'],
|
125
|
+
rd_ssh_port: ['rd_ssh_port'],
|
126
|
+
rd_winrm_port: ['rd_winrm_port'],
|
127
|
+
rd_username: ['rd_username']
|
126
128
|
}
|
127
129
|
end
|
128
130
|
|
@@ -131,7 +133,7 @@ module ChefRunDeck
|
|
131
133
|
#
|
132
134
|
# => Default Elements can be removed by passing them in here as null or empty
|
133
135
|
#
|
134
|
-
def search_filter_additions
|
136
|
+
private def search_filter_additions
|
135
137
|
attribs = {}
|
136
138
|
Array(Config.rundeck[:extras]).each do |attrib|
|
137
139
|
attribs[attrib.to_sym] = [attrib]
|
@@ -143,7 +145,7 @@ module ChefRunDeck
|
|
143
145
|
#
|
144
146
|
# => Construct the Search Filter
|
145
147
|
#
|
146
|
-
def search_filter
|
148
|
+
private def search_filter
|
147
149
|
# => Merge the Default Filter with Additions
|
148
150
|
default_search_filter.merge(search_filter_additions).reject { |_k, v| v.nil? || String(v).empty? }
|
149
151
|
end
|
@@ -151,7 +153,7 @@ module ChefRunDeck
|
|
151
153
|
#
|
152
154
|
# => Define Extra Attributes for Resource Return
|
153
155
|
#
|
154
|
-
def custom_attributes(node)
|
156
|
+
private def custom_attributes(node)
|
155
157
|
attribs = {}
|
156
158
|
Array(Config.rundeck[:extras]).each do |attrib|
|
157
159
|
attribs[attrib.to_sym] = node[attrib].inspect
|
@@ -174,20 +176,67 @@ module ChefRunDeck
|
|
174
176
|
result.rows.collect do |node|
|
175
177
|
{
|
176
178
|
nodename: node['name'],
|
177
|
-
hostname: node
|
179
|
+
hostname: build_hostname(node),
|
178
180
|
osArch: node['kernel_machine'],
|
179
181
|
osFamily: node['platform'],
|
180
182
|
osName: node['platform'],
|
181
183
|
osVersion: node['platform_version'],
|
182
184
|
description: node['name'],
|
183
|
-
roles: node['roles'].join(','),
|
184
|
-
recipes: node['recipes'].join(','),
|
185
|
-
tags: [node['roles'], node['
|
185
|
+
roles: node['roles'].sort.join(','),
|
186
|
+
recipes: node['recipes'].sort.join(','),
|
187
|
+
tags: [node['roles'], node['chef_environment'], node['tags']].flatten.sort.join(','),
|
186
188
|
environment: node['chef_environment'],
|
187
189
|
editUrl: ::File.join(Config.chef_api_endpoint, 'nodes', node['name']),
|
188
|
-
username:
|
190
|
+
username: remote_username(node)
|
189
191
|
}.merge(custom_attributes(node)).reject { |_k, v| v.nil? || String(v).empty? }
|
190
192
|
end
|
191
193
|
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# => Build the Hostname
|
197
|
+
#
|
198
|
+
private def build_hostname(node) # rubocop:
|
199
|
+
# => anode.bdwyertech.net:22
|
200
|
+
[remote_hostname(node), remote_port(node)].compact.join(':')
|
201
|
+
end
|
202
|
+
|
203
|
+
#
|
204
|
+
# => Determine the Remote Hostname
|
205
|
+
#
|
206
|
+
private def remote_hostname(node)
|
207
|
+
node['rd_hostname'] || node['fqdn'] || node['hostname']
|
208
|
+
end
|
209
|
+
|
210
|
+
#
|
211
|
+
# => Determine the Remote Port
|
212
|
+
#
|
213
|
+
private def remote_port(node)
|
214
|
+
# => WinRM if Windows
|
215
|
+
if node['platform'] == 'windows'
|
216
|
+
[
|
217
|
+
node['rd_winrm_port'],
|
218
|
+
Config.query_params['winrm_port'],
|
219
|
+
project['winrm_port']
|
220
|
+
].find { |winrm_port| winrm_port }
|
221
|
+
else
|
222
|
+
# => SSH for Everything Else
|
223
|
+
[
|
224
|
+
node['rd_ssh_port'],
|
225
|
+
Config.query_params['ssh_port'],
|
226
|
+
project['ssh_port']
|
227
|
+
].find { |ssh_port| ssh_port }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
#
|
231
|
+
# => Determine the Remote Username
|
232
|
+
#
|
233
|
+
private def remote_username(node)
|
234
|
+
[
|
235
|
+
node['rd_username'],
|
236
|
+
Config.query_params['username'],
|
237
|
+
project['username'],
|
238
|
+
Config.rd_node_username
|
239
|
+
].find { |username| username }
|
240
|
+
end
|
192
241
|
end
|
193
242
|
end
|
data/lib/chef-rundeck/cli.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# rubocop: disable LineLength, MethodLength, AbcSize
|
3
3
|
#
|
4
4
|
# Gem Name:: chef-rundeck
|
5
|
-
#
|
5
|
+
# Module:: CLI
|
6
6
|
#
|
7
7
|
# Copyright (C) 2016 Brian Dwyer - Intelligent Digital Services
|
8
8
|
#
|
@@ -99,24 +99,33 @@ module ChefRunDeck
|
|
99
99
|
cli = Options.new
|
100
100
|
cli.parse_options(argv)
|
101
101
|
|
102
|
-
# => Parse JSON Config File (If Specified & Exists)
|
103
|
-
json_config = Util.parse_json_config(cli.config[:config_file])
|
104
|
-
|
105
102
|
# => Grab the Default Values
|
106
|
-
default =
|
103
|
+
default = Config.options
|
104
|
+
|
105
|
+
# => Parse JSON Config File (If Specified and Exists)
|
106
|
+
json_config = Util.parse_json_config(cli.config[:config_file] || Config.config_file)
|
107
|
+
|
108
|
+
# => # => Flatten the JSON Config
|
109
|
+
# => if json_config && json_config[:chef]
|
110
|
+
# => json_config[:chef].each do |k, v|
|
111
|
+
# => next unless v && !v.empty?
|
112
|
+
# => json_config[:"chef_#{k}"] = v
|
113
|
+
# => end
|
114
|
+
# => json_config.delete(:chef)
|
115
|
+
# => end
|
107
116
|
|
108
|
-
# => Merge Configuration (
|
117
|
+
# => Merge Configuration (CLI Wins)
|
109
118
|
config = [default, json_config, cli.config].compact.reduce(:merge)
|
110
119
|
|
111
120
|
# => Apply Configuration
|
112
|
-
|
121
|
+
Config.setup do |cfg|
|
113
122
|
cfg.config_file = config[:config_file]
|
114
123
|
cfg.cache_timeout = config[:cache_timeout].to_i
|
115
124
|
cfg.bind = config[:bind]
|
116
125
|
cfg.port = config[:port]
|
117
126
|
cfg.auth_file = config[:auth_file]
|
118
127
|
cfg.state_file = config[:state_file]
|
119
|
-
cfg.environment = config[:environment].to_sym
|
128
|
+
cfg.environment = config[:environment].to_sym.downcase
|
120
129
|
cfg.chef_api_endpoint = config[:chef_api_endpoint]
|
121
130
|
cfg.chef_api_client = config[:chef_api_client]
|
122
131
|
cfg.chef_api_client_key = config[:chef_api_client_key]
|
@@ -126,7 +135,7 @@ module ChefRunDeck
|
|
126
135
|
end
|
127
136
|
|
128
137
|
# => Launch the API
|
129
|
-
|
138
|
+
API.run!
|
130
139
|
end
|
131
140
|
end
|
132
141
|
end
|
data/lib/chef-rundeck/config.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Encoding: UTF-8
|
2
2
|
#
|
3
3
|
# Gem Name:: chef-rundeck
|
4
|
-
#
|
4
|
+
# Module:: Config
|
5
5
|
#
|
6
6
|
# Copyright (C) 2016 Brian Dwyer - Intelligent Digital Services
|
7
7
|
#
|
@@ -43,6 +43,9 @@ module ChefRunDeck
|
|
43
43
|
# => Project Configuration File
|
44
44
|
define_setting :projects_file, File.join(root, 'config', 'projects.json')
|
45
45
|
|
46
|
+
# => Limit Deletions to only Authorized Users
|
47
|
+
define_setting :authorize_deletes, true
|
48
|
+
|
46
49
|
#
|
47
50
|
# => Chef API Configuration
|
48
51
|
#
|
data/lib/chef-rundeck/state.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# rubocop: disable LineLength
|
3
3
|
#
|
4
4
|
# Gem Name:: chef-rundeck
|
5
|
-
#
|
5
|
+
# Module:: State
|
6
6
|
#
|
7
7
|
# Copyright (C) 2016 Brian Dwyer - Intelligent Digital Services
|
8
8
|
#
|
@@ -28,12 +28,11 @@ module ChefRunDeck
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def find_state(node)
|
31
|
-
state.detect { |h| h[:name].casecmp(node)
|
31
|
+
state.detect { |h| h[:name].casecmp(node).zero? }
|
32
32
|
end
|
33
33
|
|
34
34
|
def update_state(hash) # rubocop: disable AbcSize
|
35
35
|
# => Check if Node Already Exists
|
36
|
-
# => existing = state.detect { |h| h[:name].casecmp(hash[:name]) == 0 }
|
37
36
|
existing = find_state(hash[:name])
|
38
37
|
if existing # => Update the Existing Node
|
39
38
|
state.delete(existing)
|
@@ -50,12 +49,19 @@ module ChefRunDeck
|
|
50
49
|
end
|
51
50
|
|
52
51
|
# => Add Node to the State
|
53
|
-
def add_state(node, user, params)
|
52
|
+
def add_state(node, user, params) # rubocop: disable MethodLength, AbcSize
|
54
53
|
# => Create a Node-State Object
|
55
54
|
(n = {}) && (n[:name] = node)
|
56
55
|
n[:created] = DateTime.now
|
57
56
|
n[:creator] = user
|
58
|
-
|
57
|
+
# => Parse our Field Values
|
58
|
+
%w(type).each do |opt|
|
59
|
+
n[opt.to_sym] = params[opt] if params[opt]
|
60
|
+
end
|
61
|
+
# => Parse our Booleans
|
62
|
+
%w(protected).each do |opt|
|
63
|
+
n[opt.to_sym] = true if params[opt] && %w(true 1).any? { |x| params[opt].to_s.casecmp(x).zero? }
|
64
|
+
end
|
59
65
|
# => Build the Updated State
|
60
66
|
update_state(n)
|
61
67
|
# => Return the Added Node
|
data/lib/chef-rundeck/util.rb
CHANGED
data/lib/chef-rundeck/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-rundeck2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Dwyer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-api
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mixlib-cli
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rack-cache
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,16 +126,16 @@ dependencies:
|
|
126
126
|
name: rubocop
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
131
|
+
version: '0.48'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
138
|
+
version: '0.48'
|
139
139
|
description:
|
140
140
|
email:
|
141
141
|
- bdwyer@IEEE.org
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- ".gitignore"
|
148
148
|
- ".gitlab-ci.yml"
|
149
149
|
- ".rubocop.yml"
|
150
|
+
- CHANGELOG.md
|
150
151
|
- Gemfile
|
151
152
|
- Gemfile.lock
|
152
153
|
- LICENSE.txt
|
@@ -191,8 +192,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
192
|
version: '0'
|
192
193
|
requirements: []
|
193
194
|
rubyforge_project:
|
194
|
-
rubygems_version: 2.6.
|
195
|
+
rubygems_version: 2.6.8
|
195
196
|
signing_key:
|
196
197
|
specification_version: 4
|
197
|
-
summary: Chef Options Provider for RunDeck with Extras
|
198
|
+
summary: '["Chef", "Options", "Provider", "for", "RunDeck", "with", "Extras"]'
|
198
199
|
test_files: []
|