rightscale-cli 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d2ce2baf29c81d2b85a867713659c964d26f890
4
- data.tar.gz: 35ae05487225b689a25e6c8b709e487ce02504b7
3
+ metadata.gz: 30b894476ef574eb618ff58fc7d74788f92b5366
4
+ data.tar.gz: e08b213e26d2701562fc84741b66b0807f50962e
5
5
  SHA512:
6
- metadata.gz: 7ee7e7330c4a4b1aa5be4cf4a11d56156398462b8e14cdfdb0eb7e0bc4935d451a27c73d89a342efbf3c7824bc80a7aeaa5272b7cae602f3b8371fe1baf6c39e
7
- data.tar.gz: d706e6fc89434481e328bbcd6cfec740abc74b001e16c415871d2997fe59bb2ad96f075fb2d8134d2bdeb4ec9e906f3368e8d43582f0ed8c8329c41612818365
6
+ metadata.gz: 9b71a5e57925a199e4b25645af5da46721340ea0af3f53ada9cf0ac42cb5f08a61f1a7562e05fd06459f66b429f08b78309052a71844320fb14516f109eba466
7
+ data.tar.gz: da846a1d796168e57f5f4d21d10de8d45b3f05d79746150445448a39aeb13b47810c980dbfe1e9fecc0e57aa803446934281b11b0a354622b3ec094f86de9da6
data/README.md CHANGED
@@ -10,7 +10,7 @@ Ruby >= 1.9.1 is required.
10
10
 
11
11
  Install the latest RubyGem from RubyGems.org:
12
12
 
13
- gem install rightscale-cli
13
+ $ gem install rightscale-cli
14
14
 
15
15
  For more information, see https://rubygems.org/gems/rightscale-cli.
16
16
 
@@ -24,9 +24,12 @@ As a result, to avoid overwriting the `/usr/bin/rs` binary, use a different loca
24
24
 
25
25
  ## Configuration
26
26
 
27
- Setup `~/.rightscale/right_api_client.yml` with your RightScale credentials.
28
- Ensure the correct shard for your account is set with `:api_url`.
27
+ This can easily be done interactively with the tool once installed:
28
+
29
+ $ rs configure all
29
30
 
31
+ Or, manually setup `~/.rightscale/right_api_client.yml` with your RightScale credentials.
32
+ Ensure the correct shard for your account is set with `:api_url`.
30
33
  An example file is available, https://github.com/rightscale/right_api_client/blob/master/config/login.yml.example.
31
34
 
32
35
  ## Usage
data/lib/ask_pass.rb ADDED
@@ -0,0 +1,23 @@
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
+ def ask_pass
18
+ require 'io/console'
19
+ print 'Password: '
20
+ password = STDIN.noecho(&:gets).strip
21
+ puts
22
+ return password
23
+ end
@@ -17,6 +17,7 @@
17
17
  require 'right_api_client'
18
18
  require 'rightscale_cli/config'
19
19
  require 'rightscale_cli/logger'
20
+ require 'ask_pass'
20
21
 
21
22
  class RightScaleCLI
22
23
  class Client
@@ -24,10 +25,16 @@ class RightScaleCLI
24
25
  attr_accessor :render
25
26
 
26
27
  def initialize(options)
27
- config = RightScaleCLI::Config::API
28
+ config = RightScaleCLI::Config.new.local
28
29
  config[:account_id] = options['account'] if options[:account]
30
+ config[:email] = options['user'] if options[:user]
29
31
  config[:api_version] = options['api'] if options[:api]
30
32
 
33
+ if options['password'] || (!config[:password] && !config[:password_base64])
34
+ config[:password] = ask_pass
35
+ config[:password_base64] = nil # set this to nil so it is not used by precedence
36
+ end
37
+
31
38
  @options = options
32
39
  @client = RightApi::Client.new(config)
33
40
  @logger = RightScaleCLI::Logger.new()
@@ -15,32 +15,30 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'yaml'
19
- require 'json'
20
- require "active_support/core_ext"
18
+ require 'rightscale_cli/client'
19
+ require 'rightscale_cli/logger'
21
20
 
22
21
  class RightScaleCLI
23
22
  class Clouds < Thor
24
23
  namespace :clouds
25
24
 
26
- desc "list", "Lists all clouds."
27
- def list()
28
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
29
- clouds = []
25
+ def initialize(*args)
26
+ super
27
+ @client = RightScaleCLI::Client.new(options)
28
+ @logger = RightScaleCLI::Logger.new()
29
+ end
30
30
 
31
- $log.info "Retrieving all clouds from #{rightscale.account_id}."
31
+ # include render options
32
+ eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
32
33
 
33
- rightscale.clouds.index.each { |cloud|
34
- clouds.push(cloud.raw)
35
- }
36
- puts clouds.to_yaml
34
+ desc "list", "Lists all clouds."
35
+ def list()
36
+ @client.render(@client.get('clouds'), 'clouds')
37
37
  end
38
38
 
39
39
  desc "show", "Shows a cloud."
40
40
  def show(cloud_id)
41
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
42
- cloud = rightscale.clouds(:id => cloud_id).show.raw
43
- puts cloud.to_yaml
41
+ @client.render(@client.show('clouds', cloud_id), 'cloud')
44
42
  end
