knife-maas 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +7 -0
- data/knife-maas.gemspec +27 -0
- data/lib/chef/knife/maas/version.rb +7 -0
- data/lib/chef/knife/maas.rb +9 -0
- data/lib/chef/knife/maas_base.rb +57 -0
- data/lib/chef/knife/maas_server_acquire.rb +28 -0
- data/lib/chef/knife/maas_server_bootstrap.rb +141 -0
- data/lib/chef/knife/maas_server_delete.rb +59 -0
- data/lib/chef/knife/maas_server_list.rb +81 -0
- data/lib/chef/knife/maas_server_release.rb +59 -0
- data/lib/chef/knife/maas_server_start.rb +30 -0
- data/lib/chef/knife/maas_server_stop.rb +25 -0
- data/spec/knife/maas_spec.rb +11 -0
- data/spec/spec_helper.rb +2 -0
- metadata +138 -0
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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
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
data/knife-maas.gemspec
ADDED
@@ -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,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
|
data/spec/spec_helper.rb
ADDED
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:
|