File: address.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 (133 lines) | stat: -rw-r--r-- 4,209 bytes parent folder | download | duplicates (2)
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
124
125
126
127
128
129
130
131
132
133
module Fog
  module Compute
    class Google
      ##
      # Represents an Address resource
      #
      # @see https://developers.google.com/compute/docs/reference/latest/addresses
      class Address < Fog::Model
        identity :name

        attribute :kind
        attribute :id
        attribute :address
        attribute :creation_timestamp, :aliases => "creationTimestamp"
        attribute :description
        attribute :region
        attribute :self_link, :aliases => "selfLink"
        attribute :status
        attribute :users

        IN_USE_STATE   = "IN_USE".freeze
        RESERVED_STATE = "RESERVED".freeze
        RESERVING_STATE = "RESERVING".freeze

        def server
          return nil if !in_use? || users.nil? || users.empty?

          service.servers.get(users.first.split("/")[-1])
        end

        def server=(server)
          requires :identity, :region
          server ? associate(server) : disassociate
        end

        def save
          requires :identity, :region

          data = service.insert_address(identity, region, attributes)
          operation = Fog::Compute::Google::Operations
                      .new(service: service)
                      .get(data.name, nil, data.region)
          operation.wait_for { ready? }
          reload
        end

        def destroy(async = true)
          requires :identity, :region

          data = service.delete_address(identity, region.split("/")[-1])
          operation = Fog::Compute::Google::Operations
                      .new(:service => service)
                      .get(data.name, nil, data.region)

          operation.wait_for { ready? } unless async
          operation
        end

        def reload
          requires :identity, :region

          data = collection.get(identity, region.split("/")[-1])
          merge_attributes(data.attributes)
          self
        end

        def in_use?
          status == IN_USE_STATE
        end

        def ready?
          status != RESERVING_STATE
        end

        private

        # Associates the ip address to a given server
        #
        # @param [String]  server - GCE instance name
        # @param [String]  nic_name - NIC interface name, defaults to GCE
        #                             standard primary nic - "nic0"
        # @param [Boolean]  async - whether to run the operation asynchronously
        #
        # @return [Fog::Compute::Google::Operation]
        def associate(server, nic_name = "nic0", async = false)
          requires :address

          data = service.add_server_access_config(
            server.name, server.zone, nic_name, :nat_ip => address
          )
          operation = Fog::Compute::Google::Operations
                      .new(:service => service)
                      .get(data.name, data.zone)
          operation.wait_for { ready? } unless async
        end

        # Disassociates the ip address from a resource it's attached to
        #
        # @param [Boolean]  async - whether to run the operation asynchronously
        #
        # @return [Fog::Compute::Google::Operation]
        def disassociate(async = false)
          requires :address

          return nil if !in_use? || users.nil? || users.empty?

          server_name = users.first.split("/")[-1]

          # An address can only be associated with one server at a time
          server = service.servers.get(server_name)
          server.network_interfaces.each do |nic|
            # Skip if nic has no access_config
            next if nic[:access_configs].nil? || nic[:access_configs].empty?

            access_config = nic[:access_configs].first

            # Skip access_config with different address
            next if access_config[:nat_ip] != address

            data = service.delete_server_access_config(
              server.name, server.zone, nic[:name], access_config[:name]
            )
            operation = Fog::Compute::Google::Operations
                        .new(:service => service)
                        .get(data.name, data.zone)
            operation.wait_for { ready? } unless async
            return operation
          end
        end
      end
    end
  end
end