crowbar-client 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/lib/crowbar/client/app/backup.rb +87 -21
  4. data/lib/crowbar/client/app/base.rb +20 -0
  5. data/lib/crowbar/client/app/batch.rb +44 -31
  6. data/lib/crowbar/client/app/host_ip.rb +2 -0
  7. data/lib/crowbar/client/app/interface.rb +2 -0
  8. data/lib/crowbar/client/app/virtual_ip.rb +2 -0
  9. data/lib/crowbar/client/command/backup.rb +3 -0
  10. data/lib/crowbar/client/command/backup/delete.rb +2 -0
  11. data/lib/crowbar/client/command/backup/download.rb +21 -14
  12. data/lib/crowbar/client/command/backup/list.rb +6 -3
  13. data/lib/crowbar/client/command/backup/restore.rb +42 -0
  14. data/lib/crowbar/client/command/backup/upload.rb +13 -0
  15. data/lib/crowbar/client/command/base.rb +3 -0
  16. data/lib/crowbar/client/command/batch/build.rb +26 -0
  17. data/lib/crowbar/client/command/batch/export.rb +43 -0
  18. data/lib/crowbar/client/command/installer/start.rb +2 -0
  19. data/lib/crowbar/client/filter/hash.rb +1 -1
  20. data/lib/crowbar/client/request/backup.rb +3 -0
  21. data/lib/crowbar/client/request/backup/create.rb +1 -3
  22. data/lib/crowbar/client/request/backup/delete.rb +1 -1
  23. data/lib/crowbar/client/request/backup/download.rb +1 -1
  24. data/lib/crowbar/client/request/backup/restore.rb +38 -0
  25. data/lib/crowbar/client/request/backup/upload.rb +0 -2
  26. data/lib/crowbar/client/request/batch/build.rb +17 -2
  27. data/lib/crowbar/client/request/batch/export.rb +22 -2
  28. data/lib/crowbar/client/version.rb +1 -1
  29. data/spec/crowbar/client/command/backup/create_spec.rb +1 -3
  30. data/spec/crowbar/client/command/backup/delete_spec.rb +1 -2
  31. data/spec/crowbar/client/command/backup/download_spec.rb +1 -1
  32. data/spec/crowbar/client/command/backup/restore_spec.rb +40 -0
  33. data/spec/crowbar/client/command/backup/upload_spec.rb +4 -1
  34. data/spec/crowbar/client/command/batch/build_spec.rb +5 -1
  35. data/spec/crowbar/client/request/backup/create_spec.rb +2 -4
  36. data/spec/crowbar/client/request/backup/delete_spec.rb +2 -2
  37. data/spec/crowbar/client/request/backup/download_spec.rb +2 -2
  38. data/spec/crowbar/client/request/backup/list_spec.rb +2 -4
  39. data/spec/crowbar/client/request/backup/restore_spec.rb +52 -0
  40. data/spec/crowbar/client/request/batch/build_spec.rb +35 -44
  41. data/spec/crowbar/client/request/batch/export_spec.rb +33 -44
  42. data/spec/crowbar/client/request/proposal/create_spec.rb +2 -1
  43. data/spec/crowbar/client/request/proposal/edit_spec.rb +2 -1
  44. data/spec/fixtures/batch.yml +0 -0
  45. metadata +11 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 196e25c8ac9b8112656985164751b9a51b732178
4
- data.tar.gz: 3d281cb6d8561bc51f78d9aae02517b714761d0f
3
+ metadata.gz: ad1e74fd43f734f1de83365be861088e5fe578f3
4
+ data.tar.gz: 7227247e2f6d0650fbaaa3a4ee94e3560f16324b
5
5
  SHA512:
