cf 4.0.0rc1 → 4.0.0rc2
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/lib/admin/README.md +30 -0
- data/lib/admin/curl.rb +59 -0
- data/lib/admin/guid.rb +89 -0
- data/lib/admin/plugin.rb +4 -0
- data/lib/admin/service_auth_token.rb +93 -0
- data/lib/admin/set_quota.rb +44 -0
- data/lib/cf.rb +2 -1
- data/lib/cf/version.rb +1 -1
- data/lib/manifests/manifests.rb +30 -1
- data/spec/admin/curl_spec.rb +52 -0
- data/spec/admin/guid_spec.rb +85 -0
- data/spec/admin/set_quota_spec.rb +89 -0
- data/spec/factories/cfoundry/v2/quota_definitions.rb +13 -0
- data/spec/manifests/manifests_spec.rb +17 -0
- metadata +19 -43
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7ac8300f500d579495c13617780f1ca367d94c0
|
4
|
+
data.tar.gz: 39e853208b4280438d21ed9d814af02199b49d63
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ee59533293c4075671a028ad563ba43139873c6a7db437232b988a33d9b835d7392703d96b76c57e194ddba908e1a6e1effe26e202c3c573b284159c55b1dfe7
|
7
|
+
data.tar.gz: 2aa939fe6949367e65bc5ff855db8daae78701bfe715df8deabfd413d8674bf04c7b82e44682f34d03d0194f615537b5602d75f5c0fa0177135cdb98f338b164
|
data/lib/admin/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
[](https://travis-ci.org/cloudfoundry/admin-cf-plugin)
|
2
|
+
[](http://badge.fury.io/rb/admin-cf-plugin)
|
3
|
+
|
4
|
+
## Admin
|
5
|
+
### Info
|
6
|
+
This plugin allows you to make manual HTTP requests to the Cloud Foundry REST API.
|
7
|
+
|
8
|
+
### Installation
|
9
|
+
|
10
|
+
If you have installed CF via gem install, use:
|
11
|
+
```
|
12
|
+
gem install admin-cf-plugin
|
13
|
+
```
|
14
|
+
|
15
|
+
If you have installed CF through bundler and the Gemfile, add the following to your Gemfile:
|
16
|
+
```
|
17
|
+
gem "admin-cf-plugin"
|
18
|
+
```
|
19
|
+
|
20
|
+
### Usage
|
21
|
+
|
22
|
+
```
|
23
|
+
curl MODE PATH HEADERS... Execute a raw request
|
24
|
+
guid TYPE [NAME] Obtain guid of an object(s)
|
25
|
+
set-quota [QUOTA_DEFINITION] [ORGANIZATION] Change the quota definition for the given (or current) organization.
|
26
|
+
service-auth-tokens List service auth tokens
|
27
|
+
create-service-auth-token [LABEL] [PROVIDER] Create a service auth token
|
28
|
+
update-service-auth-token [SERVICE_AUTH_TOKEN] Update a service auth token
|
29
|
+
delete-service-auth-token [SERVICE_AUTH_TOKEN] Delete a service auth token
|
30
|
+
```
|
data/lib/admin/curl.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
|
3
|
+
require "cf/cli"
|
4
|
+
|
5
|
+
module CFAdmin
|
6
|
+
class Curl < CF::CLI
|
7
|
+
def precondition
|
8
|
+
check_target
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Execute a raw request"
|
12
|
+
group :admin
|
13
|
+
input :mode, :argument => :required, :desc => "Request mode (Get/Put/etc.)"
|
14
|
+
input :path, :argument => :required, :desc => "Request path"
|
15
|
+
input :headers, :argument => :splat, :desc => "Headers (i.e. Foo: bar)"
|
16
|
+
input :body, :alias => "-b", :desc => "Request body"
|
17
|
+
def curl
|
18
|
+
mode = input[:mode].upcase
|
19
|
+
path = input[:path]
|
20
|
+
body = input[:body]
|
21
|
+
|
22
|
+
headers = {}
|
23
|
+
input[:headers].each do |h|
|
24
|
+
k, v = h.split(/\s*:\s*/, 2)
|
25
|
+
headers[k.downcase] = v
|
26
|
+
end
|
27
|
+
|
28
|
+
content = headers["content-type"]
|
29
|
+
accept = headers["accept"]
|
30
|
+
|
31
|
+
content ||= :json if body
|
32
|
+
accept ||= :json unless %w(DELETE HEAD).include?(mode)
|
33
|
+
|
34
|
+
req, res =
|
35
|
+
client.base.rest_client.request(
|
36
|
+
mode,
|
37
|
+
remove_leading_slash(path),
|
38
|
+
:headers => headers,
|
39
|
+
:accept => accept,
|
40
|
+
:payload => body,
|
41
|
+
:content => body && content)
|
42
|
+
|
43
|
+
body = res[:body]
|
44
|
+
|
45
|
+
type = res[:headers]["content-type"]
|
46
|
+
|
47
|
+
if type && type.include?("application/json")
|
48
|
+
json = MultiJson.load(body)
|
49
|
+
puts MultiJson.dump(json, :pretty => true)
|
50
|
+
else
|
51
|
+
puts body
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def remove_leading_slash(path)
|
56
|
+
path.sub(%r{^/}, '')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/admin/guid.rb
ADDED
@@ -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
|
data/lib/admin/plugin.rb
ADDED
@@ -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,44 @@
|
|
1
|
+
require "cf/cli"
|
2
|
+
|
3
|
+
module CFAdmin
|
4
|
+
class SetQuota < CF::CLI
|
5
|
+
def precondition
|
6
|
+
check_target
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Change the quota definition for the given (or current) organization."
|
10
|
+
group :admin
|
11
|
+
input :quota_definition, :argument => :optional,
|
12
|
+
:from_given => by_name(:quota_definition),
|
13
|
+
:desc => "Quota definition to set on the organization"
|
14
|
+
input :organization, :aliases => %w(org o), :argument => :optional,
|
15
|
+
:from_given => by_name(:organization),
|
16
|
+
:default => proc { client.current_organization || interact },
|
17
|
+
:desc => "Organization to update"
|
18
|
+
def set_quota
|
19
|
+
org = input[:organization]
|
20
|
+
quota = input[:quota_definition]
|
21
|
+
|
22
|
+
with_progress(<<MESSAGE.chomp) do
|
23
|
+
Setting quota of #{c(org.name, :name)} to #{c(quota.name, :name)}
|
24
|
+
MESSAGE
|
25
|
+
org.quota_definition = quota
|
26
|
+
org.update!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def ask_quota_definition
|
33
|
+
ask("Quota",
|
34
|
+
:choices => client.quota_definitions,
|
35
|
+
:display => proc(&:name))
|
36
|
+
end
|
37
|
+
|
38
|
+
def ask_organization
|
39
|
+
ask("Organization",
|
40
|
+
:choices => client.organizations,
|
41
|
+
:display => proc(&:name))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/cf.rb
CHANGED
data/lib/cf/version.rb
CHANGED
data/lib/manifests/manifests.rb
CHANGED
@@ -7,6 +7,18 @@ module CFManifests
|
|
7
7
|
MANIFEST_FILE = "manifest.yml"
|
8
8
|
|
9
9
|
@@showed_manifest_usage = false
|
10
|
+
|
11
|
+
class BadManifestError < StandardError
|
12
|
+
|
13
|
+
def initialize(attr)
|
14
|
+
@attr = attr
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"#{@attr} is not a valid attribute, please visit the Manifest " +
|
19
|
+
"Documentation for a list of valid attributes."
|
20
|
+
end
|
21
|
+
end
|
10
22
|
|
11
23
|
def manifest
|
12
24
|
return @manifest if @manifest
|
@@ -50,7 +62,24 @@ module CFManifests
|
|
50
62
|
|
51
63
|
# load and resolve a given manifest file
|
52
64
|
def load_manifest(file)
|
53
|
-
Loader.new(file, self).manifest
|
65
|
+
check_manifest! Loader.new(file, self).manifest
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_manifest!(manifest_hash)
|
69
|
+
manifest_hash[:applications].each{|app| check_attributes! app}
|
70
|
+
manifest_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_attributes!(app)
|
74
|
+
app.each do |k, v|
|
75
|
+
raise BadManifestError.new(k) unless known_manifest_attributes.include? k
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def known_manifest_attributes
|
80
|
+
[:path, :name, :memory, :instances, :host, :domain,
|
81
|
+
:command, :buildpack, :services, :env, :properties,
|
82
|
+
:inherit, :mem, :disk, :runtime, :applications]
|
54
83
|
end
|
55
84
|
|
56
85
|
# dynamic symbol resolution
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CFAdmin::Curl do
|
4
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_admin_dir" }
|
5
|
+
|
6
|
+
stub_home_dir_with { fake_home_dir }
|
7
|
+
|
8
|
+
let(:client) { fake_client }
|
9
|
+
|
10
|
+
context "when the response is JSON" do
|
11
|
+
it "pretty-prints the response" do
|
12
|
+
stub_request(:get, "https://api.some-target-for-cf-curl.com/foo").to_return(
|
13
|
+
:headers => {
|
14
|
+
"content-type" => "application/json; charset=utf8"
|
15
|
+
},
|
16
|
+
:status => 200,
|
17
|
+
:body => '{"foo":"bar"}'
|
18
|
+
)
|
19
|
+
|
20
|
+
cf %W[curl GET /foo]
|
21
|
+
expect(output).to say(<<OUT)
|
22
|
+
{
|
23
|
+
"foo": "bar"
|
24
|
+
}
|
25
|
+
OUT
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with an implicit target" do
|
30
|
+
it "makes a request to the current target" do
|
31
|
+
stub_request(:get, "https://api.some-target-for-cf-curl.com/apps/5/instances").to_return(
|
32
|
+
:status => 200,
|
33
|
+
:body => 'some-body'
|
34
|
+
)
|
35
|
+
|
36
|
+
cf %W[curl GET /apps/5/instances]
|
37
|
+
expect(output).to say("some-body")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with an explicit target" do
|
42
|
+
it "makes a request to the given target" do
|
43
|
+
stub_request(:get, "https://some-other-domain.com/apps/5/instances").to_return(
|
44
|
+
:status => 200,
|
45
|
+
:body => 'some-other-body'
|
46
|
+
)
|
47
|
+
|
48
|
+
cf %W[curl GET https://some-other-domain.com/apps/5/instances]
|
49
|
+
expect(output).to say("some-other-body")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CFAdmin::Guid do
|
4
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_admin_dir" }
|
5
|
+
stub_home_dir_with { fake_home_dir }
|
6
|
+
|
7
|
+
before do
|
8
|
+
CFoundry::Client.any_instance.stub(:info) { { :version => 2 } }
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:api_response) {{
|
12
|
+
:total_results => 1,
|
13
|
+
:total_pages => 1,
|
14
|
+
:resources => [
|
15
|
+
:metadata => {
|
16
|
+
:guid => "guid",
|
17
|
+
},
|
18
|
+
:entity => {
|
19
|
+
:name => "name",
|
20
|
+
},
|
21
|
+
]
|
22
|
+
}}
|
23
|
+
|
24
|
+
def stub_api(path, response, opts={})
|
25
|
+
stub = stub_request(:get, "https://api.some-target-for-cf-curl.com#{path}")
|
26
|
+
response = MultiJson.dump(response) unless opts[:not_json]
|
27
|
+
stub.to_return(:status => 200, :body => response)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when api returns >0 resources" do
|
31
|
+
context "with known type" do
|
32
|
+
let(:args) { ["guid", "--type", "organizations"] }
|
33
|
+
|
34
|
+
it "shows results" do
|
35
|
+
stub_api("/v2/organizations?", api_response)
|
36
|
+
cf(args)
|
37
|
+
expect(stdout.string).to match(/name.*guid/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with short known type" do
|
42
|
+
let(:args) { ["guid", "--type", "or"] }
|
43
|
+
|
44
|
+
it "shows results" do
|
45
|
+
stub_api("/v2/organizations?", api_response)
|
46
|
+
cf(args)
|
47
|
+
expect(stdout.string).to match(/name.*guid/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with unknown type" do
|
52
|
+
let(:args) { ["guid", "--type", "some-unknown-type"] }
|
53
|
+
|
54
|
+
it "makes a request with unknown type" do
|
55
|
+
stub_api("/v2/some-unknown-type?", api_response)
|
56
|
+
cf(args)
|
57
|
+
expect(stdout.string).to match(/name.*guid/)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when api returns 0 resources" do
|
63
|
+
before do
|
64
|
+
api_response[:total_results] = 0
|
65
|
+
api_response[:total_pages] = 0
|
66
|
+
api_response[:resources] = []
|
67
|
+
end
|
68
|
+
|
69
|
+
it "shows 0 results" do
|
70
|
+
stub_api("/v2/organizations?", api_response)
|
71
|
+
cf(["guid", "--type", "organizations"])
|
72
|
+
expect(stdout.string).to match(/No results/)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when api does not return resources (errors, etc.)" do
|
77
|
+
["", "not-json"].each do |response|
|
78
|
+
it "shows unexpected response for api resonse '#{response}'" do
|
79
|
+
stub_api("/v2/organizations?", response, :not_json => true)
|
80
|
+
cf(["guid", "--type", "organizations"])
|
81
|
+
expect(stdout.string).to match(/Unexpected response/)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CFAdmin::SetQuota do
|
4
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_admin_dir" }
|
5
|
+
|
6
|
+
stub_home_dir_with { fake_home_dir }
|
7
|
+
|
8
|
+
let(:paid_quota) { build :quota_definition, :name => "paid" }
|
9
|
+
let(:free_quota) { build :quota_definition, :name => "free" }
|
10
|
+
|
11
|
+
let(:organization) do
|
12
|
+
build :organization, :name => "some-org-name",
|
13
|
+
:quota_definition => free_quota
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:client) do
|
17
|
+
build(:client).tap do |client|
|
18
|
+
client.stub(
|
19
|
+
:organizations => [organization],
|
20
|
+
:quota_definitions => [paid_quota, free_quota])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
CF::CLI.any_instance.stub(:client) { client }
|
26
|
+
organization.stub(:update!)
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when given an organization and a quota definition" do
|
30
|
+
it "promotes the organization to the given quota definition" do
|
31
|
+
expect {
|
32
|
+
cf %W[set-quota paid some-org-name]
|
33
|
+
}.to change {
|
34
|
+
organization.quota_definition
|
35
|
+
}.from(free_quota).to(paid_quota)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "shows progress to the user" do
|
39
|
+
cf %W[set-quota paid some-org-name]
|
40
|
+
expect(output).to say("Setting quota of some-org-name to paid... OK")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "saves the changes made to the organization" do
|
44
|
+
organization.should_receive(:update!)
|
45
|
+
cf %W[set-quota paid some-org-name]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when NOT given a quota definition" do
|
50
|
+
it "prompts for the quota definition" do
|
51
|
+
should_ask("Quota", hash_including(:choices => client.quota_definitions)) do
|
52
|
+
paid_quota
|
53
|
+
end
|
54
|
+
|
55
|
+
cf %W[set-quota --organization some-org-name]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when NOT given an organization" do
|
60
|
+
context "and the user has a current organization" do
|
61
|
+
before { client.current_organization = organization }
|
62
|
+
|
63
|
+
it "promotes the current to the given quota definition" do
|
64
|
+
expect {
|
65
|
+
cf %W[set-quota paid]
|
66
|
+
}.to change {
|
67
|
+
organization.quota_definition
|
68
|
+
}.from(free_quota).to(paid_quota)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "saves the changes made to the organization" do
|
72
|
+
organization.should_receive(:update!)
|
73
|
+
cf %W[set-quota paid]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "and the user does NOT have a current organization" do
|
78
|
+
before { client.current_organization = nil }
|
79
|
+
|
80
|
+
it "prompts for the organization" do
|
81
|
+
should_ask("Organization", hash_including(:choices => client.organizations)) do
|
82
|
+
organization
|
83
|
+
end
|
84
|
+
|
85
|
+
cf %W[set-quota paid]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module CFoundry
|
2
|
+
FactoryGirl.define do
|
3
|
+
factory :quota_definition, class: CFoundry::V2::QuotaDefinition do
|
4
|
+
sequence(:guid) { |n| "quota-definition-guid-#{n}" }
|
5
|
+
|
6
|
+
ignore do
|
7
|
+
client { FactoryGirl.build(:client) }
|
8
|
+
end
|
9
|
+
|
10
|
+
initialize_with { new(guid, client) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -289,4 +289,21 @@ describe CFManifests do
|
|
289
289
|
expect(subject).to eq [{ :name => "foo", :path => "/abc"}, { :name => "bar", :path => "/abc" }]
|
290
290
|
end
|
291
291
|
end
|
292
|
+
|
293
|
+
describe "#check_manifest!" do
|
294
|
+
|
295
|
+
it "raise if there is some unknown attribute" do
|
296
|
+
wrong_manifest_hash = {:applications => [ {:bad_attr => 'boom'}]}
|
297
|
+
msg = "bad_attr is not a valid attribute, please visit the Manifest " +
|
298
|
+
"Documentation for a list of valid attributes."
|
299
|
+
expect{cmd.check_manifest!(wrong_manifest_hash)}.to raise_error(CFManifests::BadManifestError, msg)
|
300
|
+
end
|
301
|
+
|
302
|
+
it "not raise if there are no unknown attributes" do
|
303
|
+
good_manifest_hash = {:path => '/here', :name => 'good_manifest', :memory => '256M',
|
304
|
+
:instances => 1, :host => 'good-manifest', :domain => 'testing',
|
305
|
+
:buildpack => 'buildy', :services => {} }
|
306
|
+
expect{cmd.check_manifest!(good_manifest_hash)}.to_not raise_error(CFManifests::BadManifestError)
|
307
|
+
end
|
308
|
+
end
|
292
309
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
5
|
-
prerelease: 5
|
4
|
+
version: 4.0.0rc2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Cloud Foundry Team
|
@@ -10,12 +9,11 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-26 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: addressable
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
18
|
- - ~>
|
21
19
|
- !ruby/object:Gem::Version
|
@@ -23,7 +21,6 @@ dependencies:
|
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
25
|
- - ~>
|
29
26
|
- !ruby/object:Gem::Version
|
@@ -31,7 +28,6 @@ dependencies:
|
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: caldecott-client
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
32
|
- - ~>
|
37
33
|
- !ruby/object:Gem::Version
|
@@ -39,7 +35,6 @@ dependencies:
|
|
39
35
|
type: :runtime
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
39
|
- - ~>
|
45
40
|
- !ruby/object:Gem::Version
|
@@ -47,7 +42,6 @@ dependencies:
|
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
43
|
name: cfoundry
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
45
|
requirements:
|
52
46
|
- - ! '>='
|
53
47
|
- !ruby/object:Gem::Version
|
@@ -58,7 +52,6 @@ dependencies:
|
|
58
52
|
type: :runtime
|
59
53
|
prerelease: false
|
60
54
|
version_requirements: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
55
|
requirements:
|
63
56
|
- - ! '>='
|
64
57
|
- !ruby/object:Gem::Version
|
@@ -69,7 +62,6 @@ dependencies:
|
|
69
62
|
- !ruby/object:Gem::Dependency
|
70
63
|
name: interact
|
71
64
|
requirement: !ruby/object:Gem::Requirement
|
72
|
-
none: false
|
73
65
|
requirements:
|
74
66
|
- - ~>
|
75
67
|
- !ruby/object:Gem::Version
|
@@ -77,7 +69,6 @@ dependencies:
|
|
77
69
|
type: :runtime
|
78
70
|
prerelease: false
|
79
71
|
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
none: false
|
81
72
|
requirements:
|
82
73
|
- - ~>
|
83
74
|
- !ruby/object:Gem::Version
|
@@ -85,7 +76,6 @@ dependencies:
|
|
85
76
|
- !ruby/object:Gem::Dependency
|
86
77
|
name: json_pure
|
87
78
|
requirement: !ruby/object:Gem::Requirement
|
88
|
-
none: false
|
89
79
|
requirements:
|
90
80
|
- - ~>
|
91
81
|
- !ruby/object:Gem::Version
|
@@ -93,7 +83,6 @@ dependencies:
|
|
93
83
|
type: :runtime
|
94
84
|
prerelease: false
|
95
85
|
version_requirements: !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
86
|
requirements:
|
98
87
|
- - ~>
|
99
88
|
- !ruby/object:Gem::Version
|
@@ -101,7 +90,6 @@ dependencies:
|
|
101
90
|
- !ruby/object:Gem::Dependency
|
102
91
|
name: mothership
|
103
92
|
requirement: !ruby/object:Gem::Requirement
|
104
|
-
none: false
|
105
93
|
requirements:
|
106
94
|
- - ! '>='
|
107
95
|
- !ruby/object:Gem::Version
|
@@ -112,7 +100,6 @@ dependencies:
|
|
112
100
|
type: :runtime
|
113
101
|
prerelease: false
|
114
102
|
version_requirements: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
103
|
requirements:
|
117
104
|
- - ! '>='
|
118
105
|
- !ruby/object:Gem::Version
|
@@ -123,7 +110,6 @@ dependencies:
|
|
123
110
|
- !ruby/object:Gem::Dependency
|
124
111
|
name: multi_json
|
125
112
|
requirement: !ruby/object:Gem::Requirement
|
126
|
-
none: false
|
127
113
|
requirements:
|
128
114
|
- - ~>
|
129
115
|
- !ruby/object:Gem::Version
|
@@ -131,7 +117,6 @@ dependencies:
|
|
131
117
|
type: :runtime
|
132
118
|
prerelease: false
|
133
119
|
version_requirements: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
120
|
requirements:
|
136
121
|
- - ~>
|
137
122
|
- !ruby/object:Gem::Version
|
@@ -139,7 +124,6 @@ dependencies:
|
|
139
124
|
- !ruby/object:Gem::Dependency
|
140
125
|
name: rest-client
|
141
126
|
requirement: !ruby/object:Gem::Requirement
|
142
|
-
none: false
|
143
127
|
requirements:
|
144
128
|
- - ~>
|
145
129
|
- !ruby/object:Gem::Version
|
@@ -147,7 +131,6 @@ dependencies:
|
|
147
131
|
type: :runtime
|
148
132
|
prerelease: false
|
149
133
|
version_requirements: !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
134
|
requirements:
|
152
135
|
- - ~>
|
153
136
|
- !ruby/object:Gem::Version
|
@@ -155,7 +138,6 @@ dependencies:
|
|
155
138
|
- !ruby/object:Gem::Dependency
|
156
139
|
name: uuidtools
|
157
140
|
requirement: !ruby/object:Gem::Requirement
|
158
|
-
none: false
|
159
141
|
requirements:
|
160
142
|
- - ~>
|
161
143
|
- !ruby/object:Gem::Version
|
@@ -163,7 +145,6 @@ dependencies:
|
|
163
145
|
type: :runtime
|
164
146
|
prerelease: false
|
165
147
|
version_requirements: !ruby/object:Gem::Requirement
|
166
|
-
none: false
|
167
148
|
requirements:
|
168
149
|
- - ~>
|
169
150
|
- !ruby/object:Gem::Version
|
@@ -171,7 +152,6 @@ dependencies:
|
|
171
152
|
- !ruby/object:Gem::Dependency
|
172
153
|
name: anchorman
|
173
154
|
requirement: !ruby/object:Gem::Requirement
|
174
|
-
none: false
|
175
155
|
requirements:
|
176
156
|
- - ! '>='
|
177
157
|
- !ruby/object:Gem::Version
|
@@ -179,7 +159,6 @@ dependencies:
|
|
179
159
|
type: :development
|
180
160
|
prerelease: false
|
181
161
|
version_requirements: !ruby/object:Gem::Requirement
|
182
|
-
none: false
|
183
162
|
requirements:
|
184
163
|
- - ! '>='
|
185
164
|
- !ruby/object:Gem::Version
|
@@ -187,7 +166,6 @@ dependencies:
|
|
187
166
|
- !ruby/object:Gem::Dependency
|
188
167
|
name: blue-shell
|
189
168
|
requirement: !ruby/object:Gem::Requirement
|
190
|
-
none: false
|
191
169
|
requirements:
|
192
170
|
- - ! '>='
|
193
171
|
- !ruby/object:Gem::Version
|
@@ -195,7 +173,6 @@ dependencies:
|
|
195
173
|
type: :development
|
196
174
|
prerelease: false
|
197
175
|
version_requirements: !ruby/object:Gem::Requirement
|
198
|
-
none: false
|
199
176
|
requirements:
|
200
177
|
- - ! '>='
|
201
178
|
- !ruby/object:Gem::Version
|
@@ -203,7 +180,6 @@ dependencies:
|
|
203
180
|
- !ruby/object:Gem::Dependency
|
204
181
|
name: factory_girl
|
205
182
|
requirement: !ruby/object:Gem::Requirement
|
206
|
-
none: false
|
207
183
|
requirements:
|
208
184
|
- - ! '>='
|
209
185
|
- !ruby/object:Gem::Version
|
@@ -211,7 +187,6 @@ dependencies:
|
|
211
187
|
type: :development
|
212
188
|
prerelease: false
|
213
189
|
version_requirements: !ruby/object:Gem::Requirement
|
214
|
-
none: false
|
215
190
|
requirements:
|
216
191
|
- - ! '>='
|
217
192
|
- !ruby/object:Gem::Version
|
@@ -219,7 +194,6 @@ dependencies:
|
|
219
194
|
- !ruby/object:Gem::Dependency
|
220
195
|
name: fakefs
|
221
196
|
requirement: !ruby/object:Gem::Requirement
|
222
|
-
none: false
|
223
197
|
requirements:
|
224
198
|
- - ~>
|
225
199
|
- !ruby/object:Gem::Version
|
@@ -227,7 +201,6 @@ dependencies:
|
|
227
201
|
type: :development
|
228
202
|
prerelease: false
|
229
203
|
version_requirements: !ruby/object:Gem::Requirement
|
230
|
-
none: false
|
231
204
|
requirements:
|
232
205
|
- - ~>
|
233
206
|
- !ruby/object:Gem::Version
|
@@ -235,7 +208,6 @@ dependencies:
|
|
235
208
|
- !ruby/object:Gem::Dependency
|
236
209
|
name: ffaker
|
237
210
|
requirement: !ruby/object:Gem::Requirement
|
238
|
-
none: false
|
239
211
|
requirements:
|
240
212
|
- - '='
|
241
213
|
- !ruby/object:Gem::Version
|
@@ -243,7 +215,6 @@ dependencies:
|
|
243
215
|
type: :development
|
244
216
|
prerelease: false
|
245
217
|
version_requirements: !ruby/object:Gem::Requirement
|
246
|
-
none: false
|
247
218
|
requirements:
|
248
219
|
- - '='
|
249
220
|
- !ruby/object:Gem::Version
|
@@ -251,7 +222,6 @@ dependencies:
|
|
251
222
|
- !ruby/object:Gem::Dependency
|
252
223
|
name: rake
|
253
224
|
requirement: !ruby/object:Gem::Requirement
|
254
|
-
none: false
|
255
225
|
requirements:
|
256
226
|
- - ~>
|
257
227
|
- !ruby/object:Gem::Version
|
@@ -259,7 +229,6 @@ dependencies:
|
|
259
229
|
type: :development
|
260
230
|
prerelease: false
|
261
231
|
version_requirements: !ruby/object:Gem::Requirement
|
262
|
-
none: false
|
263
232
|
requirements:
|
264
233
|
- - ~>
|
265
234
|
- !ruby/object:Gem::Version
|
@@ -267,7 +236,6 @@ dependencies:
|
|
267
236
|
- !ruby/object:Gem::Dependency
|
268
237
|
name: rspec
|
269
238
|
requirement: !ruby/object:Gem::Requirement
|
270
|
-
none: false
|
271
239
|
requirements:
|
272
240
|
- - ~>
|
273
241
|
- !ruby/object:Gem::Version
|
@@ -275,7 +243,6 @@ dependencies:
|
|
275
243
|
type: :development
|
276
244
|
prerelease: false
|
277
245
|
version_requirements: !ruby/object:Gem::Requirement
|
278
|
-
none: false
|
279
246
|
requirements:
|
280
247
|
- - ~>
|
281
248
|
- !ruby/object:Gem::Version
|
@@ -283,7 +250,6 @@ dependencies:
|
|
283
250
|
- !ruby/object:Gem::Dependency
|
284
251
|
name: rspec-instafail
|
285
252
|
requirement: !ruby/object:Gem::Requirement
|
286
|
-
none: false
|
287
253
|
requirements:
|
288
254
|
- - ~>
|
289
255
|
- !ruby/object:Gem::Version
|
@@ -291,7 +257,6 @@ dependencies:
|
|
291
257
|
type: :development
|
292
258
|
prerelease: false
|
293
259
|
version_requirements: !ruby/object:Gem::Requirement
|
294
|
-
none: false
|
295
260
|
requirements:
|
296
261
|
- - ~>
|
297
262
|
- !ruby/object:Gem::Version
|
@@ -299,7 +264,6 @@ dependencies:
|
|
299
264
|
- !ruby/object:Gem::Dependency
|
300
265
|
name: webmock
|
301
266
|
requirement: !ruby/object:Gem::Requirement
|
302
|
-
none: false
|
303
267
|
requirements:
|
304
268
|
- - ~>
|
305
269
|
- !ruby/object:Gem::Version
|
@@ -307,7 +271,6 @@ dependencies:
|
|
307
271
|
type: :development
|
308
272
|
prerelease: false
|
309
273
|
version_requirements: !ruby/object:Gem::Requirement
|
310
|
-
none: false
|
311
274
|
requirements:
|
312
275
|
- - ~>
|
313
276
|
- !ruby/object:Gem::Version
|
@@ -322,6 +285,12 @@ extra_rdoc_files: []
|
|
322
285
|
files:
|
323
286
|
- LICENSE
|
324
287
|
- Rakefile
|
288
|
+
- lib/admin/curl.rb
|
289
|
+
- lib/admin/guid.rb
|
290
|
+
- lib/admin/plugin.rb
|
291
|
+
- lib/admin/README.md
|
292
|
+
- lib/admin/service_auth_token.rb
|
293
|
+
- lib/admin/set_quota.rb
|
325
294
|
- lib/cf/cli/app/app.rb
|
326
295
|
- lib/cf/cli/app/apps.rb
|
327
296
|
- lib/cf/cli/app/base.rb
|
@@ -419,6 +388,9 @@ files:
|
|
419
388
|
- lib/tunnel/plugin.rb
|
420
389
|
- lib/tunnel/README.md
|
421
390
|
- lib/tunnel/tunnel.rb
|
391
|
+
- spec/admin/curl_spec.rb
|
392
|
+
- spec/admin/guid_spec.rb
|
393
|
+
- spec/admin/set_quota_spec.rb
|
422
394
|
- spec/assets/hello-sinatra/config.ru
|
423
395
|
- spec/assets/hello-sinatra/fat-cat-makes-app-larger.png
|
424
396
|
- spec/assets/hello-sinatra/Gemfile
|
@@ -522,6 +494,7 @@ files:
|
|
522
494
|
- spec/factories/cfoundry/v2/clients_factory.rb
|
523
495
|
- spec/factories/cfoundry/v2/domains_factory.rb
|
524
496
|
- spec/factories/cfoundry/v2/organizations_factory.rb
|
497
|
+
- spec/factories/cfoundry/v2/quota_definitions.rb
|
525
498
|
- spec/factories/cfoundry/v2/routes_factory.rb
|
526
499
|
- spec/factories/cfoundry/v2/service_bindings_factory.rb
|
527
500
|
- spec/factories/cfoundry/v2/service_instances_factory.rb
|
@@ -558,29 +531,31 @@ files:
|
|
558
531
|
- bin/cf
|
559
532
|
homepage: http://github.com/cloudfoundry/cf
|
560
533
|
licenses: []
|
534
|
+
metadata: {}
|
561
535
|
post_install_message:
|
562
536
|
rdoc_options: []
|
563
537
|
require_paths:
|
564
538
|
- lib
|
565
539
|
required_ruby_version: !ruby/object:Gem::Requirement
|
566
|
-
none: false
|
567
540
|
requirements:
|
568
541
|
- - ! '>='
|
569
542
|
- !ruby/object:Gem::Version
|
570
543
|
version: '0'
|
571
544
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
572
|
-
none: false
|
573
545
|
requirements:
|
574
546
|
- - ! '>'
|
575
547
|
- !ruby/object:Gem::Version
|
576
548
|
version: 1.3.1
|
577
549
|
requirements: []
|
578
550
|
rubyforge_project: cf
|
579
|
-
rubygems_version:
|
551
|
+
rubygems_version: 2.0.3
|
580
552
|
signing_key:
|
581
|
-
specification_version:
|
553
|
+
specification_version: 4
|
582
554
|
summary: Friendly command-line interface for Cloud Foundry.
|
583
555
|
test_files:
|
556
|
+
- spec/admin/curl_spec.rb
|
557
|
+
- spec/admin/guid_spec.rb
|
558
|
+
- spec/admin/set_quota_spec.rb
|
584
559
|
- spec/assets/hello-sinatra/config.ru
|
585
560
|
- spec/assets/hello-sinatra/fat-cat-makes-app-larger.png
|
586
561
|
- spec/assets/hello-sinatra/Gemfile
|
@@ -684,6 +659,7 @@ test_files:
|
|
684
659
|
- spec/factories/cfoundry/v2/clients_factory.rb
|
685
660
|
- spec/factories/cfoundry/v2/domains_factory.rb
|
686
661
|
- spec/factories/cfoundry/v2/organizations_factory.rb
|
662
|
+
- spec/factories/cfoundry/v2/quota_definitions.rb
|
687
663
|
- spec/factories/cfoundry/v2/routes_factory.rb
|
688
664
|
- spec/factories/cfoundry/v2/service_bindings_factory.rb
|
689
665
|
- spec/factories/cfoundry/v2/service_instances_factory.rb
|