rightscale-cli 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9f392d4242167db76694675551a365d026cb066
4
- data.tar.gz: 651df9b631bfbc4c5c75bb2f7839e9cff6075dfc
3
+ metadata.gz: 9731067ddae5d72c5f362abb7e0b35b51a549978
4
+ data.tar.gz: 9fc0433996190ff469911813204e89ecdadfb792
5
5
  SHA512:
6
- metadata.gz: 1f12aa5f64660219a8bebec31319d9a18fe78f0ee6ed9b831c09c25f9ba3c57bd21ddc23b3e4b11d87b044a907c49229c11da294f7ddad59d29a1f61a9045499
7
- data.tar.gz: 5d1e9b6f60a8442794c0b2875c35e2a824dbdd2eab51c5042e2c0e2e25416c58e6988c2f48d442ac393d09f5c6933017d83228950072dac96c798213778779b5
6
+ metadata.gz: 598196162d973d27e094c94c19d71a703970e4bc48c3bdb1853cc19c198650f5ef218ca183679e63875c73761b525dc62801a82e028b33d5d0e6cb6a08f5df52
7
+ data.tar.gz: bb671f3665f19f82302535a930c6358386a5b1d2b4d438ce9d1b4e4cd0da6ffc8103a9fa7ef0495686cad6261f409f125c28a76e70107ad4083a5d9933982ceb
data/README.md CHANGED
@@ -1,4 +1,41 @@
1
- rightscale-cli
2
- ==============
1
+ # RightScale CLI
2
+
3
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/rightscale-cli.png)](http://badge.fury.io/rb/rightscale-cli)
3
4
 
4
5
  RightScale CLI client. Currently in early development stages.
6
+
7
+ ## Installation
8
+
9
+ Ruby >= 1.9.1 is required.
10
+
11
+ Install the latest RubyGem from RubyGems.org:
12
+
13
+ gem install rightscale-cli
14
+
15
+ For more information, see https://rubygems.org/gems/rightscale-cli.
16
+
17
+ ### Mac OS X, FreeBSD
18
+
19
+ The executable, `rs` will conflict with RS(1) on Mac OS X (http://www.freebsd.org/cgi/man.cgi?query=rs&sektion=1&apropos=0&manpath=freebsd).
20
+
21
+ As a result, to avoid overwriting the `/usr/bin/rs` binary, use a different location in your `~/.gemrc` or `/etc/gemrc`, for example:
22
+
23
+ gem: --bindir /usr/local/bin
24
+
25
+ ## License and Authors
26
+
27
+ * Author:: Chris Fordham <chris [at] fordham [hyphon] nagy [dot] id [dot] au>
28
+
29
+ * Copyright:: 2013, Chris Fordham
30
+
31
+ Licensed under the Apache License, Version 2.0 (the "License");
32
+ you may not use this file except in compliance with the License.
33
+ You may obtain a copy of the License at
34
+
35
+ http://www.apache.org/licenses/LICENSE-2.0
36
+
37
+ Unless required by applicable law or agreed to in writing, software
38
+ distributed under the License is distributed on an "AS IS" BASIS,
39
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40
+ See the License for the specific language governing permissions and
41
+ limitations under the License.
@@ -0,0 +1,62 @@
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 "net/https"
20
+ require "uri"
21
+ require 'rightscale_cli/logger'
22
+ require 'rightscale_cli/client'
23
+
24
+ class RightScaleCLI
25
+ class Dashboard < Thor
26
+ namespace :dashboard
27
+
28
+ desc "overview", "RightScale Dashboard Overview."
29
+ def overview()
30
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
31
+
32
+ uri = URI.parse("#{rightscale.api_url}/acct/#{rightscale.account_id}/dashboard;overview")
33
+ http = Net::HTTP.new(uri.host, uri.port)
34
+ http.use_ssl = true
35
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
36
+ request = Net::HTTP::Get.new(uri.request_uri)
37
+ request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
38
+
39
+ response = http.request(request)
40
+ puts response.body
41
+ end
42
+
43
+ desc "scrape", "Scrape a dashboard URL by href"
44
+ def scrape(href)
45
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
46
+
47
+ uri = URI.parse("#{rightscale.api_url}#{href}")
48
+ http = Net::HTTP.new(uri.host, uri.port)
49
+ http.use_ssl = true
50
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
51
+ request = Net::HTTP::Get.new(uri.request_uri)
52
+ request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
53
+
54
+ response = http.request(request)
55
+ puts response.body
56
+ end
57
+
58
+ def self.banner(task, namespace = true, subcommand = false)
59
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,32 @@
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
+ class RightScaleCLI
18
+ class Output
19
+ 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)
23
+ elsif options[:json]
24
+ require 'json'
25
+ puts JSON.pretty_generate(content)
26
+ else
27
+ require 'yaml'
28
+ puts content.to_yaml
29
+ end
30
+ end
31
+ end
32
+ end
@@ -15,10 +15,13 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
+ require 'rightscale_cli/output'
18
19
  require 'rightscale_cli/clouds'
20
+ require 'rightscale_cli/dashboard'
19
21
  require 'rightscale_cli/deployments'
20
22
  require 'rightscale_cli/servers'
21
23
  require 'rightscale_cli/server_arrays'
24
+ require 'rightscale_cli/server_templates'
22
25
 
23
26
  # http://stackoverflow.com/questions/5663519/namespacing-thor-commands-in-a-standalone-ruby-executable
24
27
 
@@ -31,8 +34,10 @@ class RightScaleCLI
31
34
  class_option :dry, :type => :boolean, :default => false, :desc => 'Dry-run only.'
32
35
 
33
36
  register(Clouds, 'clouds', 'clouds <command>', 'Query clouds.')
37
+ register(Dashboard, 'dashboard', 'dashboard <command>', 'RightScale Dashboard (HTTP hax).')
34
38
  register(ServerArrays, 'arrays', 'arrays <command>', 'Manage server arrays.')
35
39
  register(Deployments, 'deployments', 'deployments <command>', 'Manage deployments.')
36
40
  register(Servers, 'servers', 'servers <command>', 'Manage servers.')
41
+ register(ServerTemplates, 'server_templates', 'server-templates <command>', 'Manage ServerTemplates.')
37
42
  end
38
43
  end
@@ -14,23 +14,53 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ require 'rightscale_cli/logger'
18
+ require 'rightscale_cli/output'
19
+
17
20
  class RightScaleCLI
18
21
  class ServerArrays < Thor
19
22
 
20
- desc "instances", "Shows a server array's current instances."
23
+ desc "instances", "Shows a server array's current instances, optionally with filters.", :type => :string, :required => false
24
+ option :datacenter, :desc => 'The href of the datacenter to filter on', :type => :string, :required => false
25
+ option :deployment, :desc => 'The href of the deployment to filter on.', :type => :string, :required => false
26
+ option :name, :desc => 'Name of the Instance to filter on.', :type => :string, :required => false
27
+ option :os, :desc => 'The OS platform to filter on.', :type => :string, :required => false
28
+ option :parent, :desc => 'The href of the parent to filter on.', :type => :string, :required => false
29
+ option :private_dns => 'The private dns name to filter on.', :type => :string, :required => false
30
+ option :private_ip, :desc => 'The private ip address to filter on.', :type => :string, :required => false
31
+ option :public_dns, :desc => 'The public dns name to filter on.', :type => :string, :required => false
32
+ option :public_ip, :desc => 'The public ip address to filter on.', :type => :string, :required => false
33
+ option :resource_uid, :desc => 'Resource Unique IDentifier for the Instance to filter on.', :type => :string, :required => false
34
+ option :server_template, :desc => 'The href of the ServerTemplate to filter on.', :type => :string, :required => false
35
+ option :state, :desc => 'The state of Instances to filter on.', :type => :string, :required => false
21
36
 
22
37
  def instances(server_array_id)
38
+ log = CLILogger.new
23
39
  rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
24
40
 
25
- array_instances = rightscale.server_arrays(:id => server_array_id).show.current_instances.index
41
+ array_instances = []
42
+ filter = []
43
+
44
+ filter.push("datacenter_href==#{options[:datacenter]}") if options[:datacenter]
45
+ filter.push("deployment_href==#{options[:deployment]}") if options[:deployment]
46
+ filter.push("name==#{options[:private_ip]}") if options[:name]
47
+ filter.push("os_platform==#{options[:os]}") if options[:os]
48
+ filter.push("parent_href==#{options[:parent]}") if options[:parent]
49
+ filter.push("private_dns_name==#{options[:private_dns]}") if options[:private_dns]
50
+ filter.push("private_ip_address==#{options[:private_ip]}") if options[:private_ip]
51
+ filter.push("public_dns==#{options[:public_dns]}") if options[:public_dns]
52
+ filter.push("public_ip_address==#{options[:public_ip]}") if options[:public_ip]
53
+ filter.push("resource_uid==#{options[:resource_uid]}") if options[:resource_uid]
54
+ filter.push("server_template_href==#{options[:server_template]}") if options[:server_template]
55
+ filter.push("state==#{options[:state]}") if options[:state]
56
+
57
+ log.info "filter: #{filter}" if options[:debug]
58
+
59
+ rightscale.server_arrays(:id => server_array_id).show.current_instances(:filter => filter).index.each { |array_instance|
60
+ array_instances.push(array_instance.raw)
61
+ }
26
62
 
27
- if options[:xml]
28
- puts current_instances.to_xml(:root => 'array_instances')
29
- elsif options[:json]
30
- puts JSON.pretty_generate(array_instances)
31
- else
32
- puts array_instances.to_yaml
33
- end
63
+ RightScaleCLI::Output.render(array_instances, 'array_instances', options)
34
64
  end
35
65
  end
36
- end
66
+ end
@@ -0,0 +1,119 @@
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 'json'
20
+ require "active_support/core_ext"
21
+ require 'rightscale_cli/logger'
22
+ require 'rightscale_cli/client'
23
+
24
+ class RightScaleCLI
25
+ class ServerTemplates < Thor
26
+ namespace :server_templates
27
+
28
+ # include render options
29
+ eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
30
+
31
+ desc "list", "Lists ServerTemplates."
32
+ def list()
33
+ log = CLILogger.new
34
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
35
+ server_templates = []
36
+ rightscale.server_templates.index.each { |server_template|
37
+ server_templates.push(server_template.raw)
38
+ }
39
+
40
+ if options[:xml]
41
+ puts server_templates.to_xml(:root => 'server_templates')
42
+ elsif options[:json]
43
+ puts JSON.pretty_generate(server_templates)
44
+ else
45
+ puts server_templates.to_yaml
46
+ end
47
+ end
48
+
49
+ desc "show", "Shows a ServerTemplate."
50
+ def show(server_template_id)
51
+ log = CLILogger.new
52
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
53
+
54
+ server_template = rightscale.server_templates(:id => server_template_id).show.raw
55
+
56
+ if options[:xml]
57
+ puts server_template.to_xml(:root => 'server_template')
58
+ elsif options[:json]
59
+ puts JSON.pretty_generate(server_template)
60
+ else
61
+ puts server_template.to_yaml
62
+ end
63
+ end
64
+
65
+ desc "inputs", "Shows a ServerTemplate's inputs."
66
+ def inputs(server_template_id)
67
+ log = CLILogger.new
68
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
69
+
70
+ server_template_inputs = []
71
+ rightscale.server_templates(:id => server_template_id).show.inputs.index.each { |input| server_template_inputs.push(input.raw) }
72
+
73
+ if options[:xml]
74
+ puts server_template_inputs.to_xml(:root => 'server_template')
75
+ elsif options[:json]
76
+ puts JSON.pretty_generate(server_template_inputs)
77
+ else
78
+ puts server_template_inputs.to_yaml
79
+ end
80
+ end
81
+
82
+ desc "inputs_dashboard", "Inputs scraped from dashboard."
83
+ def inputs_dashboard(server_template_id)
84
+ rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
85
+ uri = URI.parse("#{rightscale.api_url}/acct/#{rightscale.account_id}/inputs/edit_inputs?container_id=#{server_template_id}&container_type=ServerTemplate")
86
+ http = Net::HTTP.new(uri.host, uri.port)
87
+ http.use_ssl = true
88
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
89
+ request = Net::HTTP::Get.new(uri.request_uri)
90
+ request.add_field("Referer", "#{rightscale.api_url}/acct/#{rightscale.account_id}/server_templates/#{server_template_id}")
91
+ request.add_field("X-Requested-With", "XMLHttpRequest")
92
+ request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
93
+ response = http.request(request)
94
+ puts response.body if options[:debug]
95
+
96
+ require 'nokogiri'
97
+ inputs = []
98
+ html = Nokogiri::HTML(response.body)
99
+ input_list = html.css('ul[class=inputList]').css('li[class=inputContainer]').css('div[class=inputInformation]').each { |input_html|
100
+ input = {}
101
+ input['name'] = input_html.css('div')[0].text.gsub!(/\s+/, "")
102
+ input['possible_values'] = []
103
+ input_html.css('div[class=inputValue]').css('select[class=possible_values] option').each { |option|
104
+ input['current'] = option['value'] if option['selected'] == 'selected'
105
+ input['possible_values'].push(option['value'])
106
+ }
107
+ inputs.push(input)
108
+ }
109
+
110
+ if options[:xml]
111
+ puts inputs.to_xml(:root => 'inputs')
112
+ elsif options[:json]
113
+ puts JSON.pretty_generate(inputs)
114
+ else
115
+ puts inputs.to_yaml
116
+ end
117
+ end
118
+ end
119
+ end
@@ -18,4 +18,4 @@ require 'rightscale_cli/version'
18
18
  require 'rightscale_cli/config'
19
19
  require 'rightscale_cli/monkey_patches/client_attributes'
20
20
  require 'rightscale_cli/logger'
21
- require 'rightscale_cli/rightscale_cli'
21
+ require 'rightscale_cli/rightscale_cli'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rightscale-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Fordham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-15 00:00:00.000000000 Z
11
+ date: 2013-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nokogiri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: RightScale command line interface client.
84
98
  email: chris@fordham-nagy.id.au
85
99
  executables:
@@ -92,11 +106,14 @@ files:
92
106
  - lib/rightscale_cli/servers.rb
93
107
  - lib/rightscale_cli/rightscale_cli.rb
94
108
  - lib/rightscale_cli/monkey_patches/client_attributes.rb
109
+ - lib/rightscale_cli/output.rb
95
110
  - lib/rightscale_cli/client.rb
96
111
  - lib/rightscale_cli/version.rb
112
+ - lib/rightscale_cli/server_templates.rb
97
113
  - lib/rightscale_cli/clouds.rb
98
114
  - lib/rightscale_cli/deployments.rb
99
115
  - lib/rightscale_cli/config.rb
116
+ - lib/rightscale_cli/dashboard.rb
100
117
  - lib/rightscale_cli/server_arrays.rb
101
118
  - lib/rightscale_cli/render_options.rb
102
119
  - lib/rightscale_cli/server_arrays/current_instances.rb