6
- metadata.gz: ba6e3e297bd4a9d22c6c737c040101af78dbf2b1c70b9ee70eddb377f72e844b3759e098dcbd646998ebababb04d9c6070d666048b95eb6bdcfa58387c99fefe
7
- data.tar.gz: 8572d1bb1472e8a57133bd94731205783011803fb5902ef8f0947591350f6197b2bd19fc1237defeec06c6a455d6352e58a2c4d9f2c85976a9b20424d0b8dfd6
6
+ metadata.gz: 48598a6ec995593fc838e7a5dfa08a476605445fb7fc0d2d6f643e1ab88b73d812b1c8e07ebc546305d72db39cdbfbeeabf2019f4c87ea38ed432b3c6079cf0d
7
+ data.tar.gz: 0deaf315129041b3fdd4209734324170476de4a6bb9b21324d6c525f957d781d7c37a2cbaa81d539e3555674b7f781e224d391ae41714343596b09e1e39bf34e
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.4.0](https://github.com/crowbar/crowbar-client/releases/tag/v2.4.0) - 2015-01-27
4
+
5
+ * BUGFIX
6
+ * Fixed backup commands by name (@tboerger)
7
+ * Fixed help output for nested commands (@tboerger)
8
+ * ENHANCEMENT
9
+ * Added subcommand to trigger a backup restore (@tboerger)
10
+ * Added subcommand for batch build and export (@tboerger)
11
+
3
12
  ## [2.3.0](https://github.com/crowbar/crowbar-client/releases/tag/v2.3.0) - 2015-01-15
4
13
 
5
14
  * BREAKING
@@ -22,9 +22,9 @@ module Crowbar
22
22
  "List existing backups"
23
23
 
24
24
  long_desc <<-LONGDESC
25
- `list` will print out a list of existing backups on the admin
26
- node. You can display the list in different output
27
- formats and you can filter the list by any search criteria.
25
+ `list` will print out a list of existing backups on the server.
26
+ You can display the list in different output formats and you
27
+ can filter the list by any search criteria.
28
28
 
29
29
  With --format <format> option you can choose an output format
30
30
  with the available options table, json or plain. You can also
@@ -73,34 +73,71 @@ module Crowbar
73
73
  catch_errors(e)
74
74
  end
75
75
 
76
+ desc "restore NAME",
77
+ "Restore from a backup"
78
+
79
+ long_desc <<-LONGDESC
80
+ `restore NAME` will trigger the restore process based on the
81
+ specified backup name. This command will override the proposals
82
+ of your server.
83
+
84
+ With --yes option you can force the restore without any further
85
+ question, this skips the otherwise required confirmation.
86
+ LONGDESC
87
+
88
+ method_option :yes,
89
+ type: :boolean,
90
+ default: false,
91
+ aliases: [],
92
+ desc: "Force the restore without any confirmation message"
93
+
94
+ def restore(name)
95
+ unless accepts_restore?
96
+ say "Canceled restore"
97
+ return
98
+ end
99
+
100
+ Command::Backup::Restore.new(
101
+ *command_params(
102
+ name: name
103
+ )
104
+ ).execute
105
+ rescue => e
106
+ catch_errors(e)
107
+ end
108
+
76
109
  desc "create",
77
110
  "Create a new backup"
78
111
 
79
112
  long_desc <<-LONGDESC
80
- `create NAME` will create a new backup on the Administration Server.
113
+ `create NAME` will trigger the creation of a new backup on the
114
+ server, to download the backup after processing you can use the
115
+ download command.
81
116
  LONGDESC
82
117
 
83
118
  def create(name)
84
119
  Command::Backup::Create.new(
85
120
  *command_params(
86
- backup: name
121
+ name: name
87
122
  )
88
123
  ).execute
89
124
  rescue => e
90
125
  catch_errors(e)
91
126
  end
92
127
 
93
- desc "download",
94
- "Download a backup"
128
+ desc "delete",
129
+ "Delete a backup"
95
130
 
96
131
  long_desc <<-LONGDESC
97
- `download ID` will download a backup from the Administration Server.
132
+ `delete NAME` will delete a backup from the server. Be careful
133
+ with that command, you are not able to restore this file after
134
+ deletion.
98
135
  LONGDESC
99
136
 
100
- def download(id)
101
- Command::Backup::Download.new(
137
+ def delete(name)
138
+ Command::Backup::Delete.new(
102
139
  *command_params(
103
- id: id
140
+ name: name
104
141
  )
105
142
  ).execute
106
143
  rescue => e
@@ -111,37 +148,66 @@ module Crowbar
111
148
  "Upload a backup"
112
149
 
113
150
  long_desc <<-LONGDESC
114
- `upload FILE` will upload a backup to the Administration Server.
151
+ `upload FILE` will upload a backup to the server. You can use
152
+ this backup later to trigger a restore.
115
153
  LONGDESC
116
154
 
117
155
  def upload(file)
118
156
  Command::Backup::Upload.new(
119
157
  *command_params(
120
- file: File.new(
121
- file
122
- )
158
+ file: file
123
159
  )
124
160
  ).execute
125
161
  rescue => e
126
162
  catch_errors(e)
127
163
  end
128
164
 
129
- desc "delete",
130
- "Delete a backup"
165
+ desc "download",
166
+ "Download a backup"
131
167
 
132
168
  long_desc <<-LONGDESC
133
- `delete ID` will delete a backup from the Administration Server.
169
+ `download NAME [FILE]` will download a backup from the server. If
170
+ you specify a `file` the download gets written to that file,
171
+ otherwise it gets saved to the current working directory with an
172
+ automatically generated filename. You can directly provide a path
173
+ to a file or just pipe the content to stdout. To pipe the content
174
+ to stdout you should just write a `-` instead of a specific
175
+ filename.
134
176
  LONGDESC
135
177
 
136
- def delete(id)
137
- Command::Backup::Delete.new(
178
+ def download(name, file = nil)
179
+ Command::Backup::Download.new(
138
180
  *command_params(
139
- id: id
181
+ name: name,
182
+ file: file
140
183
  )
141
184
  ).execute
142
185
  rescue => e
143
186
  catch_errors(e)
144
187
  end
188
+
189
+ no_commands do
190
+ def accepts_restore?
191
+ return true if options[:yes]
192
+
193
+ question = <<-QUESTION.strip_heredoc
194
+ Usage of this command is dangerous as it overwrites the
195
+ current state of the server and the proposals. Are you
196
+ sure you want to proceed?
197
+ QUESTION
198
+
199
+ answer = ask(
200
+ question,
201
+ :red,
202
+ limited_to: [
203
+ "yes",
204
+ "no"
205
+ ]
206
+ )
207
+
208
+ answer == "yes"
209
+ end
210
+ end
145
211
  end
146
212
  end
147
213
  end
@@ -80,6 +80,26 @@ module Crowbar
80
80
  end
81
81
  end
82
82
  end
83
+
84
+ class << self
85
+ def handle_argument_error(command, error, args, arity)
86
+ $stderr.puts("Usage: #{banner(command)}")
87
+ exit(2)
88
+ end
89
+
90
+ def banner(command, namespace = nil, subcommand = true)
91
+ addition = command.formatted_usage(
92
+ self,
93
+ false,
94
+ subcommand
95
+ )
96
+
97
+ [
98
+ basename,
99
+ addition
100
+ ].compact.join(" ")
101
+ end
102
+ end
83
103
  end
84
104
  end
85
105
  end
@@ -28,24 +28,29 @@ module Crowbar
28
28
  stdin you should just write a `-` instead of a specific
29
29
  filename.
30
30
 
31
- With --include <barclamp[.proposal]> option you can process
32
- only a specific part from the provided YAML file structure.
31
+ With --includes BARCLAMP[.PROPOSAL] option you can process
32
+ only a specific part from the provided YAML file structure,
33
+ the `default` proposal will be taken if you don't provide a
34
+ proposal name. This option allows multiple values, separated
35
+ by a `,` from each other.
33
36
 
34
- With --exclude <barclamp[.proposal]> option you exclude
37
+ With --excludes BARCLAMP[.PROPOSAL] option you exclude
35
38
  specific parts from the provided YAML file structure to be
36
- processed.
39
+ processed, the `default` proposal will be taken if you don't
40
+ provide a proposal name. This option allows multiple values,
41
+ separated by a `,` from each other.
37
42
  LONGDESC
38
43
 
39
- method_option :include,
40
- type: :string,
41
- default: nil,
42
- banner: "<barclamp[.proposal]>",
44
+ method_option :includes,
45
+ type: :array,
46
+ default: [],
47
+ banner: "BARCLAMP[.PROPOSAL]",
43
48
  desc: "Include a specific barclamp or proposal for processing"
44
49
 
45
- method_option :exclude,
46
- type: :string,
47
- default: nil,
48
- banner: "<barclamp[.proposal]>",
50
+ method_option :excludes,
51
+ type: :array,
52
+ default: [],
53
+ banner: "BARCLAMP[.PROPOSAL]",
49
54
  desc: "Exclude a specific barclamp or proposal for processing"
50
55
 
51
56
  def build(file)
@@ -58,37 +63,45 @@ module Crowbar
58
63
  catch_errors(e)
59
64
  end
60
65
 
61
- desc "export PROPOSAL [PROPOSAL]",
62
- "Export proposals to stdout"
66
+ desc "export FILE",
67
+ "Export proposals to file or stdout"
63
68
 
64
69
  long_desc <<-LONGDESC
65
- `export PROPOSAL [PROPOSAL]` will collect the informations
66
- for the provided proposals and print it out to stdout in a
67
- YAML format that can be used to build again.
70
+ `export FILE` will collect the informations of the proposals
71
+ in a YAML format. You can directly provide a path to a file or
72
+ just pipe the content into stdout. To pipe the content to
73
+ stdout you should just write a `-` instead of a specific
74
+ filename.
68
75
 
69
- With --include <barclamp[.proposal]> option you can export
70
- only a specific part from the existing proposals.
76
+ With --includes BARCLAMP[.PROPOSAL] option you can export
77
+ only a specific part from the existing proposals, the `default`
78
+ proposal will be taken if you don't provide a proposal name.
79
+ This option allows multiple values, separated by a `,` from
80
+ each other.
71
81
 
72
- With --exclude <barclamp[.proposal]> option you exclude
73
- specific parts from the existing proposals to be exported.
82
+ With --excludes BARCLAMP[.PROPOSAL] option you exclude specific
83
+ parts from the existing proposals to be exported, the `default`
84
+ proposal will be taken if you don't provide a proposal name.
85
+ This option allows multiple values, separated by a `,` from
86
+ each other.
74
87
  LONGDESC
75
88
 
76
- method_option :include,
77
- type: :string,
78
- default: nil,
79
- banner: "<barclamp[.proposal]>",
89
+ method_option :includes,
90
+ type: :array,
91
+ default: [],
92
+ banner: "BARCLAMP[.PROPOSAL]",
80
93
  desc: "Include a specific barclamp or proposal for export"
81
94
 
82
- method_option :exclude,
83
- type: :string,
84
- default: nil,
85
- banner: "<barclamp[.proposal]>",
95
+ method_option :excludes,
96
+ type: :array,
97
+ default: [],
98
+ banner: "BARCLAMP[.PROPOSAL]",
86
99
  desc: "Exclude a specific barclamp or proposal for export"
87
100
 
88
- def export(*proposals)
101
+ def export(file)
89
102
  Command::Batch::Export.new(
90
103
  *command_params(
91
- proposals: proposals
104
+ file: file
92
105
  )
93
106
  ).execute
94
107
  rescue => e
@@ -18,6 +18,8 @@ module Crowbar
18
18
  module Client
19
19
  module App
20
20
  class HostIP < Base
21
+ namespace "network hostip"
22
+
21
23
  desc "allocate PROPOSAL NODE NETWORK RANGE [SUGGESTION]",
22
24
  "Allocate a host IP address"
23
25
 
@@ -18,6 +18,8 @@ module Crowbar
18
18
  module Client
19
19
  module App
20
20
  class Interface < Base
21
+ namespace "network interface"
22
+
21
23
  desc "enable PROPOSAL NODE NETWORK",
22
24
  "Enable a network interface"
23
25
 
@@ -18,6 +18,8 @@ module Crowbar
18
18
  module Client
19
19
  module App
20
20
  class VirtualIP < Base
21
+ namespace "network virtualip"
22
+
21
23
  desc "allocate PROPOSAL SERVICE NETWORK RANGE [SUGGESTION]",
22
24
  "Allocate a virtual IP address"
23
25
 
@@ -30,6 +30,9 @@ module Crowbar
30
30
  autoload :List,
31
31
  File.expand_path("../backup/list", __FILE__)
32
32
 
33
+ autoload :Restore,
34
+ File.expand_path("../backup/restore", __FILE__)
35
+
33
36
  autoload :Upload,
34
37
  File.expand_path("../backup/upload", __FILE__)
35
38
  end
@@ -30,6 +30,8 @@ module Crowbar
30
30
  case request.code
31
31
  when 200
32
32
  say "Successfully deleted the backup"
33
+ when 404
34
+ err "Backup does not exist"
33
35
  else
34
36
  err request.parsed_response["error"]
35
37
  end
@@ -14,8 +14,6 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require "httparty"
18
-
19
17
  module Crowbar
20
18
  module Client
21
19
  module Command
@@ -32,12 +30,14 @@ module Crowbar
32
30
  case request.code
33
31
  when 200
34
32
  if write(request.body)
35
- say "Successfully downloaded backup to #{path}"
33
+ say "Successfully downloaded backup"
36
34
  else
37
- say "Failed to download backup to #{path}"
35
+ err "Failed to download backup"
38
36
  end
37
+ when 404
38
+ err "Backup does not exist"
39
39
  else
40
- err request.parsed_response["error"]
40
+ err request.body
41
41
  end
42
42
  end
43
43
  end
@@ -45,21 +45,28 @@ module Crowbar
45
45
  protected
46
46
 
47
47
  def write(body)
48
- path.open("wb") do |f|
49
- f.binmode
50
- f.write body
48
+ path.binmode
49
+ path.write body
51
50
 
52
- true
53
- end
51
+ true
54
52
  rescue
53
+ path.unlink if path.file?
55
54
  false
56
55
  end
57
56
 
58
57
  def path
59
- filename = Request::Backup::List.new.process do |p|
60
- p.parsed_response.select { |s| s["id"] == args.id.to_i }
61
- end.first["name"]
62
- Pathname.new("#{filename}.tar.gz")
58
+ @path ||=
59
+ case args.file
60
+ when "-"
61
+ stdout.to_io
62
+ when File
63
+ args.file
64
+ else
65
+ File.new(
66
+ args.file || "#{args.name}.tar.gz",
67
+ File::CREAT | File::TRUNC | File::RDWR
68
+ )
69
+ end
63
70
  end
64
71
  end
65
72
  end
@@ -55,18 +55,21 @@ module Crowbar
55
55
  protected
56
56
 
57
57
  def headings
58
- ["Id", "Name", "Created", "Size", "Version"]
58
+ ["Name", "Created", "Size", "Version"]
59
59
  end
60
60
 
61
61
  def content_from(request)
62
62
  request.parsed_response.map do |row|
63
63
  row.slice(
64
- "id",
65
64
  "name",
66
65
  "created_at",
67
66
  "size",
68
67
  "version"
69
- )
68
+ ).tap do |values|
69
+ values["size"] = number_to_human_size(
70
+ values["size"]
71
+ )
72
+ end
70
73
  end
71
74
  end
72
75
  end