cloudflock 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +15 -0
  2. data/bin/cloudflock +7 -1
  3. data/bin/cloudflock-files +2 -14
  4. data/bin/cloudflock-profile +3 -15
  5. data/bin/cloudflock-servers +3 -22
  6. data/bin/cloudflock.default +3 -22
  7. data/lib/cloudflock/app/common/cleanup/unix.rb +23 -0
  8. data/lib/cloudflock/app/common/cleanup.rb +107 -0
  9. data/lib/cloudflock/app/common/exclusions/unix/centos.rb +18 -0
  10. data/lib/cloudflock/app/common/exclusions/unix/redhat.rb +18 -0
  11. data/lib/cloudflock/app/common/exclusions/unix.rb +58 -0
  12. data/lib/cloudflock/app/common/exclusions.rb +57 -0
  13. data/lib/cloudflock/app/common/platform_action.rb +59 -0
  14. data/lib/cloudflock/app/common/rackspace.rb +63 -0
  15. data/lib/cloudflock/app/common/servers.rb +673 -0
  16. data/lib/cloudflock/app/files-migrate.rb +246 -0
  17. data/lib/cloudflock/app/server-migrate.rb +327 -0
  18. data/lib/cloudflock/app/server-profile.rb +130 -0
  19. data/lib/cloudflock/app.rb +87 -0
  20. data/lib/cloudflock/error.rb +6 -19
  21. data/lib/cloudflock/errstr.rb +31 -0
  22. data/lib/cloudflock/remote/files.rb +82 -22
  23. data/lib/cloudflock/remote/ssh.rb +234 -278
  24. data/lib/cloudflock/target/servers/platform.rb +92 -115
  25. data/lib/cloudflock/target/servers/profile.rb +331 -340
  26. data/lib/cloudflock/task/server-profile.rb +651 -0
  27. data/lib/cloudflock.rb +6 -8
  28. metadata +49 -68
  29. data/lib/cloudflock/interface/cli/app/common/servers.rb +0 -128
  30. data/lib/cloudflock/interface/cli/app/files.rb +0 -179
  31. data/lib/cloudflock/interface/cli/app/servers/migrate.rb +0 -491
  32. data/lib/cloudflock/interface/cli/app/servers/profile.rb +0 -88
  33. data/lib/cloudflock/interface/cli/app/servers.rb +0 -2
  34. data/lib/cloudflock/interface/cli/console.rb +0 -213
  35. data/lib/cloudflock/interface/cli/opts/servers.rb +0 -20
  36. data/lib/cloudflock/interface/cli/opts.rb +0 -87
  37. data/lib/cloudflock/interface/cli.rb +0 -15
  38. data/lib/cloudflock/target/servers/data/exceptions/base.txt +0 -44
  39. data/lib/cloudflock/target/servers/data/exceptions/platform/amazon.txt +0 -10
  40. data/lib/cloudflock/target/servers/data/exceptions/platform/centos.txt +0 -7
  41. data/lib/cloudflock/target/servers/data/exceptions/platform/debian.txt +0 -0
  42. data/lib/cloudflock/target/servers/data/exceptions/platform/redhat.txt +0 -7
  43. data/lib/cloudflock/target/servers/data/exceptions/platform/suse.txt +0 -1
  44. data/lib/cloudflock/target/servers/data/post-migration/chroot/base.txt +0 -1
  45. data/lib/cloudflock/target/servers/data/post-migration/chroot/platform/amazon.txt +0 -19
  46. data/lib/cloudflock/target/servers/data/post-migration/pre/base.txt +0 -3
  47. data/lib/cloudflock/target/servers/data/post-migration/pre/platform/amazon.txt +0 -4
  48. data/lib/cloudflock/target/servers/migrate.rb +0 -466
  49. data/lib/cloudflock/target/servers/platform/v1.rb +0 -97
  50. data/lib/cloudflock/target/servers/platform/v2.rb +0 -93
  51. data/lib/cloudflock/target/servers.rb +0 -5
  52. data/lib/cloudflock/version.rb +0 -3
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjNmYTg2NmMyOTExM2M1YjlkM2ExMjkzMDE0Yzc1ZjlhYzNmNGIyOQ==
5
+ data.tar.gz: !binary |-
6
+ N2Q2M2Y4ZjMyNmE2MDYzNTA3MjRmYTYyNTQ0OWRlNDIyYWY5ODdhOQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MTZlYTlmOWMwMTMwM2IxMTRjOWFjY2Y1OGNlMWQ4YjE2OGZkMDUyNjMxNDI1
10
+ NDU1OTczYTBhNzI3OTYzNjhlY2QwNDI5NTQ0NTE4MzExM2NiMjkwNWZmZWUy
11
+ Y2U1ZjJkZjgyZmJkMTViMzMzMTBlZjljMGUxNzRjN2IxMjM2YTg=
12
+ data.tar.gz: !binary |-
13
+ MWY2ZGYyMDUwYTFkYzZmZDhkMDZiMmQ5NDU1ZDA3Y2U0MzhiYWFjNDQ0NTc4
14
+ NDYyZjM4ZjNhMWVlZTU1OTUxNTk2MzhlODgyMDRhY2UxYjRlYjhjZjgwNzMw
15
+ NTlhYmFlMjQ5YzQ0NzY3ZjA3MmJmNzJkNWFjMDc1M2VjZTEyZTE=
data/bin/cloudflock CHANGED
@@ -1,8 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ # Trap C-c to kill the application without a stack trace
4
+ trap 'INT' do
5
+ puts "\nCaught SIGINT, exiting..."
6
+ exit 1
7
+ end
8
+
3
9
  current_path = File.expand_path('../', __FILE__)
4
10
  function = ARGV.shift.to_s
5
- bin = File.basename($0, '.dev')
11
+ bin = File.basename($0)
6
12
 
7
13
  if function.match(/^[^-]/)
8
14
  target = "#{current_path}/#{bin}-#{function}"
data/bin/cloudflock-files CHANGED
@@ -1,18 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'cloudflock/app/files-migrate'
3
4
  $0 = 'cloudflock-files'
4
5
 
5
- require 'cloudflock/interface/cli/app/files'
6
- CLI = CloudFlock::Interface::CLI::Console
7
- Opts = CloudFlock::Interface::CLI::Opts
8
-
9
- # Trap C-c to kill the application in a friendly manner
10
- trap 'INT' do
11
- puts "\nCaught SIGINT, exiting..."
12
- exit 1
13
- end
14
-
15
- options = Opts.parse
16
- options[:config] = Opts.parse_config_file(options[:config_file])
17
-
18
- CloudFlock::Interface::CLI::App::Files.new(options)
6
+ CloudFlock::App::FilesMigrate.new
@@ -1,19 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $0 = 'cloudflock-profile'
4
-
5
- require 'cloudflock/interface/cli/app/servers/profile'
6
- CLI = CloudFlock::Interface::CLI::Console
7
- Opts = CloudFlock::Interface::CLI::Opts
3
+ require 'cloudflock/app/server-profile'
8
4
 
9
- # Trap C-c to kill the application in a friendly manner
10
- trap 'INT' do
11
- puts "\nCaught SIGINT, exiting..."
12
- exit 1
13
- end
14
-
15
- options = Opts.parse
16
- options[:function] = :profile
17
- options[:config] = Opts.parse_config_file(options[:config_file])
5
+ $0 = 'cloudflock-profile'
18
6
 
19
- CloudFlock::Interface::CLI::App::Servers::Profile.new(options)
7
+ CloudFlock::App::ServerProfile.new
@@ -1,26 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $0 = 'cloudflock-servers'
4
-
5
- require 'cloudflock/interface/cli/app/servers/migrate'
6
- CLI = CloudFlock::Interface::CLI::Console
7
- Opts = CloudFlock::Interface::CLI::Opts
8
-
9
- # Trap C-c to kill the application in a friendly manner
10
- trap 'INT' do
11
- puts "\nCaught SIGINT, exiting..."
12
- exit 1
13
- end
3
+ require 'cloudflock/app/server-migrate'
14
4
 
15
- options = Opts.parse(:servers)
16
- type_prompt = "Type of migration (servers, opencloud)?"
17
-
18
- if options[:function].nil?
19
- options[:function] = CLI.prompt(type_prompt, valid_answers:
20
- ["servers", "opencloud"],
21
- default_answer: "opencloud")
22
- end
23
- options[:function] = options[:function].to_sym
24
- options[:config] = Opts.parse_config_file(options[:config_file])
5
+ $0 = 'cloudflock-servers'
25
6
 
26
- CloudFlock::Interface::CLI::App::Servers::Migrate.new(options)
7
+ CloudFlock::App::ServerMigrate.new
@@ -1,26 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $0 = 'cloudflock-servers'
4
-
5
- require 'cloudflock/interface/cli/app/servers/migrate'
6
- CLI = CloudFlock::Interface::CLI::Console
7
- Opts = CloudFlock::Interface::CLI::Opts
8
-
9
- # Trap C-c to kill the application in a friendly manner
10
- trap 'INT' do
11
- puts "\nCaught SIGINT, exiting..."
12
- exit 1
13
- end
3
+ require 'cloudflock/app/server-migrate'
14
4
 
15
- options = Opts.parse(:servers)
16
- type_prompt = "Type of migration (servers, opencloud)?"
17
-
18
- if options[:function].nil?
19
- options[:function] = CLI.prompt(type_prompt, valid_answers:
20
- ["servers", "opencloud"],
21
- default_answer: "opencloud")
22
- end
23
- options[:function] = options[:function].to_sym
24
- options[:config] = Opts.parse_config_file(options[:config_file])
5
+ $0 = 'cloudflock-servers'
25
6
 
26
- CloudFlock::Interface::CLI::App::Servers::Migrate.new(options)
7
+ CloudFlock::App::ServerMigrate.new
@@ -0,0 +1,23 @@
1
+ require 'cloudflock/app/common/servers'
2
+
3
+ module CloudFlock; module App; module Common; class Cleanup
4
+ # Public: The Unix module provides cleanup steps which are appropriate for
5
+ # all Unix-like hosts.
6
+ module Unix extend self
7
+ # Public: Define pre-, during-, and post-chroot steps which will be
8
+ # applicable to all Unix-like hosts.
9
+ #
10
+ # Returns nothing.
11
+ def unix_cleanup
12
+ pre_step 'mount proc -t proc /mnt/migration_target/proc'
13
+ pre_step 'mount /dev /mnt/migration_target/dev -o rbind'
14
+ pre_step 'mount /sys /mnt/migration_target/sys -o rbind'
15
+
16
+ chroot_step 'find /var/run -type f -exec rm {} \;'
17
+
18
+ post_step 'umount /mnt/migration_target/sys'
19
+ post_step 'umount /mnt/migration_target/dev'
20
+ post_step 'umount /mnt/migration_target/proc'
21
+ end
22
+ end
23
+ end; end; end; end
@@ -0,0 +1,107 @@
1
+ require 'cloudflock/app/common/platform_action'
2
+
3
+ module CloudFlock; module App; module Common
4
+ # Public: The Cleanup Class allows for building tasks leading up to, during
5
+ # and following chrooting into a staged post-migration environment to perform
6
+ # cleanup tasks.
7
+ class Cleanup < PlatformAction
8
+ # Public: Initialize the internal state, then find suitable tasks for the
9
+ # detected platform.
10
+ #
11
+ # cpe - CPE object.
12
+ def initialize(cpe)
13
+ super
14
+
15
+ define_steps
16
+ end
17
+
18
+ # Public: Define a step to be performed prior to chrooting.
19
+ #
20
+ # step - String containing a command to be performed.
21
+ #
22
+ # Returns nothing.
23
+ def pre_step(step)
24
+ pre << step
25
+ end
26
+
27
+ # Public: Define a step to be performed in a chroot environment.
28
+ #
29
+ # step - String containing a command to be performed.
30
+ #
31
+ # Returns nothing.
32
+ def chroot_step(step)
33
+ chroot << step
34
+ end
35
+
36
+ # Public: Define a step to be performed after leaving the chroot
37
+ # environment.
38
+ #
39
+ # step - String containing a command to be performed.
40
+ #
41
+ # Returns nothing.
42
+ def post_step(step)
43
+ post << step
44
+ end
45
+
46
+ # Public: Return all pre-chroot steps separated by newlines.
47
+ #
48
+ # Returns a String.
49
+ def pre_s
50
+ pre.join("\n")
51
+ end
52
+
53
+ # Public: Return all chroot steps separated by newlines.
54
+ #
55
+ # Returns a String.
56
+ def chroot_s
57
+ chroot.join("\n")
58
+ end
59
+
60
+ # Public: Return all post-chroot steps separated by newlines.
61
+ #
62
+ # Returns a String.
63
+ def post_s
64
+ post.join("\n")
65
+ end
66
+
67
+ private
68
+
69
+ # Internal: Gets the internal Array of pre-chroot steps. Initializes to an
70
+ # empy Array if it doesn't exist.
71
+ #
72
+ # Returns an Array.
73
+ def pre
74
+ @collection[:pre] ||= []
75
+ end
76
+
77
+ # Internal: Gets the internal Array of chroot environment steps.
78
+ # Initializes to an empy Array if it doesn't exist.
79
+ #
80
+ # Returns an Array.
81
+ def chroot
82
+ @collection[:chroot] ||= []
83
+ end
84
+
85
+ # Internal: Gets the internal Array of post-chroot steps. Initializes to
86
+ # an empy Array if it doesn't exist.
87
+ #
88
+ # Returns an Array.
89
+ def post
90
+ @collection[:post] ||= []
91
+ end
92
+
93
+ # Internal: Iterate through available modules for the current platform,
94
+ # calling all methods available which end in '_cleanup'.
95
+ #
96
+ # Returns nothing.
97
+ def define_steps
98
+ load_each do |mod|
99
+ extend mod
100
+
101
+ mod.public_methods.select { |m| /_cleanup$/.match m }.each do |m|
102
+ self.send(m)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end; end; end
@@ -0,0 +1,18 @@
1
+ module CloudFlock; module App; module Common; class Exclusions; module Unix
2
+ # Public: The Centos module provides exclusions which are expected to be
3
+ # appropriate for CentOS hosts.
4
+ module Centos extend self
5
+ # Public: Exclude paths which are expected to be appropriate for CentOS
6
+ # hosts.
7
+ #
8
+ # Returns nothing.
9
+ def centos_exclusions
10
+ exclude '/etc/yum.repos.d/'
11
+ exclude '/usr/lib/yum-plugins'
12
+ exclude '/etc/yum.conf'
13
+ exclude '/etc/yum'
14
+ exclude '/etc/yum.repos.d'
15
+ exclude '/etc/sysconfig/iptables'
16
+ end
17
+ end
18
+ end; end; end; end; end
@@ -0,0 +1,18 @@
1
+ module CloudFlock; module App; module Common; class Exclusions; module Unix
2
+ # Public: The Redhat module provides exclusions which are expected to be
3
+ # appropriate for Redhat hosts.
4
+ module Redhat extend self
5
+ # Public: Exclude paths which are expected to be appropriate for RedHat
6
+ # hosts.
7
+ #
8
+ # Returns nothing.
9
+ def redhat_exclusions
10
+ exclude '/etc/yum.repos.d/'
11
+ exclude '/usr/lib/yum-plugins'
12
+ exclude '/etc/yum.conf'
13
+ exclude '/etc/yum'
14
+ exclude '/etc/yum.repos.d'
15
+ exclude '/etc/sysconfig/iptables'
16
+ end
17
+ end
18
+ end; end; end; end; end
@@ -0,0 +1,58 @@
1
+ require 'cloudflock/app/common/servers'
2
+
3
+ module CloudFlock; module App; module Common; class Exclusions
4
+ # Public: The Unix module provides exclusions which are expected to be
5
+ # appropriate for all Unix-like hosts.
6
+ module Unix extend self
7
+ # Public: Exclude paths which are expected to be appropriate for all
8
+ # Unix-like hosts.
9
+ #
10
+ # Returns nothing.
11
+ def unix_exclusions
12
+ exclude '/boot'
13
+ exclude '/dev'
14
+ exclude '/etc/fstab'
15
+ exclude '/etc/hosts'
16
+ exclude '/etc/init.d/nova-agent*'
17
+ exclude '/etc/driveclient'
18
+ exclude '/etc/initramfs-tools'
19
+ exclude '/etc/issue'
20
+ exclude '/etc/issue.net'
21
+ exclude '/etc/lvm'
22
+ exclude '/etc/mdadm*'
23
+ exclude '/etc/mtab'
24
+ exclude '/etc/mod*'
25
+ exclude '/etc/network/'
26
+ exclude '/etc/network.d/*'
27
+ exclude '/etc/networks'
28
+ exclude '/etc/rc3.d/S99Galaxy'
29
+ exclude '/etc/resolv.conf'
30
+ exclude '/etc/sysconfig/network'
31
+ exclude '/etc/sysconfig/network-scripts/*'
32
+ exclude '/etc/system-release'
33
+ exclude '/etc/system-release-cpe'
34
+ exclude '/etc/udev'
35
+ exclude '/etc/prelink*'
36
+ exclude '/etc/rc.conf'
37
+ exclude '/etc/conf.d/net'
38
+ exclude '/lib/init/rw'
39
+ exclude '/lib/firmware'
40
+ exclude '/lib/modules'
41
+ exclude '/lib/udev'
42
+ exclude '/root/.rackspace'
43
+ exclude '/mnt'
44
+ exclude '/net'
45
+ exclude '/opt/galaxy/'
46
+ exclude '/proc'
47
+ exclude '/sys'
48
+ exclude '/tmp'
49
+ exclude '/usr/sbin/nova-agent*'
50
+ exclude '/usr/share/initramfs-tools'
51
+ exclude '/usr/share/nova-agent*'
52
+ exclude '/var/cache/yum/*'
53
+ exclude '/var/lib/initramfs-tools'
54
+ exclude '/var/lock'
55
+ exclude '/var/log'
56
+ end
57
+ end
58
+ end; end; end; end
@@ -0,0 +1,57 @@
1
+ require 'cloudflock/app/common/platform_action'
2
+
3
+ module CloudFlock; module App; module Common
4
+ # Public: The Exclusions Class allows for building exclusions lists suitable
5
+ # for migrating live hosts based upon the detected platform.
6
+ class Exclusions < PlatformAction
7
+ # Public: Initialize the internal state, then find suitable exclusions for
8
+ # the detected platform.
9
+ #
10
+ # cpe - CPE object.
11
+ def initialize(cpe)
12
+ super
13
+
14
+ find_exclusions
15
+ end
16
+
17
+ # Public: Add a location to the list of paths to exclude from a migration.
18
+ #
19
+ # location - String containing a path.
20
+ #
21
+ # Returns nothing.
22
+ def exclude(location)
23
+ exclusions << location
24
+ end
25
+
26
+ # Public: Return all exclusions separated by newlines.
27
+ #
28
+ # Returns a String.
29
+ def to_s
30
+ exclusions.join("\n")
31
+ end
32
+
33
+ private
34
+
35
+ # Internal: Gets the internal Array of exclusions. Initializes to an empy
36
+ # Array if it doesn't exist.
37
+ #
38
+ # Returns an Array.
39
+ def exclusions
40
+ @collection[:exclude] ||= []
41
+ end
42
+
43
+ # Internal: Iterate through available modules for the current platform,
44
+ # calling all methods available which end in '_exclusions'.
45
+ #
46
+ # Returns nothing.
47
+ def find_exclusions
48
+ load_each do |mod|
49
+ extend mod
50
+
51
+ mod.public_methods.select { |m| /_exclusions$/.match m }.each do |m|
52
+ self.send(m)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end; end; end
@@ -0,0 +1,59 @@
1
+ module CloudFlock; module App; module Common
2
+ # Public: The PlatformAction Class provides the template for actions to be
3
+ # taken dependant upon the platform targeted.
4
+ class PlatformAction
5
+ # Public: Gets the Array containing the platform details.
6
+ attr_reader :platform
7
+
8
+ # Public: Gets the path prefix for including any applicable files.
9
+ attr_reader :prefix
10
+
11
+ # Public: Set internal parameters and initialize an empty Hash to be used
12
+ # as a collection.
13
+ #
14
+ # cpe - CPE object containing information off of which the platform
15
+ # parameters will be based.
16
+ def initialize(cpe)
17
+ classname = self.class.name.downcase.split(/::/).last
18
+ @prefix = "cloudflock/app/common/#{classname}/"
19
+ @platform = ['unix', cpe.vendor, cpe.product + cpe.version]
20
+ @collection = {}
21
+ end
22
+
23
+ # Public: Map a block to the platform Array.
24
+ #
25
+ # Yields each item in platform (per map).
26
+ def map_platforms(&block)
27
+ platform.map(&block)
28
+ end
29
+
30
+ # Public: Applies a block to each item in the platform Array.
31
+ #
32
+ # Yields each item in platform (per each).
33
+ def each_platform(&block)
34
+ platform.each(&block)
35
+ end
36
+
37
+ # Public: Loads each available file corresponding to a given platform in
38
+ # order of ascending specificity, then passes the Module to the block
39
+ # passed.
40
+ #
41
+ # Yields each Module.
42
+ def load_each(&block)
43
+ platforms = map_platforms { |name| name.gsub(/[^a-zA-Z0-9]/, '_') }
44
+
45
+ paths = (0...platforms.length).map { |i| platforms[(0...i)].join('/') }
46
+ mods = (0...platforms.length).map do |i|
47
+ platforms[(0...i)].map(&:capitalize)
48
+ end
49
+
50
+ (0...paths.length).each do |index|
51
+ begin
52
+ require prefix + paths[index]
53
+ block.call(mods[index].reduce(self.class) { |c,e| c.const_get(e) })
54
+ rescue LoadError
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end; end; end
@@ -0,0 +1,63 @@
1
+ require 'fog'
2
+ require 'console-glitter'
3
+ require 'cloudflock/app'
4
+
5
+ module CloudFlock; module App
6
+ # Public: The Rackspace module provides common methods for CLI interaction
7
+ # pertaining to interaction with the Rackspace API.
8
+ module Rackspace
9
+ include ConsoleGlitter
10
+ # Public: Gather information necessary to manage Rackspace cloud assets via
11
+ # API.
12
+ #
13
+ # Returns a Hash containing information necessary to establish an API
14
+ # session.
15
+ def define_rackspace_api
16
+ api = { provider: 'rackspace' }
17
+
18
+ api[:rackspace_username] = UI.prompt('Rackspace Cloud Username')
19
+ api[:rackspace_api_key] = UI.prompt('Rackspace Cloud API key')
20
+
21
+ region = UI.prompt('Account Region (us, uk)',
22
+ valid_answers: [/^u[sk]$/i])
23
+ region.gsub!(/$/, '_AUTH_ENDPOINT')
24
+ api[:rackspace_region] = Fog::Rackspace.const_get(region.upcase)
25
+
26
+ api
27
+ end
28
+
29
+ # Public: Wrap define_rackspace_service_region, specifying
30
+ # 'cloudServersOpenStack' as the service type.
31
+ #
32
+ # api - Authenticated Fog API instance.
33
+ def define_rackspace_cloudservers_region(api)
34
+ api.merge(define_rackspace_service_region(api, 'cloudServersOpenStack'))
35
+ end
36
+
37
+ # Public: Wrap define_rackspace_service_region, specifying 'cloudFiles' as
38
+ # the service type.
39
+ #
40
+ # api - Authenticated Fog API instance.
41
+ def define_rackspace_files_region(api)
42
+ api.merge(define_rackspace_service_region(api, 'cloudFiles'))
43
+ end
44
+
45
+ # Public: Have the user select from a list of regions available to their
46
+ # Rackspace account.
47
+ #
48
+ # api - Authenticated Fog API instance.
49
+ # service - String describing the service to be used (e.g. 'cloudFiles',
50
+ # 'cloudServersOpenStack').
51
+ #
52
+ # Returns a Hash containing a :rackspace_region => String mapping.
53
+ def define_rackspace_service_region(api, service)
54
+ identity = Fog::Identity.new(api)
55
+ regions = identity.service_catalog.display_service_regions(service)
56
+ regions = regions.split(', ').map { |e| e.gsub(/^:/, '') }
57
+
58
+ region = UI.prompt("Target Region (#{regions.join(', ')})",
59
+ valid_answers: regions)
60
+ { rackspace_region: region }
61
+ end
62
+ end
63
+ end; end