rightscale-cli 0.5.6 → 0.6.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.
@@ -15,6 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  module RightApi
18
+ # Client monkey patch to read API connection properties
18
19
  class Client
19
20
  attr_reader :api_version, :api_url, :account_id
20
21
  end
@@ -0,0 +1,61 @@
1
+ # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
+ # Copyright:: Copyright (c) 2013-2015 Chris Fordham
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'thor'
18
+ require 'rightscale_cli/client'
19
+ require 'rightscale_cli/logger'
20
+
21
+ class RightScaleCLI
22
+ # Represents Network Manager Networks
23
+ class Networks < Thor
24
+ namespace :networks
25
+
26
+ def initialize(*args)
27
+ super
28
+ @client = RightScaleCLI::Client.new(options)
29
+ @logger = RightScaleCLI::Logger.new
30
+ end
31
+
32
+ class_option :xml,
33
+ type: :boolean,
34
+ default: false,
35
+ aliases: '-X',
36
+ required: false,
37
+ desc: 'returns xml'
38
+ class_option :json,
39
+ type: :boolean,
40
+ default: false,
41
+ aliases: '-J',
42
+ required: false,
43
+ desc: 'returns json'
44
+
45
+ desc 'list', 'lists all networks'
46
+ def list
47
+ filter = []
48
+ @logger.debug "filter: #{filter}" if options[:debug]
49
+
50
+ networks = []
51
+ @client.client.networks.index(filter: filter).each do |network|
52
+ networks.push(network)
53
+ end
54
+ @client.render(networks, 'networks')
55
+ end
56
+
57
+ def self.banner(task, _namespace = true, subcommand = false)
58
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,155 @@
1
+ # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
+ # Copyright:: Copyright (c) 2013 Chris Fordham
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'thor'
18
+ require 'rightscale_cli/client'
19
+ require 'rightscale_cli/logger'
20
+
21
+ class RightScaleCLI
22
+ # Represents Network Manager Security Groups
23
+ class SecurityGroups < Thor
24
+ namespace :secgroups
25
+
26
+ def initialize(*args)
27
+ super
28
+ @client = RightScaleCLI::Client.new(options)
29
+ @logger = RightScaleCLI::Logger.new
30
+ end
31
+
32
+ # include render options
33
+ eval(IO.read(
34
+ "#{File.dirname(File.expand_path(__FILE__))}/../render_options.rb"), binding
35
+ )
36
+
37
+ desc 'list', 'Lists all security groups.'
38
+ option :cloud,
39
+ desc: 'The cloud to filter on.',
40
+ type: :string,
41
+ required: true
42
+ def list
43
+ filter = []
44
+
45
+ @logger.debug "filter: #{filter}" if options[:debug]
46
+
47
+ security_groups = []
48
+ @client.client.clouds(id: options[:cloud])\
49
+ .show.security_groups(filter: filter).index.each do |sec_group|
50
+ security_groups.push(sec_group)
51
+ end
52
+ @client.render(security_groups, 'security_groups')
53
+ end
54
+
55
+ desc 'show', 'Shows a single security group.'
56
+ def show(secgroup_id)
57
+ filter = []
58
+ @client.render(@client.client.clouds(id: options[:cloud]).show.instances.index(id: instance_id).show.raw, 'instance')
59
+ end
60
+
61
+ desc 'create', 'Creates a security group.'
62
+ option :cloud,
63
+ desc: 'The cloud to filter on.',
64
+ type: :string,
65
+ required: true
66
+ def create(name, description=false)
67
+ @client.create('security_group',
68
+ cloud: options[:cloud],
69
+ security_group: { name: name, description: description })
70
+ end
71
+
72
+ desc 'create_rs_mgmt', 'Creates a new security group with ' \
73
+ 'rules needed for outbound traffic to RightScale.'
74
+ option :cloud,
75
+ desc: 'The cloud to filter on.',
76
+ type: :string,
77
+ required: true
78
+ def create_rs_mgmt(network_id)
79
+ sg_href = @client.create('security_group',
80
+ cloud: options[:cloud],
81
+ security_group: {
82
+ name: 'mgmt-rightscale-egress',
83
+ description: 'Enables all RightScale ' \
84
+ 'use cases (end-user access to UI and ' \
85
+ 'API, RightLink system management, ' \
86
+ 'monitoring, alerting).',
87
+ network_href: "/api/networks/#{network_id}" })
88
+ sg_rules = [
89
+ {
90
+ cidr_ips: '54.187.254.128/26',
91
+ security_group_href: sg_href,
92
+ source_type: 'cidr_ips',
93
+ protocol: 'all',
94
+ direction: 'egress'
95
+ },
96
+ {
97
+ cidr_ips: '54.225.248.128/27',
98
+ security_group_href: sg_href,
99
+ source_type: 'cidr_ips',
100
+ protocol: 'all',
101
+ direction: 'egress'
102
+ },
103
+ {
104
+ cidr_ips: '54.244.88.96/27',
105
+ security_group_href: sg_href,
106
+ source_type: 'cidr_ips',
107
+ protocol: 'all',
108
+ direction: 'egress'
109
+ },
110
+ {
111
+ cidr_ips: '54.246.247.16/28',
112
+ security_group_href: sg_href,
113
+ source_type: 'cidr_ips',
114
+ protocol: 'all',
115
+ direction: 'egress'
116
+ },
117
+ {
118
+ cidr_ips: '54.255.255.208/28',
119
+ security_group_href: sg_href,
120
+ source_type: 'cidr_ips',
121
+ protocol: 'all',
122
+ direction: 'egress'
123
+ },
124
+ {
125
+ cidr_ips: '54.86.63.128/26',
126
+ security_group_href: sg_href,
127
+ source_type: 'cidr_ips',
128
+ protocol: 'all',
129
+ direction: 'egress'
130
+ },
131
+ {
132
+ cidr_ips: '0.0.0.0/0',
133
+ security_group_href: sg_href,
134
+ source_type: 'cidr_ips',
135
+ protocol: 'udp',
136
+ protocol_details: {
137
+ start_port: '3011',
138
+ end_port: '3011'
139
+ },
140
+ direction: 'egress'
141
+ }
142
+ ]
143
+ sg_rules.each do |rule|
144
+ @logger.info rule
145
+ @client.create('security_group_rule', security_group_rule: rule)
146
+ end
147
+ @logger.info 'Please remember to delete the outbound ' \
148
+ '0.0.0.0/0 rule now (TODO: automatically delete).'
149
+ end
150
+
151
+ def self.banner(task, namespace = true, subcommand = false)
152
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
153
+ end
154
+ end
155
+ end
@@ -1,5 +1,5 @@
1
1
  # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
