Automatic OS IP assignment. What do I need to make this happen?

Hi All,

Is it possible to get ON to automatically assign an IP to the OS (similar to cloud-init) ?

Tried. Not able to get that quite right. VM instances show an IP has been assigned to the profile but it’s not assigned on the guest VM.

Ideally, I’m looking for a solution whereby I run my own tool to look for a free IP on my network and assign it. ON’s approach appears sequential as seen from the UI. This is good for a free range, but I need something more dynamic.

Cheers,

Hi All,

“Tried. Not able to get that quite right. VM instances show an IP has been assigned to the profile but it’s not assigned on the guest VM.”

I’ve solved the first part above. I would like to find out if there is a way to modify the OneGate and OneGate Context logic to include the running off a custom script responsible for selecting a free IP. Is there such a way built-in?

Thx,
TK

I’m looking for something along the lines of a plugin system such as the following:

  1. Define a variable such as EXT_IP_ASSIGN = “yes” followed by EXT_IP_ASSIGN_CMD = “/path/to/my/ip-script.sh”

  2. Above returns an IP from a subnet which already has preallocated IP’s for other servers. How I determine the available IP would be up to me.

Thx,

Hi,

I’d guess you’ve followed Open Cloud Contextualization ?

I think that instead of looking how to alter the OneGate service you should to take a look at the IPAM Driver. Just for a refence/ideas/ you could take a look at the Included driver for Packet.

Hope this helps.

Best Regards,
Anton Todorov

Hi,

I’d guess you’ve followed Open Cloud Contextualization ?

Correct.

I think that instead of looking how to alter the OneGate service you should to take a look at the IPAM Driver. Just for a refence/ideas/ you could take a look at the Included driver for Packet.

That looks very promising. I’ll take a look and get back to you if it meets our needs. Thank you!

Hope this helps.

Best Regards,
Anton Todorov

Hey Anton,

I’m revisiting this topic.

Given this:

[root@one01 dummy]# ls -altri
total 32
202709534 -rwxr-xr-x. 1 oneadmin oneadmin 2287 Sep 24 09:59 unregister_address_range
202709533 -rwxr-xr-x. 1 oneadmin oneadmin 4666 Sep 24 09:59 register_address_range
202709532 -rwxr-xr-x. 1 oneadmin oneadmin 4249 Sep 24 09:59 get_address
202709531 -rwxr-xr-x. 1 oneadmin oneadmin 3768 Sep 24 09:59 free_address
202709530 -rwxr-xr-x. 1 oneadmin oneadmin 3866 Sep 24 09:59 allocate_address
202709529 drwxr-x---. 2 oneadmin oneadmin 4096 Nov  3 19:37 .
134569729 drwxr-x---. 4 oneadmin oneadmin   31 Nov  3 19:37 ..
[root@one01 dummy]# pwd
/var/lib/one/remotes/ipam/dummy
[root@one01 dummy]# cd ..
[root@one01 ipam]# ls -altri
total 12
202709529 drwxr-x---.  2 oneadmin oneadmin 4096 Nov  3 19:37 dummy
134569729 drwxr-x---.  4 oneadmin oneadmin   31 Nov  3 19:37 .
   635507 drwxr-x---.  2 oneadmin oneadmin 4096 Nov  3 19:37 packet
134569666 drwxr-x---. 13 oneadmin oneadmin 4096 Nov  3 19:37 ..
[root@one01 ipam]#

and the above two pages, I’m free to write any code in any language as long as it has the following components?

allocate_address  
free_address  
get_address  
register_address_range  
unregister_address_range

In my case, my VLAN has randomly allocated addressed and I don’t know ahead of time what these could be. In that respect I can only define the top three (perhaps) to get and free single addresses. To that end, have the following questions:

  1. Will the plugin system break or have issues if I don’t define all the functions in my code?

  2. I need to return a single IP address to register a VM with and unregister the IP when VM is disposed of. There will be a VLAN (subnet) to choose from that I could pass but it will represent randomly allocated IP’s. How will this look like if I want to reserve a single IP and free a single IP.

  3. Does the plugin system support calling subscripts as root to automatically register the environment with said IP to the DNS?

