capistrano-cook 2.0.2
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/.chef/knife.rb +5 -0
- data/.chef/stickywicket.pem +27 -0
- data/.gitignore +5 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +141 -0
- data/Rakefile +10 -0
- data/capistrano-cook.gemspec +29 -0
- data/lib/capistrano/chef.rb +9 -0
- data/lib/capistrano/chef/helpers.rb +11 -0
- data/lib/capistrano/chef/test_case.rb +72 -0
- data/lib/capistrano/chef/version.rb +5 -0
- data/lib/capistrano/cook.rb +1 -0
- data/lib/capistrano/dsl/chef.rb +135 -0
- data/test/capistrano/chef_test.rb +15 -0
- data/test/capistrano/dsl/chef_test.rb +104 -0
- data/test/minitest_helper.rb +5 -0
- metadata +149 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: bf3660e0e4fdba0e74b570347a9eff467e5ed5f3
|
|
4
|
+
data.tar.gz: 1ff846b5e65c836ef4259cfaacfc9a057a82e81b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a24116cefc428d2a7d6b2110cb47afd845831af4573bda608d883aab179eb10a63e3112d2f90f3ab9f4c443f604a467034320dfba4806d90df48aa57e0019649
|
|
7
|
+
data.tar.gz: 2b26ef5808784874f74ba8785fa037f269695ec1220a6d6a5d94ab7b4f36698925e96e427e1f3b8939e6ac59d675913dbe3138d485a9232e1ba8ecb565363472
|
data/.chef/knife.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
+
MIIEpAIBAAKCAQEA0sOY9tHvVtLZ6xmVmH8d8LrRrNcWOXbrvvCrai+T3GtRvRSL
|
|
3
|
+
hksLrpOpD0L9EHM6NdThNF/eGA9Oq+UKAe6yXR0hwsKuxKXqQ8SEmlhZZ9GiuggD
|
|
4
|
+
B/zYD3ItB6SGpdkRe7kQqTChQyrIXqbRkJqxoTXLyeJDF0sCyTdp3L8IZCUWodM8
|
|
5
|
+
oV9TlQBJHYtG1gLUwIi8kcMVEoCn2Q8ltCj0/ftnwhTtwO52RkWA0uYOLGVayHsL
|
|
6
|
+
SCFfx+ACWPU/oWCwW5/KBqb3veTv0aEg/nh0QsFzRLoTx6SRFI5dT2Nf8iiJe4WC
|
|
7
|
+
UG8WKEB2G8QPnxsxfOPYDBdTJ4CXEi2e+z41VQIDAQABAoIBAALhqbW2KQ+G0nPk
|
|
8
|
+
ZacwFbi01SkHx8YBWjfCEpXhEKRy0ytCnKW5YO+CFU2gHNWcva7+uhV9OgwaKXkw
|
|
9
|
+
KHLeUJH1VADVqI4Htqw2g5mYm6BPvWnNsjzpuAp+BR+VoEGkNhj67r9hatMAQr0I
|
|
10
|
+
itTvSH5rvd2EumYXIHKfz1K1SegUk1u1EL1RcMzRmZe4gDb6eNBs9Sg4im4ybTG6
|
|
11
|
+
pPIytA8vBQVWhjuAR2Tm+wZHiy0Az6Vu7c2mS07FSX6FO4E8SxWf8idaK9ijMGSq
|
|
12
|
+
FvIS04mrY6XCPUPUC4qm1qNnhDPpOr7CpI2OO98SqGanStS5NFlSFXeXPpM280/u
|
|
13
|
+
fZUA0AECgYEA+x7QUnffDrt7LK2cX6wbvn4mRnFxet7bJjrfWIHf+Rm0URikaNma
|
|
14
|
+
h0/wNKpKBwIH+eHK/LslgzcplrqPytGGHLOG97Gyo5tGAzyLHUWBmsNkRksY2sPL
|
|
15
|
+
uHq6pYWJNkqhnWGnIbmqCr0EWih82x/y4qxbJYpYqXMrit0wVf7yAgkCgYEA1twI
|
|
16
|
+
gFaXqesetTPoEHSQSgC8S4D5/NkdriUXCYb06REcvo9IpFMuiOkVUYNN5d3MDNTP
|
|
17
|
+
IdBicfmvfNELvBtXDomEUD8ls1UuoTIXRNGZ0VsZXu7OErXCK0JKNNyqRmOwcvYL
|
|
18
|
+
JRqLfnlei5Ndo1lu286yL74c5rdTLs/nI2p4e+0CgYB079ZmcLeILrmfBoFI8+Y/
|
|
19
|
+
gJLmPrFvXBOE6+lRV7kqUFPtZ6I3yQzyccETZTDvrnx0WjaiFavUPH27WMjY01S2
|
|
20
|
+
TMtO0Iq1MPsbSrglO1as8MvjB9ldFcvp7gy4Q0Sv6XT0yqJ/S+vo8Df0m+H4UBpU
|
|
21
|
+
f5o6EwBSd/UQxwtZIE0lsQKBgQCswfjX8Eg8KL/lJNpIOOE3j4XXE9ptksmJl2sB
|
|
22
|
+
jxDnQYoiMqVO808saHVquC/vTrpd6tKtNpehWwjeTFuqITWLi8jmmQ+gNTKsC9Gn
|
|
23
|
+
1Pxf2Gb67PqnEpwQGln+TRtgQ5HBrdHiQIi+5am+gnw89pDrjjO5rZwhanAo6KPJ
|
|
24
|
+
1zcPNQKBgQDxFu8v4frDmRNCVaZS4f1B6wTrcMrnibIDlnzrK9GG6Hz1U7dDv8s8
|
|
25
|
+
Nf4UmeMzDXjlPWZVOvS5+9HKJPdPj7/onv8B2m18+lcgTTDJBkza7R1mjL1Cje/Z
|
|
26
|
+
KcVGsryKN6cjE7yCDasnA7R2rVBV/7NWeJV77bmzT5O//rW4yIfUIg==
|
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2014 Justin Reagor <cheapRoc>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# capistrano-cook
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/cheapRoc/capistrano-cook) [](https://gemnasium.com/cheapRoc/capistrano-cook)
|
|
4
|
+
|
|
5
|
+
_capistrano-cook_ is a fork of [Capistrano::Chef][fork].
|
|
6
|
+
|
|
7
|
+
The goal of _capistrano-cook_ is to provide a set of tools you may or may not
|
|
8
|
+
need when you'd like to use [Capistrano][cap] and [Chef][chef] together.
|
|
9
|
+
|
|
10
|
+
**Note**: capistrano-cook will not support older versions of Capistrano prior to
|
|
11
|
+
version 3.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
$ echo "gem 'capistrano-cook'" >> Gemfile
|
|
16
|
+
$ bundle install
|
|
17
|
+
$ echo "require 'capistrano/chef'" >> Capfile
|
|
18
|
+
|
|
19
|
+
It doesn't matter if you require `"capistrano/chef"` or `"capistrano/cook"`.
|
|
20
|
+
|
|
21
|
+
## Knife Configuration
|
|
22
|
+
|
|
23
|
+
A Chef Server configuration is expected to be available as [Knife][knife] is
|
|
24
|
+
used to configure this library. You must have a `.chef` directory including a
|
|
25
|
+
configured `knife.rb` in either the current directory or one it's parents. After
|
|
26
|
+
running `bundle install` check to see if you can use the `knife` command
|
|
27
|
+
properly.
|
|
28
|
+
|
|
29
|
+
If you're using [Hosted Chef][hosted] these configuration files will be provided
|
|
30
|
+
to you.
|
|
31
|
+
|
|
32
|
+
If not, the configuration can be generated with `knife configure -i`.
|
|
33
|
+
|
|
34
|
+
See the [Chef Documentation][config] for more details.
|
|
35
|
+
|
|
36
|
+
**TIP**: Symlink it in from another project.
|
|
37
|
+
|
|
38
|
+
## Roles
|
|
39
|
+
|
|
40
|
+
Capistrano allows you to specify the roles of your application and which
|
|
41
|
+
specific server hosts are members of those roles.
|
|
42
|
+
|
|
43
|
+
Chef also has its own unique concept of roles. A role in Chef can be assigned to
|
|
44
|
+
any node and provide that node with with special attributes or cookbooks.
|
|
45
|
+
|
|
46
|
+
__capistrano-cook__ provides a number of helper methods that allow you to utilize
|
|
47
|
+
Chef roles and their data from within Capistrano.
|
|
48
|
+
|
|
49
|
+
### Examples
|
|
50
|
+
|
|
51
|
+
A normal `deploy.rb` in an app using capistrano defines roles like this:
|
|
52
|
+
|
|
53
|
+
role :web, '10.0.0.2', '10.0.0.3'
|
|
54
|
+
role :db, '10.0.0.2', :primary => true
|
|
55
|
+
|
|
56
|
+
Using `capistrano-cook`, you can do this:
|
|
57
|
+
|
|
58
|
+
require 'capistrano/chef'
|
|
59
|
+
|
|
60
|
+
chef_role :web 'role:web'
|
|
61
|
+
chef_role :db, 'role:database AND tag:master', primary: true,
|
|
62
|
+
attribute: :private_ip,
|
|
63
|
+
limit: 1
|
|
64
|
+
|
|
65
|
+
Use a Hash to get a specific network interface.
|
|
66
|
+
|
|
67
|
+
The Hash must be in the form of `{ 'interface-name' => 'network-family-name' }`.
|
|
68
|
+
|
|
69
|
+
chef_role :web, 'role:web', attribute: { eth1: :inet }
|
|
70
|
+
|
|
71
|
+
For a more deep and complex attribute search, call with a block.
|
|
72
|
+
|
|
73
|
+
chef_role :web, 'roles:web' do |node|
|
|
74
|
+
node["network"]["interfaces"]["eth1"]["addresses"].select do |address, data|
|
|
75
|
+
data["family"] == "inet"
|
|
76
|
+
end.keys.first
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
This defines the same roles using [Chef's search feature][search]. Nodes are
|
|
80
|
+
searched using the given query. The node's `ipaddress` attribute is used by
|
|
81
|
+
default, but other attributes can be specified in the options as shown in the
|
|
82
|
+
examples above. The rest of the options are the same as those used by
|
|
83
|
+
Capistrano.
|
|
84
|
+
|
|
85
|
+
You can also define multiple roles at the same time if the host list is
|
|
86
|
+
identical. Instead of running multiple searches to the Chef server, you can pass
|
|
87
|
+
an Array to `chef_role`:
|
|
88
|
+
|
|
89
|
+
chef_role [:web, :app], 'role:web'
|
|
90
|
+
|
|
91
|
+
## Search
|
|
92
|
+
|
|
93
|
+
You can also perform generic searches against your Chef Server search indexes.
|
|
94
|
+
|
|
95
|
+
### Examples
|
|
96
|
+
|
|
97
|
+
Calling `chef_search` will result in an enumerable of Chef::Node objects.
|
|
98
|
+
|
|
99
|
+
nodes = chef_search :node, "name:backup_database"
|
|
100
|
+
nodes.each { |node| puts node.name }
|
|
101
|
+
|
|
102
|
+
You can also scope your search calls so that you don't need to constantly
|
|
103
|
+
include the same search terms for each `chef_role` or `chef_search` call.
|
|
104
|
+
|
|
105
|
+
This next example will return all nodes which are tagged with "migrations"
|
|
106
|
+
within the "myface_production" Chef environment.
|
|
107
|
+
|
|
108
|
+
chef_scope "chef_environment:myface_production"
|
|
109
|
+
|
|
110
|
+
chef_search :node, "tag:migrations"
|
|
111
|
+
|
|
112
|
+
There is also a short hand version for defining your environment name. The
|
|
113
|
+
following performs the same as the above `chef_scope` call.
|
|
114
|
+
|
|
115
|
+
chef_env "myface_production"
|
|
116
|
+
|
|
117
|
+
## Contributing
|
|
118
|
+
|
|
119
|
+
* Fork the project.
|
|
120
|
+
* Make your feature addition or bug fix in a topic branch.
|
|
121
|
+
* Add tests for it. This is important so I don't break it in a future version
|
|
122
|
+
unintentionally.
|
|
123
|
+
* Commit, do not mess with Rakefile or version (if you want to have your own
|
|
124
|
+
version, that is fine but bump version in a commit by itself I can ignore when
|
|
125
|
+
I pull)
|
|
126
|
+
* Update (rebase) your commits with my master.
|
|
127
|
+
* Send me a pull request.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
See [LICENSE](license).
|
|
132
|
+
|
|
133
|
+
[chef]: http://www.getchef.com/
|
|
134
|
+
[cap]: http://capistranorb.com/
|
|
135
|
+
[old]: http://rubygems.org/gems/capistrano-chef/versions/0.1.0
|
|
136
|
+
[fork]: http://github.com/gofullstack/capistrano-chef
|
|
137
|
+
[search]: http://wiki.opscode.com/display/chef/Search
|
|
138
|
+
[knife]: http://wiki.opscode.com/display/chef/Knife
|
|
139
|
+
[config]: http://wiki.opscode.com/display/chef/Chef+Repository#ChefRepository-Configuration
|
|
140
|
+
[hosted]: http://www.opscode.com/hosted-chef/
|
|
141
|
+
[license]: http://github.com/cheapRoc/capistrano-cook/blob/master/LICENSE
|
data/Rakefile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "capistrano/chef/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "capistrano-cook"
|
|
7
|
+
s.version = Capistrano::Chef::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ['Justin Reagor']
|
|
10
|
+
s.email = ['cheapRoc+gh@gmail.com']
|
|
11
|
+
s.homepage = "https://github.com/cheapRoc/capistrano-cook"
|
|
12
|
+
s.summary = %q{Capistrano 3 support for working with Chef, not replacing it}
|
|
13
|
+
s.description = %q{Provides easy support for using Capistrano and Chef together}
|
|
14
|
+
s.license = 'MIT'
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
s.add_dependency "capistrano", "~> 3.2.1"
|
|
22
|
+
s.add_dependency "chef", "~> 11.12.8"
|
|
23
|
+
|
|
24
|
+
s.add_development_dependency "bundler", "~> 1.6"
|
|
25
|
+
s.add_development_dependency "rake"
|
|
26
|
+
s.add_development_dependency "minitest"
|
|
27
|
+
s.add_development_dependency "chef-zero"
|
|
28
|
+
end
|
|
29
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require "sshkit"
|
|
2
|
+
require "capistrano/configuration"
|
|
3
|
+
require "chef_zero/server"
|
|
4
|
+
|
|
5
|
+
module Capistrano
|
|
6
|
+
module Chef
|
|
7
|
+
# @api private
|
|
8
|
+
module TestHelpers
|
|
9
|
+
|
|
10
|
+
include Capistrano::DSL::Chef
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
|
|
14
|
+
def_delegators ::Capistrano::Configuration, :env, :reset!
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
if chef_server.running?
|
|
18
|
+
chef_server.stop
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
chef_server.start_background
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def teardown
|
|
26
|
+
reset!
|
|
27
|
+
chef_server.stop if chef_server.running?
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def chef_server
|
|
32
|
+
@chef_server ||= ::ChefZero::Server.new \
|
|
33
|
+
port: 8889,
|
|
34
|
+
debug: !!ENV['DEBUG'],
|
|
35
|
+
single_org: false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def servers
|
|
39
|
+
env.send(:servers)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def servers_with_role(role)
|
|
43
|
+
servers.map do |server|
|
|
44
|
+
next unless server.properties.roles.include?(role)
|
|
45
|
+
yield server if block_given?
|
|
46
|
+
server
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def nodes
|
|
51
|
+
@nodes ||= {}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def stub_node(name, &block)
|
|
55
|
+
name = name.to_s || "test_node_#{nodes.keys.size}"
|
|
56
|
+
nodes[name] = ::Chef::Node.build(name).tap(&block)
|
|
57
|
+
data = ::JSON.fast_generate(nodes[name])
|
|
58
|
+
chef_server.load_data({ "nodes" => { name => data }})
|
|
59
|
+
nodes[name]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def method_missing(name, *args)
|
|
63
|
+
if env.respond_to?(name)
|
|
64
|
+
env.__send__(name, *args)
|
|
65
|
+
else
|
|
66
|
+
super name, *args
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative "chef"
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
require 'chef/search/query'
|
|
2
|
+
require 'capistrano/chef/helpers'
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
module DSL
|
|
6
|
+
# @api private
|
|
7
|
+
module Chef
|
|
8
|
+
#
|
|
9
|
+
# @attr_writer chef_query_class [Chef::Search::Query, #new<#search>] the dependency class we query for Chef data
|
|
10
|
+
#
|
|
11
|
+
# @attr_writer chef_context [Capistrano::Configuration] the Capistrano.env object we configure
|
|
12
|
+
#
|
|
13
|
+
# @api public
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Includes some private library helpers
|
|
18
|
+
#
|
|
19
|
+
include Capistrano::Chef::Helpers
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Provide a way to customize the interface methods our internals use at
|
|
23
|
+
# runtime.
|
|
24
|
+
#
|
|
25
|
+
def self.included(klass)
|
|
26
|
+
klass.send :attr_writer, :chef_query_class
|
|
27
|
+
klass.send :attr_writer, :chef_context
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Set a default Chef environment name for our #chef_search calls.
|
|
32
|
+
#
|
|
33
|
+
# @param env [Symbol, String] name of the Chef environment to search
|
|
34
|
+
#
|
|
35
|
+
# @api public
|
|
36
|
+
#
|
|
37
|
+
def chef_env(env)
|
|
38
|
+
chef_scope :chef_environment, env
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Set a term that is included for every #chef_search call.
|
|
43
|
+
#
|
|
44
|
+
# @param field [Symbol, String] field to search
|
|
45
|
+
# @param term [String] query term to search
|
|
46
|
+
#
|
|
47
|
+
# @api public
|
|
48
|
+
#
|
|
49
|
+
def chef_scope(field, term="*")
|
|
50
|
+
scopes = fetch(:chef_scopes) || []
|
|
51
|
+
set :chef_scopes, scopes << [field, term].join(":")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Set a Capistrano roles by searching a Chef Server for appropriate node
|
|
56
|
+
# data
|
|
57
|
+
#
|
|
58
|
+
# @param name [String, Symbol, Array<String, Symbol>] roles to set
|
|
59
|
+
# @param query [String] query for searching a chef server
|
|
60
|
+
# @param options [Hash] optional role and search criteria
|
|
61
|
+
# @param block [Proc] block used to filter search result nodes
|
|
62
|
+
# @return [Array<Hash>] map of hashes of user and host pairs by role name
|
|
63
|
+
#
|
|
64
|
+
# @api public
|
|
65
|
+
#
|
|
66
|
+
def chef_role(names, query=nil, options={}, &block)
|
|
67
|
+
user = options[:user] ||= fetch(:user)
|
|
68
|
+
attribute = options.delete(:attribute) || :ipaddress
|
|
69
|
+
index = options.delete(:index) || :node
|
|
70
|
+
results_proc = block_given? ? block : chef_results_by(attribute)
|
|
71
|
+
terms = [index, query].compact
|
|
72
|
+
addresses = chef_search(*terms).flat_map(&results_proc)
|
|
73
|
+
|
|
74
|
+
addresses.each do |address|
|
|
75
|
+
server address, options.merge(roles: names)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
#
|
|
80
|
+
# Query a Chef Server to search for specific nodes
|
|
81
|
+
#
|
|
82
|
+
# @param type [Symbol] type of chef objects to query
|
|
83
|
+
# @param query [String] query string
|
|
84
|
+
# @return [Array<Chef::Node>] list of node results found
|
|
85
|
+
#
|
|
86
|
+
# @api public
|
|
87
|
+
#
|
|
88
|
+
def chef_search(type, query="*:*")
|
|
89
|
+
chef_scopes = fetch(:chef_scopes) || []
|
|
90
|
+
queries = [chef_scopes, query].flatten.join(" AND ")
|
|
91
|
+
puts "Searching Chef types \"#{type}\" with \"#{queries}\"" if debug?
|
|
92
|
+
results = chef_query_class.new.search(type, queries).first
|
|
93
|
+
puts "Found #{results.count}" if debug?
|
|
94
|
+
results
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Interface dependency using Chef for searching by default
|
|
101
|
+
#
|
|
102
|
+
def chef_query_class
|
|
103
|
+
@chef_query_class ||= ::Chef::Search::Query
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Interface dependency of our Capistrano config context
|
|
108
|
+
#
|
|
109
|
+
def chef_context
|
|
110
|
+
@chef_context || ::Capistrano.env
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# Query a Chef Server to search for specific nodes
|
|
115
|
+
#
|
|
116
|
+
def chef_results_by(attribute)
|
|
117
|
+
case attribute
|
|
118
|
+
when Symbol, String
|
|
119
|
+
lambda { |node| node[attribute] }
|
|
120
|
+
when Hash # not tested
|
|
121
|
+
iface, family = attribute.keys.first.to_s, attribute.values.first.to_s
|
|
122
|
+
lambda do |nodes|
|
|
123
|
+
addresses = node["network"]["interfaces"][iface]["addresses"]
|
|
124
|
+
addresses.select do |address, data|
|
|
125
|
+
data["family"] == family
|
|
126
|
+
end.to_a.first.first
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
Proc.new {} # noop
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'minitest_helper'
|
|
2
|
+
require 'capistrano/chef'
|
|
3
|
+
|
|
4
|
+
# HACK until this DSL is scoped within a task
|
|
5
|
+
$extended_modules = (class << self; self end).included_modules
|
|
6
|
+
|
|
7
|
+
class Capistrano::ChefTest < Minitest::Test
|
|
8
|
+
def test_that_it_has_a_version_number
|
|
9
|
+
refute_nil ::Capistrano::Chef::VERSION
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_it_does_something_useful
|
|
13
|
+
assert_includes $extended_modules, ::Capistrano::DSL::Chef
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'minitest_helper'
|
|
2
|
+
|
|
3
|
+
class Capistrano::DSL::ChefTest < Minitest::Test
|
|
4
|
+
|
|
5
|
+
include Capistrano::Chef::TestHelpers
|
|
6
|
+
|
|
7
|
+
def test_chef_role
|
|
8
|
+
user = "jimbo"
|
|
9
|
+
hostname = "10.1.2.3"
|
|
10
|
+
|
|
11
|
+
set :user, user
|
|
12
|
+
stub_node :test_node_1 do |node|
|
|
13
|
+
node.normal.ipaddress = hostname
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
chef_role :cachey, "name:test_node_1"
|
|
17
|
+
|
|
18
|
+
servers_with_role :cachey do |server|
|
|
19
|
+
assert_equal user, server.user
|
|
20
|
+
assert_equal hostname, server.hostname
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_chef_role_block
|
|
25
|
+
user = "duder"
|
|
26
|
+
hostname = "129.1.2.3"
|
|
27
|
+
|
|
28
|
+
set :user, user
|
|
29
|
+
stub_node :test_node_2 do |node|
|
|
30
|
+
node.normal.ipaddress = "88.1.2.3"
|
|
31
|
+
node.normal.network.interfaces.eth0.addresses[hostname].family = "inet"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
chef_role :webbie, "name:test_node_2" do |node|
|
|
35
|
+
node["network"]["interfaces"]["eth0"]["addresses"].map do |ipaddress, address|
|
|
36
|
+
next ipaddress if address.family == "inet"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
servers_with_role :webbie do |server|
|
|
41
|
+
assert_equal user, server.user
|
|
42
|
+
assert_equal hostname, server.hostname
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_chef_env
|
|
47
|
+
env = "bumville"
|
|
48
|
+
hostname = "84.9.1.11"
|
|
49
|
+
|
|
50
|
+
stub_node :test_node_3 do |node|
|
|
51
|
+
node.chef_environment = "box_spring"
|
|
52
|
+
node.normal.ipaddress = "197.3.2.1"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
stub_node :test_node_4 do |node|
|
|
56
|
+
node.chef_environment = env
|
|
57
|
+
node.normal.ipaddress = hostname
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
assert servers.to_a.size.zero?, "Should be no servers"
|
|
61
|
+
|
|
62
|
+
chef_env env
|
|
63
|
+
|
|
64
|
+
assert_includes fetch(:chef_scopes), "chef_environment:#{env}"
|
|
65
|
+
|
|
66
|
+
chef_role :rubix, "name:test_node_*"
|
|
67
|
+
|
|
68
|
+
assert_equal 1, servers.to_a.size
|
|
69
|
+
|
|
70
|
+
servers_with_role :rubix do |server|
|
|
71
|
+
assert_equal hostname, server.hostname
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_chef_scope
|
|
76
|
+
env = "livefree"
|
|
77
|
+
hostname = "197.3.2.1"
|
|
78
|
+
|
|
79
|
+
stub_node :test_node_6 do |node|
|
|
80
|
+
node.chef_environment = env
|
|
81
|
+
node.normal.ipaddress = hostname
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
stub_node :test_node_5 do |node|
|
|
85
|
+
node.chef_environment = "bumville"
|
|
86
|
+
node.normal.ipaddress = "84.9.1.11"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
assert servers.to_a.size.zero?, "Should be no servers"
|
|
90
|
+
|
|
91
|
+
chef_scope :chef_environment, env
|
|
92
|
+
|
|
93
|
+
assert_includes fetch(:chef_scopes), "chef_environment:#{env}"
|
|
94
|
+
|
|
95
|
+
chef_role :rubix, "name:test_node_*"
|
|
96
|
+
|
|
97
|
+
assert_equal 1, servers.to_a.size
|
|
98
|
+
|
|
99
|
+
servers_with_role :rubix do |server|
|
|
100
|
+
assert_equal hostname, server.hostname
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: capistrano-cook
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 2.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Justin Reagor
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-07-29 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: capistrano
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 3.2.1
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 3.2.1
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: chef
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 11.12.8
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 11.12.8
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.6'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.6'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: minitest
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: chef-zero
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description: Provides easy support for using Capistrano and Chef together
|
|
98
|
+
email:
|
|
99
|
+
- cheapRoc+gh@gmail.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".chef/knife.rb"
|
|
105
|
+
- ".chef/stickywicket.pem"
|
|
106
|
+
- ".gitignore"
|
|
107
|
+
- ".travis.yml"
|
|
108
|
+
- Gemfile
|
|
109
|
+
- LICENSE
|
|
110
|
+
- README.md
|
|
111
|
+
- Rakefile
|
|
112
|
+
- capistrano-cook.gemspec
|
|
113
|
+
- lib/capistrano/chef.rb
|
|
114
|
+
- lib/capistrano/chef/helpers.rb
|
|
115
|
+
- lib/capistrano/chef/test_case.rb
|
|
116
|
+
- lib/capistrano/chef/version.rb
|
|
117
|
+
- lib/capistrano/cook.rb
|
|
118
|
+
- lib/capistrano/dsl/chef.rb
|
|
119
|
+
- test/capistrano/chef_test.rb
|
|
120
|
+
- test/capistrano/dsl/chef_test.rb
|
|
121
|
+
- test/minitest_helper.rb
|
|
122
|
+
homepage: https://github.com/cheapRoc/capistrano-cook
|
|
123
|
+
licenses:
|
|
124
|
+
- MIT
|
|
125
|
+
metadata: {}
|
|
126
|
+
post_install_message:
|
|
127
|
+
rdoc_options: []
|
|
128
|
+
require_paths:
|
|
129
|
+
- lib
|
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - ">="
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '0'
|
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '0'
|
|
140
|
+
requirements: []
|
|
141
|
+
rubyforge_project:
|
|
142
|
+
rubygems_version: 2.2.2
|
|
143
|
+
signing_key:
|
|
144
|
+
specification_version: 4
|
|
145
|
+
summary: Capistrano 3 support for working with Chef, not replacing it
|
|
146
|
+
test_files:
|
|
147
|
+
- test/capistrano/chef_test.rb
|
|
148
|
+
- test/capistrano/dsl/chef_test.rb
|
|
149
|
+
- test/minitest_helper.rb
|