- # Copyright:: Copyright (c) 2013 Chris Fordham
2
+ # Copyright:: Copyright (c) 2013-2015 Chris Fordham
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,11 +15,12 @@
15
15
  # limitations under the License.
16
16
 
17
17
  class RightScaleCLI
18
+ # Represents an output factory
18
19
  class Output
19
20
  def self.render(content, root_element, options)
20
- if options[:xml]
21
- require "active_support/core_ext"
22
- puts content.to_xml(:root => root_element)
21
+ if options[:xml]
22
+ require 'active_support/core_ext'
23
+ puts content.to_xml(root: root_element)
23
24
  elsif options[:json]
24
25
  require 'json'
25
26
  puts JSON.pretty_generate(content)
@@ -0,0 +1,50 @@
1
+ # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
+ # Copyright:: Copyright (c) 2013 Chris Fordham
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'thor'
18
+ require 'yaml'
19
+ require 'rightscale_cli/client'
20
+
21
+ class RightScaleCLI
22
+ class RecurringVolumeAttachments < Thor
23
+ namespace :re_attachments
24
+
25
+ def initialize(*args)
26
+ super
27
+ @client = RightScaleCLI::Client.new(options)
28
+ @logger = RightScaleCLI::Logger.new
29
+ end
30
+
31
+ # include render options
32
+ eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
33
+
34
+ desc "list", "Lists all recurring volume/snapshot attachments."
35
+ option :cloud, :desc => 'The cloud to filter on.', :type => :string, :required => true
36
+ def list()
37
+ attachments = []
38
+ filter = []
39
+ @client.client.clouds(:id => options[:cloud]).show.recurring_volume_attachments(:filter => filter).index.each do |attach|
40
+ attachments.push(attach)
41
+ end
42
+ @client.render(attachments, 'recurring_volume_attachments')
43
+ end
44
+
45
+
46
+ def self.banner(task, namespace = true, subcommand = false)
47
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,63 @@
1
+ # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
+ # Copyright:: Copyright (c) 2013-2015 Chris Fordham
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'thor'
18
+ require 'rightscale_cli/logger'
19
+ require 'rightscale_cli/client'
20
+ require 'rightscale_cli/config'
21
+ require 'net/https'
22
+ require 'uri'
23
+ require 'json'
24
+
25
+ class RightScaleCLI
26
+ # Represents an API token refresh
27
+ class Refresh < Thor
28
+ # namespace :volumes
29
+
30
+ def initialize(*args)
31
+ super
32
+ # @client = RightScaleCLI::Client.new(options)
33
+ @logger = RightScaleCLI::Logger.new
34
+ @config = RightScaleCLI::Config.new
35
+ @directives = @config.directives
36
+ end
37
+
38
+ desc 'token', 'refresh the api token' \
39
+ 'description, name, parent volume snapshot or resource UID (default)'
40
+ def token
41
+ token_endpoint = @directives[:token_endpoint]
42
+ refresh_token = @directives[:refresh_token]
43
+ @logger.info "Requesting API token from #{token_endpoint}"
44
+ uri = URI.parse(token_endpoint)
45
+ https = Net::HTTP.new(uri.host, uri.port)
46
+ https.set_debug_output($stdout) if options[:debug]
47
+ https.use_ssl = true
48
+ request = Net::HTTP::Post.new(uri.path)
49
+ request['X-API-Version'] = '1.5'
50
+ request.set_form_data(grant_type: 'refresh_token',
51
+ refresh_token: refresh_token)
52
+ response = https.request(request)
53
+ access_token = JSON.parse(response.body)['access_token']
54
+ @directives[:access_token] = access_token
55
+ File.open(@config.config_path, 'w') {|f| f.write(ERB.new(IO.read(@config.template_path)).result(binding)) }
56
+ @logger.info 'API token refreshed.'
57
+ end
58
+
59
+ def self.banner(task, _namespace = true, subcommand = false)
60
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
61
+ end
62
+ end
63
+ end
@@ -1,2 +1,12 @@
1
- class_option :xml, :type => :boolean, :default => false, :aliases => '-X', :required => false, :desc => 'Returns XML.'
2
- class_option :json, :type => :boolean, :default => false, :aliases => '-J', :required => false, :desc => 'Returns JSON.'
1
+ class_option :xml,
2
+ type: :boolean,
3
+ default: false,
4
+ aliases: '-X',
5
+ required: false,
6
+ desc: 'returns xml'
7
+ class_option :json,
8
+ type: :boolean,
9
+ default: false,
10
+ aliases: '-J',
11
+ required: false,
12
+ desc: 'returns json'
@@ -23,10 +23,15 @@ require 'rightscale_cli/dashboard'
23
23
  require 'rightscale_cli/deployments'
