cf 0.1.5 → 0.6.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.
Files changed (140) hide show
  1. data/LICENSE +1277 -30
  2. data/Rakefile +12 -1
  3. data/bin/cf +0 -3
  4. data/lib/cf.rb +6 -0
  5. data/lib/cf/cli.rb +389 -190
  6. data/lib/cf/cli/app/app.rb +45 -0
  7. data/lib/cf/cli/app/apps.rb +99 -0
  8. data/lib/cf/cli/app/base.rb +90 -0
  9. data/lib/cf/cli/app/crashes.rb +42 -0
  10. data/lib/cf/cli/app/delete.rb +95 -0
  11. data/lib/cf/cli/app/deprecated.rb +11 -0
  12. data/lib/cf/cli/app/env.rb +78 -0
  13. data/lib/cf/cli/app/files.rb +137 -0
  14. data/lib/cf/cli/app/health.rb +26 -0
  15. data/lib/cf/cli/app/instances.rb +53 -0
  16. data/lib/cf/cli/app/logs.rb +76 -0
  17. data/lib/cf/cli/app/push.rb +105 -0
  18. data/lib/cf/cli/app/push/create.rb +149 -0
  19. data/lib/cf/cli/app/push/interactions.rb +94 -0
  20. data/lib/cf/cli/app/push/sync.rb +64 -0
  21. data/lib/cf/cli/app/rename.rb +35 -0
  22. data/lib/cf/cli/app/restart.rb +20 -0
  23. data/lib/cf/cli/app/scale.rb +69 -0
  24. data/lib/cf/cli/app/start.rb +143 -0
  25. data/lib/cf/cli/app/stats.rb +67 -0
  26. data/lib/cf/cli/app/stop.rb +27 -0
  27. data/lib/cf/cli/domain/base.rb +8 -0
  28. data/lib/cf/cli/domain/domains.rb +40 -0
  29. data/lib/cf/cli/domain/map.rb +55 -0
  30. data/lib/cf/cli/domain/unmap.rb +56 -0
  31. data/lib/cf/cli/help.rb +15 -0
  32. data/lib/cf/cli/interactive.rb +105 -0
  33. data/lib/cf/cli/organization/base.rb +12 -0
  34. data/lib/cf/cli/organization/create.rb +32 -0
  35. data/lib/cf/cli/organization/delete.rb +73 -0
  36. data/lib/cf/cli/organization/org.rb +45 -0
  37. data/lib/cf/cli/organization/orgs.rb +35 -0
  38. data/lib/cf/cli/organization/rename.rb +36 -0
  39. data/lib/cf/cli/route/base.rb +8 -0
  40. data/lib/cf/cli/route/map.rb +70 -0
  41. data/lib/cf/cli/route/routes.rb +26 -0
  42. data/lib/cf/cli/route/unmap.rb +62 -0
  43. data/lib/cf/cli/service/base.rb +8 -0
  44. data/lib/cf/cli/service/bind.rb +44 -0
  45. data/lib/cf/cli/service/create.rb +107 -0
  46. data/lib/cf/cli/service/delete.rb +82 -0
  47. data/lib/cf/cli/service/rename.rb +35 -0
  48. data/lib/cf/cli/service/service.rb +40 -0
  49. data/lib/cf/cli/service/services.rb +99 -0
  50. data/lib/cf/cli/service/unbind.rb +38 -0
  51. data/lib/cf/cli/space/base.rb +19 -0
  52. data/lib/cf/cli/space/create.rb +63 -0
  53. data/lib/cf/cli/space/delete.rb +95 -0
  54. data/lib/cf/cli/space/rename.rb +39 -0
  55. data/lib/cf/cli/space/space.rb +64 -0
  56. data/lib/cf/cli/space/spaces.rb +55 -0
  57. data/lib/cf/cli/space/switch.rb +16 -0
  58. data/lib/cf/cli/start/base.rb +93 -0
  59. data/lib/cf/cli/start/colors.rb +13 -0
  60. data/lib/cf/cli/start/info.rb +124 -0
  61. data/lib/cf/cli/start/login.rb +94 -0
  62. data/lib/cf/cli/start/logout.rb +17 -0
  63. data/lib/cf/cli/start/target.rb +69 -0
  64. data/lib/cf/cli/start/target_interactions.rb +37 -0
  65. data/lib/cf/cli/start/targets.rb +16 -0
  66. data/lib/cf/cli/user/base.rb +29 -0
  67. data/lib/cf/cli/user/create.rb +39 -0
  68. data/lib/cf/cli/user/passwd.rb +43 -0
  69. data/lib/cf/cli/user/register.rb +42 -0
  70. data/lib/cf/cli/user/users.rb +32 -0
  71. data/lib/cf/constants.rb +10 -7
  72. data/lib/cf/detect.rb +113 -48
  73. data/lib/cf/errors.rb +17 -0
  74. data/lib/cf/plugin.rb +28 -12
  75. data/lib/cf/spacing.rb +89 -0
  76. data/lib/cf/spec_helper.rb +1 -0
  77. data/lib/cf/test_support.rb +6 -0
  78. data/lib/cf/version.rb +1 -1
  79. data/spec/assets/hello-sinatra/Gemfile +3 -0
  80. data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
  81. data/spec/assets/hello-sinatra/config.ru +3 -0
  82. data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
  83. data/spec/assets/hello-sinatra/main.rb +6 -0
  84. data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
  85. data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
  86. data/spec/cf/cli/app/base_spec.rb +17 -0
  87. data/spec/cf/cli/app/delete_spec.rb +188 -0
  88. data/spec/cf/cli/app/instances_spec.rb +65 -0
  89. data/spec/cf/cli/app/push/create_spec.rb +661 -0
  90. data/spec/cf/cli/app/push_spec.rb +369 -0
  91. data/spec/cf/cli/app/rename_spec.rb +104 -0
  92. data/spec/cf/cli/app/scale_spec.rb +75 -0
  93. data/spec/cf/cli/app/start_spec.rb +208 -0
  94. data/spec/cf/cli/app/stats_spec.rb +68 -0
  95. data/spec/cf/cli/domain/map_spec.rb +130 -0
  96. data/spec/cf/cli/domain/unmap_spec.rb +69 -0
  97. data/spec/cf/cli/organization/orgs_spec.rb +108 -0
  98. data/spec/cf/cli/organization/rename_spec.rb +113 -0
  99. data/spec/cf/cli/route/map_spec.rb +121 -0
  100. data/spec/cf/cli/route/unmap_spec.rb +155 -0
  101. data/spec/cf/cli/service/bind_spec.rb +25 -0
  102. data/spec/cf/cli/service/delete_spec.rb +22 -0
  103. data/spec/cf/cli/service/rename_spec.rb +105 -0
  104. data/spec/cf/cli/service/service_spec.rb +23 -0
  105. data/spec/cf/cli/service/unbind_spec.rb +25 -0
  106. data/spec/cf/cli/space/create_spec.rb +93 -0
  107. data/spec/cf/cli/space/rename_spec.rb +102 -0
  108. data/spec/cf/cli/space/spaces_spec.rb +104 -0
  109. data/spec/cf/cli/space/switch_space_spec.rb +55 -0
  110. data/spec/cf/cli/start/info_spec.rb +160 -0
  111. data/spec/cf/cli/start/login_spec.rb +142 -0
  112. data/spec/cf/cli/start/logout_spec.rb +50 -0
  113. data/spec/cf/cli/start/target_spec.rb +123 -0
  114. data/spec/cf/cli/user/create_spec.rb +54 -0
  115. data/spec/cf/cli/user/passwd_spec.rb +102 -0
  116. data/spec/cf/cli/user/register_spec.rb +140 -0
  117. data/spec/cf/cli_spec.rb +442 -0
  118. data/spec/cf/detect_spec.rb +54 -0
  119. data/spec/console_app_specker/console_app_specker_matchers_spec.rb +173 -0
  120. data/spec/console_app_specker/specker_runner_spec.rb +167 -0
  121. data/spec/features/account_lifecycle_spec.rb +85 -0
  122. data/spec/features/login_spec.rb +66 -0
  123. data/spec/features/push_flow_spec.rb +125 -0
  124. data/spec/features/switching_targets_spec.rb +32 -0
  125. data/spec/spec_helper.rb +72 -0
  126. data/spec/support/command_helper.rb +81 -0
  127. data/spec/support/config_helper.rb +15 -0
  128. data/spec/support/console_app_specker_matchers.rb +86 -0
  129. data/spec/support/fake_home_dir.rb +55 -0
  130. data/spec/support/interact_helper.rb +29 -0
  131. data/spec/support/shared_examples/errors.rb +40 -0
  132. data/spec/support/shared_examples/input.rb +14 -0
  133. data/spec/support/specker_runner.rb +80 -0
  134. data/spec/support/tracking_expector.rb +71 -0
  135. metadata +427 -66
  136. data/lib/cf/cli/app.rb +0 -595
  137. data/lib/cf/cli/command.rb +0 -444
  138. data/lib/cf/cli/dots.rb +0 -133
  139. data/lib/cf/cli/service.rb +0 -112
  140. data/lib/cf/cli/user.rb +0 -71