Thx,
TK

Hello @TomK

1 - You have to define all the functions, but if one of them has to be empty, just put exit 0.
2 - With allocate script you can just allocate one IP, see comments in this file. Just use size 1 and it will allocate just one IP.
3 - Yes, you can call all the scripts you want, but remember that the main script has to return the needed information by OpenNebula, you can find this information here.

1 - Ok

2 - So I’m thinking something like this then for say the get_address script as an example. Assuming a range of 10.0.0.1/24 is available but half of the IP’s are used randomly within this subnet. So my script should accept an XML message like this then it determines a free IP available on this subnet:

<IPAM_DRIVER_ACTION_DATA>
<AR>
  <TYPE>IP4</TYPE>
  <IP>10.0.0.117</IP>
  <MAC>AA:BB:CC:DD:EE:FF:00:01</MAC
  <SIZE>1</SIZE>
  <NETWORK_ADDRESS>10.0.0.117</NETWORK_ADDRESS>
  <NETWORK_MASK>255.255.255.0</NETWORK_MASK>
  <GATEWAY>10.0.0.1</GATEWAY>
  <DNS>192.168.0.1 192.168.0.2 192.168.0.3</DNS>
  <GUEST_MTU>1500</GUEST_MTU>
  <SEARCH_DOMAIN>dom.com sub.dom.com new.dom.com</SEARCH_DOMAIN>
</AR>
</IPAM_DRIVER_ACTION_DATA>

The script should then return:

ADDRESS = [ IP = "10.0.0.117", SIZE=1 ]

to STDOUT. And also return -1 if it fails to allocate, otherwise it must exit 0.

3 - Great!

Cheers,
TK

Hi

A few more questions if I may please.

  1. Are the above assumptions I posted correct?

Additional questions:

  1. Which IPAM module does OpenNebula use right now? The list on my install has the following: dummy, packet. Does it use the packet IPAM module to allocate right now or an internal system not exposed via IPAM?

  2. Looking at the existing ipam module packet code for register_address_range, there is code that instantiates objects from OpenNebula, decrypts a few elements from the first parameter passed ARGV[0], which is the XML input message, from Base64 using nokogiri, retrieves ONE_KEY from the object. It then get’s a PACKET_TOKEN from the passed ARGV[0] parameter, which is not mentioned on the docs page. Should I care about all this or just focus on what the docs page has? The reason is I need to do this in bash and in case I need higher-level functions to interact with OpenNebula objects or perform API calls, I may need to go the python route. Are there examples of ipam modules in bash or python I can use as examples and extend for my purpose?

Thx,
TK

Hello @TomK

  1. Are the above assumptions I posted correct?

Yes, they are correct.

4- Yes, currently only dummy and Packet are available. The Packet IPAM is used in VMs deployed on baremetal Packet host so they get public connectivity.

5 - In the new version (5.10) you don’t need to decrypt anything, it’s done in the core using the ENCRYPTED_ATTR. PACKET_TOKEN is needed by Packet, so you don’t need this token. We don’t have examples in Python, but of course you can use it, the only thing is to respect the inputs and outputs.

Álex.

Thank you very much. Let me give these a try this weekend.

Hey All, Can the code be ran as root or will it be ran as the oneadmin user?

I’m trying to pass additional parameters to the scripts to limit the IP’s returned to a specific range. For example, I want the IP’s returned to be within the range of 10.0.0.50 - 10.0.0.254 .

  1. Is it possible to do this by adding additional elements to the XML
  2. Thinking using GetOpts on paramters such as --limit or -l isn’t possible right now?

Thx,
TK

Can the code be ran as root or will it be ran as the oneadmin user?

The code is ran as oneadmin user, but you can use sudo inside of it if you need it.

  1. Is it possible to do this by adding additional elements to the XML

The script is going to receive the address range information, so if you add an extra field, you will have it.

  1. Thinking using GetOpts on paramters such as --limit or -l isn’t possible right now?

It’s not possible.

Hi,

Writing and testing the Python class that now dynamically returns the block below, based on what IP ranges are free. However, I have a few questions that just came up.