24
24
  require 'rightscale_cli/instances'
25
25
  require 'rightscale_cli/multi_cloud_images'
26
+ require 'rightscale_cli/recurring_volume_attachments'
26
27
  require 'rightscale_cli/repositories'
28
+ require 'rightscale_cli/network/networks'
29
+ require 'rightscale_cli/network/security_groups'
30
+ require 'rightscale_cli/refresh'
27
31
  require 'rightscale_cli/servers'
28
32
  require 'rightscale_cli/server_arrays'
29
33
  require 'rightscale_cli/server_templates'
34
+ require 'rightscale_cli/ssh_keys'
30
35
  require 'rightscale_cli/tags'
31
36
  require 'rightscale_cli/volumes'
32
37
 
@@ -94,9 +99,14 @@ class RightScaleCLI
94
99
  register(Deployments, 'deployments', 'deployments <command>', 'Manage deployments.')
95
100
  register(Instances, 'instances', 'instances <command>', 'Manage instances.')
96
101
  register(MultiCloudImages, 'mcis', 'mcis <command>', 'Manage MultiCloud Images.')
102
+ register(Networks, 'networks', 'networks <command>', 'Manage Networks.')
103
+ register(Refresh, 'refresh', 'refresh', 'refresh the API access token')
104
+ register(RecurringVolumeAttachments, 're_attachments', 're-attachments <command>', 'Manage recurring volume/snapshot attachments to servers.')
97
105
  register(Repositories, 'repositories', 'repositories <command>', 'Manage (Chef) Repositories.')
