rubineti 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +33 -0
  4. data/LICENSE +4 -0
  5. data/README.md +44 -0
  6. data/Rakefile +22 -0
  7. data/VERSION +1 -0
  8. data/lib/ganeti.rb +6 -0
  9. data/lib/rubineti/compute/cluster.rb +74 -0
  10. data/lib/rubineti/compute/instances.rb +245 -0
  11. data/lib/rubineti/compute/jobs.rb +42 -0
  12. data/lib/rubineti/compute/node.rb +140 -0
  13. data/lib/rubineti/compute.rb +125 -0
  14. data/lib/rubineti.rb +2 -0
  15. data/rubineti.gemspec +106 -0
  16. data/test/fixtures/cassettes/cluster_info.yml +96 -0
  17. data/test/fixtures/cassettes/cluster_oses.yml +32 -0
  18. data/test/fixtures/cassettes/cluster_redistribute_config.yml +32 -0
  19. data/test/fixtures/cassettes/cluster_version.yml +30 -0
  20. data/test/fixtures/cassettes/instance_create.yml +32 -0
  21. data/test/fixtures/cassettes/instance_delete.yml +30 -0
  22. data/test/fixtures/cassettes/instance_info.yml +30 -0
  23. data/test/fixtures/cassettes/instance_list.yml +93 -0
  24. data/test/fixtures/cassettes/instance_reboot.yml +32 -0
  25. data/test/fixtures/cassettes/instance_reinstall.yml +32 -0
  26. data/test/fixtures/cassettes/instance_shutdown.yml +32 -0
  27. data/test/fixtures/cassettes/instance_startup.yml +32 -0
  28. data/test/fixtures/cassettes/instances.yml +95 -0
  29. data/test/fixtures/cassettes/job_list.yml +135 -0
  30. data/test/fixtures/cassettes/jobs.yml +35 -0
  31. data/test/fixtures/cassettes/node_list.yml +55 -0
  32. data/test/fixtures/cassettes/node_role_list.yml +30 -0
  33. data/test/fixtures/cassettes/nodes.yml +39 -0
  34. data/test/lib/rubineti/compute/test_cluster.rb +71 -0
  35. data/test/lib/rubineti/compute/test_instances.rb +202 -0
  36. data/test/lib/rubineti/compute/test_jobs.rb +41 -0
  37. data/test/lib/rubineti/compute/test_node.rb +77 -0
  38. data/test/lib/rubineti/test_compute.rb +92 -0
  39. data/test/support.rb +35 -0
  40. metadata +225 -0
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.2-p0@rubineti
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "yajl-ruby", "~> 0.7.8"
4
+ gem "net-http-persistent", "~> 1.4.1"
5
+
6
+ group :development do
7
+ gem "rake"
8
+ gem "jeweler", "~> 1.5.1"
9
+ gem "vcr", "~> 1.3.3"
10
+ gem "webmock", "~> 1.6.1"
11
+ gem "minitest", "~> 2.0.0"
12
+ gem "mocha", "~> 0.9.10"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,33 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.2)
5
+ crack (0.1.8)
6
+ git (1.2.5)
7
+ jeweler (1.5.1)
8
+ bundler (~> 1.0.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ minitest (2.0.0)
12
+ mocha (0.9.10)
13
+ rake
14
+ net-http-persistent (1.4.1)
15
+ rake (0.8.7)
16
+ vcr (1.3.3)
17
+ webmock (1.6.1)
18
+ addressable (>= 2.2.2)
19
+ crack (>= 0.1.7)
20
+ yajl-ruby (0.7.8)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ jeweler (~> 1.5.1)
27
+ minitest (~> 2.0.0)
28
+ mocha (~> 0.9.10)
29
+ net-http-persistent (~> 1.4.1)
30
+ rake
31
+ vcr (~> 1.3.3)
32
+ webmock (~> 1.6.1)
33
+ yajl-ruby (~> 0.7.8)
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ "THE BEER-WARE LICENSE" (Revision 42):
2
+ <john@dewey.ws> wrote this file. As long as you retain this notice you
3
+ can do whatever you want with this stuff. If we meet some day, and you think
4
+ this stuff is worth it, you can buy me a beer in return John-B Dewey Jr.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # rubineti
2
+
3
+ [Ruby](http://www.ruby-lang.org/) bindings to [Ganeti's](http://code.google.com/p/ganeti/) Version 2 Remote API.
4
+
5
+ ## Usage
6
+
7
+ ### Bundler
8
+
9
+ gem "rubineti"
10
+
11
+ ### Examples
12
+
13
+ Initialize a connection
14
+
15
+ @connection = Rubineti::Compute.new :host => "ganeti.primary", :credentials => "fake:credentials"
16
+
17
+ View all jobs
18
+
19
+ @connection.jobs_list
20
+
21
+ Handling query params
22
+
23
+ @connection.instance_info "instance_name", :query => "bulk=1"
24
+
25
+ The responses are objectified [(by Yajl)](https://github.com/lloyd/yajl), and returned unmodified.
26
+
27
+ ## Testing
28
+
29
+ Tests can run offline thanks to [VCR](https://github.com/myronmarston/vcr).
30
+
31
+ $ bundle exec rake
32
+
33
+ ## Documents
34
+
35
+ * [Ganeti's remote API](http://docs.ganeti.org/ganeti/2.1/html/rapi.html)
36
+
37
+ ## Contributions
38
+
39
+ I have implemented the end-points immediately needed. Feel free to send me pull requests, if you
40
+ wish to help out.
41
+
42
+ ## Credits
43
+
44
+ Wesley Beary's [fog](https://github.com/geemus/fog), for which I referenced.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require "jeweler"
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "rubineti"
5
+ gem.summary = %Q{Ruby bindings to Ganeti's v2 Remote API.}
6
+ gem.email = "john@dewey.ws"
7
+ gem.homepage = "http://github.com/retr0h/rubineti"
8
+ gem.authors = ["retr0h"]
9
+ end
10
+ Jeweler::GemcutterTasks.new
11
+ rescue LoadError
12
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
13
+ end
14
+
15
+ require "rake/testtask"
16
+ Rake::TestTask.new(:test) do |test|
17
+ test.libs << "./lib" << "./test"
18
+ test.pattern = "test/**/test_*.rb"
19
+ test.verbose = true
20
+ end
21
+
22
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.2
data/lib/ganeti.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Ganeti
2
+ ##
3
+ # Remote API Version.
4
+
5
+ Version = 2
6
+ end
@@ -0,0 +1,74 @@
1
+ module Rubineti
2
+ module Cluster
3
+ ##
4
+ # Returns a list of features supported by the RAPI server.
5
+
6
+ def cluster_features
7
+ warn "WARNING: Cluster#cluster_features not implemented."
8
+ # get "/#{Ganeti::Version}/features"
9
+ end
10
+
11
+ ##
12
+ # Returns a list of cluster information.
13
+
14
+ def cluster_info
15
+ get "/#{Ganeti::Version}/info"
16
+ end
17
+
18
+ ##
19
+ # Redistribute configuration to all nodes.
20
+ # Returns a job_id.
21
+
22
+ def cluster_redistribute_config
23
+ put "/#{Ganeti::Version}/redistribute-config"
24
+ end
25
+
26
+ ##
27
+ # Adds a set of tags.
28
+ # Returns a job_id.
29
+ #
30
+ # If the optional dry-run parameter (?dry-run=1) is provided,
31
+ # the job will not be actually executed, only the pre-execution
32
+ # checks will be done.
33
+
34
+ def cluster_tags_create params = {}
35
+ warn "WARNING: Cluster#cluster_tags_create not implemented."
36
+ # put "/#{Ganeti::Version}/tags", params
37
+ end
38
+
39
+ ##
40
+ # Delete tags.
41
+ # Returns a job_id.
42
+ #
43
+ # If the optional dry-run parameter (?dry-run=1) is provided,
44
+ # the job will not be actually executed, only the pre-execution
45
+ # checks will be done.
46
+
47
+ def cluster_tags_delete params = {}
48
+ warn "WARNING: Cluster#cluster_tags_delete not implemented."
49
+ # delete "/#{Ganeti::Version}/tags", params
50
+ end
51
+
52
+ ##
53
+ # Returns the cluster tags.
54
+
55
+ def cluster_tags_list
56
+ warn "WARNING: Cluster#cluster_tags_list not implemented."
57
+ # get "/#{Ganeti::Version}/tags"
58
+ end
59
+
60
+ ##
61
+ # Returns the cluster API version.
62
+
63
+ def cluster_version
64
+ get "/version"
65
+ end
66
+
67
+ ##
68
+ # Return a list of all OSes.
69
+
70
+ def cluster_os_list
71
+ get "/#{Ganeti::Version}/os"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,245 @@
1
+ module Rubineti
2
+ module Instances
3
+ ##
4
+ # Activate disks on an instance.
5
+ # Returns a job id.
6
+ #
7
+ # Takes the bool parameter ignore_size.
8
+ # (useful for forcing activation when recorded size is wrong).
9
+
10
+ def instance_activate_disks instance_name, params = {}
11
+ warn "WARNING: Instances#instance_activate_disks not implemented."
12
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/activate-disks", params
13
+ end
14
+
15
+ ##
16
+ # Creates an instance.
17
+ # Returns a job id.
18
+ #
19
+ # Body parameters:
20
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.2/html/rapi.html#instances
21
+ #
22
+ # If the optional dry-run parameter (?dry-run=1) is provided,
23
+ # the job will not be actually executed, only the pre-execution
24
+ # checks will be done.
25
+
26
+ def instance_create params = {}
27
+ post "/#{Ganeti::Version}/instances", params
28
+ end
29
+
30
+ ##
31
+ # Deactivate disks on an instance.
32
+ # Returns a job id.
33
+
34
+ def instance_deactivate_disks instance_name
35
+ warn "WARNING: Instances#instance_deactivate_disks not implemented."
36
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/deactivate-disks"
37
+ end
38
+
39
+ ##
40
+ # Deletes an instance.
41
+ # Returns a job id.
42
+ #
43
+ # If the optional dry-run parameter (?dry-run=1) is provided,
44
+ # the job will not be actually executed, only the pre-execution
45
+ # checks will be done.
46
+
47
+ def instance_delete instance_name, params = {}
48
+ delete "/#{Ganeti::Version}/instances/#{instance_name}", params
49
+ end
50
+
51
+ ##
52
+ # Exports an instance.
53
+ # Returns a job id.
54
+ #
55
+ # Body parameters:
56
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.2/html/rapi.html#instances-instance-name-export
57
+
58
+ def instance_export instance_name, params = {}
59
+ warn "WARNING: Instances#instance_export not implemented."
60
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/export", params
61
+ end
62
+
63
+ ##
64
+ # Requests detailed information about the instance.
65
+ #
66
+ # An optional parameter, static (bool), can be set to return only static
67
+ # information from the configuration without querying the instance’s nodes.
68
+ # The result will be a job id.
69
+
70
+ def instance_info instance_name, params = {}
71
+ get "/#{Ganeti::Version}/instances/#{instance_name}/info", params
72
+ end
73
+
74
+ ##
75
+ # Returns information about an instance, similar to
76
+ # the bulk output from +#instances_list+.
77
+
78
+ def instance_list instance_name
79
+ get "/#{Ganeti::Version}/instances/#{instance_name}"
80
+ end
81
+
82
+ ##
83
+ # Migrates an instance.
84
+ # Returns a job id.
85
+ #
86
+ # Body parameters:
87
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.2/html/rapi.html#instances-instance-name-migrate
88
+
89
+ def instance_migrate instance_name, params = {}
90
+ warn "WARNING: Instances#instance_migrate not implemented."
91
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/migrate", params
92
+ end
93
+
94
+ ##
95
+ # Modifies an instance.
96
+ # Returns a job id.
97
+ #
98
+ # Body parameters:
99
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.2/html/rapi.html#instances-instance-name-modify
100
+
101
+ def instance_modify instance_name, params = {}
102
+ warn "WARNING: Instances#instance_modify not implemented."
103
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/modify", params
104
+ end
105
+
106
+ ##
107
+ # Prepares an export of an instance.
108
+ # Returns a job id.
109
+ #
110
+ # Takes one parameter, mode, for the export mode.
111
+
112
+ def instance_prepare_export instance_name, params = {}
113
+ warn "WARNING: Instances#instance_prepare_export not implemented."
114
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/prepare-disks", params
115
+ end
116
+
117
+ ##
118
+ # Reboots the instance.
119
+ # Returns a job id.
120
+ #
121
+ # The URI takes optional type=soft|hard|full and ignore_secondaries=0|1 parameters.
122
+ # - soft is just a normal reboot, without terminating the hypervisor.
123
+ # - hard means full shutdown (including terminating the hypervisor process)
124
+ # and startup again.
125
+ # - full is like hard but also recreates the configuration from ground up
126
+ # as if you would have done a gnt-instance shutdown and gnt-instance start on it.
127
+ # - ignore_secondaries parameter (?ignore_secondaries=1), will start the
128
+ # instance even if secondary disks are failing.
129
+ #
130
+ # If the optional dry-run parameter (?dry-run=1) is provided,
131
+ # the job will not be actually executed, only the pre-execution
132
+ # checks will be done.
133
+
134
+ def instance_reboot instance_name, params = {}
135
+ post "/#{Ganeti::Version}/instances/#{instance_name}/reboot", params
136
+ end
137
+
138
+ ##
139
+ # Reinstalls the instance's operating system.
140
+ # Returns a job id.
141
+ #
142
+ # Takes the parameters os (OS template name) and nostartup (bool).
143
+
144
+ def instance_reinstall instance_name, params = {}
145
+ post "/#{Ganeti::Version}/instances/#{instance_name}/reinstall", params
146
+ end
147
+
148
+ ##
149
+ # Renames an instance.
150
+ # Returns a job id.
151
+ #
152
+ # Body parameters:
153
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.2/html/rapi.html#instances-instance-name-rename
154
+
155
+ def instance_rename instance_name, params = {}
156
+ $stderr.print "WARNING: Instances#instance_rename not implemented."
157
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/rename", params
158
+ end
159
+
160
+ ##
161
+ # Replaces disks on an instance.
162
+ # Returns a job id.
163
+ #
164
+ # Takes the mandatory parameters mode:
165
+ # - (one of replace_on_primary, replace_on_secondary, replace_new_secondary or replace_auto),
166
+ # - disks (comma separated list of disk indexes)
167
+ # - remote_node and iallocator
168
+ #
169
+ # Either remote_node or iallocator needs to be defined when using mode=replace_new_secondary.
170
+ # replace_auto tries to determine the broken disk(s) on its own and replacing it.
171
+
172
+ def instance_replace_disks instance_name, params = {}
173
+ warn "WARNING: Instances#instance_replace_disks not implemented."
174
+ # post "/#{Ganeti::Version}/instances/#{instance_name}/replace-disks", params
175
+ end
176
+
177
+ ##
178
+ # Shutdown an instance.
179
+ # Returns a job id.
180
+ #
181
+ # If the optional dry-run parameter (?dry-run=1) is provided,
182
+ # the job will not be actually executed, only the pre-execution
183
+ # checks will be done.
184
+
185
+ def instance_shutdown instance_name, params = {}
186
+ put "/#{Ganeti::Version}/instances/#{instance_name}/shutdown", params
187
+ end
188
+
189
+ ##
190
+ # Returns a list of all available instances.
191
+ #
192
+ # If the optional bulk parameter (?bulk=1) is provided,
193
+ # the output contains detailed information about instances as a list.
194
+
195
+ def instances_list params = {}
196
+ get "/#{Ganeti::Version}/instances", params
197
+ end
198
+
199
+ ##
200
+ # Startup an instance.
201
+ # Returns a job id.
202
+ #
203
+ # If the optional dry-run parameter (?dry-run=1) is provided,
204
+ # the job will not be actually executed, only the pre-execution
205
+ # checks will be done.
206
+
207
+ def instance_startup instance_name, params = {}
208
+ put "/#{Ganeti::Version}/instances/#{instance_name}/startup", params
209
+ end
210
+
211
+ ##
212
+ # Add a set of tags.
213
+ # Returns a job id.
214
+ #
215
+ # If the optional dry-run parameter (?dry-run=1) is provided,
216
+ # the job will not be actually executed, only the pre-execution
217
+ # checks will be done.
218
+
219
+ def instance_tag_create instance_name, params = {}
220
+ warn "WARNING: Instances#instance_tag_create not implemented."
221
+ # put "/#{Ganeti::Version}/instances/#{instance_name}/tags", params
222
+ end
223
+
224
+ ##
225
+ # Delete a tag.
226
+ # Returns a job id.
227
+ #
228
+ # If the optional dry-run parameter (?dry-run=1) is provided,
229
+ # the job will not be actually executed, only the pre-execution
230
+ # checks will be done.
231
+
232
+ def instance_tag_delete instance_name, params = {}
233
+ warn "WARNING: Instances#instance_tag_delete not implemented."
234
+ # delete "/#{Ganeti::Version}/instances/#{instance_name}/tags", params
235
+ end
236
+
237
+ ##
238
+ # Return a list of tags.
239
+
240
+ def instance_tag_list instance_name, params = {}
241
+ warn "WARNING: Instances#instance_tag_list not implemented."
242
+ # get "/#{Ganeti::Version}/instances/#{instance_name}/tags", params
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,42 @@
1
+ module Rubineti
2
+ module Jobs
3
+ ##
4
+ # Returns an Array of all jobs.
5
+
6
+ def jobs_list
7
+ get "/#{Ganeti::Version}/jobs"
8
+ end
9
+
10
+ ##
11
+ # Returns a jobs status.
12
+ #
13
+ # +job_id+: A String of the 'job id'.
14
+
15
+ def job_list job_id
16
+ get "/#{Ganeti::Version}/jobs/#{job_id}"
17
+ end
18
+
19
+ ##
20
+ # Cancel a not-yet-started job.
21
+ #
22
+ # +job_id+: A String of the 'job id'.
23
+
24
+ def job_delete job_id
25
+ warn "WARNING: Jobs#job_delete not implemented."
26
+ # delete "/#{Ganeti::Version}/jobs/#{job_id}/delete"
27
+ end
28
+
29
+ ##
30
+ # Waits for changes on a job.
31
+ #
32
+ # +job_id+: A String of the 'job id'.
33
+ #
34
+ # Body parameters:
35
+ # - http://docs.ganeti.org/ganeti/#{Ganeti::Version}.1/html/rapi.html#jobs-job-id-wait
36
+
37
+ def job_wait job_id, params = {}
38
+ warn "WARNING: Jobs#job_wait not implemented."
39
+ # get "/#{Ganeti::Version}/jobs/#{job_id}/wait", params
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,140 @@
1
+ module Rubineti
2
+ module Node
3
+
4
+ ##
5
+ # Evacuates all secondary instances off a node.
6
+ #
7
+ # To evacuate a node, either one of the iallocator or remote_node parameters must be passed:
8
+ # - evacuate?iallocator=[iallocator]
9
+ # - evacuate?remote_node=[nodeX.example.com]
10
+ # See: http://docs.ganeti.org/ganeti/2.2/html/rapi.html#nodes-node-name-evacuate
11
+ #
12
+ # If the optional dry-run parameter (?dry-run=1) is provided,
13
+ # the job will not be actually executed, only the pre-execution
14
+ # checks will be done.
15
+
16
+ def node_evacuate node_name, params = {}
17
+ warn "WARNING: Node#node_evacuate not implemented."
18
+ # post "/2/nodes/#{node_name}/evacuate", params
19
+ end
20
+
21
+ ##
22
+ # Returns information about a node.
23
+
24
+ def node_list node_name
25
+ get "/2/nodes/#{node_name}"
26
+ end
27
+
28
+ ##
29
+ # Migrates all primary instances from a node.
30
+ #
31
+ # If no mode is explicitly specified, each instances’ hypervisor
32
+ # default migration mode will be used. Query parameters:
33
+ # - live (bool): If set, use live migration if available.
34
+ # - mode (string): Sets migration mode, live for live migration
35
+ # and non-live for non-live migration. Supported by Ganeti 2.2 and above.
36
+
37
+ def node_migrate node_name, params = {}
38
+ warn "WARNING: Node#node_migrate not implemented."
39
+ # post "/2/nodes/#{node_name}/migrate", params
40
+ end
41
+
42
+ ##
43
+ # Change the node role.
44
+ # Returns a job id.
45
+ #
46
+ # It supports the bool force argument.
47
+
48
+ def node_role_create node_name
49
+ warn "WARNING: Node#node_role_create not implemented."
50
+ # TODO: API Docs do not describe it's usage well.
51
+ # put "/2/nodes/#{node_name}/role"
52
+ end
53
+
54
+ ##
55
+ # Returns the current node role.
56
+
57
+ def node_role_list node_name
58
+ get "/2/nodes/#{node_name}/role"
59
+ end
60
+
61
+ ##
62
+ # Returns a list of all nodes.
63
+ #
64
+ # If the optional bulk parameter (?bulk=1) is provided,
65
+ # the output contains detailed information about instances as a list.
66
+
67
+ def nodes_list params = {}
68
+ get "/2/nodes", params
69
+ end
70
+
71
+ ##
72
+ # Requests a list of storage units on a node.
73
+ # Returns a job id.
74
+ #
75
+ # Requires the parameters storage_type (one of file, lvm-pv or lvm-vg) and output_fields.
76
+
77
+ def node_storage_list node_name, params = {}
78
+ warn "WARNING: Node#node_storage_list not implemented."
79
+ # get "/2/nodes/#{node_name}/storage", params
80
+ end
81
+
82
+ ##
83
+ # Modifies storage units on the node.
84
+ # Returns a job id.
85
+ #
86
+ # Requires the parameters storage_type (one of file, lvm-pv or lvm-vg) and name (name of the storage unit).
87
+ # Parameters can be passed additionally. Currently only allocatable (bool) is supported.
88
+
89
+ def node_storage_modify node_name, params = {}
90
+ warn "WARNING: Node#node_storage_modify not implemented."
91
+ # put "/2/nodes/#{node_name}/storage/modify", params
92
+ end
93
+
94
+ ##
95
+ # Repairs a storage unit on the node.
96
+ # Returns a job id.
97
+ #
98
+ # Requires the parameters storage_type (currently only lvm-vg can be repaired) and
99
+ # name (name of the storage unit).
100
+
101
+ def node_storage_repair node_name, params = {}
102
+ warn "WARNING: Node#node_storage_repair not implemented."
103
+ # put "/2/nodes/#{node_name}/repair", params
104
+ end
105
+
106
+ ##
107
+ # Add a set of tags.
108
+ # Returns a job id.
109
+ #
110
+ # If the optional dry-run parameter (?dry-run=1) is provided,
111
+ # the job will not be actually executed, only the pre-execution
112
+ # checks will be done.
113
+
114
+ def node_tags_create node_name, params = {}
115
+ warn "WARNING: Node#node_tags_create not implemented."
116
+ # put "/2/nodes/#{node_name}/tags", params
117
+ end
118
+
119
+ ##
120
+ # Deletes tags.
121
+ # Returns a job id.
122
+ #
123
+ # If the optional dry-run parameter (?dry-run=1) is provided,
124
+ # the job will not be actually executed, only the pre-execution
125
+ # checks will be done.
126
+
127
+ def node_tags_delete node_name, params = {}
128
+ warn "WARNING: Node#node_tags_delete not implemented."
129
+ # delete "/2/nodes/#{node_name}/tags", params
130
+ end
131
+
132
+ ##
133
+ # Return a list of tags.
134
+
135
+ def node_tags_list node_name
136
+ warn "WARNING: Node#node_tags_list not implemented."
137
+ # get "/2/nodes/#{node_name}/tags"
138
+ end
139
+ end
140
+ end