File: servers.rb

package info (click to toggle)
ruby-fog-google 1.19.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,568 kB
  • sloc: ruby: 16,775; makefile: 3
file content (123 lines) | stat: -rw-r--r-- 3,979 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Fog
  module Compute
    class Google
      class Servers < Fog::Collection
        model Fog::Compute::Google::Server

        def all(zone: nil, filter: nil, max_results: nil,
                order_by: nil, page_token: nil)
          opts = {
            :filter => filter,
            :max_results => max_results,
            :order_by => order_by,
            :page_token => page_token
          }

          if zone
            data = service.list_servers(zone, **opts).to_h[:items] || []
          else
            data = []
            service.list_aggregated_servers(**opts).items.each_value do |scoped_lst|
              if scoped_lst && scoped_lst.instances
                data.concat(scoped_lst.instances.map(&:to_h))
              end
            end
          end
          load(data)
        end

        # TODO: This method needs to take self_links as well as names
        def get(identity, zone = nil)
          if zone
            server = service.get_server(identity, zone).to_h
            return new(server)
          elsif identity
            response = all(:filter => "name eq .*#{identity}",
                           :max_results => 1)
            server = response.first unless response.empty?
            return server
          end
        rescue ::Google::Apis::ClientError => e
          raise e unless e.status_code == 404
          nil
        end

        def bootstrap(public_key_path: nil, **opts)
          name = "fog-#{Time.now.to_i}"
          zone_name = "us-central1-f"

          disks = opts[:disks]

          if disks.nil? || disks.empty?
            # create the persistent boot disk
            source_img = service.images.get_from_family("debian-9")
            disk_defaults = {
              :name => name,
              :size_gb => 10,
              :zone_name => zone_name,
              :source_image => source_img.self_link
            }
            disk = service.disks.create(**disk_defaults.merge(opts))
            disk.wait_for { disk.ready? }

            disks = [disk]
          end

          # TODO: Remove the network init when #360 is fixed
          network = { :network => "global/networks/default",
                      :access_configs => [{ :name => "External NAT",
                                            :type => "ONE_TO_ONE_NAT" }] }

          # Merge the options with the defaults, overwriting defaults
          # if an option is provided
          data = { :name => name,
                   :zone => zone_name,
                   :disks => disks,
                   :network_interfaces => [network],
                   :public_key => get_public_key(public_key_path),
                   :username => ENV["USER"] }.merge(opts)

          data[:machine_type] = "n1-standard-1" unless data[:machine_type]

          server = new(data)
          server.save
          server.wait_for { ready? }

          # Set the disk to be autodeleted
          # true - autodelete setting
          # nil - device name (not needed if there's only one disk)
          # false - set async to false so set the property synchronously
          server.set_disk_auto_delete(true, nil, false)

          server
        end

        private

        # Defaults to:
        # 1. ~/.ssh/google_compute_engine.pub
        # 2. ~/.ssh/id_rsa.pub
        PUBLIC_KEY_DEFAULTS = %w(
          ~/.ssh/google_compute_engine.pub
          ~/.ssh/id_rsa.pub
        ).freeze
        def get_public_key(public_key_path)
          unless public_key_path
            PUBLIC_KEY_DEFAULTS.each do |path|
              if File.exist?(File.expand_path(path))
                public_key_path = path
                break
              end
            end
          end

          if public_key_path.nil? || public_key_path.empty?
            raise Fog::Errors::Error.new("Cannot bootstrap instance without a public key")
          end

          File.read(File.expand_path(public_key_path))
        end
      end
    end
  end
end