106
+ register(SecurityGroups, 'sec_groups', 'sec-groups <command>', 'Manage security groups.')
98
107
  register(Servers, 'servers', 'servers <command>', 'Manage servers.')
99
108
  register(ServerTemplates, 'server_templates', 'server-templates <command>', 'Manage ServerTemplates.')
109
+ register(SSHKeys, 'ssh_keys', 'ssh_keys <command>', 'Manage cloud SSH keys.')
100
110
  register(Tags, 'tags', 'tags <command>', 'Manage tags.')
101
111
  register(Volumes, 'volumes', 'volumes <command>', 'Manage volumes.')
102
112
  end
@@ -17,7 +17,7 @@
17
17
  require 'thor'
18
18
  require 'yaml'
19
19
  require 'json'
20
- require "active_support/core_ext"
20
+ require 'active_support/core_ext/object/blank'
21
21
  require 'rightscale_cli/logger'
22
22
  require 'rightscale_cli/client'
23
23
 
@@ -51,6 +51,11 @@ class RightScaleCLI
51
51
  # todo
52
52
  end
53
53
 
54
+ desc "terminate", "Terminates a server."
55
+ def destroy(server)
56
+ # todo
57
+ end
58
+
54
59
  def self.banner(task, namespace = true, subcommand = false)
55
60
  "#{basename} #{task.formatted_usage(self, true, subcommand)}"
56
61
  end
@@ -0,0 +1,87 @@
1
+ # Author:: Chris Fordham (<chris@fordham-nagy.id.au>)
2
+ # Copyright:: Copyright (c) 2013 Chris Fordham
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'thor'
18
+ require 'rightscale_cli/client'
19
+ require 'rightscale_cli/logger'
20
+
21
+ class RightScaleCLI
22
+ # interface /api/clouds/ssh_keys
23
+ class SSHKeys < Thor
24
+ namespace :ssh_keys
25
+
26
+ def initialize(*args)
27
+ super
28
+ @client = RightScaleCLI::Client.new(options)
29
+ @logger = RightScaleCLI::Logger.new
30
+ end
31
+
32
+ # include render options
33
+ eval(IO.read(
34
+ "#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding
35
+ )
36
+
37
+ desc 'list', 'Lists all SSH keys in a cloud.'
38
+ option :cloud,
39
+ desc: 'The cloud to filter on.',
40
+ type: 'string',
41
+ required: true
42
+ option :uid,
43
+ desc: 'Resource Unique IDentifier for the SSH key to filter on.',
44
+ type: 'string',
45
+ required: false,
46
+ default: false
47
+ def list
48
+ filter = [].push("resource_uid==#{options[:uid]}") if options[:uid]
49
+
50
+ results = @client.client.clouds(
51
+ id: options[:cloud]
52
+ ).show.ssh_keys(filter: filter).index
53
+
54
+ ssh_keys = []
55
+ results.each do |result|
56
+ ssh_key = result.raw
57
+ ssh_key['href'] = result.href
58
+ ssh_keys.push(ssh_key)
59
+ end
60
+
61
+ @client.render(ssh_keys, 'ssh_keys')
62
+ end
63
+
64
+ desc 'show', 'Shows a SSH key in a cloud.'
65
+ option :cloud,
66
+ desc: 'The cloud the SSH key resides in.',
67
+ type: 'string',
68
+ required: true
69
+ def show(ssh_key_id)
70
+ @client.render(@client.client.clouds(id: options[:cloud]).show.ssh_keys(id: ssh_key_id).show.raw, 'ssh_key')
71
+ end
72
+
73
+ desc 'create', 'Creates an SSH key in a cloud.'
74
+ def create(name)
75
+ # todo
76
+ end
77
+
78
+ desc 'destroy', 'Deletes an SSH key in a cloud.'
79
+ def destroy(server)
80
+ # todo
81
+ end
82
+
83
+ def self.banner(task, namespace = true, subcommand = false)
84
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
85
+ end
86
+ end
87
+ end