knife-topo 0.0.4 → 0.0.5
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.
- data/README.md +43 -43
- data/lib/chef/knife/topo/version.rb +1 -1
- data/lib/chef/knife/topo_bootstrap.rb +2 -0
- data/lib/chef/knife/topo_create.rb +18 -7
- data/lib/chef/knife/topo_export.rb +6 -7
- data/lib/chef/knife/topo_update.rb +15 -2
- data/lib/chef/knife/topology_helper.rb +27 -36
- metadata +2 -2
data/README.md
CHANGED
@@ -24,19 +24,19 @@ This plugin has been tested with Chef Version 11.12 on Ubuntu 14.04 LTS.
|
|
24
24
|
|
25
25
|
# Usage #
|
26
26
|
|
27
|
-
Define one or more topologies in a [topology file](#
|
27
|
+
Define one or more topologies in a [topology file](#topology-file).
|
28
28
|
|
29
29
|
Import the topology file into your local chef repo using
|
30
|
-
[knife topo import](#
|
30
|
+
[knife topo import](#import). Create and optionally
|
31
31
|
bootstrap a topology on the Chef server using
|
32
|
-
[knife topo create](#
|
33
|
-
using [knife topo update](#
|
32
|
+
[knife topo create](#create), and update it
|
33
|
+
using [knife topo update](#update).
|
34
34
|
|
35
35
|
# Getting Started #
|
36
36
|
|
37
|
-
Try out this plugin using a [test repo](
|
37
|
+
Try out this plugin using a [test repo](test-repo)
|
38
38
|
which you can download from Github or is included in the installed gem. See the
|
39
|
-
[Instructions](
|
39
|
+
[Instructions](Instructions.md) for a
|
40
40
|
demo script, explanation, and troubleshooting.
|
41
41
|
|
42
42
|
The instructions assume you have
|
@@ -44,17 +44,17 @@ The instructions assume you have
|
|
44
44
|
or equivalent installed and working with Vagrant and VirtualBox, but
|
45
45
|
none of these are requirements for this plugin.
|
46
46
|
|
47
|
-
# Topology File
|
47
|
+
# Topology File <a name="topology-file"></a>#
|
48
48
|
|
49
|
-
See the [example topology file](
|
49
|
+
See the [example topology file](test-repo/topology.json)
|
50
50
|
|
51
51
|
The topology file contains a single topology, or an array of topologies.
|
52
52
|
Each topology has some overall properties, an array of nodes and
|
53
53
|
an array defining topology cookbook attributes.
|
54
54
|
|
55
|
-
## Overall Properties
|
55
|
+
## Overall Topology Properties <a name="topology-properties"></a>
|
56
56
|
|
57
|
-
```
|
57
|
+
```
|
58
58
|
{
|
59
59
|
"name": "test1",
|
60
60
|
"chef_environment": "test",
|
@@ -69,7 +69,7 @@ an array defining topology cookbook attributes.
|
|
69
69
|
],
|
70
70
|
"cookbook_attributes" : [
|
71
71
|
]
|
72
|
-
}
|
72
|
+
}
|
73
73
|
```
|
74
74
|
The `name` is how you will refer to the topology in the
|
75
75
|
`knife topo` subcommands.
|
@@ -79,13 +79,13 @@ here will be applied to all nodes in the topology, unless alternative
|
|
79
79
|
values are provided for a specific node. The `tags`
|
80
80
|
will be added to each node.
|
81
81
|
|
82
|
-
## Node List
|
82
|
+
## Node List <a name="node-list"></a>
|
83
83
|
Each topology contains a list of `nodes`.
|
84
84
|
|
85
|
-
```
|
86
|
-
|
85
|
+
```
|
86
|
+
{
|
87
87
|
"name": "test1",
|
88
|
-
|
88
|
+
...
|
89
89
|
"nodes": {
|
90
90
|
"buildserver": {
|
91
91
|
"name": "buildserver01",
|
@@ -94,8 +94,9 @@ Each topology contains a list of `nodes`.
|
|
94
94
|
"chef_environment": "dev",
|
95
95
|
"run_list": ["role[base-ubuntu]", "ypo::db", "recipe[ypo::appserver]"],
|
96
96
|
"normal": {
|
97
|
-
"topo
|
98
|
-
|
97
|
+
"topo" : {
|
98
|
+
node_type": "buildserver"
|
99
|
+
}
|
99
100
|
},
|
100
101
|
"tags": ["build"]
|
101
102
|
},
|
@@ -114,14 +115,14 @@ fields are optional.
|
|
114
115
|
The `ssh_host` and `ssh_port` are optional fields that are used to
|
115
116
|
bootstrap a node.
|
116
117
|
|
117
|
-
## Topology Cookbook Attributes
|
118
|
+
## Topology Cookbook Attributes <a name="cookbook-attributes"></a>
|
118
119
|
|
119
120
|
Each topology may have attributes that are set via
|
120
121
|
an attribute file in a topology-specific cookbook. Each
|
121
122
|
attribute file is described in an entry in the 'cookbook_attributes'
|
122
123
|
array.
|
123
124
|
|
124
|
-
```
|
125
|
+
```
|
125
126
|
"cookbook_attributes": [
|
126
127
|
{
|
127
128
|
"cookbook": "testsys_test1",
|
@@ -168,27 +169,27 @@ in the above) will generate an entry in the attribute file such as:
|
|
168
169
|
Attributes listed under the `conditional` property will generate an
|
169
170
|
entry in the attribute file such as:
|
170
171
|
|
171
|
-
```
|
172
|
+
```
|
172
173
|
if (node['topo']['node_type'] == "buildserver")
|
173
|
-
normal['mongodb'][package_version] = "2.5.1"
|
174
|
+
normal['mongodb']['package_version'] = "2.5.1"
|
174
175
|
end
|
175
176
|
```
|
176
177
|
|
177
|
-
# Subcommands
|
178
|
+
# Subcommands <a name="subcommands"></a>
|
178
179
|
|
179
180
|
The main subcommands for `knife topo` are:
|
180
181
|
|
181
|
-
*
|
182
|
-
*
|
183
|
-
*
|
182
|
+
* [knife topo import](#import) - Import one or more into your workspace/local repo
|
183
|
+
* [knife topo create](#create) - Create and optionally bootstrap a topology of nodes
|
184
|
+
* [knife topo update](#update) - Update a topology of nodes
|
184
185
|
|
185
186
|
The additional subcommands can also be useful, depending on your
|
186
187
|
workflow:
|
187
188
|
|
188
|
-
*
|
189
|
-
*
|
190
|
-
*
|
191
|
-
*
|
189
|
+
* [knife topo bootstrap](#bootstrap)- Bootstraps a topology of nodes
|
190
|
+
* [knife topo cookbook create](#cookbook-create) - Generate the topology cookbooks
|
191
|
+
* [knife topo cookbook upload](#cookbook-upload) - Upload the topology cookbooks
|
192
|
+
* [knife export](#export) - Export data from a topology (or from nodes that you want in a topology)
|
192
193
|
|
193
194
|
The topologies are data bag items in the 'topologies' data bag, so
|
194
195
|
you can also use knife commands such as:
|
@@ -205,7 +206,7 @@ Option | Description
|
|
205
206
|
------------ | -----------
|
206
207
|
-D, --data-bag DATA_BAG | The data bag to use for the topologies. Defaults to 'topologies'.
|
207
208
|
|
208
|
-
## knife topo bootstrap
|
209
|
+
## knife topo bootstrap <a name="bootstrap"></a>
|
209
210
|
|
210
211
|
knife topo bootstrap TOPOLOGY
|
211
212
|
|
@@ -228,12 +229,12 @@ user name of vagrant, password of vagrant, and running using sudo.
|
|
228
229
|
|
229
230
|
$ knife topo bootstrap sys1_test test1 -x vagrant -P vagrant --sudo
|
230
231
|
|
231
|
-
## knife topo cookbook create
|
232
|
+
## knife topo cookbook create <a name="cookbook-create"></a>
|
232
233
|
|
233
234
|
knife topo cookbook create TOPOLOGY
|
234
235
|
|
235
236
|
Generates the topology cookbook attribute files and attributes described in the
|
236
|
-
|
237
|
+
[cookbook_attributes](#cookbook-attributes) property.
|
237
238
|
|
238
239
|
### Options:
|
239
240
|
|
@@ -241,7 +242,7 @@ The knife topo cookbook create subcommand supports the following additional opti
|
|
241
242
|
|
242
243
|
Option | Description
|
243
244
|
------------ | -----------
|
244
|
-
See [knife cookbook create](http://docs.opscode.com/chef/knife.html#cookbook) |
|
245
|
+
See [knife cookbook create](http://docs.opscode.com/chef/knife.html#cookbook) | Options supported by `knife cookbook create` are passed through
|
245
246
|
|
246
247
|
### Examples:
|
247
248
|
The following will generate the topology cookbook attribute files for
|
@@ -249,7 +250,7 @@ topology test1.
|
|
249
250
|
|
250
251
|
$ knife topo cookbook create test1
|
251
252
|
|
252
|
-
## knife topo cookbook upload
|
253
|
+
## knife topo cookbook upload <a name="cookbook-upload"></a>
|
253
254
|
|
254
255
|
knife topo cookbook upload TOPOLOGY
|
255
256
|
|
@@ -261,7 +262,7 @@ The knife topo cookbook upload subcommand supports the following additional opti
|
|
261
262
|
|
262
263
|
Option | Description
|
263
264
|
------------ | -----------
|
264
|
-
See [knife cookbook upload](http://docs.opscode.com/chef/knife.html#cookbook) |
|
265
|
+
See [knife cookbook upload](http://docs.opscode.com/chef/knife.html#cookbook) | Options supported by `knife cookbook upload` are passed through
|
265
266
|
|
266
267
|
|
267
268
|
### Examples:
|
@@ -271,7 +272,7 @@ topology test1.
|
|
271
272
|
$ knife topo cookbook create test1
|
272
273
|
|
273
274
|
|
274
|
-
## knife topo create
|
275
|
+
## knife topo create <a name="create"></a>
|
275
276
|
|
276
277
|
knife topo create TOPOLOGY
|
277
278
|
|
@@ -288,7 +289,7 @@ The knife topo create subcommand supports the following additional options.
|
|
288
289
|
|
289
290
|
Option | Description
|
290
291
|
------------ | -----------
|
291
|
-
--bootstrap | Bootstrap the topology (see [topo bootstrap](#
|
292
|
+
--bootstrap | Bootstrap the topology (see [topo bootstrap](#bootstrap))
|
292
293
|
See [knife bootstrap](http://docs.opscode.com/knife_bootstrap.html) | Options supported by `knife bootstrap` are passed through to the bootstrap command
|
293
294
|
--no-upload | Do not upload topology cookbooks
|
294
295
|
|
@@ -302,7 +303,7 @@ or upload topology cookbooks.
|
|
302
303
|
|
303
304
|
$ knife topo create test1 --no-upload
|
304
305
|
|
305
|
-
## knife topo export
|
306
|
+
## knife topo export <a name="export"></a>
|
306
307
|
|
307
308
|
knife topo export [ TOPOLOGY [ NODE ... ]
|
308
309
|
|
@@ -310,11 +311,10 @@ Exports the specified topology as JSON. If the topology does not already exist,
|
|
310
311
|
an outline for a new topology will be exported. The exported JSON
|
311
312
|
can be used as the basis for a new topology definition.
|
312
313
|
|
313
|
-
If nodes are specified, these will be
|
314
|
+
If nodes are specified, these will be exported in addition
|
314
315
|
to any nodes that are in the topology.
|
315
316
|
|
316
|
-
If no topology is specified, all
|
317
|
-
will be exported.
|
317
|
+
If no topology is specified, all defined topologies will be exported.
|
318
318
|
|
319
319
|
### Examples:
|
320
320
|
The following will export all topologies to a file called 'sys1_test.json'.
|
@@ -326,7 +326,7 @@ The following will create an outline for a new topology called 'christine_test'
|
|
326
326
|
$ knife topo export christine_test > christine_test.json
|
327
327
|
|
328
328
|
|
329
|
-
## knife topo import
|
329
|
+
## knife topo import <a name="import"></a>
|
330
330
|
|
331
331
|
knife topo import [ TOPOLOGY_FILE [ TOPOLOGY ... ]]
|
332
332
|
|
@@ -346,7 +346,7 @@ The following will import the 'test1' topology
|
|
346
346
|
|
347
347
|
$ knife topo import topology.json test1
|
348
348
|
|
349
|
-
## knife topo update
|
349
|
+
## knife topo update <a name="update"></a>
|
350
350
|
|
351
351
|
knife topo update [ TOPOLOGY ]
|
352
352
|
|
@@ -89,12 +89,14 @@ class Chef
|
|
89
89
|
# Setup the bootstrap args and run the bootstrap command
|
90
90
|
def run_bootstrap(node_data)
|
91
91
|
node_name = node_data['name']
|
92
|
+
|
92
93
|
args = @bootstrap_args
|
93
94
|
args += ['-N', node_name] if(node_name)
|
94
95
|
args += ['-E', node_data['chef_environment']] if(node_data['chef_environment'])
|
95
96
|
args[1] = node_data['ssh_host']
|
96
97
|
args += [ '--ssh-port', node_data['ssh_port']] if node_data['ssh_port']
|
97
98
|
args += [ '--run-list' , node_data['run_list'].join(',')] if node_data['run_list']
|
99
|
+
args += [ '--json-attributes' , node_data['normal'].to_json] if node_data['normal']
|
98
100
|
|
99
101
|
ui.info "Bootstrapping node #{node_name}"
|
100
102
|
begin
|
@@ -91,14 +91,25 @@ class Chef
|
|
91
91
|
# make sure env and cookbooks are in place
|
92
92
|
check_chef_env(topo['chef_environment']) if topo['chef_environment']
|
93
93
|
upload_cookbooks(@topo_upload_args) if (!config[:no_upload])
|
94
|
-
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
# if bootstrap is specified, run the bootstrap command
|
100
|
-
run_cmd(Chef::Knife::TopoBootstrap, @topo_bootstrap_args) if config[:bootstrap]
|
94
|
+
|
95
|
+
# update any existing nodes
|
96
|
+
topo_hash = topo.raw_data
|
97
|
+
nodes = merge_topo_properties(topo_hash['nodes'], topo_hash)
|
98
|
+
config[:disable_editing] = true
|
101
99
|
|
100
|
+
if nodes.length > 0
|
101
|
+
nodes.each do |updates|
|
102
|
+
node_name = updates['name']
|
103
|
+
node = update_node(updates)
|
104
|
+
end
|
105
|
+
# if bootstrap is specified, run the bootstrap command
|
106
|
+
run_cmd(Chef::Knife::TopoBootstrap, @topo_bootstrap_args) if config[:bootstrap]
|
107
|
+
else
|
108
|
+
ui.info "No nodes found for topology #{topo_hash.name}"
|
109
|
+
end
|
110
|
+
|
111
|
+
ui.info("Topology created")
|
112
|
+
|
102
113
|
end
|
103
114
|
|
104
115
|
|
@@ -48,6 +48,7 @@ class Chef
|
|
48
48
|
export = topo.raw_data
|
49
49
|
else
|
50
50
|
export = empty_topology
|
51
|
+
export['nodes'].push(empty_node("node1")) if @node_names.length == 0
|
51
52
|
end
|
52
53
|
|
53
54
|
# merge in data for nodes that user explicitly specified
|
@@ -78,9 +79,7 @@ class Chef
|
|
78
79
|
"chef_environment" => "_default",
|
79
80
|
"tags" => [ ],
|
80
81
|
"normal" => { },
|
81
|
-
"nodes" => [
|
82
|
-
"node1" => empty_node("node1")
|
83
|
-
],
|
82
|
+
"nodes" => [ ],
|
84
83
|
"cookbook_attributes" => [{
|
85
84
|
"cookbook" => @topo_name || "topo1",
|
86
85
|
"filename" => "topology"
|
@@ -115,7 +114,7 @@ class Chef
|
|
115
114
|
|
116
115
|
rescue Net::HTTPServerException => e
|
117
116
|
raise unless e.to_s =~ /^404/
|
118
|
-
|
117
|
+
node_data = empty_node(node_name)
|
119
118
|
end
|
120
119
|
|
121
120
|
node_data
|
@@ -125,10 +124,10 @@ class Chef
|
|
125
124
|
def merge_node_properties!(nodes, node_name)
|
126
125
|
# find out if the node is already in the array
|
127
126
|
found = nodes.index{|n| n["name"] == node_name }
|
128
|
-
if found
|
129
|
-
nodes[found] = node_export(node_name)
|
130
|
-
else
|
127
|
+
if found.nil?
|
131
128
|
nodes.push(node_export(node_name))
|
129
|
+
else
|
130
|
+
nodes[found] = node_export(node_name)
|
132
131
|
end
|
133
132
|
end
|
134
133
|
|
@@ -99,8 +99,21 @@ class Chef
|
|
99
99
|
def update_topo(topo)
|
100
100
|
topo.save
|
101
101
|
@topo_upload_args[3] = topo['name']
|
102
|
-
upload_cookbooks(@topo_upload_args) if (!config[:no_upload])
|
103
|
-
|
102
|
+
upload_cookbooks(@topo_upload_args) if (!config[:no_upload])
|
103
|
+
|
104
|
+
topo_hash = topo.raw_data
|
105
|
+
nodes = merge_topo_properties(topo_hash['nodes'], topo_hash)
|
106
|
+
config[:disable_editing] = true
|
107
|
+
|
108
|
+
if nodes.length > 0
|
109
|
+
nodes.each do |updates|
|
110
|
+
node_name = updates['name']
|
111
|
+
node = update_node(updates)
|
112
|
+
ui.info "Node #{node_name} does not exist - skipping update" if (!node)
|
113
|
+
end
|
114
|
+
else
|
115
|
+
ui.info "No nodes found for topology #{topo_hash.name}"
|
116
|
+
end
|
104
117
|
end
|
105
118
|
|
106
119
|
include Chef::Knife::TopologyHelper
|
@@ -119,46 +119,37 @@ class Chef
|
|
119
119
|
|
120
120
|
end
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
if updates['chef_environment'] && updates['chef_environment'] != node['chef_environment']
|
138
|
-
check_chef_env(topo['chef_environment'])
|
139
|
-
end
|
140
|
-
|
141
|
-
if updated_values = update_node_with_values(node, updates)
|
142
|
-
ui.info "Updating #{updated_values.join(', ')} on node #{node.name}"
|
143
|
-
node.save
|
144
|
-
ui.output(format_for_display(node)) if config[:print_after]
|
145
|
-
else
|
146
|
-
ui.info "No updates found for node #{node.name}"
|
147
|
-
end
|
148
|
-
|
149
|
-
rescue Net::HTTPServerException => e
|
150
|
-
raise unless e.to_s =~ /^404/
|
151
|
-
# Create the node
|
152
|
-
node = Chef::Node.new
|
153
|
-
node.name(node_name)
|
154
|
-
update_node_with_values(node, updates)
|
155
|
-
create_object(node)
|
156
|
-
end
|
122
|
+
|
123
|
+
# Update an existing node
|
124
|
+
def update_node(node_updates)
|
125
|
+
|
126
|
+
config[:disable_editing] = true
|
127
|
+
|
128
|
+
node_name = node_updates['name']
|
129
|
+
begin
|
130
|
+
|
131
|
+
# load then update and save the node
|
132
|
+
node = Chef::Node.load(node_name)
|
133
|
+
|
134
|
+
if node_updates['chef_environment'] && node_updates['chef_environment'] != node['chef_environment']
|
135
|
+
check_chef_env(node_updates['chef_environment'])
|
157
136
|
end
|
137
|
+
|
138
|
+
if updated_values = update_node_with_values(node, node_updates)
|
139
|
+
ui.info "Updating #{updated_values.join(', ')} on node #{node.name}"
|
140
|
+
node.save
|
141
|
+
ui.output(format_for_display(node)) if config[:print_after]
|
158
142
|
else
|
159
|
-
ui.info "No
|
143
|
+
ui.info "No updates found for node #{node.name}"
|
160
144
|
end
|
145
|
+
|
146
|
+
rescue Net::HTTPServerException => e
|
147
|
+
raise unless e.to_s =~ /^404/
|
148
|
+
# Node has not been created
|
161
149
|
end
|
150
|
+
|
151
|
+
return node
|
152
|
+
end
|
162
153
|
|
163
154
|
# Make updates into the original node, returning the list of updated properties.
|
164
155
|
def update_node_with_values(node, updates)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-topo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-07-
|
12
|
+
date: 2014-07-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Knife plugin that to manage topologies of nodes
|
15
15
|
email:
|