@@ -0,0 +1,55 @@
1
+ require "cf/cli/space/base"
2
+
3
+ module CF::Space
4
+ class Spaces < Base
5
+ desc "List spaces in an organization"
6
+ group :spaces
7
+ input :organization, :desc => "Organization to list spaces from",
8
+ :aliases => %w{--org -o}, :argument => :optional,
9
+ :from_given => by_name(:organization),
10
+ :default => proc { client.current_organization }
11
+ input :name, :desc => "Filter by name"
12
+ input :full, :desc => "Show full information for apps, services, etc.",
13
+ :default => false
14
+ def spaces
15
+ org = input[:organization]
16
+ spaces =
17
+ with_progress("Getting spaces in #{c(org.name, :name)}") do
18
+ org.spaces(:depth => quiet? ? 0 : 1).sort_by(&:name)
19
+ end
20
+
21
+ return if spaces.empty?
22
+
23
+ line unless quiet?
24
+
25
+ spaces.reject! do |s|
26
+ !space_matches?(s, input)
27
+ end
28
+
29
+ if input[:full]
30
+ spaced(spaces) do |s|
31
+ invoke :space, :space => s, :full => input[:full]
32
+ end
33
+ else
34
+ table(
35
+ %w{name apps services},
36
+ spaces.collect { |s|
37
+ [ c(s.name, :name),
38
+ name_list(s.apps),
39
+ name_list(s.service_instances)
40
+ ]
41
+ })
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def space_matches?(s, options)
48
+ if name = options[:name]
49
+ return false if s.name !~ /#{name}/
50
+ end
51
+
52
+ true
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ require "cf/cli/space/base"
2
+
3
+ module CF::Space
4
+ class Switch < Base
5
+ desc "Switch to a space"
6
+ group :spaces, :hidden => true
7
+ input :name, :desc => "Space name", :argument => true
8
+ def switch_space
9
+ if (space = client.space_by_name(input[:name]))
10
+ invoke :target, :space => space
11
+ else
12
+ raise CF::UserError, "The space #{input[:name]} does not exist, please create the space first."
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,93 @@
1
+ require "cf/cli"
2
+
3
+ module CF
4
+ module Start
5
+ class Base < CLI
6
+ # Make sure we only show the target once
7
+ @@displayed_target = false
8
+
9
+ def displayed_target?
10
+ @@displayed_target
11
+ end
12
+
13
+
14
+ # These commands don't require authentication.
15
+ def precondition; end
16
+
17
+ private
18
+
19
+ def show_context
20
+ return if quiet? || displayed_target?
21
+
22
+ display_target
23
+
24
+ line
25
+
26
+ @@displayed_target = true
27
+ end
28
+
29
+ def display_target
30
+ if quiet?
31
+ line client.target
32
+ else
33
+ line "target: #{c(client.target, :name)}"
34
+ end
35
+ end
36
+
37
+ def select_org(input, info)
38
+ if input.has?(:organization) || !org_valid?(info[:organization])
39
+ org = input[:organization]
40
+ if org
41
+ with_progress("Switching to organization #{c(org.name, :name)}") {}
42
+ client.current_organization = org
43
+ end
44
+ info[:organization] = org ? org.guid : nil
45
+ !!org
46
+ else
47
+ info[:organization] = nil
48
+ client.current_organization = nil
49
+ false
50
+ end
51
+ end
52
+
53
+ def select_space(input, info, changed_org)
54
+ if input.has?(:space) || !space_valid?(info[:space])
55
+ line if changed_org && !quiet?
56
+ space = input[:space, client.current_organization]
57
+ if space
58
+ with_progress("Switching to space #{c(space.name, :name)}") {}
59
+ client.current_space = space
60
+ end
61
+ info[:space] = space ? space.guid : nil
62
+ else
63
+ info[:space] = nil
64
+ client.current_space = nil
65
+ end
66
+ end
67
+
68
+ def select_org_and_space(input, info)
69
+ changed_org = select_org(input, info)
70
+ if client.current_organization
71
+ select_space(input, info, changed_org)
72
+ else
73
+ info[:space] = nil
74
+ client.current_space = nil
75
+ end
76
+ end
77
+
78
+ def org_valid?(guid, user = client.current_user)
79
+ return false unless guid
80
+ client.organization(guid).users.include? user
81
+ rescue CFoundry::APIError
82
+ false
83
+ end
84
+
85
+ def space_valid?(guid, user = client.current_user)
86
+ return false unless guid
87
+ client.space(guid).developers.include? user
88
+ rescue CFoundry::APIError
89
+ false
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,13 @@
1
+ require "cf/cli/start/base"
2
+
3
+ module CF::Start
4
+ class Colors < Base
5
+ desc "Show color configuration"
6
+ group :start, :hidden => true
7
+ def colors
8
+ user_colors.each do |n, c|
9
+ line "#{n}: #{c(c.to_s, n)}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,124 @@
1
+ require "cf/cli/start/base"
2
+
3
+ module CF::Start
4
+ class Info < Base
5
+ def precondition
6
+ check_target
7
+ end
8
+
9
+ desc "Display information on the current target, user, etc."
10
+ group :start
11
+ input :runtimes, :desc => "List supported runtimes", :alias => "-r",
12
+ :default => false
13
+ input :frameworks, :desc => "List supported frameworks", :alias => "-f",
14
+ :default => false
15
+ input :services, :desc => "List supported services", :alias => "-s",
16
+ :default => false
17
+ input :all, :desc => "Show all information", :alias => "-a",
18
+ :default => false
19
+ def info
20
+ all = input[:all]
21
+
22
+ if all || input[:runtimes]
23
+ runtimes =
24
+ with_progress("Getting runtimes") do
25
+ client.runtimes
26
+ end
27
+ end
28
+
29
+ if all || input[:frameworks]
30
+ frameworks =
31
+ with_progress("Getting frameworks") do
32
+ client.frameworks
33
+ end
34
+ end
35
+
36
+ if all || input[:services]
37
+ services =
38
+ with_progress("Getting services") do
39
+ client.services
40
+ end
41
+ end
42
+
43
+ showing_any = runtimes || services || frameworks
44
+
45
+ unless !all && showing_any
46
+ info = client.info
47
+
48
+ line if showing_any
49
+ line info[:description]
50
+ line
51
+ line "target: #{b(client.target)}"
52
+
53
+ indented do
54
+ line "version: #{info[:version]}"
55
+ line "support: #{info[:support]}"
56
+ end
57
+
58
+ if user = client.current_user
59
+ line
60
+ line "user: #{b(user.email || user.guid)}"
61
+ end
62
+ end
63
+
64
+ if runtimes
65
+ line unless quiet?
66
+
67
+ if runtimes.empty? && !quiet?
68
+ line "#{d("none")}"
69
+ elsif input[:quiet]
70
+ runtimes.each do |r|
71
+ line r.name
72
+ end
73
+ else
74
+ table(
75
+ %w{runtime description},
76
+ runtimes.sort_by(&:name).collect { |r|
77
+ [c(r.name, :name), r.description]
78
+ })
79
+ end
80
+ end
81
+
82
+ if frameworks
83
+ line unless quiet?
84
+
85
+ if frameworks.empty? && !quiet?
86
+ line "#{d("none")}"
87
+ elsif input[:quiet]
88
+ frameworks.each do |f|
89
+ line f.name
90
+ end
91
+ else
92
+ table(
93
+ %w{framework description},
94
+ frameworks.sort_by(&:name).collect { |f|
95
+ [c(f.name, :name), f.description]
96
+ })
97
+ end
98
+ end
99
+
100
+ if services
101
+ line unless quiet?
102
+
103
+ if services.empty? && !quiet?
104
+ line "#{d("none")}"
105
+ elsif input[:quiet]
106
+ services.each do |s|
107
+ line s.label
108
+ end
109
+ else
110
+ table(
111
+ ["service", "version", "provider", "plans", "description"],
112
+ services.sort_by(&:label).collect { |s|
113
+ [c(s.label, :name),
114
+ s.version,
115
+ s.provider,
116
+ s.service_plans.collect(&:name).join(", "),
117
+ s.description
118
+ ]
119
+ })
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,94 @@
1
+ require "cf/cli/start/base"
2
+ require "cf/cli/start/target_interactions"
3
+
4
+ module CF::Start
5
+ class Login < Base
6
+ def precondition
7
+ check_target
8
+ end
9
+
10
+ desc "Authenticate with the target"
11
+ group :start
12
+ input :username, :value => :email, :desc => "Account email",
13
+ :alias => "--email", :argument => :optional
14
+ input :password, :desc => "Account password"
15
+ input :organization, :desc => "Organization" , :aliases => %w{--org -o},
16
+ :from_given => by_name(:organization)
17
+ input :space, :desc => "Space", :alias => "-s",
18
+ :from_given => by_name(:space)
19
+ interactions TargetInteractions
20
+ def login
21
+ show_context
22
+
23
+ credentials =
24
+ { :username => input[:username],
25
+ :password => input[:password]
26
+ }
27
+
28
+ prompts = client.login_prompts
29
+
30
+ # ask username first
31
+ if prompts.key? :username
32
+ type, label = prompts.delete :username
33
+ credentials[:username] ||= ask_prompt(type, label)
34
+ end
35
+
36
+ info = target_info
37
+
38
+ auth_token = nil
39
+ authenticated = false
40
+ failed = false
41
+ remaining_attempts = 3
42
+ until authenticated || remaining_attempts <= 0
43
+ remaining_attempts -= 1
44
+ unless force?
45
+ ask_prompts(credentials, prompts)
46
+ end
47
+
48
+ with_progress("Authenticating") do |s|
49
+ begin
50
+ auth_token = client.login(credentials[:username], credentials[:password])
51
+ authenticated = true
52
+ rescue CFoundry::Denied
53
+ return if force?
54
+
55
+ s.fail do
56
+ failed = true
57
+ credentials.delete(:password)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ info.merge!(auth_token.to_hash)
64
+ save_target_info(info)
65
+ invalidate_client
66
+
67
+ line if input.interactive?(:organization) || input.interactive?(:space)
68
+ select_org_and_space(input, info)
69
+
70
+ save_target_info(info)
71
+ ensure
72
+ exit_status 1 if not authenticated
73
+ end
74
+
75
+ private
76
+
77
+ def ask_prompts(credentials, prompts)
78
+ prompts.each do |name, meta|
79
+ type, label = meta
80
+ credentials[name] ||= ask_prompt(type, label)
81
+ end
82
+ end
83
+
84
+ def ask_prompt(type, label)
85
+ if type == "password"
86
+ options = { :echo => "*", :forget => true }
87
+ else
88
+ options = {}
89
+ end
90
+
91
+ ask(label, options)
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,17 @@
1
+ require "cf/cli/start/base"
2
+
3
+ module CF::Start
4
+ class Logout < Base
5
+ def precondition
6
+ check_target
7
+ end
8
+
9
+ desc "Log out from the target"
10
+ group :start
11
+ def logout
12
+ with_progress("Logging out") do
13
+ remove_target_info
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ require "cf/cli/start/base"
2
+ require "cf/cli/start/target_interactions"
3
+
4
+ module CF::Start
5
+ class Target < Base
6
+ desc "Set or display the target cloud, organization, and space"
7
+ group :start
8
+ input :url, :desc => "Target URL to switch to", :argument => :optional
9
+ input :organization, :desc => "Organization" , :aliases => %w{--org -o},
10
+ :from_given => by_name(:organization)
11
+ input :space, :desc => "Space", :alias => "-s",
12
+ :from_given => by_name(:space)
13
+ interactions TargetInteractions
14
+ def target
15
+ unless input.has?(:url) || input.has?(:organization) || \
16
+ input.has?(:space)
17
+ display_target
18
+ display_org_and_space unless quiet?
19
+ return
20
+ end
21
+
22
+ if input.has?(:url)
23
+ target = sane_target_url(input[:url])
24
+ with_progress("Setting target to #{c(target, :name)}") do
25
+ begin
26
+ CFoundry::Client.new(target) # check that it's valid before setting
27
+ rescue CFoundry::TargetRefused
28
+ fail "Target refused connection."
29
+ rescue CFoundry::InvalidTarget
30
+ fail "Invalid target URI."
31
+ end
32
+
33
+ set_target(target)
34
+ end
35
+ end
36
+
37
+ return unless client.logged_in?
38
+
39
+ if input.has?(:organization) || input.has?(:space)
40
+ info = target_info
41
+
42
+ select_org_and_space(input, info)
43
+
44
+ save_target_info(info)
45
+ end
46
+
47
+ return if quiet?
48
+
49
+ invalidate_client
50
+
51
+ line
52
+ display_target
53
+ display_org_and_space
54
+ end
55
+
56
+ private
57
+
58
+ def display_org_and_space
59
+ if org = client.current_organization
60
+ line "organization: #{c(org.name, :name)}"
61
+ end
62
+
63
+ if space = client.current_space
64
+ line "space: #{c(space.name, :name)}"
65
+ end
66
+ rescue CFoundry::APIError
67
+ end
68
+ end
69
+ end