If I have the following return block for register_address_range (or get_address):

        AR = [
            IPAM_MAD = "ipmapper",
            TYPE = "IP4",
            IP   = "10.0.0.100",
            SIZE = "155",
            NETWORK_ADDRESS   = "10.0.0.0",
            NETWORK_MASK      = "255.255.255.0",
            GATEWAY           = "10.0.0.1",
            DNS               = "192.168.0.10 192.168.0.11 192.168.0.12 192.168.0.13 192.168.0.14 192.168.0.15 192.168.0.16",
            IPAM_ATTR         = "10.0.0.255",
            OTHER_IPAM_ATTR   = "my.dom.abc"
        ]
  1. What is IPAM_ATTR?

  2. Do I need a ‘.’ before the OTHER_IPAM_ATTR string?

  3. What are the functional differences between allocate_address and get_address? allocate_address appears like a check?

  4. When using unregister_address_range, can you elaborate with more details on what exactly happens within ON when this is called? In other words, could you please share more exact details what happens at each step of the way when this function is called?

Cheers,
TK

If I’m unregistering an address range, is there some OpenNebula API’s I need to call that will tell me if any VM is using an IP in the range I’m unregistering?

Just want to confirm since the page here did not have this information:

http://docs.opennebula.org/5.10/integration/infrastructure_integration/devel-ipam.html

Cheers,
TK

FYI.

Using and testing the new IPAM drivers. In the process of instantiating a VM from a template that uses the new IPAM driver, I run into a crash:

Tue Mar 10 01:54:47 2020 [Z0][AuM][D]: Message received: AUTHENTICATE SUCCESS 1 -

Tue Mar 10 01:54:47 2020 [Z0][ReM][D]: Req:6592 UID:0 IP:127.0.0.1 one.template.info invoked , 2, false
Tue Mar 10 01:54:47 2020 [Z0][ReM][D]: Req:6592 UID:0 one.template.info result SUCCESS, "<VMTEMPLATE><ID>2</I..."
Tue Mar 10 01:54:47 2020 [Z0][ReM][D]: Req:6080 UID:0 IP:127.0.0.1 one.template.instantiate invoked , 2, "getautonet01.nix.mds...", false, "DISK=[
  FORMAT="raw...", false
Tue Mar 10 01:54:49 2020 [Z0][IPM][D]: Message received: GET_ADDRESS SUCCESS 2 QVIgPSBbIAogICAgSVAgPSAiMTAuMC4wLjE1MiIsIAogICAgU0laRSA9ICIxIiAKXQo=


==> sunstone.log <==
Tue Mar 10 01:54:49 2020 [I]: 192.168.0.76 - - [10/Mar/2020:01:54:49 -0400] "POST /vmtemplate/2/action HTTP/1.1" 500 - 3.2293
tail: oned.log: file truncated
Tue Mar 10 01:54:55 2020 [Z0][ONE][I]: Starting OpenNebula 5.8.5
----------------------------------------
     OpenNebula Configuration File
----------------------------------------
API_LIST_ORDER=DESC
AUTH_MAD=AUTHN=ssh,x509,ldap,server_cipher,server_x509,EXECUTABLE=one_auth_mad
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=core,PASSWORD_CHANGE=YES
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=public,PASSWORD_CHANGE=NO
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=ssh,PASSWORD_CHANGE=YES
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=x509,PASSWORD_CHANGE=NO
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=YES,MAX_TOKEN_TIME=86400,NAME=ldap,PASSWORD_CHANGE=YES
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=server_cipher,PASSWORD_CHANGE=NO
AUTH_MAD_CONF=DRIVER_MANAGED_GROUPS=NO,MAX_TOKEN_TIME=-1,NAME=server_x509,PASSWORD_CHANGE=NO
DATASTORE_CAPACITY_CHECK=yes
DATASTORE_LOCATION=/var/lib/one//datastores
DATASTORE_MAD=ARGUMENTS=-t 15 -d dummy,fs,lvm,ceph,dev,iscsi_libvirt,vcenter -s shared,ssh,ceph,fs_lvm,qcow2,vcenter,EXECUTABLE=one_datastore
DB=BACKEND=mysql,CONNECTIONS=50,DB_NAME=opennebula,PASSWD=cman90-,PORT=0,SERVER=mysql-c01.nix.mds.xyz,USER=oneadmin
DEFAULT_AUTH=default
DEFAULT_CDROM_DEVICE_PREFIX=hd
DEFAULT_COST=CPU_COST=0,DISK_COST=0,MEMORY_COST=0
DEFAULT_DEVICE_PREFIX=hd
DEFAULT_IMAGE_PERSISTENT=
DEFAULT_IMAGE_PERSISTENT_NEW=
DEFAULT_IMAGE_TYPE=OS
DEFAULT_UMASK=177

