Statistics
| Branch: | Tag: | Revision:

one / src / ipamm_mad / one_ipam.rb @ 9a87a333

History | View | Annotate | Download (5.51 KB)

1
#!/usr/bin/env ruby
2

    
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

    
19
ONE_LOCATION=ENV["ONE_LOCATION"]
20

    
21
if !ONE_LOCATION
22
    RUBY_LIB_LOCATION="/usr/lib/one/ruby"
23
    ETC_LOCATION="/etc/one/"
24
else
25
    RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
26
    ETC_LOCATION=ONE_LOCATION+"/etc/"
27
end
28

    
29
$: << RUBY_LIB_LOCATION
30

    
31

    
32
require 'scripts_common'
33
require 'OpenNebulaDriver'
34
require 'rexml/document'
35
require 'getoptlong'
36
require 'shellwords'
37

    
38
# IPAM Manager driver
39
class IPAMDriver < OpenNebulaDriver
40

    
41
    # IPAM Driver Protocol constants
42
    ACTION = {
43
        :register_address_range => "REGISTER_ADDRESS_RANGE",
44
        :allocate_address       => "ALLOCATE_ADDRESS",
45
        :get_address            => "GET_ADDRESS",
46
        :free_address           => "FREE_ADDRESS"
47
    }
48

    
49
    # Init the driver
50
    def initialize(ipam_type, options={})
51
        @options={
52
            :concurrency   => 1,
53
            :threaded      => false,
54
            :retries       => 0,
55
            :local_actions => {
56
                ACTION[:register_address_range] => nil,
57
                ACTION[:allocate_address]       => nil,
58
                ACTION[:get_address]            => nil,
59
                ACTION[:free_address]           => nil
60
            }
61
        }.merge!(options)
62

    
63
        super("ipam/", @options)
64

    
65
        if ipam_type == nil
66
            @types = Dir["#{@local_scripts_path}/*/"].map do |d|
67
                d.split('/')[-1]
68
            end
69
        elsif ipam_type.class == String
70
            @types = [ipam_type]
71
        else
72
            @types = ipam_type
73
        end
74

    
75
        register_action(ACTION[:register_address_range].to_sym,
76
            method("register_address_range"))
77

    
78
        register_action(ACTION[:allocate_address].to_sym,
79
            method("allocate_address"))
80

    
81
        register_action(ACTION[:get_address].to_sym, method("get_address"))
82

    
83
        register_action(ACTION[:free_address].to_sym, method("free_address"))
84
    end
85

    
86
    def register_address_range(id, drv_message)
87
        do_ipam_action(id, :register_address_range, drv_message)
88
    end
89

    
90
    def allocate_address(id, drv_message)
91
        do_ipam_action(id, :allocate_address, drv_message)
92
    end
93

    
94
    def get_address(id, drv_message)
95
        do_ipam_action(id, :get_address, drv_message)
96
    end
97

    
98
    def free_address(id, drv_message)
99
        do_ipam_action(id, :free_address, drv_message)
100
    end
101
    private
102

    
103
    def do_ipam_action(id, action, arguments)
104
        begin
105
            message = Base64.decode64(arguments)
106
            xml_doc = REXML::Document.new(message)
107

    
108
            xml_doc.root
109
            ipam = xml_doc.elements['IPAM_DRIVER_ACTION_DATA/AR/IPAM_MAD'].text.strip
110
            raise if ipam.empty?
111
        rescue
112
            send_message(ACTION[action], RESULT[:failure], id,
113
                "Cannot perform #{action}, cannot find ipman driver")
114
            return
115
        end
116

    
117
        return if not is_available?(ipam, id, action)
118

    
119
        path = File.join(@local_scripts_path, ipam)
120
        cmd  = File.join(path, ACTION[action].downcase)
121
        cmd << " " << arguments
122

    
123
        rc = LocalCommand.run(cmd, log_method(id))
124

    
125
        result, info = get_info_from_execution(rc)
126

    
127
        info = Base64::encode64(info).strip.delete("\n")
128

    
129
        send_message(ACTION[action], result, id, info)
130
    end
131

    
132
    def is_available?(ipam, id, action)
133
        if @types.include?(ipam)
134
            return true
135
        else
136
            send_message(ACTION[action], RESULT[:failure], id,
137
                "IPAM driver '#{ipam}' not available")
138
            return false
139
        end
140
    end
141
end
142

    
143
################################################################################
144
# IPAM Driver Main program
145
################################################################################
146
opts = GetoptLong.new(
147
    [ '--threads',    '-t', GetoptLong::OPTIONAL_ARGUMENT ],
148
    [ '--ipam-types', '-i', GetoptLong::REQUIRED_ARGUMENT ],
149
    [ '--timeout',    '-w', GetoptLong::OPTIONAL_ARGUMENT ]
150
)
151

    
152
i_types = nil
153
threads = 1
154
timeout = nil
155

    
156
begin
157
    opts.each do |opt, arg|
158
        case opt
159
            when '--ipam-types'
160
                i_types = arg.split(',').map {|a| a.strip }
161
            when '--threads'
162
                threads = arg.to_i
163
            when '--timeout'
164
                timeout = arg.to_i
165
        end
166
    end
167
rescue Exception => e
168
    exit(-1)
169
end
170

    
171
ipam_driver = IPAMDriver.new(i_types,
172
                             :concurrency   => threads,
173
                             :timeout       => timeout)
174
ipam_driver.start_driver
175