45
43
 
46
44
  desc "search", "Searches for clouds by cloud type, name, description."
@@ -48,22 +46,21 @@ class RightScaleCLI
48
46
  option :cloud_type, :type => :string, :required => false
49
47
  option :description, :type => :string, :required => false
50
48
  def search()
51
-
52
49
  filter = []
53
50
  filter.push("name==#{options[:name]}") if options[:name]
54
51
  filter.push("cloud_type==#{options[:cloud_type]}") if options[:cloud_type]
55
52
  filter.push("description==#{options[:cloud]}") if options[:description]
56
53
 
57
- $log.info "Searching for clouds!"
54
+ @logger.info "Searching for clouds!"
58
55
 
59
56
  puts "filter: #{filter}" if options[:debug]
60
57
 
61
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
62
58
  clouds = []
63
- rightscale.clouds.index(:filter => filter).each { |cloud|
59
+ @client.client.clouds.index(:filter => filter).each { |cloud|
64
60
  clouds.push(cloud.raw)
65
61
  }
66
- puts clouds.to_yaml
62
+
63
+ @client.render(clouds, 'clouds')
67
64
  end
68
65
 
69
66
  def self.banner(task, namespace = true, subcommand = false)
@@ -18,6 +18,11 @@ require 'yaml'
18
18
 
19
19
  class RightScaleCLI
20
20
  class Config
21
- API = YAML.load_file(File.join(ENV['HOME'], '.rightscale', 'right_api_client.yml'))
21
+ attr_accessor :local, :path
22
+
23
+ def initialize(*args)
24
+ @path = File.join(ENV['HOME'], '.rightscale', 'right_api_client.yml')
25
+ @local = YAML.load_file(@path)
26
+ end
22
27
  end
23
28
  end
@@ -0,0 +1,101 @@
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/config'
20
+ require 'rightscale_cli/logger'
21
+ require 'rightscale_cli/client'
22
+ require 'ask_pass'
23
+ require 'erb'
24
+ require "base64"
25
+
26
+ class RightScaleCLI
27
+ class Configure < Thor
28
+ namespace :configure
29
+
30
+ def initialize(*args)
31
+ super
32
+ @logger = RightScaleCLI::Logger.new()
33
+ @template_path = File.join(File.dirname(__FILE__), '..', 'templates', '/right_api_client.yml.erb')
34
+ @config = RightScaleCLI::Config.new
35
+ @directives = {}
36
+ end
37
+
38
+ no_commands{
39
+ def update_conf(directives)
40
+ renderer = ERB.new(IO.read(@template_path))
41
+ File.open(@config.path, 'w') {|f| f.write(renderer.result(binding)) }
42
+ end
43
+ }
44
+
45
+ desc "account", "Configure the RightScale account ID for the client."
46
+ def account()
47
+ update_conf(@config.local.merge({:account_id => ask("RightScale account ID (e.g. 1337):")}))
48
+ end
49
+
50
+ desc "user", "Configure the RightScale user for the client."
51
+ def user()
52
+ update_conf(@config.local.merge({:email => ask("RightScale username (e.g. bill.gates@microsoft.com):")}))
53
+ end
54
+
55
+ desc "password", "Configure the RightScale user password for the client."
56
+ def password()
57
+ update_conf(@config.local.merge({:password_base64 => Base64.encode64(ask_pass).strip}))
58
+ end
59
+
60
+ desc "api", "Configure the RightScale API version used by the client."
61
+ def api()
62
+ update_conf(@config.local.merge({:api_version => ask("RightScale API version (e.g. 1.5):")}))
63
+ end
64
+
65
+ desc "shard", "Configure the RightScale shard used by the client."
66
+ def shard()
67
+ update_conf(@config.local.merge({:api_url => "https://#{ask("RightScale shard (e.g. us-4.rightscale.com):")}"}))
68
+ end
69
+
70
+ desc "show", "Print the current configuration from ~/.rightscale/right_api_client.yml."
71
+ def show()
72
+ puts @config.local
73
+ end
74
+
75
+ desc "all", "Configure RightScale CLI."
76
+ def all()
77
+ #directives = {
78
+ # :account_id => account(),
79
+ # :email => user(),
80
+ # :password_base64 => Base64.encode64(ask_pass).strip,
81
+ # :api_url => shard(),
82
+ # :api_version => api()
83
+ #}
84
+ #@logger.debug(directives)
85
+
86
+ # currently this is the lazy way, each is written sequentially
87
+ account()
88
+ user()
89
+ password()
90
+ shard()
91
+ api()
92
+ puts 'Configuration saved.'
93
+ end
94
+
95
+ #default_task :all
96
+
97
+ def self.banner(task, namespace = true, subcommand = false)
98
+ "#{basename} #{task.formatted_usage(self, true, subcommand)}"
99
+ end
100
+ end
101
+ end
@@ -15,7 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'yaml'
19
18
  require "net/https"
20
19
  require "uri"
21
20
  require 'rightscale_cli/logger'
@@ -24,17 +23,21 @@ require 'rightscale_cli/client'
24
23
  class RightScaleCLI
25
24
  class Dashboard < Thor
26
25
  namespace :dashboard
27
-
26
+
27
+ def initialize(*args)
28
+ super
29
+ @client = RightScaleCLI::Client.new(options)
30
+ @logger = RightScaleCLI::Logger.new()
31
+ end
32
+
28
33
  desc "overview", "RightScale Dashboard Overview."
29
34
  def overview()
30
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
31
-
32
- uri = URI.parse("#{rightscale.api_url}/acct/#{rightscale.account_id}/dashboard;overview")
35
+ uri = URI.parse("#{@client.client.api_url}/acct/#{@client.client.account_id}/dashboard;overview")
33
36
  http = Net::HTTP.new(uri.host, uri.port)
34
37
  http.use_ssl = true
35
38
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
36
39
  request = Net::HTTP::Get.new(uri.request_uri)
37
- request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
40
+ request.add_field("Cookie", @client.client.last_request[:request].headers[:cookie])
38
41
 
39
42
  response = http.request(request)
40
43
  puts response.body
@@ -42,14 +45,12 @@ class RightScaleCLI
42
45
 
43
46
  desc "scrape", "Scrape a dashboard URL by href."
44
47
  def scrape(href)
45
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
46
-
47
- uri = URI.parse("#{rightscale.api_url}#{href}")
48
+ uri = URI.parse("#{@client.client.api_url}#{href}")
48
49
  http = Net::HTTP.new(uri.host, uri.port)
49
50
  http.use_ssl = true
50
51
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
51
52
  request = Net::HTTP::Get.new(uri.request_uri)
52
- request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
53
+ request.add_field("Cookie", @client.client.last_request[:request].headers[:cookie])
53
54
 
54
55
  response = http.request(request)
55
56
  puts response.body
@@ -57,14 +58,12 @@ class RightScaleCLI
57
58
 
58
59
  desc "ajax", "Scrape a dashboard URL via AJAX."
59
60
  def ajax(href)
60
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
61
-
62
- uri = URI.parse("#{rightscale.api_url}#{href}")
61
+ uri = URI.parse("#{@client.client.api_url}#{href}")
63
62
  http = Net::HTTP.new(uri.host, uri.port)
64
63
  http.use_ssl = true
65
64
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
66
65
  request = Net::HTTP::Get.new(uri.request_uri)
67
- request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
66
+ request.add_field("Cookie", @client.client.last_request[:request].headers[:cookie])
68
67
  request.add_field("X-Requested-With", "XMLHttpRequest")
69
68
 
70
69
  response = http.request(request)
@@ -16,8 +16,9 @@
16
16
 
17
17
  require 'thor'
18
18
  require 'yaml'
19
- require 'right_api_client'
20
-
19
+ require 'rightscale_cli/client'
20
+ require 'rightscale_cli/logger'
21
+
21
22
  class RightScaleCLI
22
23
  class Deployments < Thor
23
24
  namespace :deployments
@@ -52,6 +53,18 @@ class RightScaleCLI
52
53
  @client.render(@client.show('deployments', deployment, 'servers'), 'servers')
53
54
  end
54
55
 
56
+ desc "terminate", "Terminates all servers in a deployment."
57
+ def terminate(deployment)
58
+ @client.show('deployments', deployment, 'servers').each { |server|
59
+ unless server['state'] == 'inactive'
60
+ current_instance = server['links'].select { |link| link['rel'] == 'current_instance' }.first['href']
61
+ cloud = current_instance.split('/')[3]
62
+ instance_id = current_instance.split('/').last
63
+ @client.client.clouds(:id => cloud).show.instances(:id => instance_id).terminate
64
+ end
65
+ }
66
+ end
67
+
55
68
  def self.banner(task, namespace = true, subcommand = false)
56
69
  "#{basename} #{task.formatted_usage(self, true, subcommand)}"
57
70
  end
@@ -15,8 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'yaml'
19
- require 'right_api_client'
18
+ require 'rightscale_cli/client'
20
19
  require 'rightscale_cli/logger'
21
20
 
22
21
  class RightScaleCLI
@@ -54,12 +53,9 @@ class RightScaleCLI
54
53
  filter.push("server_template_href==#{options[:server_template]}") if options[:server_template]
55
54
  filter.push("state==#{options[:state]}") if options[:state]
56
55
 
57
- $log.debug "filter: #{filter}" if options[:debug]
56
+ @logger.debug "filter: #{filter}" if options[:debug]
58
57
 
59
- RightApi::Client.new(RightScaleCLI::Config::API).clouds(:id => options[:cloud]).show.instances(:filter => filter).index.each { |instance|
60
- instances.push(instance.raw)
61
- }
62
- puts instances.to_yaml
58
+ @client.render(@client.clent.clouds(:id => options[:cloud]).show.instances(:filter => filter).index)
63
59
  end
64
60
 
65
61
  desc "run-exec", "Runs a chef recipe or rightscript on instances of a given cloud."
@@ -100,12 +96,10 @@ class RightScaleCLI
100
96
  filter.push("state==#{options[:state]}") if options[:state]
101
97
 
102
98
  params['filter'] = filter
103
- $log.debug "filter: #{filter}" if options[:debug]
104
- $log.debug "params: #{params}" if options[:debug]
99
+ @logger.debug "filter: #{filter}" if options[:debug]
100
+ @logger.debug "params: #{params}" if options[:debug]
105
101
 
106
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
107
-
108
- rightscale.clouds(:id => options[:cloud]).show.instances.multi_run_executable(params)
102
+ @client.client.clouds(:id => options[:cloud]).show.instances.multi_run_executable(params)
109
103
  end
110
104
 
111
105
  def self.banner(task, namespace = true, subcommand = false)
@@ -16,7 +16,6 @@
16
16
 
17
17
  require 'thor'
18
18
  require 'yaml'
19
- require 'right_api_client'
20
19
  require 'rightscale_cli/client'
21
20
  require 'rightscale_cli/logger'
22
21
 
@@ -15,17 +15,22 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'right_api_client'
18
+ require 'rightscale_cli/client'
19
+ require 'rightscale_cli/logger'
19
20
 
20
21
  class RightScaleCLI
21
22
  class Repositories < Thor
22
23
  namespace :repositories
23
24
 
25
+ def initialize(*args)
26
+ super
27
+ @client = RightScaleCLI::Client.new(options)
28
+ @logger = RightScaleCLI::Logger.new()
29
+ end
30
+
24
31
  desc "list", "Lists all (Chef) Repositories."
25
32
  def list()
26
- repositories = []
27
- RightApi::Client.new(RightScaleCLI::Config::API).repositories.index.each { |repos| repositories.push(repos.raw) }
28
- RightScaleCLI::Output.render(repositories, 'repositories', options)
33
+ @client.render(@client.get('repositories'), 'repositories')
29
34
  end
30
35
 
31
36
  desc "create", "Creates a (Chef) Repository."
@@ -48,12 +53,12 @@ class RightScaleCLI
48
53
  puts repository if options[:verbose]
49
54
 
50
55
  $log.info "Creating RightScale repository, '#{repository['name']}'."
51
- repo = RightApi::Client.new(RightScaleCLI::Config::API).repositories.create({ :repository => repository })
56
+ @client.client.repositories.create({ :repository => repository })
52
57
  end
53
58
 
54
59
  desc "destroy", "Deletes a (Chef) Repository."
55
60
  def destroy(id)
56
- RightApi::Client.new(RightScaleCLI::Config::API).repositories.index(:id => id).destroy
61
+ @client.client.repositories.index(:id => id).destroy
57
62
  end
58
63
 
59
64
  def self.banner(task, namespace = true, subcommand = false)
@@ -17,6 +17,7 @@
17
17
  require 'thor'
18
18
  require 'rightscale_cli/config'
19
19
  require 'rightscale_cli/logger'
20
+ require 'rightscale_cli/configure'
20
21
  require 'rightscale_cli/clouds'
21
22
  require 'rightscale_cli/dashboard'
22
23
  require 'rightscale_cli/deployments'
@@ -37,13 +38,25 @@ class RightScaleCLI
37
38
  :type => :string,
38
39
  :aliases => '-a',
39
40
  :required => false,
40
- :desc => 'The RightScale account ID.'
41
+ :desc => 'RightScale account ID.'
42
+
43
+ class_option :user,
44
+ :type => :string,
45
+ :aliases => '-u',
46
+ :required => false,
47
+ :desc => 'RightScale user.'
48
+
49
+ class_option :password,
50
+ :type => :boolean,
51
+ :aliases => '-p',
52
+ :required => false,
53
+ :desc => 'RightScale user password.'
41
54
 
42
55
  class_option :api,
43
56
  :type => :string,
44
57
  :aliases => '-A',
45
58
  :required => false,
46
- :desc => 'The RightScale API version.'
59
+ :desc => 'RightScale API version.'
47
60
 
48
61
  class_option :debug,
49
62
  :type => :boolean,
@@ -74,6 +87,7 @@ class RightScaleCLI
74
87
  :default => false,
75
88
  :desc => 'Dry-run only.'
76
89
 
90
+ register(Configure, 'configure', 'configure <command>', 'Configure the RightScale credentials used by the client.')
77
91
  register(Clouds, 'clouds', 'clouds <command>', 'Query clouds.')
78
92
  register(Dashboard, 'dashboard', 'dashboard <command>', 'RightScale Dashboard (HTTP hax).')
79
93
  register(ServerArrays, 'arrays', 'arrays <command>', 'Manage server arrays.')
@@ -15,9 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'yaml'
19
- require 'json'
20
- require "active_support/core_ext"
21
18
  require 'rightscale_cli/logger'
22
19
  require 'rightscale_cli/client'
23
20
  require 'rightscale_cli/server_arrays/alerts'
@@ -45,27 +42,19 @@ class RightScaleCLI
45
42
  option :deployment, :type => :string, :required => false
46
43
  option :name, :type => :string, :required => false
47
44
  def list()
48
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
49
-
50
45
  filter = []
51
46
  filter.push("cloud_href==/api/clouds/#{options[:cloud]}") if options[:cloud]
52
47
  filter.push("deployment_href==/api/deployments/#{options[:cloud]}") if options[:deployment]
53
48
  filter.push("name==#{options[:name]}") if options[:name]
54
49
 
55
- $log.debug "filter: #{filter}" if options[:debug]
50
+ @logger.debug "filter: #{filter}" if options[:debug]
56
51
 
57
52
  server_arrays = []
58
- rightscale.server_arrays.index(:filter => filter).each { |server_array|
53
+ @client.client.server_arrays.index(:filter => filter).each { |server_array|
59
54
  server_arrays.push(server_array.raw)
60
55
  }
61
56
 
62
- if options[:xml]
63
- puts server_arrays.to_xml(:root => 'server_arrays')
64
- elsif options[:json]
65
- puts JSON.pretty_generate(server_arrays)
66
- else
67
- puts server_arrays.to_yaml
68
- end
57
+ @client.render(server_arrays, 'server_arrays')
69
58
  end
70
59
 
71
60
  desc "show", "Shows a particular server array."
@@ -75,38 +64,32 @@ class RightScaleCLI
75
64
 
76
65
  desc "state", "Shows the state of a server array."
77
66
  def state(server_array_id)
78
- $log.info "Retrieving state for server array, #{server_array_id}."
79
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
80
- puts rightscale.server_arrays(:id => server_array_id).show.state
67
+ @logger.info "Retrieving state for server array, #{server_array_id}."
68
+ puts @client.client.server_arrays(:id => server_array_id).show.state
81
69
  end
82
70
 
83
71
  desc "instances_count", "Shows the instances count of a server array."
84
72
  def instances_count(server_array_id)
85
- $log.info "Retrieving instances count for server array, #{server_array_id}."
86
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
87
- puts rightscale.server_arrays(:id => server_array_id).show.instances_count
73
+ @logger.info "Retrieving instances count for server array, #{server_array_id}."
74
+ puts @client.client.server_arrays(:id => server_array_id).show.instances_count
88
75
  end
89
76
 
90
77
  desc "desc", "Shows the description of a server array."
91
78
  def desc(server_array_id)
92
- $log.info "Retrieving description for server array, #{server_array_id}."
93
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
94
- puts rightscale.server_arrays(:id => server_array_id).show.description
79
+ @logger.info "Retrieving description for server array, #{server_array_id}."
80
+ puts @client.client.server_arrays(:id => server_array_id).show.description
95
81
  end
96
82
 
97
83
  desc "name", "Shows the name of a server array."
98
84
  def name(server_array_id)
99
- $log.info "Retrieving name for server array, #{server_array_id}."
100
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
101
- puts rightscale.server_arrays(:id => server_array_id).show.name
85
+ @logger.info "Retrieving name for server array, #{server_array_id}."
86
+ puts @client.client.server_arrays(:id => server_array_id).show.name
102
87
  end
103
88
 
104
89
  desc "api_methods", "Lists the API methods available to a server array."
105
90
  def api_methods(server_array_id)
106
- $log.info "Retrieving API methods for server array, #{server_array_id}."
107
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
108
- server_array = rightscale.server_arrays(:id => server_array_id).show.api_methods
109
- puts server_array
91
+ @logger.info "Retrieving API methods for server array, #{server_array_id}."
92
+ puts @client.client.server_arrays(:id => server_array_id).show.api_methods
110
93
  end
111
94
 
112
95
  desc "inputs", 'Update the inputs of the server array.'
@@ -20,20 +20,12 @@ class RightScaleCLI
20
20
  desc "alert_specs", "Shows a server array's alert specifications."
21
21
 
22
22
  def alert_specs(server_array_id)
23
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
24
-
25
23
  alert_specs = []
26
- rightscale.server_arrays(:id => server_array_id).show.alert_specs.index.each { |alert_spec|
24
+ @client.client.server_arrays(:id => server_array_id).show.alert_specs.index.each { |alert_spec|
27
25
  alert_specs.push(alert_spec.raw)
28
26
  }
29
27
 
30
- if options[:xml]
31
- puts alert_specs.to_xml(:root => 'alert_specs')
32
- elsif options[:json]
33
- puts JSON.pretty_generate(alert_specs)
34
- else
35
- puts alert_specs.to_yaml
36
- end
28
+ @client.render(alert_specs, 'server_array')
37
29
  end
38
30
  end
39
31
  end
@@ -20,17 +20,7 @@ class RightScaleCLI
20
20
  desc "alerts", "Shows a server array's active alerts."
21
21
 
22
22
  def alerts(server_array_id)
23
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
24
-
25
- array_alerts = rightscale.server_arrays(:id => server_array_id).show.alerts.index
26
-
27
- if options[:xml]
28
- puts array_alerts.to_xml(:root => 'alerts')
29
- elsif options[:json]
30
- puts JSON.pretty_generate(array_alerts)
31
- else
32
- puts array_alerts.to_yaml
33
- end
23
+ @client.render(@client.client.server_arrays(:id => server_array_id).show.alerts.index, 'alert_specs')
34
24
  end
35
25
  end
36
26
  end
@@ -35,11 +35,7 @@ class RightScaleCLI
35
35
  option :state, :desc => 'The state of Instances to filter on.', :type => :string, :required => false
36
36
 
37
37
  def instances(server_array_id)
38
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
39
-
40
- array_instances = []
41
38
  filter = []
42
-
43
39
  filter.push("datacenter_href==#{options[:datacenter]}") if options[:datacenter]
44
40
  filter.push("deployment_href==#{options[:deployment]}") if options[:deployment]
45
41
  filter.push("name==#{options[:private_ip]}") if options[:name]
@@ -53,13 +49,14 @@ class RightScaleCLI
53
49
  filter.push("server_template_href==#{options[:server_template]}") if options[:server_template]
54
50
  filter.push("state==#{options[:state]}") if options[:state]
55
51
 
56
- $log.debug "filter: #{filter}" if options[:debug]
52
+ @logger.debug "filter: #{filter}" if options[:debug]
57
53
 
58
- rightscale.server_arrays(:id => server_array_id).show.current_instances(:filter => filter).index.each { |array_instance|
54
+ array_instances = []
55
+ @client.client.server_arrays(:id => server_array_id).show.current_instances(:filter => filter).index.each { |array_instance|
59
56
  array_instances.push(array_instance.raw)
60
57
  }
61
58
 
62
- RightScaleCLI::Output.render(array_instances, 'array_instances', options)
59
+ @client.render(array_instances, 'array_instances')
63
60
  end
64
61
  end
65
62
  end
@@ -20,9 +20,8 @@ class RightScaleCLI
20
20
  desc "params", "Lists the elasticity parameters for a server array."
21
21
 
22
22
  def params(server_array_id)
23
- $log.info "Retrieving elasticity parameters for server array, #{server_array_id}."
24
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
25
- puts rightscale.server_arrays(:id => server_array_id).show.elasticity_params.to_yaml
23
+ @logger.info "Retrieving elasticity parameters for server array, #{server_array_id}."
24
+ @client.render(@client.client.server_arrays(:id => server_array_id).show.elasticity_params, 'server_array')
26
25
  end
27
26
  end
28
27
  end
@@ -14,17 +14,23 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ require 'rightscale_cli/client'
17
18
  require 'rightscale_cli/logger'
18
19
 
19
20
  class RightScaleCLI
20
21
  class ServerArrays < Thor
21
22
 
23
+ def initialize(*args)
24
+ super
25
+ @client = RightScaleCLI::Client.new(options)
26
+ @logger = RightScaleCLI::Logger.new()
27
+ end
28
+
22
29
  desc "links", "Lists the links for a server array."
23
30
 
24
31
  def links(server_array_id)
25
- $log.info "Retrieving links for server array, #{server_array_id}."
26
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
27
- puts rightscale.server_arrays(:id => server_array_id).show.links.to_yaml
32
+ @logger.info "Retrieving links for server array, #{server_array_id}."
33
+ @client.render(@client.client.server_arrays(:id => server_array_id).show.links, 'links')
28
34
  end
29
35
  end
30
36
  end
@@ -20,8 +20,6 @@ class RightScaleCLI
20
20
  desc "run_exec", "Runs a RightScript or Chef recipe on the array instances."
21
21
 
22
22
  def run_exec(server_array_id, exec_type, exec_identifier)
23
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
24
-
25
23
  params = {}
26
24
 
27
25
  if exec_type == 'recipe'
@@ -30,10 +28,10 @@ class RightScaleCLI
30
28
  params['right_script_href'] = "/api/right_scripts/#{exec_identifier}"
31
29
  end
32
30
 
33
- server_array = rightscale.server_arrays(:id => server_array_id)
31
+ server_array = @client.client.server_arrays(:id => server_array_id)
34
32
 
35
- $log.info "params: #{params}" if options[:debug]
36
- $log.info "Running executable on server array."
33
+ @logger.info "params: #{params}" if options[:debug]
34
+ @logger.info "Running executable on server array."
37
35
 
38
36
  server_array.multi_run_executable(params)
39
37
  end
@@ -25,68 +25,44 @@ class RightScaleCLI
25
25
  class ServerTemplates < Thor
26
26
  namespace :server_templates
27
27
 
28
+ def initialize(*args)
29
+ super
30
+ @client = RightScaleCLI::Client.new(options)
31
+ @logger = RightScaleCLI::Logger.new()
32
+ end
33
+
28
34
  # include render options
29
35
  eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
30
36
 
31
37
  desc "list", "Lists ServerTemplates."
32
38
  def list()
33
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
34
- server_templates = []
35
- rightscale.server_templates.index.each { |server_template|
36
- server_templates.push(server_template.raw)
37
- }
38
-
39
- if options[:xml]
40
- puts server_templates.to_xml(:root => 'server_templates')
41
- elsif options[:json]
42
- puts JSON.pretty_generate(server_templates)
43
- else
44
- puts server_templates.to_yaml
45
- end
39
+ @client.render(@client.get('server_templates'), 'server_templates')
46
40
  end
47
41
 
48
42
  desc "show", "Shows a ServerTemplate."
49
43
  def show(server_template_id)
50
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
51
-
52
- server_template = rightscale.server_templates(:id => server_template_id).show.raw
53
-
54
- if options[:xml]
55
- puts server_template.to_xml(:root => 'server_template')
56
- elsif options[:json]
57
- puts JSON.pretty_generate(server_template)
58
- else
59
- puts server_template.to_yaml
60
- end
44
+ @client.render(@client.show('server_templates', server_template_id), 'server_template')
61
45
  end
62
46
 
63
47
  desc "inputs", "Shows a ServerTemplate's inputs."
64
48
  def inputs(server_template_id)
65
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
66
-
67
- server_template_inputs = []
68
- rightscale.server_templates(:id => server_template_id).show.inputs.index.each { |input| server_template_inputs.push(input.raw) }
69
-
70
- if options[:xml]
71
- puts server_template_inputs.to_xml(:root => 'server_template')
72
- elsif options[:json]
73
- puts JSON.pretty_generate(server_template_inputs)
74
- else
75
- puts server_template_inputs.to_yaml
49
+ server_template_inputs = []
50
+ @client.client.server_templates(:id => server_template_id).show.inputs.index.each do |input|
51
+ server_template_inputs.push(input.raw)
76
52
  end
53
+ @client.render(server_template_inputs, 'inputs')
77
54
  end
78
55
 
79
56
  desc "inputs_dashboard", "Inputs scraped from dashboard."
80
57
  def inputs_dashboard(server_template_id)
81
- rightscale = RightApi::Client.new(RightScaleCLI::Config::API)
82
- uri = URI.parse("#{rightscale.api_url}/acct/#{rightscale.account_id}/inputs/edit_inputs?container_id=#{server_template_id}&container_type=ServerTemplate")
58
+ uri = URI.parse("#{@client.client.api_url}/acct/#{@client.client.account_id}/inputs/edit_inputs?container_id=#{server_template_id}&container_type=ServerTemplate")
83
59
  http = Net::HTTP.new(uri.host, uri.port)
84
60
  http.use_ssl = true
85
61
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
86
62
  request = Net::HTTP::Get.new(uri.request_uri)
87
- request.add_field("Referer", "#{rightscale.api_url}/acct/#{rightscale.account_id}/server_templates/#{server_template_id}")
63
+ request.add_field("Referer", "#{@client.client.api_url}/acct/#{@client.client.account_id}/server_templates/#{server_template_id}")
88
64
  request.add_field("X-Requested-With", "XMLHttpRequest")
89
- request.add_field("Cookie", rightscale.last_request[:request].headers[:cookie])
65
+ request.add_field("Cookie", @client.client.last_request[:request].headers[:cookie])
90
66
  response = http.request(request)
91
67
  puts response.body if options[:debug]
92
68
 
@@ -104,13 +80,7 @@ class RightScaleCLI
104
80
  inputs.push(input)
105
81
  }
106
82
 
107
- if options[:xml]
108
- puts inputs.to_xml(:root => 'inputs')
109
- elsif options[:json]
110
- puts JSON.pretty_generate(inputs)
111
- else
112
- puts inputs.to_yaml
113
- end
83
+ @client.render(inputs, 'inputs')
114
84
  end
115
85
  end
116
86
  end
@@ -34,8 +34,9 @@ class RightScaleCLI
34
34
  eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
35
35
 
36
36
  desc "search", "Search for resources having a list of tags in a specific resource_type."
37
- def search()
38
- # todo
37
+ def search(resource_type, tag)
38
+ #@client.render(@client.client.tags.by_tag({:resource_type => resource_type, :tags => [ tag ]}), 'servers')
39
+ puts @client.client.tags.by_tag({:resource_type => resource_type, :tags => [ tag ]}).count
39
40
  end
40
41
 
41
42
  desc "resource", "Get tags for a list of resource hrefs."
@@ -45,12 +46,12 @@ class RightScaleCLI
45
46
 
46
47
  desc "add", "Adds tag(s) to resource(s)."
47
48
  def add(hrefs, tags)
48
- @client.client.tags.multi_add(:resource_hrefs => [hrefs.split(',')], :tags => [tags.split(',')])
49
+ @client.client.tags.multi_add(:resource_hrefs => hrefs.split(','), :tags => tags.split(','))
49
50
  end
50
51
 
51
52
  desc "delete", "Deletes tags from resource(s)."
52
53
  def delete(hrefs, tags)
53
- @client.client.tags.multi_delete(:resource_hrefs => [hrefs.split(',')], :tags => [tags.split(',')])
54
+ @client.client.tags.multi_delete(:resource_hrefs => hrefs.split(','), :tags => tags.split(','))
54
55
  end
55
56
 
56
57
  def self.banner(task, namespace = true, subcommand = false)
@@ -15,5 +15,5 @@
15
15
  # limitations under the License.
16
16
 
17
17
  class RightScaleCLI
18
- VERSION = '0.4.1'
18
+ VERSION = '0.5.0'
19
19
  end
@@ -15,9 +15,6 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'thor'
18
- require 'yaml'
19
- require 'json'
20
- require "active_support/core_ext"
21
18
  require 'rightscale_cli/logger'
22
19
  require 'rightscale_cli/client'
23
20
 
@@ -25,6 +22,12 @@ class RightScaleCLI
25
22
  class Volumes < Thor
26
23
  namespace :volumes
27
24
 
25
+ def initialize(*args)
26
+ super
27
+ @client = RightScaleCLI::Client.new(options)
28
+ @logger = RightScaleCLI::Logger.new()
29
+ end
30
+
28
31
  # include render options
29
32
  eval(IO.read("#{File.dirname(File.expand_path(__FILE__))}/render_options.rb"), binding)
30
33
 
@@ -35,31 +38,28 @@ class RightScaleCLI
35
38
  option :name, :desc => "The name of the Volume to filter on.", :type => :string, :required => false
36
39
  option :parent, :desc => "The href of the snapshot from which the volume was created.", :type => :string, :required => false
37
40
  option :resource_uid, :desc => "Resource Unique IDentifier for the Volume to filter on.", :type => :string, :required => false
38
-
39
41
  def list()
40
- volumes = []
41
42
  filter = []
42
-
43
43
  filter.push("datacenter_href==/api/clouds/#{options[:cloud]}/datacenters/#{options[:datacenter]}") if options[:datacenter]
44
44
  filter.push("description==#{options[:description]}") if options[:description]
45
45
  filter.push("name==#{options[:name]}") if options[:name]
46
46
  filter.push("parent_volume_snapshot_href==#{options[:parent]}") if options[:parent]
47
47
  filter.push("resource_uid==#{options[:resource_uid]}") if options[:resource_uid]
48
48
 
49
- $log.debug "filter: #{filter}" if options[:debug]
49
+ @logger.debug "filter: #{filter}" if options[:debug]
50
50
 
51
- RightApi::Client.new(RightScaleCLI::Config::API).clouds(:id => options[:cloud]).show.volumes(:filter => filter).index.each { |volume|
51
+ volumes = []
52
+ @client.client.clouds(:id => options[:cloud]).show.volumes(:filter => filter).index.each { |volume|
52
53
  volumes.push(volume.raw)
53
54
  }
54
55
 
55
- RightScaleCLI::Output.render(volumes, 'volumes', options)
56
+ @client.render(volumes, 'volumes')
56
57
  end
57
58
 
58
59
  desc "show", "Shows a volume."
59
60
  option :cloud, :desc => "The cloud to query for volumes in.", :type => :string, :required => true
60
61
  def show(volume_id)
61
- volume = RightApi::Client.new(RightScaleCLI::Config::API).clouds(:id => options[:cloud]).show.volumes(:id => volume_id).show.raw
62
- RightScaleCLI::Output.render(volume, 'volume', options)
62
+ @client.render(@client.client.clouds(:id => options[:cloud]).show.volumes(:id => volume_id).show.raw, 'volume')
63
63
  end
64
64
 
65
65
  def self.banner(task, namespace = true, subcommand = false)
@@ -0,0 +1,35 @@
1
+ # The API login details can be put in a YAML file. This is an example login.yml which
2
+ # will be needed for login_to_client_irb.rb quick login method.
3
+
4
+ # Account ID is a required parameter. You can find your account number by logging into the
5
+ # RightScale dashboard (https://my.rightscale.com), navigate to the Settings > Account Settings page.
6
+ # The account number is at the end of the browser address bar.
7
+ :account_id: <%= directives[:account_id] %>
8
+
9
+ # There are five login mechanisms:
10
+
11
+ # 0. Use the following parameters to login with your email and base64-encoded password:
12
+ # To encode your plaintext password, use 'base64' command or similar.
13
+ :email: <%= directives[:email] %>
14
+ :password_base64: <%= directives[:password_base64] %>
15
+
16
+ # 1. Use the following parameters to login with your email and plaintext password:
17
+ #:email: <%= directives[:email] %>
18
+ #:password: my_password
19
+
20
+ # 2. Use the following parameter to login with an instance_token:
21
+ # To find the instance_token, launch a server, navigate to the info page and under
22
+ # User Data box, you will see RS_API_TOKEN = your_account_id:the_instance_token
23
+ #:instance_token: my_instance_token
24
+
25
+ # 3. Use the following parameter to send a pre-authenticated cookie with every request:
26
+ #:cookies: my_cookie_string
27
+
28
+ # 4. Use the following parameter to send an existing OAuth access token with every request:
29
+ # To learn more about OAuth and how to obtain an access token, see
30
+ # http://support.rightscale.com/12-Guides/03-Rightscale_API/OAuth
31
+ #:access_token: my_token_string
32
+
33
+ # The following are optional parameters:
34
+ :api_url: <%= directives[:api_url] %>
35
+ :api_version: <%= directives[:api_version] %>
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.4.1
4
+ version: 0.5.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: 2014-02-13 00:00:00.000000000 Z
11
+ date: 2014-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -104,10 +104,12 @@ files:
104
104
  - LICENSE
105
105
  - README.md
106
106
  - bin/rs
107
+ - lib/ask_pass.rb
107
108
  - lib/rightscale_cli.rb
108
109
  - lib/rightscale_cli/client.rb
109
110
  - lib/rightscale_cli/clouds.rb
110
111
  - lib/rightscale_cli/config.rb
112
+ - lib/rightscale_cli/configure.rb
111
113
  - lib/rightscale_cli/dashboard.rb
112
114
  - lib/rightscale_cli/deployments.rb
113
115
  - lib/rightscale_cli/instances.rb
@@ -130,6 +132,7 @@ files:
130
132
  - lib/rightscale_cli/tags.rb
131
133
  - lib/rightscale_cli/version.rb
132
134
  - lib/rightscale_cli/volumes.rb
135
+ - lib/templates/right_api_client.yml.erb
133
136
  - lib/yesno.rb
134
137
  homepage: https://github.com/flaccid/rightscale-cli
135
138
  licenses: