vagrant-oneandone 1.0.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +29 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +12 -0
  7. data/LICENSE +201 -0
  8. data/README.md +275 -0
  9. data/Rakefile +33 -0
  10. data/box/README.md +13 -0
  11. data/box/Vagrantfile +7 -0
  12. data/box/dummy.box +0 -0
  13. data/box/metadata.json +3 -0
  14. data/examples/01_coreos_simple/Vagrantfile +12 -0
  15. data/examples/02_django_centos7_app/Vagrantfile +14 -0
  16. data/examples/03_ubuntu12.04_shell_provision/Vagrantfile +19 -0
  17. data/examples/04_parallel_servers/Vagrantfile +26 -0
  18. data/examples/05_debian8_docker_provision/Vagrantfile +17 -0
  19. data/lib/vagrant-oneandone.rb +26 -0
  20. data/lib/vagrant-oneandone/action.rb +163 -0
  21. data/lib/vagrant-oneandone/action/connect_1and1.rb +28 -0
  22. data/lib/vagrant-oneandone/action/create.rb +76 -0
  23. data/lib/vagrant-oneandone/action/destroy.rb +69 -0
  24. data/lib/vagrant-oneandone/action/get_state.rb +17 -0
  25. data/lib/vagrant-oneandone/action/power_off.rb +49 -0
  26. data/lib/vagrant-oneandone/action/power_on.rb +39 -0
  27. data/lib/vagrant-oneandone/action/read_ssh_info.rb +54 -0
  28. data/lib/vagrant-oneandone/action/read_state.rb +44 -0
  29. data/lib/vagrant-oneandone/action/reload.rb +48 -0
  30. data/lib/vagrant-oneandone/command/list_appliances.rb +38 -0
  31. data/lib/vagrant-oneandone/command/list_datacenters.rb +36 -0
  32. data/lib/vagrant-oneandone/command/list_firewalls.rb +32 -0
  33. data/lib/vagrant-oneandone/command/list_ips.rb +45 -0
  34. data/lib/vagrant-oneandone/command/list_load_balancers.rb +43 -0
  35. data/lib/vagrant-oneandone/command/list_monitor_policies.rb +32 -0
  36. data/lib/vagrant-oneandone/command/list_servers.rb +32 -0
  37. data/lib/vagrant-oneandone/command/list_sizes.rb +43 -0
  38. data/lib/vagrant-oneandone/command/main.rb +85 -0
  39. data/lib/vagrant-oneandone/command/utils.rb +31 -0
  40. data/lib/vagrant-oneandone/config.rb +65 -0
  41. data/lib/vagrant-oneandone/config_resolver.rb +97 -0
  42. data/lib/vagrant-oneandone/errors.rb +45 -0
  43. data/lib/vagrant-oneandone/plugin.rb +36 -0
  44. data/lib/vagrant-oneandone/provider.rb +41 -0
  45. data/lib/vagrant-oneandone/version.rb +5 -0
  46. data/locales/en.yml +124 -0
  47. data/vagrant-oneandone.gemspec +29 -0
  48. data/vagrant-spec.config.rb +9 -0
  49. metadata +189 -0
@@ -0,0 +1,43 @@
1
+ require 'vagrant-oneandone/command/utils'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ module Command
6
+ class ListLoadBalancers < Vagrant.plugin('2', :command)
7
+ include VagrantPlugins::OneAndOne::Command::Utils
8
+
9
+ def execute
10
+ options = OptionParser.new do |o|
11
+ o.banner = I18n.t('vagrant_1and1.command.list_load_balancers')
12
+ o.separator ''
13
+ o.separator 'Usage: vagrant oneandone loadbalancers [<api_key>]'
14
+ o.separator ''
15
+ end
16
+
17
+ argv = parse_options(options)
18
+ return unless argv
19
+
20
+ compute = fog_oneandone(argv[0])
21
+
22
+ rows = []
23
+ compute.list_load_balancers.body.each do |lb|
24
+ rows << [
25
+ lb['id'],
26
+ lb['name'],
27
+ lb['ip'],
28
+ lb['method'],
29
+ lb['state'],
30
+ lb['datacenter']['country_code']
31
+ ]
32
+ end
33
+
34
+ display_table(
35
+ @env,
36
+ ['ID', 'Name', 'IP Address', 'Method', 'State', 'Data Center'],
37
+ rows
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ require 'vagrant-oneandone/command/utils'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ module Command
6
+ class ListMonitorPolicies < Vagrant.plugin('2', :command)
7
+ include VagrantPlugins::OneAndOne::Command::Utils
8
+
9
+ def execute
10
+ options = OptionParser.new do |o|
11
+ o.banner = I18n.t('vagrant_1and1.command.list_monitor_policies')
12
+ o.separator ''
13
+ o.separator 'Usage: vagrant oneandone monitors [<api_key>]'
14
+ o.separator ''
15
+ end
16
+
17
+ argv = parse_options(options)
18
+ return unless argv
19
+
20
+ compute = fog_oneandone(argv[0])
21
+
22
+ rows = []
23
+ compute.monitoring_policies.all.each do |mp|
24
+ rows << [mp.id, mp.name, mp.email, mp.state, mp.agent ? 'yes' : 'no']
25
+ end
26
+
27
+ display_table(@env, %w(ID Name Email State Agent), rows)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require 'vagrant-oneandone/command/utils'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ module Command
6
+ class ListServers < Vagrant.plugin('2', :command)
7
+ include VagrantPlugins::OneAndOne::Command::Utils
8
+
9
+ def execute
10
+ options = OptionParser.new do |o|
11
+ o.banner = I18n.t('vagrant_1and1.command.list_servers')
12
+ o.separator ''
13
+ o.separator 'Usage: vagrant oneandone servers [<api_key>]'
14
+ o.separator ''
15
+ end
16
+
17
+ argv = parse_options(options)
18
+ return unless argv
19
+
20
+ compute = fog_oneandone(argv[0])
21
+
22
+ rows = []
23
+ compute.servers.all.each do |s|
24
+ rows << [s.id, s.name, s.status['state'], s.datacenter['country_code']]
25
+ end
26
+
27
+ display_table(@env, ['ID', 'Name', 'State', 'Data Center'], rows)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ require 'vagrant-oneandone/command/utils'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ module Command
6
+ class ListSizes < Vagrant.plugin('2', :command)
7
+ include VagrantPlugins::OneAndOne::Command::Utils
8
+
9
+ def execute
10
+ options = OptionParser.new do |o|
11
+ o.banner = I18n.t('vagrant_1and1.command.list_sizes')
12
+ o.separator ''
13
+ o.separator 'Usage: vagrant oneandone sizes [<api_key>]'
14
+ o.separator ''
15
+ end
16
+
17
+ argv = parse_options(options)
18
+ return unless argv
19
+
20
+ compute = fog_oneandone(argv[0])
21
+
22
+ rows = []
23
+ compute.list_fixed_servers.body.each do |s|
24
+ rows << [
25
+ s['id'],
26
+ s['name'],
27
+ s['hardware']['ram'],
28
+ s['hardware']['vcore'],
29
+ s['hardware']['cores_per_processor'],
30
+ s['hardware']['hdds'][0]['size']
31
+ ]
32
+ end
33
+
34
+ display_table(
35
+ @env,
36
+ ['ID', 'Name', 'RAM (GB)', 'CPU No.', 'Cores per CPU', 'Disk Size (GB)'],
37
+ rows
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,85 @@
1
+ require 'vagrant-oneandone/action'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ module Command
6
+ class Main < Vagrant.plugin('2', :command)
7
+ def self.synopsis
8
+ I18n.t('vagrant_1and1.command.synopsis')
9
+ end
10
+
11
+ def initialize(argv, env)
12
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
13
+
14
+ @subcommands = Vagrant::Registry.new
15
+
16
+ @subcommands.register(:appliances) do
17
+ require File.expand_path('../list_appliances', __FILE__)
18
+ ListAppliances
19
+ end
20
+ @subcommands.register(:datacenters) do
21
+ require File.expand_path('../list_datacenters', __FILE__)
22
+ ListDatacenters
23
+ end
24
+ @subcommands.register(:firewalls) do
25
+ require File.expand_path('../list_firewalls', __FILE__)
26
+ ListFirewalls
27
+ end
28
+ @subcommands.register(:ips) do
29
+ require File.expand_path('../list_ips', __FILE__)
30
+ ListIPs
31
+ end
32
+ @subcommands.register(:loadbalancers) do
33
+ require File.expand_path('../list_load_balancers', __FILE__)
34
+ ListLoadBalancers
35
+ end
36
+ @subcommands.register(:monitors) do
37
+ require File.expand_path('../list_monitor_policies', __FILE__)
38
+ ListMonitorPolicies
39
+ end
40
+ @subcommands.register(:servers) do
41
+ require File.expand_path('../list_servers', __FILE__)
42
+ ListServers
43
+ end
44
+ @subcommands.register(:sizes) do
45
+ require File.expand_path('../list_sizes', __FILE__)
46
+ ListSizes
47
+ end
48
+
49
+ super(argv, env)
50
+ end
51
+
52
+ def execute
53
+ if @main_args.include?('-h') || @main_args.include?('--help')
54
+ return help
55
+ end
56
+
57
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
58
+ return help if !command_class || !@sub_command
59
+
60
+ # Initialize and execute the command class
61
+ command_class.new(@sub_args, @env).execute
62
+ end
63
+
64
+ def help
65
+ opts = OptionParser.new do |o|
66
+ o.banner = 'Usage: vagrant oneandone <subcommand> [<api_key>]'
67
+ o.separator ''
68
+ o.separator I18n.t('vagrant_1and1.command.available_subcommands')
69
+
70
+ keys = []
71
+ @subcommands.each { |key| keys << key.to_s }
72
+
73
+ keys.sort.each { |key| o.separator " #{key}" }
74
+
75
+ o.separator ''
76
+ o.separator I18n.t('vagrant_1and1.command.help_subcommands') +
77
+ ' `vagrant oneandone <subcommand> -h`'
78
+ end
79
+
80
+ @env.ui.info(opts.help)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,31 @@
1
+ require 'fog-oneandone'
2
+ require 'terminal-table'
3
+
4
+ module VagrantPlugins
5
+ module OneAndOne
6
+ module Command
7
+ module Utils
8
+ def fog_oneandone(token)
9
+ api_key = token ? token : ENV['ONEANDONE_API_KEY']
10
+
11
+ raise Errors::NoApiKeyError unless api_key
12
+
13
+ params = {
14
+ oneandone_api_key: api_key
15
+ }
16
+
17
+ Fog::Compute::OneAndOne.new params
18
+ end
19
+
20
+ def display_table(env, headers, rows)
21
+ table = Terminal::Table.new headings: headers, rows: rows
22
+ if env.respond_to?('ui')
23
+ env.ui.info(table.to_s)
24
+ else
25
+ env[:ui].info(table.to_s)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,65 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantPlugins
4
+ module OneAndOne
5
+ class Config < Vagrant.plugin('2', :config)
6
+ attr_accessor :api_key
7
+ attr_accessor :name
8
+ attr_accessor :description
9
+ attr_accessor :fixed_size
10
+ attr_accessor :datacenter
11
+ attr_accessor :appliance
12
+ attr_accessor :password
13
+ attr_accessor :firewall_id
14
+ attr_accessor :ip
15
+ attr_accessor :load_balancer_id
16
+ attr_accessor :monitoring_policy_id
17
+ attr_accessor :timeout
18
+
19
+ def initialize
20
+ @api_key = UNSET_VALUE
21
+ @name = UNSET_VALUE
22
+ @description = UNSET_VALUE
23
+ @fixed_size = UNSET_VALUE
24
+ @datacenter = UNSET_VALUE
25
+ @appliance = UNSET_VALUE
26
+ @password = UNSET_VALUE
27
+ @firewall_id = UNSET_VALUE
28
+ @ip = UNSET_VALUE
29
+ @load_balancer_id = UNSET_VALUE
30
+ @monitoring_policy_id = UNSET_VALUE
31
+ @timeout = UNSET_VALUE
32
+ end
33
+
34
+ def finalize!
35
+ @api_key = ENV['ONEANDONE_API_KEY'] if @api_key == UNSET_VALUE
36
+ @name = nil if @name == UNSET_VALUE
37
+ @password = nil if @password == UNSET_VALUE
38
+ @appliance = 'ubuntu1404-64std' if @appliance == UNSET_VALUE
39
+ @datacenter = 'US' if @datacenter == UNSET_VALUE
40
+ @fixed_size = 'M' if @fixed_size == UNSET_VALUE
41
+ @timeout = nil if @timeout == UNSET_VALUE
42
+ @ip = nil if @ip == UNSET_VALUE
43
+ @firewall_id = nil if @firewall_id == UNSET_VALUE
44
+ @load_balancer_id = nil if @load_balancer_id == UNSET_VALUE
45
+ @monitoring_policy_id = nil if @monitoring_policy_id == UNSET_VALUE
46
+ @description = nil if @description == UNSET_VALUE
47
+ end
48
+
49
+ def validate(machine)
50
+ errors = []
51
+ errors << I18n.t('vagrant_1and1.config.api_key_required') unless @api_key
52
+
53
+ key = machine.config.ssh.private_key_path
54
+ key = key[0] if key.is_a?(Array)
55
+ if !key
56
+ errors << I18n.t('vagrant_1and1.config.private_key')
57
+ elsif !File.file?(File.expand_path("#{key}.pub", machine.env.root_path))
58
+ errors << I18n.t('vagrant_1and1.config.public_key', key: "#{key}.pub")
59
+ end
60
+
61
+ { 'OneAndOne Provider' => errors }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,97 @@
1
+ module VagrantPlugins
2
+ module OneAndOne
3
+ class ConfigResolver
4
+ def initialize(env)
5
+ @logger = Log4r::Logger.new('vagrant_1and1::action::config_resolver')
6
+ @compute = env[:oneandone_compute]
7
+ @provider_config = env[:machine].provider_config
8
+ end
9
+
10
+ def resolve_fixed_instance_size(env)
11
+ @logger.info 'Obtaining fixed-instance list'
12
+
13
+ env[:ui].info(I18n.t('vagrant_1and1.finding_fixed_instance_size'))
14
+
15
+ sizes = @compute.list_fixed_servers
16
+
17
+ @logger.info "Finding size matching '#{@provider_config.fixed_size}'"
18
+
19
+ size = find_matching(sizes.body, %w(id name), @provider_config.fixed_size)
20
+
21
+ raise Errors::NoMatchingFixedSizeError unless size
22
+ size['id']
23
+ end
24
+
25
+ def resolve_appliance(env)
26
+ @logger.info 'Obtaining server appliances'
27
+
28
+ env[:ui].info(I18n.t('vagrant_1and1.finding_appliance'))
29
+
30
+ appliances = @compute.list_server_appliances(q: @provider_config.appliance)
31
+
32
+ @logger.info "Finding server appliance matching '#{@provider_config.appliance}'"
33
+
34
+ app = find_matching(appliances.body, %w(id name), @provider_config.appliance)
35
+
36
+ raise Errors::NoMatchingApplianceError unless app
37
+ raise Errors::UnsupportedApplianceError if 'linux'.casecmp(app['os_family']) != 0
38
+ app['id']
39
+ end
40
+
41
+ def resolve_datacenter(env)
42
+ @logger.info 'Obtaining data centers'
43
+
44
+ env[:ui].info(I18n.t('vagrant_1and1.finding_datacenter'))
45
+
46
+ datacenters = @compute.list_datacenters
47
+
48
+ @logger.info "Finding data center matching '#{@provider_config.datacenter}'"
49
+
50
+ dc = find_matching(datacenters.body, %w(id country_code), @provider_config.datacenter)
51
+
52
+ raise Errors::NoMatchingDataCenterError unless dc
53
+ dc['id']
54
+ end
55
+
56
+ def resolve_public_ip(env)
57
+ # do nothing unless IP is set
58
+ if @provider_config.ip
59
+ @logger.info 'Obtaining public IPs'
60
+
61
+ env[:ui].info(I18n.t('vagrant_1and1.finding_public_ip'))
62
+
63
+ public_ips = @compute.list_public_ips
64
+
65
+ @logger.info "Finding public IP matching '#{@provider_config.ip}'"
66
+
67
+ ip = find_matching(public_ips.body, %w(id ip), @provider_config.ip)
68
+
69
+ raise Errors::NoMatchingPublicIPAddressError unless ip
70
+
71
+ raise Errors::IPAddressInUseError if ip['assigned_to']
72
+
73
+ ip['id']
74
+ end
75
+ end
76
+
77
+ def resolve_ssh_key(env)
78
+ private_key = env[:machine].config.ssh.private_key_path
79
+ private_key = private_key[0] if private_key.is_a?(Array)
80
+ private_key = File.expand_path(private_key, env[:machine].env.root_path)
81
+ OneAndOne.public_key(private_key)
82
+ end
83
+
84
+ private
85
+
86
+ def find_matching(collection, keys, value)
87
+ collection.each do |item|
88
+ keys.each do |key|
89
+ return item if value.casecmp(item[key]) == 0
90
+ end
91
+ end
92
+ @logger.error "No item key '#{value}' found in collection #{collection}"
93
+ nil
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,45 @@
1
+ module VagrantPlugins
2
+ module OneAndOne
3
+ module Errors
4
+ class OneAndOneError < Vagrant::Errors::VagrantError
5
+ error_namespace('vagrant_1and1.errors')
6
+ end
7
+
8
+ class IPAddressInUseError < OneAndOneError
9
+ error_key(:ip_address_already_in_use)
10
+ end
11
+
12
+ class NoApiKeyError < OneAndOneError
13
+ error_key(:missing_api_key)
14
+ end
15
+
16
+ class NoMatchingFixedSizeError < OneAndOneError
17
+ error_key(:no_matching_fixed_size)
18
+ end
19
+
20
+ class NoMatchingApplianceError < OneAndOneError
21
+ error_key(:no_matching_appliance)
22
+ end
23
+
24
+ class NoMatchingDataCenterError < OneAndOneError
25
+ error_key(:no_matching_datacenter)
26
+ end
27
+
28
+ class NoMatchingPublicIPAddressError < OneAndOneError
29
+ error_key(:no_matching_public_ip)
30
+ end
31
+
32
+ class PublicKeyError < OneAndOneError
33
+ error_key(:ssh_key_not_found)
34
+ end
35
+
36
+ class RsyncError < OneAndOneError
37
+ error_key(:rsync)
38
+ end
39
+
40
+ class UnsupportedApplianceError < OneAndOneError
41
+ error_key(:unsupported_appliance)
42
+ end
43
+ end
44
+ end
45
+ end