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 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](#markdown-header-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](#markdown-header-knife-topo-import). Create and optionally
30
+ [knife topo import](#import). Create and optionally
31
31
  bootstrap a topology on the Chef server using
32
- [knife topo create](#markdown-header-knife-topo-create), and update it
33
- using [knife topo update](#markdown-header-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](knife-topo/src/master/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](knife-topo/src/master/test-repo/Instructions.md) for a
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](knife-topo/src/master/test-repo/topology.json)
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
- ```json
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
- ```json
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.node_type": "buildserver",
98
- "another": "Value 1"
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
- ```json
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
- ```ruby
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
- * `knife topo import` - Import one or more into your workspace/local repo
182
- * `knife topo create` - Create and optionally bootstrap a topology of nodes
183
- * `knife topo update` - Update a topology of nodes
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
- * `knife topo bootstrap` - Bootstraps a topology of nodes
189
- * `knife topo cookbook create` - Generate the topology cookbooks
190
- * `knife topo cookbook upload` - Upload the topology cookbooks
191
- * `knife export` - Export data from a topology (or from nodes that you want in a topology)
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
- 'cookbook_attributes' property.
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](#markdown-header-knife-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 added into the export in addition
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 existing topologies in that environment
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
 
@@ -1,5 +1,5 @@
1
1
  module Knife
2
2
  module Topo
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -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
- # setup the actual nodes on the server
96
- create_or_update_nodes(topo)
97
- ui.info("Topology created")
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
- node = empty_node(node_name)
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
- create_or_update_nodes(topo)
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
- # Get nodes from the topology, create them and/or set their run lists
123
- def create_or_update_nodes(topo)
124
-
125
- topo_hash = topo.raw_data
126
- nodes = merge_topo_properties(topo_hash['nodes'], topo_hash)
127
- config[:disable_editing] = true
128
-
129
- if nodes.length > 0
130
- nodes.each do |updates|
131
- node_name = updates['name']
132
- begin
133
-
134
- # load then update and save the node
135
- node = Chef::Node.load(node_name)
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 nodes found for topology #{topo_hash.name}"
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
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-20 00:00:00.000000000 Z
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: