admin-cf-plugin 0.2.0.rc1

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.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require "rake"
2
+ require "rspec/core/rake_task"
3
+
4
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
5
+ require "admin-cf-plugin/version"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ task :default => :spec
9
+
10
+ namespace :deploy do
11
+ def last_staging_sha
12
+ `git rev-parse latest-staging`.strip
13
+ end
14
+
15
+ def last_release_sha
16
+ `git rev-parse latest-release`.strip
17
+ end
18
+
19
+ def last_staging_ref_was_released?
20
+ last_staging_sha == last_release_sha
21
+ end
22
+
23
+ task :staging, :version do |_, args|
24
+ sh "gem bump --push #{"--version #{args.version}" if args.version}" if last_staging_ref_was_released?
25
+ sh "git tag -f latest-staging"
26
+ sh "git push origin :latest-staging"
27
+ sh "git push origin latest-staging"
28
+ end
29
+
30
+ task :gem do
31
+ sh "git fetch"
32
+ sh "git checkout #{last_staging_sha}"
33
+ sh "gem release --tag"
34
+ sh "git tag -f latest-release"
35
+ sh "git push origin :latest-release"
36
+ sh "git push origin latest-release"
37
+ end
38
+ end
@@ -0,0 +1,56 @@
1
+ require "cf/cli"
2
+
3
+ module CFAdmin
4
+ class Curl < CF::CLI
5
+ def precondition
6
+ check_target
7
+ end
8
+
9
+ desc "Execute a raw request"
10
+ group :admin
11
+ input :mode, :argument => :required,
12
+ :desc => "Request mode (Get/Put/etc.)"
13
+ input :path, :argument => :required,
14
+ :desc => "Request path"
15
+ input :headers, :argument => :splat,
16
+ :desc => "Headers (i.e. Foo: bar)"
17
+ input :body, :alias => "-b",
18
+ :desc => "Request body"
19
+ def curl
20
+ mode = input[:mode].upcase
21
+ path = input[:path]
22
+ body = input[:body]
23
+
24
+ headers = {}
25
+ input[:headers].each do |h|
26
+ k, v = h.split(/\s*:\s*/, 2)
27
+ headers[k.downcase] = v
28
+ end
29
+
30
+ content = headers["content-type"]
31
+ accept = headers["accept"]
32
+
33
+ content ||= :json if body
34
+ accept ||= :json unless %w(DELETE HEAD).include?(mode)
35
+
36
+ req, res =
37
+ client.base.rest_client.request(
38
+ mode,
39
+ remove_leading_slash(path),
40
+ :headers => headers,
41
+ :accept => accept,
42
+ :payload => body,
43
+ :content => body && content)
44
+
45
+ if [:json, "application/json"].include? accept
46
+ puts MultiJson.dump(res, :pretty => true)
47
+ else
48
+ puts res
49
+ end
50
+ end
51
+
52
+ def remove_leading_slash(path)
53
+ path.sub(%r{^/}, '')
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,89 @@
1
+ require "cf/cli"
2
+
3
+ module CFAdmin
4
+ class Guid < CF::CLI
5
+ def precondition
6
+ check_target
7
+ end
8
+
9
+ desc "Obtain guid of an object(s)"
10
+ group :admin
11
+ input :type, :argument => :required, :desc => "Object type (e.g. org, space, app, domain, ...)"
12
+ input :name, :argument => :optional, :desc => "Object name (e.g. some-app, ...)"
13
+ def guid
14
+ type = expand_type(input[:type])
15
+ name = input[:name]
16
+
17
+ _, res = client.base.rest_client.request("GET", api_path(type, name))
18
+
19
+ puts "Listing #{type} for '#{name}'...\n\n"
20
+ puts_response(res[:body])
21
+ end
22
+
23
+ private
24
+
25
+ def api_path(type, name)
26
+ "".tap do |url|
27
+ url << "v2/#{type}?"
28
+ url << "q=name:#{name}" if name
29
+ end
30
+ end
31
+
32
+ EXPANDED_TYPES = %w(
33
+ organizations
34
+ spaces
35
+ domains
36
+ routes
37
+ apps
38
+ services
39
+ service_instances
40
+ users
41
+ )
42
+
43
+ def expand_type(type)
44
+ EXPANDED_TYPES.detect do |expanded_type|
45
+ expanded_type.start_with?(type)
46
+ end || type
47
+ end
48
+
49
+ def puts_response(body)
50
+ # passing nil to load causes segfault
51
+ hash = MultiJson.load(body || "{}") rescue {}
52
+
53
+ puts_pagination(*hash.values_at("total_results", "total_pages"))
54
+ puts_resources(hash["resources"])
55
+ end
56
+
57
+ def puts_pagination(results, pages)
58
+ if results.nil?
59
+ puts "Unexpected response."
60
+ elsif results == 0
61
+ puts "No results."
62
+ else
63
+ puts "Found #{results} results on #{pages} pages. First page:"
64
+ end
65
+ end
66
+
67
+ def puts_resources(resources)
68
+ resources ||= []
69
+
70
+ sorted_resources = \
71
+ resources.sort_by { |r| [r["entity"]["name"].downcase] }
72
+
73
+ max_name_size = \
74
+ resources.map { |r| r["entity"]["name"].size }.max
75
+
76
+ sorted_resources.each_with_index do |resource, i|
77
+ puts_resource(resource, :max_name_size => max_name_size)
78
+ puts "---" if i % 3 == 2
79
+ end
80
+ end
81
+
82
+ def puts_resource(resource, opts={})
83
+ puts [
84
+ resource["entity"]["name"].ljust(opts[:max_name_size] + 2),
85
+ resource["metadata"]["guid"],
86
+ ].join
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ require "admin-cf-plugin/curl"
2
+ require "admin-cf-plugin/guid"
3
+ require "admin-cf-plugin/service_auth_token"
@@ -0,0 +1,93 @@
1
+ require "cf/cli"
2
+
3
+ module CFAdmin
4
+ class ServiceAuthToken < CF::CLI
5
+ def precondition
6
+ unless File.exists? target_file
7
+ fail "Please select a target with 'cf target'."
8
+ end
9
+
10
+ unless client.logged_in?
11
+ fail "Please log in with 'cf login'."
12
+ end
13
+ end
14
+
15
+
16
+ desc "List service auth tokens"
17
+ group :admin
18
+ def service_auth_tokens
19
+ spaced(client.service_auth_tokens) do |t|
20
+ line "#{c(t.label, :name)}:"
21
+
22
+ indented do
23
+ line "guid: #{t.guid}"
24
+ line "provider: #{t.provider}"
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+ desc "Create a service auth token"
31
+ group :admin
32
+ input(:label, :argument => :optional, :desc => "Auth token label") {
33
+ ask("Label")
34
+ }
35
+ input :provider, :argument => :optional, :default => "core",
36
+ :desc => "Auth token provider"
37
+ input(:token, :desc => "Auth token value") {
38
+ ask("Token")
39
+ }
40
+ def create_service_auth_token
41
+ sat = client.service_auth_token
42
+ sat.label = input[:label]
43
+ sat.provider = input[:provider]
44
+ sat.token = input[:token]
45
+
46
+ with_progress("Creating service auth token") do
47
+ sat.create!
48
+ end
49
+ end
50
+
51
+
52
+ desc "Update a service auth token"
53
+ group :admin
54
+ input(:service_auth_token, :argument => :optional,
55
+ :from_given => proc { |guid| client.service_auth_token(guid) },
56
+ :desc => "Auth token to delete") {
57
+ tokens = client.service_auth_tokens
58
+ fail "No tokens!" if tokens.empty?
59
+
60
+ ask("Which token?", :choices => tokens, :display => proc(&:label))
61
+ }
62
+ input(:token, :desc => "Auth token value") {
63
+ ask("Token")
64
+ }
65
+ def update_service_auth_token
66
+ sat = input[:service_auth_token]
67
+ sat.token = input[:token]
68
+
69
+ with_progress("Updating token #{c(sat.label, :name)}") do
70
+ sat.update!
71
+ end
72
+ end
73
+
74
+
75
+ desc "Delete a service auth token"
76
+ group :admin
77
+ input(:service_auth_token, :argument => :optional,
78
+ :from_given => proc { |guid| client.service_auth_token(guid) },
79
+ :desc => "Auth token to delete") {
80
+ tokens = client.service_auth_tokens
81
+ fail "No tokens!" if tokens.empty?
82
+
83
+ ask("Which token?", :choices => tokens, :display => proc(&:label))
84
+ }
85
+ def delete_service_auth_token
86
+ sat = input[:service_auth_token]
87
+
88
+ with_progress("Deleting token #{c(sat.label, :name)}") do
89
+ sat.delete!
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module CFAdmin
2
+ VERSION = "0.2.0.rc1".freeze
3
+ end
data/spec/curl_spec.rb ADDED
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe CFAdmin::Curl do
4
+ let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dir" }
5
+ stub_home_dir_with { fake_home_dir }
6
+
7
+ subject { cf ["curl", "--mode", "GET", "--path", path] }
8
+
9
+ before do
10
+ any_instance_of(CFoundry::Client) do |client|
11
+ stub(client).info { { :version => 2 } }
12
+ end
13
+ end
14
+
15
+ context "with an implicit target" do
16
+ let(:path) { "apps/5/instances" }
17
+
18
+ it "makes a request to the current target" do
19
+ stub_request(:get, "https://api.some-target-for-cf-curl.com/apps/5/instances").to_return(
20
+ :status => 200,
21
+ :body => 'some-body'
22
+ )
23
+
24
+ subject
25
+
26
+ expect(stdout.string).to include('"status": "200"')
27
+ expect(stdout.string).to include('"body": "some-body"')
28
+ end
29
+ end
30
+
31
+ context "with an explicit target" do
32
+ let(:path) { "https://example.com/apps/5/instances" }
33
+
34
+ it "makes a request to the given target" do
35
+ stub_request(:get, "https://example.com/apps/5/instances").to_return(
36
+ :status => 200,
37
+ :body => 'some-other-body'
38
+ )
39
+
40
+ subject
41
+
42
+ expect(stdout.string).to include('"status": "200"')
43
+ expect(stdout.string).to include('"body": "some-other-body"')
44
+ end
45
+ end
46
+ end
data/spec/guid_spec.rb ADDED
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+
3
+ describe CFAdmin::Guid do
4
+ let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dir" }
5
+ stub_home_dir_with { fake_home_dir }
6
+
7
+ before do
8
+ any_instance_of(CFoundry::Client) do |client|
9
+ stub(client).info { { :version => 2 } }
10
+ end
11
+ end
12
+
13
+ let(:api_response) {{
14
+ :total_results => 1,
15
+ :total_pages => 1,
16
+ :resources => [
17
+ :metadata => {
18
+ :guid => "guid",
19
+ },
20
+ :entity => {
21
+ :name => "name",
22
+ },
23
+ ]
24
+ }}
25
+
26
+ def stub_api(path, response, opts={})
27
+ stub = stub_request(:get, "https://api.some-target-for-cf-curl.com#{path}")
28
+ response = MultiJson.dump(response) unless opts[:not_json]
29
+ stub.to_return(:status => 200, :body => response)
30
+ end
31
+
32
+ context "when api returns >0 resources" do
33
+ context "with known type" do
34
+ let(:args) { ["guid", "--type", "organizations"] }
35
+
36
+ it "shows results" do
37
+ stub_api("/v2/organizations?", api_response)
38
+ cf(args)
39
+ expect(stdout.string).to match(/name.*guid/)
40
+ end
41
+ end
42
+
43
+ context "with short known type" do
44
+ let(:args) { ["guid", "--type", "or"] }
45
+
46
+ it "shows results" do
47
+ stub_api("/v2/organizations?", api_response)
48
+ cf(args)
49
+ expect(stdout.string).to match(/name.*guid/)
50
+ end
51
+ end
52
+
53
+ context "with unknown type" do
54
+ let(:args) { ["guid", "--type", "some-unknown-type"] }
55
+
56
+ it "makes a request with unknown type" do
57
+ stub_api("/v2/some-unknown-type?", api_response)
58
+ cf(args)
59
+ expect(stdout.string).to match(/name.*guid/)
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when api returns 0 resources" do
65
+ before do
66
+ api_response[:total_results] = 0
67
+ api_response[:total_pages] = 0
68
+ api_response[:resources] = []
69
+ end
70
+
71
+ it "shows 0 results" do
72
+ stub_api("/v2/organizations?", api_response)
73
+ cf(["guid", "--type", "organizations"])
74
+ expect(stdout.string).to match(/No results/)
75
+ end
76
+ end
77
+
78
+ context "when api does not return resources (errors, etc.)" do
79
+ ["", "not-json"].each do |response|
80
+ it "shows unexpected response for api resonse '#{response}'" do
81
+ stub_api("/v2/organizations?", response, :not_json => true)
82
+ cf(["guid", "--type", "organizations"])
83
+ expect(stdout.string).to match(/Unexpected response/)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,18 @@
1
+ SPEC_ROOT = File.dirname(__FILE__).freeze
2
+
3
+ require "rspec"
4
+ require "cf"
5
+ require "cfoundry"
6
+ require "cfoundry/test_support"
7
+ require "webmock/rspec"
8
+ require "cf/test_support"
9
+
10
+ require "#{SPEC_ROOT}/../lib/admin-cf-plugin/plugin"
11
+
12
+ RSpec.configure do |c|
13
+ c.include Fake::FakeMethods
14
+ c.mock_with :rr
15
+
16
+ c.include FakeHomeDir
17
+ c.include CommandHelper
18
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: admin-cf-plugin
3
+ version: !ruby/object:Gem::Version
4
+ hash: 3583608865
5
+ prerelease: 6
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ - rc
11
+ - 1
12
+ version: 0.2.0.rc1
13
+ platform: ruby
14
+ authors:
15
+ - Alex Suraci
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2013-03-18 00:00:00 Z
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: cfoundry
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 11
31
+ segments:
32
+ - 0
33
+ - 5
34
+ - 0
35
+ version: 0.5.0
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ description:
39
+ email:
40
+ - asuraci@vmware.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - Rakefile
49
+ - lib/admin-cf-plugin/curl.rb
50
+ - lib/admin-cf-plugin/guid.rb
51
+ - lib/admin-cf-plugin/plugin.rb
52
+ - lib/admin-cf-plugin/service_auth_token.rb
53
+ - lib/admin-cf-plugin/version.rb
54
+ - spec/curl_spec.rb
55
+ - spec/guid_spec.rb
56
+ - spec/spec_helper.rb
57
+ homepage: http://cloudfoundry.com/
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">"
78
+ - !ruby/object:Gem::Version
79
+ hash: 25
80
+ segments:
81
+ - 1
82
+ - 3
83
+ - 1
84
+ version: 1.3.1
85
+ requirements: []
86
+
87
+ rubyforge_project: admin-cf-plugin
88
+ rubygems_version: 1.8.24
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Cloud Foundry administration commands.
92
+ test_files:
93
+ - spec/curl_spec.rb
94
+ - spec/guid_spec.rb
95
+ - spec/spec_helper.rb