[root@one01 log]# grep -Ei oned messages
Mar 8 18:55:19 one01 kernel: oned[14897]: segfault at 20 ip 000000000041f4b0 sp 00007ff6d1ff8450 error 4 in oned[400000+346000]
Mar 8 19:00:10 one01 kernel: oned[16189]: segfault at 20 ip 000000000041f4b0 sp 00007fb4d2ffa450 error 4 in oned[400000+346000]
Mar 8 19:09:45 one01 kernel: oned[18863]: segfault at 20 ip 000000000041f4b0 sp 00007f02acff6450 error 4 in oned[400000+346000]
Mar 10 01:33:44 one01 kernel: oned[10548]: segfault at 20 ip 000000000041f4b0 sp 00007f5adaffa450 error 4 in oned[400000+346000]
Mar 10 01:34:13 one01 kernel: oned[11208]: segfault at 20 ip 000000000041f4b0 sp 00007f0716ffa450 error 4 in oned[400000+346000]
Mar 10 01:54:15 one01 kernel: oned[12870]: segfault at 20 ip 000000000041f4b0 sp 00007f03417f7450 error 4 in oned[400000+346000]
Mar 10 01:54:49 one01 kernel: oned[13475]: segfault at 20 ip 000000000041f4b0 sp 00007f3708ff6450 error 4 in oned[400000+346000]
[root@one01 log]#

The UI error displayed is:

end of file reached

This was due to the wrong tag for the return address:

AR = [ 
    IP = "10.0.0.152", 
    SIZE = "1" 
]

Fixed by correcting as follows:

ADDRESS = [ IP = "10.0.0.152", SIZE = "1" ]

( In case it helps someone writing similar drivers. )

Cheers,

1 Like

Hello @TomK

First of all, thanks for sharing the last tip you used!

If I’m unregistering an address range, is there some OpenNebula API’s I need to call that will tell me if any VM is using an IP in the range I’m unregistering?

Related with this, when you try to unregister an address range, OpenNebula will first check if the address range has no leases in use. So if it has any lease it won’t call the IPAM script. Then there is no need to check that in your script.

Best,
Álex.

Ty for the above note.

While doing further testing of the IPAM driver, I notice that a default MAC is used regardless of what I specify on the Virtual Network definition page.

After some investigation, I noticed that the register-address-range return AR does not include a MAC as per the following page:

http://docs.opennebula.org/5.8/integration/infrastructure_integration/devel-ipam.html#register-address-range

But in fact, the AR should return a MAC otherwise a default MAC will be populated by OpenNebula.

Thx,

IPAM Driver GetAutoNet completed. Basic testing with OpenNebula 5.8.3 completed:

GitHub Project Page

RHEL 7 / CentOS 7 RPM:
https://github.com/tomkcpr/GetAutoNet/blob/master/rpmbuild/RPMS/noarch/GetAutoNet-16.03.2020-1.2.noarch.rpm

Features

Checks IP’s and IP ranges using nmap for availability.
Checks IP and IP range availability against DNS servers.
Returns only available IP’s and IP ranges.
Supports .xml files, base64 encoded strings and plain .xml arguments (last item remains to be tested)

Notes

Please read the notes on the project page including the support page at the end of the README.md file.

Code is written in Python 3.X . Please use the provided RPM file for RHEL 7 / CentOS 7 or roll one yourself from the provided SPECS file.

Not yet tested on OpenNebula 5.10.X . Haven’t upgraded my setup yet. Should work.

Interested in feedback. In case of issues, please let me know.

Cheers,
TK

1 Like