knife-maas 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a55cbfd0fc6cc2a84c574c898c33fc60845fe95
4
+ data.tar.gz: 28ee2af338a2bac60fadcf0b57dc223fe0afd676
5
+ SHA512:
6
+ metadata.gz: 76c098617c486849c7a8b9a964270b02ab5b10070f477664fa388dfe9b0988fc4eec3d082e80b6f3b6d5e95d35c0cde16d4ef80a201cd75e12a0edef33034f76
7
+ data.tar.gz: 6165ed1303a426e801b0034968fe382da40e158c4feee9ee763f4b1c48f14a68bae5bd3b591bf82af0a7db5cbd1433bb14909eeb36ed41d0899cc4ef9246fc49
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## v1.0.0
2
+ * initial public release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in knife-maas.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 JJ Asghar
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # knife-maas
2
+
3
+ This is the knife plugin to talk to [MAAS](http://maas.ubuntu.com/). This also assumes you have MAAS
4
+ configured with at least one user account. You'll need your API key as one of the
5
+ configuration options. There is a [MAAS cookbook](https://supermarket.chef.io/cookbooks/maas) that
6
+ this plugin has been tested against.
7
+
8
+ This also assumes you have >= 1.7.1 of MAAS installed, and >= [Chef](http://chef.io) 12 installed.
9
+
10
+ Please refer to the [CHANGELOG](CHANGELOG.md) for version history.
11
+
12
+ ## Installation
13
+
14
+ Run the following to install the plugin.
15
+
16
+ ```shell
17
+ gem install knife-maas
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Configuration
23
+
24
+ `knife[:maas_site]` - The MAAS that you'd like to interact with, ex: `"http://172.16.100.54/MAAS/"`, you'll need the ending `/` like the web gui.
25
+
26
+ `knife[:maas_api_key]` - The MAAS API key from your settings page, ex: `"Th1sIsFAKEY3f9Lvm:jaaMAASfgDVbjR9:jS6JPX8bKEYFp8W2DR7MBuPb9QrEFbYT"`
27
+
28
+ ## Commands
29
+
30
+ **Note**: Due to some limitations in the [MAAS API](http://maas.ubuntu.com/docs1.7/api.html) anything that has both `-h` and
31
+ `-s` are required to function. Hopefully future releases will only require one option.
32
+
33
+ `knife maas server list` - Outputs the nodes inside on MAAS
34
+
35
+ `knife maas server <subcommand> --help` - is available and there are other options that aren't listed here. These are the most commonly used ones.
36
+
37
+ `knife maas server acquire -h HOSTNAME` - Acquires the node under your account
38
+
39
+ `knife maas server bootstrap -h HOSTNAME -s NODE-(UUID)` - Acquires and starts the node under your account, and bootstraps chef on it with your default settings
40
+
41
+ `knife maas server start -s NODE-(UUID)` - Starts up the node
42
+
43
+ `knife maas server stop -s NODE-(UUID)` - Stops the node
44
+
45
+ `knife maas server release -s NODE-(UUID) -h HOSTNAME`- Releases the node and puts it back in the available resources. This also has a `-P` command to purge it from
46
+ your chef server.
47
+
48
+ `knife maas server delete -s NODE-(UUID) -h HOSTNAME` - Removes the node completely from MAAS. This also has a `-P` command to purge it from your chef server.
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it ( https://github.com/jjasghar/knife-maas/fork )
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create a new Pull Request
57
+
58
+ ## License
59
+ Author:: JJ Asghar <jj@chef.io>
60
+
61
+ Copyright:: Copyright (c) 2015 Chef Software, Inc.
62
+
63
+ License:: Apache License, Version 2.0
64
+
65
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
66
+ this file except in compliance with the License. You may obtain a copy of the License at
67
+
68
+ http://www.apache.org/licenses/LICENSE-2.0
69
+
70
+ Unless required by applicable law or agreed to in writing, software distributed under the
71
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
72
+ either express or implied. See the License for the specific language governing permissions
73
+ and limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chef/knife/maas/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "knife-maas"
8
+ spec.version = Chef::Knife::Maas::VERSION
9
+ spec.authors = ["JJ Asghar"]
10
+ spec.email = ["jj@chef.io"]
11
+ spec.summary = %q{A knife plugin to interact with MaaS}
12
+ spec.description = %q{A knife plugin to interact with MaaS}
13
+ spec.homepage = "http://github.com/jjasghar/knife-maas"
14
+ spec.license = "Apache2"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "chef", "~> 12.0.0"
22
+ spec.add_dependency "oauth"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,7 @@
1
+ class Chef
2
+ class Knife
3
+ module Maas
4
+ VERSION = "1.0.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require "chef/knife/maas/version"
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerList < Knife
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,57 @@
1
+
2
+
3
+ class Chef
4
+ class Knife
5
+ module MaasBase
6
+
7
+ def self.included(includer)
8
+ includer.class_eval do
9
+
10
+ deps do
11
+ require 'oauth'
12
+ require 'oauth/signature/plaintext'
13
+ require 'chef/json_compat'
14
+ require 'chef/knife'
15
+ require 'readline'
16
+ Chef::Knife.load_deps
17
+ end
18
+ # add common knife option flags here
19
+ end
20
+ end
21
+
22
+ def prepare_access_token(oauth_token, oauth_token_secret, consumer_key, consumer_secret)
23
+
24
+ consumer = OAuth::Consumer.new( consumer_key,
25
+ consumer_secret,
26
+ {
27
+ :site => locate_config_value(:maas_site)+"api/1.0/",
28
+ :scheme => :header,
29
+ :signature_method => "PLAINTEXT"
30
+ })
31
+
32
+ access_token = OAuth::AccessToken.new( consumer,
33
+ oauth_token,
34
+ oauth_token_secret
35
+ )
36
+ return access_token
37
+ end
38
+
39
+ def access_token
40
+ maas_key = "#{locate_config_value(:maas_api_key)}"
41
+ customer_key = maas_key.split(":")[0]
42
+ customer_secret = ""
43
+ token_key = maas_key.split(":")[1]
44
+ token_secret = maas_key.split(":")[2]
45
+ prepare_access_token(token_key, token_secret, customer_key, customer_secret)
46
+ end
47
+
48
+ def locate_config_value(key)
49
+ key = key.to_sym
50
+ Chef::Config[:knife][key] || config[key]
51
+ end
52
+
53
+
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ require 'chef/knife/maas_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerAcquire < Knife
6
+
7
+ include Chef::Knife::MaasBase
8
+
9
+ deps do
10
+ end
11
+
12
+ banner "knife maas server acquire (options)"
13
+
14
+ option :hostname,
15
+ :short => "-h HOSTNAME",
16
+ :long => "--hostname HOSTNAME",
17
+ :description => "The HOSTNAME inside of MaaS"
18
+
19
+ def run
20
+ hostname = locate_config_value(:hostname)
21
+ response = access_token.request(:post, "/nodes/?op=acquire&name=#{hostname}")
22
+ puts "Acquiring #{hostname} under your account now...."
23
+ end
24
+
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,141 @@
1
+ require 'chef/knife/maas_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerBootstrap < Knife
6
+
7
+ include Chef::Knife::MaasBase
8
+
9
+ deps do
10
+ require 'chef/knife/bootstrap'
11
+ Chef::Knife::Bootstrap.load_deps
12
+ end
13
+
14
+ banner "knife maas server bootstrap (options)"
15
+
16
+ option :hostname,
17
+ :short => "-h HOSTNAME",
18
+ :long => "--hostname HOSTNAME",
19
+ :description => "The HOSTNAME inside of MaaS"
20
+
21
+ option :system_id,
22
+ :short => "-s SYSTEM_ID",
23
+ :long => "--system-id SYSTEM_ID",
24
+ :description => "The System ID inside of MaaS"
25
+
26
+ option :template_file,
27
+ :long => "--template-file TEMPLATE",
28
+ :description => "Full path to location of template to use",
29
+ :proc => Proc.new { |t| Chef::Config[:knife][:template_file] = t },
30
+ :default => false
31
+
32
+ option :run_list,
33
+ :short => "-r RUN_LIST",
34
+ :long => "--run-list RUN_LIST",
35
+ :description => "Comma separated list of roles/recipes to apply",
36
+ :proc => lambda { |o| o.split(/[\s,]+/) },
37
+ :default => []
38
+
39
+ def run
40
+ hostname = locate_config_value(:hostname)
41
+ system_id = locate_config_value(:system_id)
42
+
43
+ response = access_token.request(:post, "/nodes/?op=acquire&name=#{hostname}")
44
+ puts "Acquiring #{hostname} under your account now...."
45
+
46
+ # hack to ensure the node have had time to spin up
47
+ print(".")
48
+ sleep 60
49
+ print(".")
50
+
51
+ response = access_token.request(:post, "/nodes/#{system_id}/?op=start")
52
+ system_info = access_token.request(:get, "/nodes/#{system_id}/")
53
+ puts "Starting up #{system_id} now...."
54
+
55
+ # hack to ensure the nodes have had time to spin up
56
+ print(".")
57
+ sleep 30
58
+ print(".")
59
+
60
+ server = JSON.parse(system_info.body)["hostname"]
61
+ netboot = JSON.parse(system_info.body)["netboot"]
62
+ power_state = JSON.parse(system_info.body)["power_state"]
63
+
64
+ until ((netboot == false) && (power_state == "on") ) do
65
+ print(".")
66
+ sleep @initial_sleep_delay ||= 10
67
+ system_info = access_token.request(:get, "/nodes/#{system_id}/")
68
+ netboot = JSON.parse(system_info.body)["netboot"]
69
+ power_state = JSON.parse(system_info.body)["power_state"]
70
+ end
71
+
72
+ bootstrap_ip_address = JSON.parse(system_info.body)["ip_addresses"][0]
73
+
74
+ print(".")
75
+ sleep 30
76
+ print(".")
77
+ sleep 30
78
+
79
+ print(".") until tcp_test_ssh(bootstrap_ip_address) {
80
+ sleep @initial_sleep_delay ||= 10
81
+ puts("connected and done")
82
+ }
83
+
84
+ os_system = JSON.parse(system_info.body)["osystem"]
85
+
86
+ case os_system
87
+ when "centos"
88
+ user = "cloud-user"
89
+ else
90
+ user = "ubuntu"
91
+ end
92
+
93
+ bootstrap_for_node(server, bootstrap_ip_address, user).run
94
+
95
+ end
96
+
97
+ def bootstrap_for_node(server, bootstrap_ip_address, user)
98
+ bootstrap = Chef::Knife::Bootstrap.new
99
+ bootstrap.name_args = bootstrap_ip_address
100
+ bootstrap.config[:run_list] = config[:run_list]
101
+ bootstrap.config[:ssh_user] = user
102
+ bootstrap.config[:identity_file] = config[:identity_file]
103
+ bootstrap.config[:host_key_verify] = config[:host_key_verify]
104
+ bootstrap.config[:chef_node_name] = server
105
+ bootstrap.config[:prerelease] = config[:prerelease]
106
+ bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
107
+ bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
108
+ bootstrap.config[:distro] = locate_config_value(:distro)
109
+ bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
110
+ bootstrap.config[:template_file] = locate_config_value(:template_file)
111
+ bootstrap.config[:environment] = config[:environment]
112
+ bootstrap
113
+ end
114
+
115
+ def tcp_test_ssh(hostname)
116
+ tcp_socket = TCPSocket.new(hostname, 22)
117
+ readable = IO.select([tcp_socket], nil, nil, 5)
118
+ if readable
119
+ Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
120
+ yield
121
+ true
122
+ else
123
+ false
124
+ end
125
+ rescue Errno::ETIMEDOUT
126
+ false
127
+ rescue Errno::EPERM
128
+ false
129
+ rescue Errno::ECONNREFUSED
130
+ sleep 2
131
+ false
132
+ rescue Errno::EHOSTUNREACH
133
+ sleep 2
134
+ false
135
+ ensure
136
+ tcp_socket && tcp_socket.close
137
+ end
138
+
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,59 @@
1
+ require 'chef/knife/maas_base'
2
+ require 'chef/node'
3
+ require 'chef/api_client'
4
+
5
+ class Chef
6
+ class Knife
7
+ class MaasServerDelete < Knife
8
+
9
+ include Chef::Knife::MaasBase
10
+
11
+ banner "knife maas server delete (options)"
12
+
13
+ option :hostname,
14
+ :short => "-h HOSTNAME",
15
+ :long => "--hostname HOSTNAME",
16
+ :description => "The HOSTNAME inside of MaaS"
17
+
18
+ option :system_id,
19
+ :short => "-s SYSTEM_ID",
20
+ :long => "--system-id SYSTEM_ID",
21
+ :description => "The System ID inside of MaaS"
22
+
23
+ option :purge,
24
+ :short => "-P",
25
+ :long => "--purge",
26
+ :boolean => true,
27
+ :default => false,
28
+ :description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the MaaS node itself. Assumes node and client have the same name as the server."
29
+
30
+ def destroy_item(klass, name, type_name)
31
+ begin
32
+ object = klass.load(name)
33
+ object.destroy
34
+ ui.warn("Deleted #{type_name} #{name}")
35
+ rescue Net::HTTPServerException
36
+ ui.warn("Could not find a #{type_name} named #{name} to delete!")
37
+ end
38
+ end
39
+
40
+ def run
41
+ system_id = locate_config_value(:system_id)
42
+ hostname = locate_config_value(:hostname)
43
+
44
+ if config[:purge]
45
+ thing_to_delete = config[:chef_node_name] || hostname
46
+ destroy_item(Chef::Node, thing_to_delete, "node")
47
+ destroy_item(Chef::ApiClient, thing_to_delete, "client")
48
+ else
49
+ ui.warn("Corresponding node and client for the #{hostname} server were not deleted and remain registered with the Chef Server")
50
+ end
51
+
52
+ response = access_token.request(:post, "/nodes/#{system_id}/?op=delete")
53
+ puts "Nuking #{system_id} From Orbit now...."
54
+ end
55
+
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,81 @@
1
+ require 'chef/knife/maas_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerList < Knife
6
+
7
+ include Chef::Knife::MaasBase
8
+
9
+ banner "knife maas server list"
10
+
11
+ def run
12
+
13
+ server_list = [
14
+ ui.color('System ID', :bold),
15
+ ui.color('Status', :bold),
16
+ ui.color('Power State', :bold),
17
+ ui.color('Hostname', :bold),
18
+ ui.color('Owner', :bold),
19
+ ui.color('IP Address', :bold)
20
+ ]
21
+
22
+ response = access_token.request(:get, "/nodes/?op=list")
23
+ JSON.parse(response.body).sort_by { |h| h["system_id"] }.each do |server|
24
+ Chef::Log.debug("Server: #{server.to_yaml}")
25
+
26
+ server_list << server['system_id'].to_s
27
+ server_list << begin
28
+ status = server['substatus'].to_s
29
+ case status
30
+ when "2","3","8","11","13","15"
31
+ ui.color("failed", :red)
32
+ when "0","1","5","7","9","10","12","14"
33
+ ui.color("deploying", :yellow)
34
+ when "4"
35
+ ui.color("ready", :green)
36
+ when "6"
37
+ ui.color("deployed", :green)
38
+ else
39
+ ui.color(state, :green)
40
+ end
41
+ end
42
+ # NEW = 0
43
+ # COMMISSIONING = 1
44
+ # FAILED_COMMISSIONING = 2
45
+ # MISSING = 3
46
+ # READY = 4
47
+ # RESERVED = 5
48
+ # DEPLOYED = 6
49
+ # RETIRED = 7
50
+ # BROKEN = 8
51
+ # DEPLOYING = 9
52
+ # ALLOCATED = 10
53
+ # FAILED_DEPLOYMENT = 11
54
+ # RELEASING = 12
55
+ # FAILED_RELEASING = 13
56
+ # DISK_ERASING = 14
57
+ # FAILED_DISK_ERASING = 15
58
+ server_list << begin
59
+ power_state = server['power_state'].to_s
60
+ case power_state
61
+ when "off"
62
+ ui.color(power_state, :red)
63
+ when "on"
64
+ ui.color(power_state, :green)
65
+ else
66
+ ui.color(power_state, :yellow)
67
+ end
68
+ end
69
+ server_list << server['hostname'].to_s
70
+ server_list << server['owner'].to_s
71
+ server_list << server['ip_addresses'].to_s
72
+
73
+ end
74
+ puts ui.list(server_list, :uneven_columns_across, 6)
75
+
76
+ end
77
+
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,59 @@
1
+ require 'chef/knife/maas_base'
2
+ require 'chef/node'
3
+ require 'chef/api_client'
4
+
5
+ class Chef
6
+ class Knife
7
+ class MaasServerRelease < Knife
8
+
9
+ include Chef::Knife::MaasBase
10
+
11
+ banner "knife maas server release (options)"
12
+
13
+ option :hostname,
14
+ :short => "-h HOSTNAME",
15
+ :long => "--hostname HOSTNAME",
16
+ :description => "The HOSTNAME inside of MaaS"
17
+
18
+ option :system_id,
19
+ :short => "-s SYSTEM_ID",
20
+ :long => "--system-id SYSTEM_ID",
21
+ :description => "The System ID inside of MaaS"
22
+
23
+ option :purge,
24
+ :short => "-P",
25
+ :long => "--purge",
26
+ :boolean => true,
27
+ :default => false,
28
+ :description => "Destroy corresponding node and client on the Chef Server, in addition to releasing the MaaS node itself. Assumes node and client have the same name as the server."
29
+
30
+ def destroy_item(klass, name, type_name)
31
+ begin
32
+ object = klass.load(name)
33
+ object.destroy
34
+ ui.warn("Deleted #{type_name} #{name}")
35
+ rescue Net::HTTPServerException
36
+ ui.warn("Could not find a #{type_name} named #{name} to delete!")
37
+ end
38
+ end
39
+
40
+ def run
41
+ system_id = locate_config_value(:system_id)
42
+ hostname = locate_config_value(:hostname)
43
+
44
+ if config[:purge]
45
+ thing_to_delete = config[:chef_node_name] || hostname
46
+ destroy_item(Chef::Node, thing_to_delete, "node")
47
+ destroy_item(Chef::ApiClient, thing_to_delete, "client")
48
+ else
49
+ ui.warn("Corresponding node and client for the #{hostname} server were not deleted and remain registered with the Chef Server")
50
+ end
51
+
52
+ response = access_token.request(:post, "/nodes/#{system_id}/?op=release")
53
+ puts "Releasing #{system_id} back to MAAS now...."
54
+ end
55
+
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,30 @@
1
+ require 'chef/knife/maas_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerStart < Knife
6
+
7
+ include Chef::Knife::MaasBase
8
+
9
+ deps do
10
+ require 'chef/knife/bootstrap'
11
+ Chef::Knife::Bootstrap.load_deps
12
+ end
13
+
14
+ banner "knife maas server start (options)"
15
+
16
+ option :system_id,
17
+ :short => "-s SYSTEM_ID",
18
+ :long => "--system-id SYSTEM_ID",
19
+ :description => "The System ID inside of MaaS"
20
+
21
+ def run
22
+ system_id = locate_config_value(:system_id)
23
+ response = access_token.request(:post, "/nodes/#{system_id}/?op=start")
24
+ puts "Starting up #{system_id} now...."
25
+ end
26
+
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ require 'chef/knife/maas_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class MaasServerStop < Knife
6
+
7
+ include Chef::Knife::MaasBase
8
+
9
+ banner "knife maas server stop (options)"
10
+
11
+ option :system_id,
12
+ :short => "-s SYSTEM_ID",
13
+ :long => "--system-id SYSTEM_ID",
14
+ :description => "The System ID inside of MaaS"
15
+
16
+ def run
17
+ system_id = locate_config_value(:system_id)
18
+ response = access_token.request(:post, "/nodes/#{system_id}/?op=stop")
19
+ puts "Stopping #{system_id} now...."
20
+ end
21
+
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Knife::Maas do
4
+ it 'has a version number' do
5
+ expect(Knife::Maas::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'does something useful' do
9
+ expect(false).to eq(true)
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'chef/knife/maas'
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knife-maas
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - JJ Asghar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chef
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 12.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 12.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
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.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
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
+ description: A knife plugin to interact with MaaS
84
+ email:
85
+ - jj@chef.io
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - CHANGELOG.md
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - knife-maas.gemspec
99
+ - lib/chef/knife/maas.rb
100
+ - lib/chef/knife/maas/version.rb
101
+ - lib/chef/knife/maas_base.rb
102
+ - lib/chef/knife/maas_server_acquire.rb
103
+ - lib/chef/knife/maas_server_bootstrap.rb
104
+ - lib/chef/knife/maas_server_delete.rb
105
+ - lib/chef/knife/maas_server_list.rb
106
+ - lib/chef/knife/maas_server_release.rb
107
+ - lib/chef/knife/maas_server_start.rb
108
+ - lib/chef/knife/maas_server_stop.rb
109
+ - spec/knife/maas_spec.rb
110
+ - spec/spec_helper.rb
111
+ homepage: http://github.com/jjasghar/knife-maas
112
+ licenses:
113
+ - Apache2
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.2.2
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: A knife plugin to interact with MaaS
135
+ test_files:
136
+ - spec/knife/maas_spec.rb
137
+ - spec/spec_helper.rb
138
+ has_rdoc: