Giter VIP home page Giter VIP logo

infoblox-client's Introduction

Infoblox Client

https://travis-ci.org/infobloxopen/infoblox-client.svg?branch=master https://codecov.io/github/infobloxopen/infoblox-client/coverage.svg?branch=master https://readthedocs.org/projects/infoblox-client/badge/?version=latest

Client for interacting with Infoblox NIOS over WAPI.

Installation

Install infoblox-client using pip:

pip install infoblox-client

Usage

Configure logger prior to loading infoblox_client to get all debug messages in console:

import logging
logging.basicConfig(level=logging.DEBUG)

Low level API, using connector module

Retrieve list of network views from NIOS:

from infoblox_client import connector

opts = {'host': '192.168.1.10', 'username': 'admin', 'password': 'admin'}
conn = connector.Connector(opts)
# get all network_views
network_views = conn.get_object('networkview')
# search network by cidr in specific network view
network = conn.get_object('network', {'network': '100.0.0.0/8', 'network_view': 'default'})

For these request data is returned as list of dicts:

network_views:
[{u'_ref': u'networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true',
  u'is_default': True,
  u'name': u'default'}]

network:
[{u'_ref': u'network/ZG5zLm5ldHdvcmskMTAwLjAuMC4wLzgvMA:100.0.0.0/8/default',
  u'network': u'100.0.0.0/8',
  u'network_view': u'default'}]

High level API, using objects

Example of creating Network View, Network, DNS View, DNSZone and HostRecord using NIOS objects:

from infoblox_client import connector
from infoblox_client import objects

opts = {'host': '192.168.1.10', 'username': 'admin', 'password': 'admin'}
conn = connector.Connector(opts)

Create a network view, and network:

nview = objects.NetworkView.create(conn, name='my_view')
network = objects.Network.create(conn, network_view='my_view', cidr='192.168.1.0/24')

Create a DNS view and zone:

view = objects.DNSView.create(conn, network_view='my_view', name='my_dns_view')
zone = objects.DNSZone.create(conn, view='my_dns_view', fqdn='my_zone.com')

Create a host record:

my_ip = objects.IP.create(ip='192.168.1.25', mac='aa:bb:cc:11:22:33')
hr = objects.HostRecord.create(conn, view='my_dns_view',
                               name='my_host_record.my_zone.com', ip=my_ip)

Create host record with Extensible Attributes (EA):

ea = objects.EA({'Tenant ID': tenantid, 'CMP Type': cmptype,
                 'Cloud API Owned': True})
host = objects.HostRecord.create(conn, name='new_host', ip=my_ip, extattrs=ea)

Create a host record with inherited Extensible Attributes (EA):

my_ip = objects.IP.create(ip='192.168.1.25', mac='aa:bb:cc:11:22:33', use_for_ea_inheritance=True)
hr = objects.HostRecord.create(conn, view='my_dns_view',
                               name='my_host_record.my_zone.com', ip=my_ip)

Set the TTL to 30 minutes:

hr = objects.HostRecord.create(conn, view='my_dns_view',
                               name='my_host_record.my_zone.com', ip=my_ip,
                               ttl = 1800)

Create a new host record, from the next available IP in a CIDR, with a MAC address, and DHCP enabled:

next = objects.IPAllocation.next_available_ip_from_cidr('default', '10.0.0.0/24')
my_ip = objects.IP.create(ip=next, mac='aa:bb:cc:11:22:33', configure_for_dhcp=True)
host = objects.HostRecord.create(conn, name='some.valid.fqdn', view='Internal', ip=my_ip)

Reply from NIOS is parsed back into objects and contains next data:

In [22]: hr
Out[22]: HostRecordV4: _ref=record:host/ZG5zLmhvc3QkLjQuY29tLm15X3pvbmUubXlfaG9zdF9yZWNvcmQ:my_host_record.my_zone.com/my_dns_view, name=my_host_record.my_zone.com, ipv4addrs=[<infoblox_client.objects.IPv4 object at 0x7f7d6b0fe9d0>], view=my_dns_view

Create a new fixed address, with a MS server DHCP reservation:

obj, created = objects.FixedAddress.create_check_exists(connector=conn,
                                                        ip='192.168.100.100',
                                                        mac='aa:bb:cc:11:22:33',
                                                        comment='My DHCP reservation',
                                                        name='My hostname',
                                                        network_view='default',
                                                        ms_server={'_struct': 'msdhcpserver',
                                                                   'ipv4addr': '192.168.0.0'})

High level API, using InfobloxObjectManager

Create a new fixed address, selecting it from the next available IP in a CIDR:

from infoblox_client.object_manager import InfobloxObjectManager

new_address = InfobloxObjectManager(conn).create_fixed_address_from_cidr(netview='default', mac='aa:bb:cc:11:22:33', cidr='10.0.0.0/24', extattrs=[])

What you get back is a FixedAddressV4 object.

Objects Interface

All top level objects support interface for CRUD operations. List of supported objects is defined in next section.

  • create(cls, connector, check_if_exists=True, update_if_exists=False, **kwargs)
    Creates object on NIOS side. Requires connector passed as the first argument, check_if_exists and update_if_exists are optional. Object related fields are passed in as kwargs: field=value, field2=value2.
  • search(cls, connector, return_fields=None, search_extattrs=None, force_proxy=False, **kwargs)
    Search single object on NIOS side, returns first object that match search criteria. Requires connector passed as the first argument. return_fields can be set to retrieve particular fields from NIOS, for example return_fields=['view', 'name']. If return_fields is [] default return_fields are returned by NIOS side for current wapi_version. search_extattrs is used to filter out results by extensible attributes. force_proxy forces search request to be processed on Grid Master (applies only in cloud environment)
  • search_all(cls, connector, return_fields=None, search_extattrs=None, force_proxy=False, **kwargs)
    Search all objects on NIOS side that match search criteria. Returns a list of objects. All other options are equal to search().
  • update(self)
    Update the object on NIOS side by pushing changes done in the local object.
  • delete(self)
    Deletes the object from NIOS side.

Supported NIOS objects

All NIOS Objects are supported in the 0.6.0 verison release. check infoblox_client/objects.py for description of the objects. Newly supported objects

  • AAAADtcRecord
  • AAAARecord
  • AAAASharedRecord
  • ADtcRecord
  • ADtcRecordBase
  • ARecord
  • ARecordBase
  • ASharedRecord
  • ASharedRecordBase
  • AdAuthServer
  • AdAuthService
  • Addressac
  • Admingroup
  • Adminrole
  • Adminuser
  • AliasRecord
  • Allendpoints
  • Allnsgroup
  • Allrecords
  • Allrpzrecords
  • AnyMember
  • Approvalworkflow
  • Authpolicy
  • Awsrte53Task
  • Awsrte53Taskgroup
  • Awsuser
  • BaseObject
  • Bfdtemplate
  • Bgpas
  • Bulkhost
  • Bulkhostnametemplate
  • CNAMEDtcRecord
  • CNAMERecord
  • CNAMESharedRecord
  • CaaRecord
  • Cacertificate
  • Capacityreport
  • CapacityreportObjectcount
  • Captiveportal
  • CaptiveportalFile
  • CertificateAuthservice
  • Changedobject
  • CiscoiseEndpoint
  • Clientsubnetdomain
  • Csvimporttask
  • DHCPLease
  • DHCPRoamingHost
  • DNSView
  • DNSZone
  • DNSZoneDelegated
  • DNSZoneForward
  • DbObjects
  • Dbsnapshot
  • DdnsPrincipalcluster
  • DdnsPrincipalclusterGroup
  • DeletedObjects
  • DhcidRecord
  • DhcpOptionDefinition
  • DhcpOptionDefinitionV4
  • DhcpOptionDefinitionV6
  • DhcpOptionSpace
  • DhcpOptionSpaceV4
  • DhcpOptionSpaceV6
  • DhcpStatistics
  • Dhcpddns
  • Dhcpfailover
  • Dhcpmember
  • Dhcpoption
  • Discovery
  • DiscoveryAutoconversionsetting
  • DiscoveryCiscoapicconfiguration
  • DiscoveryClicredential
  • DiscoveryDevice
  • DiscoveryDevicecomponent
  • DiscoveryDeviceinterface
  • DiscoveryDeviceneighbor
  • DiscoveryDevicesupportbundle
  • DiscoveryDiagnostictask
  • DiscoveryGridproperties
  • DiscoveryIfaddrinfo
  • DiscoveryMemberproperties
  • DiscoveryNetworkinfo
  • DiscoveryPort
  • DiscoveryScaninterface
  • DiscoverySeedrouter
  • DiscoverySnmp3Credential
  • DiscoverySnmpcredential
  • DiscoveryStatus
  • DiscoveryVlaninfo
  • DiscoveryVrf
  • DiscoveryVrfmappingrule
  • Discoverytask
  • Discoverytaskport
  • Discoverytaskvserver
  • Distributionschedule
  • DnameRecord
  • Dns64Group
  • DnskeyRecord
  • Dnsseckey
  • Dnssectrustedkey
  • DsRecord
  • Dtc
  • DtcAllrecords
  • DtcCertificate
  • DtcLbdn
  • DtcMonitor
  • DtcMonitorHttp
  • DtcMonitorIcmp
  • DtcMonitorPdp
  • DtcMonitorSip
  • DtcMonitorSnmp
  • DtcMonitorSnmpOid
  • DtcMonitorTcp
  • DtcObject
  • DtcPool
  • DtcPoolConsolidatedMonitorHealth
  • DtcPoolLink
  • DtcServer
  • DtcServerLink
  • DtcServerMonitor
  • DtcTopology
  • DtcTopologyLabel
  • DtcTopologyRule
  • DtcTopologyRuleSource
  • DtclbdnRecord
  • DxlEndpoint
  • DxlEndpointBroker
  • EA
  • EADefinition
  • Exclusionrange
  • Exclusionrangetemplate
  • ExtensibleattributedefListvalues
  • Extserver
  • Extsyslogbackupserver
  • Fileop
  • Filterfingerprint
  • Filtermac
  • Filternac
  • Filteroption
  • Filterrelayagent
  • Filterrule
  • Fingerprint
  • FixedAddress
  • FixedAddressTemplate
  • FixedAddressTemplateV4
  • FixedAddressTemplateV6
  • FixedAddressV4
  • FixedAddressV6
  • Forwardingmemberserver
  • Ftpuser
  • Grid
  • GridCloudapi
  • GridCloudapiCloudstatistics
  • GridCloudapiUser
  • GridCloudapiVm
  • GridCloudapiVmaddress
  • GridDashboard
  • GridDhcpproperties
  • GridDns
  • GridDnsFixedrrsetorderfqdn
  • GridFiledistribution
  • GridLicensePool
  • GridLicensePoolContainer
  • GridLicensesubpool
  • GridMaxminddbinfo
  • GridMemberCloudapi
  • GridServicerestartGroup
  • GridServicerestartGroupOrder
  • GridServicerestartRequest
  • GridServicerestartRequestChangedobject
  • GridServicerestartStatus
  • GridThreatanalytics
  • GridThreatprotection
  • GridX509Certificate
  • GridmemberSoamname
  • GridmemberSoaserial
  • HostRecord
  • HostRecordV4
  • HostRecordV6
  • Hostnamerewritepolicy
  • Hotfix
  • HsmAllgroups
  • HsmSafenet
  • HsmSafenetgroup
  • HsmThales
  • HsmThalesgroup
  • IP
  • IPAddress
  • IPAllocation
  • IPRange
  • IPRangeV4
  • IPRangeV6
  • IPv4
  • IPv4Address
  • IPv4HostAddress
  • IPv6
  • IPv6Address
  • IPv6HostAddress
  • InfobloxObject
  • Interface
  • IpamStatistics
  • Ipv6Networksetting
  • Kerberoskey
  • LdapAuthService
  • LdapEamapping
  • LdapServer
  • LicenseGridwide
  • LocaluserAuthservice
  • Logicfilterrule
  • Lomnetworkconfig
  • Lomuser
  • MXRecord
  • MXSharedRecord
  • Macfilteraddress
  • Mastergrid
  • Member
  • MemberDhcpproperties
  • MemberDns
  • MemberDnsgluerecordaddr
  • MemberDnsip
  • MemberFiledistribution
  • MemberLicense
  • MemberParentalcontrol
  • MemberThreatanalytics
  • MemberThreatprotection
  • Memberserver
  • Memberservicecommunication
  • Memberservicestatus
  • Msdhcpoption
  • Msdhcpserver
  • Msdnsserver
  • Msserver
  • MsserverAdsitesDomain
  • MsserverAdsitesSite
  • MsserverDcnsrecordcreation
  • MsserverDhcp
  • MsserverDns
  • Mssuperscope
  • Namedacl
  • NaptrDtcRecord
  • NaptrRecord
  • Natgroup
  • Network
  • NetworkContainer
  • NetworkContainerV4
  • NetworkContainerV6
  • NetworkDiscovery
  • NetworkTemplate
  • NetworkTemplateV4
  • NetworkTemplateV6
  • NetworkV4
  • NetworkV6
  • NetworkView
  • Networkuser
  • NetworkviewAssocmember
  • Nodeinfo
  • NotificationRestEndpoint
  • NotificationRestTemplate
  • NotificationRestTemplateparameter
  • NotificationRule
  • NotificationRuleexpressionop
  • NsRecord
  • Nsec3ParamRecord
  • Nsec3Record
  • NsecRecord
  • Nsgroup
  • NsgroupDelegation
  • NsgroupForwardingmember
  • NsgroupForwardstubserver
  • NsgroupStubmember
  • Nxdomainrule
  • OcspResponder
  • Option60Matchrule
  • Orderedranges
  • Orderedresponsepolicyzones
  • Ospf
  • OutboundCloudclient
  • OutboundCloudclientEvent
  • ParentalcontrolAbs
  • ParentalcontrolAvp
  • ParentalcontrolBlockingpolicy
  • ParentalcontrolIpspacediscriminator
  • ParentalcontrolMsp
  • ParentalcontrolNasgateway
  • ParentalcontrolSitemember
  • ParentalcontrolSpm
  • ParentalcontrolSubscriber
  • ParentalcontrolSubscribersite
  • Permission
  • PtrRecord
  • PtrRecordV4
  • PtrRecordV6
  • RadiusAuthservice
  • RadiusServer
  • RangeTemplate
  • RangeTemplateV4
  • RangeTemplateV6
  • Rdatasubfield
  • Recordnamepolicy
  • Remoteddnszone
  • Restartservicestatus
  • Rir
  • RirOrganization
  • RpzAIpaddressRecord
  • RpzARecord
  • RpzAaaaIpaddressRecord
  • RpzAaaaRecord
  • RpzCnameClientipaddressRecord
  • RpzCnameClientipaddressdnRecord
  • RpzCnameIpaddressRecord
  • RpzCnameIpaddressdnRecord
  • RpzCnameRecord
  • RpzMxRecord
  • RpzNaptrRecord
  • RpzPtrRecord
  • RpzPtrRecordV4
  • RpzPtrRecordV6
  • RpzSrvRecord
  • RpzTxtRecord
  • RrsigRecord
  • Ruleset
  • SRVDtcRecord
  • SRVRecord
  • SRVSharedRecord
  • SamlAuthservice
  • Scavengingtask
  • Scheduledtask
  • Search
  • SettingNetwork
  • SettingViewaddress
  • SharedNetwork
  • SharedNetworkV4
  • SharedNetworkV6
  • Sharedrecordgroup
  • SmartfolderChildren
  • SmartfolderGlobal
  • SmartfolderGroupby
  • SmartfolderPersonal
  • SmartfolderQueryitem
  • Snmpuser
  • Sortlist
  • SubObjects
  • Superhost
  • Superhostchild
  • SyslogEndpoint
  • SyslogEndpointServers
  • Syslogserver
  • TXTRecord
  • TXTSharedRecord
  • TacacsplusAuthservice
  • TacacsplusServer
  • Taxii
  • TaxiiRpzconfig
  • Tenant
  • Tftpfiledir
  • ThreatanalyticsModuleset
  • ThreatanalyticsWhitelist
  • ThreatinsightCloudclient
  • ThreatprotectionGridRule
  • ThreatprotectionNatrule
  • ThreatprotectionProfile
  • ThreatprotectionProfileRule
  • ThreatprotectionRule
  • ThreatprotectionRulecategory
  • ThreatprotectionRuleset
  • ThreatprotectionRuletemplate
  • ThreatprotectionStatinfo
  • ThreatprotectionStatistics
  • Thresholdtrap
  • TlsaRecord
  • Trapnotification
  • UnknownRecord
  • Updatesdownloadmemberconfig
  • Upgradegroup
  • UpgradegroupMember
  • UpgradegroupSchedule
  • Upgradeschedule
  • Upgradestatus
  • Upgradestep
  • Userprofile
  • Vdiscoverytask
  • Vlan
  • Vlanlink
  • Vlanrange
  • Vlanview
  • Vtftpdirmember
  • ZoneAuthDiscrepancy
  • ZoneRp
  • ZoneStub
  • Zoneassociation
  • Zonenameserver

Until 0.4.25 this project supported

  • NetworkView for 'networkview'
  • DNSView for 'view'
  • DNSZone for 'zone_auth'
  • Member for 'member'
  • Network (V4 and V6)
    • NetworkV4 for 'network'
    • NetworkV6 for 'ipv6network'
  • IPRange (V4 and V6)
    • IPRangeV4 for 'range'
    • IPRangeV6 for 'ipv6range'
  • HostRecord (V4 and V6)
    • HostRecordV4 for 'record:host'
    • HostRecordV6 for 'record:host'
  • FixedAddress (V4 and V6)
    • FixedAddressV4 for 'fixedaddress'
    • FixedAddressV6 for 'ipv6fixedaddress'
  • IPAddress (V4 and V6)
    • IPv4Address for 'ipv4address'
    • IPv6Address for 'ipv6address'
  • ARecordBase
    • ARecord for 'record:a'
    • AAAARecord for 'record:aaaa'
  • PtrRecord (V4 and V6)
    • PtrRecordV4 for 'record:ptr'
    • PtrRecordV6 for 'record:ptr'
  • EADefinition for 'extensibleattributedef'
  • CNAMERecord for 'record:cname'
  • MXRecord for 'record:mx'

Search by regular expression

Search for partial match is supported only by low-level API for now. Use '~' with field name to search by regular expressions. Not all fields support search by regular expression. Refer to wapidoc to find out complete list of fields that can be searched this way. Examples:

Find all networks that starts with '10.10.':

conn = connector.Connector(opts)
nw = conn.get_object('network', {'network~': '10.10.'})

Find all host records that starts with '10.10.':

conn = connector.Connector(opts)
hr = conn.get_object('record:host', {'ipv4addr~': '10.10.'})

More examples

Utilizing extensible attributes and searching on them can easily be done with the get_object function. The default field in return_fields acts like the + does in WAPI.

> _return_fields+ Specified list of fields (comma separated) will be returned in addition to the basic fields of the object (documented for each object).

This enables you to always get the default values in return, in addition to what you specify whether you search for a network or a networkcontainer, defined as place_to_check in the code below.

from infoblox_client.connector import Connector


def default_infoblox_connection():
    opts = {'host': '192.168.1.10', 'username': 'admin', 'password': 'admin'}
    conn = Connector(opts)
    return conn

def search_extensible_attribute(connection, place_to_check: str, extensible_attribute: str, value: str):
    """
    Find extensible attributes.
    :param connection: Infoblox connection
    :param place_to_check: Can be `network`, `networkcontainer` or `record:host` and so on.
    :param extensible_attribute: Which extensible attribute to search for. Can be `CustomerCode`, `Location`
    and so on.
    :param value: The value you want to search for.
    :return: result
    """
    extensible_args = [
        place_to_check,
        {
            f"*{extensible_attribute}:~": value,
        }
    ]
    kwargs = {
        'return_fields': [
            'default',
            'extattrs',
        ]
    }
    result = {"type": f"{place_to_check}", "objects": connection.get_object(*extensible_args, **kwargs)}
    return result

connection = default_infoblox_connection()

search_network = search_extensible_attribute(connection, "network", "CustomerCode", "Infoblox")
# Print the output:
print(search_network)
{
  "type": "network",
  "objects": [
    {
      "_ref": "network/ZG5zLmhvc3QkLjQuY29tLm15X3pvbmUubXlfaG9zdF9yZWNvcmQ:192.168.1.1/28/default",
      "comment": "Infoblox Network",
      "extattrs": {
        "CustomerCode": {
          "value": "Infoblox"
        }
      },
      "network": "192.168.1.0/28",
      "network_view": "default"
    }
  ]
}

search_host = search_extensible_attribute(connection, "record:host", "CustomerCode", "Infoblox")
# Print the output:
print(search_host)
{
  "type": "record:host",
  "objects": [
    {
      "_ref": "record:host/ZG5zLm5ldHdvcmtfdmlldyQw:InfobloxHost",
      "extattrs": {
        "CustomerCode": {
          "value": "Infoblox"
        }
      },
      "ipv4addrs": [
        {
          "_ref": "record:host_ipv4addr/ZG5zLm5ldHdvcmtfdmlldyQwdvcmtfdmlldyQw:192.168.1.1/InfobloxHost",
          "configure_for_dhcp": false,
          "host": "InfobloxHost",
          "ipv4addr": "192.168.1.1"
        }
      ],
      "name": "InfobloxHost",
      "view": " "
    }
  ]
}

Features

  • TODO

infoblox-client's People

Contributors

achernevskii avatar adsri avatar akuzminsky avatar anagha-infoblox avatar avrajath avatar badnetmask avatar bondar-pavel avatar brampling avatar brandune avatar chrisschroeder92 avatar ddiguru avatar emfl avatar exaneserverteam avatar hosunghwang avatar ingvaldlorentzen avatar jhenahan avatar jkraj avatar jobec avatar johnbelamaric avatar jonasks avatar lingfish avatar mithun avatar noziwatele avatar rhgrant10 avatar saiprasannasastry avatar sarya-infoblox avatar serbaniuliuscezar avatar somashekhar avatar userlocalhost avatar yuewko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

infoblox-client's Issues

Expose ip_version as a public property

Currently I need to get ip version info by accessing a private variable like below.

self.ib_network._ip_version

Expose it to public so that I can do

self.ib_network.ip_version

Fix errors reported by 'make docs'

Currently 'make docs' reports quite a lot of errors/warning.
Need to fix them all before job for checking documentation can be added to Travis CI.

Build log:

reading sources... [100%] usage
../HISTORY.rst:7: WARNING: Title underline too short.

0.3.1 (2016-01-14)
_________________
/home/apostal/PycharmProjects/infoblox-client/docs/index.rst:7: WARNING: Title underline too short.

Welcome to Infoblox Client's documentation!
======================================
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/connector.py:docstring of infoblox_client.connector.Connector.create_object:6: WARNING: Definition list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/connector.py:docstring of infoblox_client.connector.Connector.get_object:13: WARNING: Definition list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/connector.py:docstring of infoblox_client.connector.Connector.get_object:17: ERROR: Unexpected indentation.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/feature.py:docstring of infoblox_client.feature.Feature:6: WARNING: Definition list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.BaseObject:5: ERROR: Unexpected indentation.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.BaseObject:6: WARNING: Block quote ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.BaseObject:8: WARNING: Bullet list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.BaseObject:9: WARNING: Block quote ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.BaseObject:10: WARNING: Bullet list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:5: WARNING: Definition list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:7: ERROR: Unexpected indentation.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:8: WARNING: Block quote ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:13: WARNING: Definition list ends without a blank line; unexpected unindent.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:15: ERROR: Unexpected indentation.
/home/apostal/PycharmProjects/infoblox-client/infoblox_client/objects.py:docstring of infoblox_client.objects.InfobloxObject:16: WARNING: Block quote ends without a blank line; unexpected unindent.
../README.rst:None: WARNING: nonlocal image URI found: https://travis-ci.org/infobloxopen/infoblox-client.svg?branch=master
../README.rst:None: WARNING: nonlocal image URI found: https://img.shields.io/pypi/v/infoblox-client.svg
../README.rst:None: WARNING: nonlocal image URI found: https://codecov.io/github/infobloxopen/infoblox-client/coverage.svg?branch=master
../README.rst:None: WARNING: nonlocal image URI found: https://readthedocs.org/projects/infoblox-client/badge/?version=latest

nameservers options should be allowed for ipv6 network

object_manager.create_network() is not allowing nameservers option for ipv6 network because of the following ipv4 check.

    if ipv4 and nameservers:
        options.append(obj.DhcpOption(name='domain-name-servers',
                                      value=",".join(nameservers)))

Just take out ipv4 in if condition. this should be allowed both ipv4 and ipv6.

IPv6 Networks can not be created if address passed in 'network' field.

Found an issue with IPv6 Network creation and search.
If address is passed using 'network' field IPv4 class is used for search, create.
But search/create works fine if 'cidr' field (alias for 'network' field) is used to pass address.
Need to add 'network' to list of fields that are tested to make decision about using V4 or V6 version of class.

Create a new api "get_network_by_subnet_id" in object_manager

The following api should return ib network by subnet id and ip_version.
But ip_version is None by default.

def get_network_by_subnet_id(self, subnet_id, ip_version=None):
ea = ib_objects.EA({'Subnet ID': subnet_id})

    if ip_version == 4 or ip_version is None:
        try:
            ib_network = ib_objects.NetworkV4.search(
                self._grid_config.gm_connector,
                network_view=network_view,
                search_extattrs=ea)
        except ib_exc.InfobloxSearchError:
            ib_network = None

    if ip_version == 6 or ib_network is None:
        try:
            ib_network = ib_objects.NetworkV6.search(
                self._grid_config.gm_connector,
                network_view=network_view,
                search_extattrs=ea)
        except ib_exc.InfobloxSearchError:
            ib_network = None

    return ib_network

Need to clean up utils.py

A lot of routines in utils.py are not used in infoblox-client, so may represent dead code.
Originally they were added from previous infoblox ipam driver, but significant part of them is not needed within new design.
Need to create list of routines that are not used by anyone (infoblox-client and networking-infoblox)
and remove them from package.

_return_fields limits lower border of wapi_version

On each request list of _return_fields is sent to NIOS.
But if field that is present in _return_fields is not supported by current wapi_version then request fails.
For example EADefinition return_fields requires wapi_version 2.2, on wapi_version below 2.2 any request to this object will fail.
Currently possible workaround for package users are:

  • set return_fields manually on search, where each listed field exists for selected wapi version;
  • set retuen_fields=[], so default fields for defined on NIOS for particular wapi version to be returned;

Need to discuss possible ways to fix it (failing on lower wapi_version) on infoblox_client side.

Floating IP creating fails

When trying to create a floating ip, add_ip_to_host_record_from_range() is executed but failed with the following error:

. . .
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 119, in exit
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource six.reraise(self.type_, self.value, self.tb)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 156, in allocate_ips_for_port_and_store
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource ips = self._allocate_ips_for_port(context, port)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 228, in _allocate_ips_for_port
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource return self._ipam_allocate_ips(context, ipam_driver, p, ips)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 135, in ipam_allocate_ips
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource "external system for %s"), addresses)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 119, in exit
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource six.reraise(self.type
, self.value, self.tb)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 120, in _ipam_allocate_ips
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource context, ipam_driver, port, ip_list)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 91, in _ipam_allocate_single_ip
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource port, subnet),
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 80, in _ipam_try_allocate_ip
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource return ipam_subnet.allocate(ip_request)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/ipam/driver.py", line 294, in allocate
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource address_request.device_owner)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/neutron/common/ipam.py", line 328, in allocate_ip_from_pool
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource ea_ip_address)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/neutron/common/ip_allocator.py", line 118, in allocate_ip_from_range
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource host_record, network_view, mac, first_ip, last_ip, use_dhcp)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/object_manager.py", line 231, in add_ip_to_host_record_from_range
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource return host_record.update()
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 289, in update
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource self.return_fields)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/connector.py", line 39, in callee
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource return func(_args, *_kwargs)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/connector.py", line 314, in update_object
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource code=r.status_code)
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource InfobloxCannotUpdateObject: Cannot update object with ref record:host/ZG5zLmhvc3QkLl9kZWZhdWx0LmNvbS5nbG9iYWwuY2xvdWQuczEuNjlhMTAyODAtMTI3Ni00YTQ4LWEyMDYtYmRmY2EzY2IwNGRh:69a10280-1276-4a48-a206-bdfca3cb04da.s1.cloud.global.com/default: { "Error": "AdmConProtoError: Field is not writable: host",
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource "code": "Client.Ibap.Proto",
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource "text": "Field is not writable: host"
2015-11-24 11:18:11.900 TRACE neutron.api.v2.resource } [code 400]

update_fields look like this:

(Pdb) p update_fields
{'ipv4addrs': [{'configure_for_dhcp': True, 'host': u'69a10280-1276-4a48-a206-bdfca3cb04da.s1.cloud.global.com', 'ipv4addr': '8.8.1.2', 'mac': u'fa:16:3e:7d:e8:b4'}, {'configure_for_dhcp': True, 'mac': 'fa:16:3e:27:fc:f1', 'ipv4addr': 'func:nextavailableip:8.8.1.2-8.8.1.254,default'}], 'extattrs': {u'VM ID': {u'value': u'dhcpa3da5f21-e3f1-5842-947d-21228419109c-3ec27738-d921-4065-a160-c12c52b7c91e'}, u'IP Type': {u'value': u'Fixed'}, u'CMP Type': {u'value': u'OpenStack'}, u'Port Attached Device - Device Owner': {u'value': u'network:dhcp'}, u'Port Attached Device - Device ID': {u'value': u'dhcpa3da5f21-e3f1-5842-947d-21228419109c-3ec27738-d921-4065-a160-c12c52b7c91e'}, u'Cloud API Owned': {u'value': u'True'}, u'Tenant ID': {u'value': u'4befcd541d594ac6a60389243a0b0ef6'}}}
(Pdb) n

I was using cloud user credentials but ‘superuser’ permission is given so probably it won't be a permission issue.

Host Record generation does not work correctly

When we generate a host record from HostRecordIPAllocator::allocate_ip_from_range,
The following code always returns a host record although fqdn is different.

    host_record = self.manager.find_hostname(
        dns_view, fqdn, first_ip)

fqdn is a randomly generated uuid in this case, so a different host record should be generated.
It looks like search is done in OR condition where it should be AND conditions in this case.

Deleting DNS records that are associated with a fixed address

According to API doc, “ipv4address” search cannot be used by cloud api because this object belongs to Host Record creation.

“ipv4address” object has restriction “The object cannot be managed on Cloud Platform members”

That is why host record worked but not fixedaddress.

Here is the API test:

curl -k1 -u cloud:cloud -H "content-type:application/json" -w "\nThe Response Code:%{http_code}\n" https://10.40.240.101/wapi/v2.3/ipv4address?ip_address=99.90.93.10
{ "Error": "AdmConProtoError: Operation read not allowed for ipv4address on Cloud Platform member in this version",
"code": "Client.Ibap.Proto",
"text": "Operation read not allowed for ipv4address on Cloud Platform member in this version"
}
The Response Code:400

But searching with fixedaddress works:

curl -k1 -u cloud:cloud -H "content-type:application/json" -w "\nThe Response Code:%{http_code}\n" https://10.40.240.101/wapi/v2.3/fixedaddress?ipv4addr=99.90.93.10
[
{
"_ref": "fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkOTkuOTAuOTMuMTAuMi4u:99.90.93.10/cloud_view",
"ipv4addr": "99.90.93.10",
"network_view": "cloud_view"
}
]
The Response Code:200

So how come we did not see this issue before?
My guess is that NIOS had this bug and recently fixed the issue so permission is checked as mentioned in the document. However we saw that NIOS did not check superuser permission either.
We allowed the superuser on cloud api user but the API still failed.

Anyway how can we resolve this issue now?

object_manager.delete_all_associated_objects() calls get_all_associated_objects().
This method does search using IPAddress.

obj.IPAddress.search(...)

If IP address is a fixed address, this will fail.
A funny thing is that delete_all_associated_objects() is only called from FixedAddressIPAllocator.

We probably need to make change in the interface from delete_all_associated_objects to
delete_associated_dns_records() and handle for DNS records associated the fixed address.

Also get_all_associated_objects is used by only delete_all_associated_objects.
So we need to change this method name to get_associated_dns_records.

Then how do we get DNS records from get_associated_dns_records?

Since we are not using admin credentails, we cannot use ip4addr and get dns records in one WAPI call. So we may have to do the following.

wapi/v2.3/record:a?ipv4addr=99.90.93.10
wapi/v2.3/record:aaaa?ipv6addr=2001::1 <= if ipv6 is used
wapi/v2.3/record:ptr?ipv4addr=99.90.93.10
wapi/v2.3/record:txt?ipv4addr=99.90.93.10
. . .
whateever record types defined in "dns_record_removable_types" to remove.

Readme - docs link is broken

infoblox-docs

The link in the readme to documentation shows me the above page. I'd be happy to submit a PR if you point me to the right link, otherwise I'm going thru the docs folder and readme to see what I can pick up. Thanks.

object_manager object search() throws InfobloxSearchError error if data is not found

When I use delete_dns_zone(), I got InfobloxSearchError because dns zone was already removed.
If this is nothing to remove, then it should safely return rather than throwing exception.

Add try except block when object.search() API is used. The following APIs are affected.

delete_network_view
delete_dns_view
get_network
delete_ip_range
delete_network
get_host_record
find_hostname
delete_host_record
delete_dns_zone
update_host_record_eas
update_fixed_address_eas
update_dns_record_eas
bind_name_with_host_record
unbind_name_from_record_a
get_all_associated_objects

I am not sure if search_all() throws InfobloxSearchError as well. If it does, this has to be taken care of as well.

Add 'make docs' to Travis CI

Currently 'make docs' executed only manually (and rearely).
Now it reports quite a lot of errors/warnings, so need to automate process of cheking and building documentation.

ssl_verify field in connector is not used correctly

The following line has to be included in _parse_options().

      self.ssl_verify = utils.try_value_to_bool(self.ssl_verify, strict_mode=False)

so that other get/update/delete_object method can use the correct value since theose meothds
access self.ssl_verify directly.
You can add it right before self.wapi_url line.

utils.try_value_to_bool() used in the _configure_session has no use.
You can just set it like this:
self.session.verify = self.ssl_verify
since self.ssl_verify is already converted to True/False.

$ diff infoblox_client/connector.py /usr/local/lib/python2.7/dist-packages/infoblox_client/connector.py

      100a101,102
      >         self.ssl_verify = utils.try_value_to_bool(self.ssl_verify,
      >                                                   strict_mode=False)
      113,114c115
      <         self.session.verify = utils.try_value_to_bool(self.ssl_verify,
      <                                                       strict_mode=False)
      ---
      >         self.session.verify = self.ssl_verify

Result set too large

When executing networks = conn.get_object('network')
DEBUG:infoblox_client.connector:Error occured on object search: { "Error": "AdmConProtoError: Result set too large (> 1000)",
"code": "Client.Ibap.Proto",
"text": "Result set too large (> 1000)"

The max number can be increased with &_max_results=-500000, but not sure how to pass it tot he url creation.

Add mapping ip field into 'ipv4_address', 'ipv6_address' for Member object

Member object is not expected to have V4 and V6 childs, but it contains ip versioned fields 'ipv4_address', 'ipv6_address'.
Need to all setter for this fields, so they could be accessed by 'ip' alias.
'ip' will map it's values into 'ipv4_address' or 'ipv6_address' depending on ip version detected from value.

Need to support "configure_for_dns" in record.host

We need to support "configure_for_dns" option for Host record.
The default should be True but we should be able to set this to False to support IPAM Only case.

Host records can be created with Configure for DNS set to False:

From the WAPI guide under the record:host object:

configure_for_dns
When configure_for_dns is false, the host does not have parent zone information.
Type
Bool.
Create
The default value is True.
Search
The field is not searchable.

Example syntax is
curl -k -u ibuser:infoblox -X POST 'https://10.10.100.51/wapi/v1.5/record:host?_return_as_object=1&_return_fields=name,ipv4addrs' -H 'Content-Type: application/json' -d '{"name": "somename", "configure_for_dns":false, "ipv4addrs":[
{"ipv4addr":"func:nextavailableip:10.10.10.0/24"}
]}'

Add 'flake8' execution to Travis CI

Currenly flake8 can be executed locally with 'make lint' command.
But it also has be executed as part of automated tests to keep code clean.

in object_manager, add a new api: count_networks()

Please add the following API:

def count_networks(self, network_view_name):
ib_networks = ib_objects.Network.search_all(self.connector,
network_view=network_view_name)
return len(ib_networks)

This is used to determine the last subnet in the current network view which can be used in subnet removal.

host record does not merge different ips for the same host name

Let's say that {instance_name} is used for host record generation and ip allocation strategy is host record.

I created an instance "vm1" with ip 11.11.1.3.
Then I created another instance "vm1" with ip 11.11.1.4.

I would expect that the existing host record will contain two ips now but it fails with the following error:

2016-01-13 18:36:46.627 ERROR networking_infoblox.neutron.common.notification_handler [-] Cannot update object with ref record:host/ZG5zLmhvc3QkLl9kZWZhdWx0LmNvbS5jbG91ZC5hZG1pbi5ob3N0LWQ4Nzk0NWE5LWE3NjItNDFhMy05NDZiLTgzZTRkNGQ0NWMxMw:host-d87945a9-a762-41a3-946b-83e4d4d45c13.admin.cloud.com/default: { "Error": "AdmConDataError: None (IBDataConflictError: IB.Data.Conflict:The record 'host-host.admin.cloud.com' already exists.)",
"code": "Client.Ibap.Data.Conflict",
"text": "The record 'host-host.admin.cloud.com' already exists."
} [code 400]

bind_name_with_host_record in object_manager may not work correctly.

Add option for connector to ignore certificate validation warning

Currently if HTTPS is used but certificate validation is turned off, log and output is polluted with insecure warnings:

/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and m
ay cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py:789: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: htt
ps://urllib3.readthedocs.org/en/latest/security.html

Need to add option for connector to be able to silent this warning.

Improve error handling in case of unexpected NIOS reply

Currently if NIOS replies with HTML (in case of error or redirect), json parsing error is shown in log.

2015-12-01 20:40:21.739 TRACE neutron   File "/usr/local/lib/python2.7/dist-packages/infoblox_client/connector.py", line 226, in _get_object
2015-12-01 20:40:21.739 TRACE neutron     response=jsonutils.loads(r.content),
2015-12-01 20:40:21.739 TRACE neutron   File "/usr/local/lib/python2.7/dist-packages/oslo_serialization/jsonutils.py", line 239, in loads
2015-12-01 20:40:21.739 TRACE neutron     return json.loads(encodeutils.safe_decode(s, encoding), **kwargs)
2015-12-01 20:40:21.739 TRACE neutron   File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
2015-12-01 20:40:21.739 TRACE neutron     return _default_decoder.decode(s)
2015-12-01 20:40:21.739 TRACE neutron   File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
2015-12-01 20:40:21.739 TRACE neutron     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
2015-12-01 20:40:21.739 TRACE neutron   File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
2015-12-01 20:40:21.739 TRACE neutron     raise ValueError("No JSON object could be decoded")
2015-12-01 20:40:21.739 TRACE neutron ValueError: No JSON object could be decoded

This error in not usefull for user, so if reply is not a valid json, the entire reply should be shown for user in exception.

NetworkView object does not return extattrs

NetworkView object does not have _return_fields field defined so it does not return 'extattrs'.
This is one of the reasons the agent sync fails when mapping conditional EA is used before sync.

For example, "Tenant ID Mapping" is used on a network view.
When sync extracts NetworkView object, the object does not contain 'extattrs' so "Tenant ID Mapping" EA is missing.
When adding new EAs on the network view, it will fail with the following error because "Tenant ID Mapping" is read only for cloud API.

InfobloxCannotUpdateObject: Cannot update object with ref networkview/ZG5zLm5ldHdvcmtfdmlldyQ1NQ:paypal1/false: { "Error": "AdmConDataError: None (IBDataConflictError: IB.Data.Conflict:Extensible attribute 'Tenant ID Mapping' is not allowed for this operation)",
2016-02-11 17:39:03.228 TRACE neutron "code": "Client.Ibap.Data.Conflict",
2016-02-11 17:39:03.228 TRACE neutron "text": "Extensible attribute 'Tenant ID Mapping' is not allowed for this operation"
2016-02-11 17:39:03.228 TRACE neutron } [code 400]

The NetworkView object definition has to include the following line:

_return_fields = ['name', 'extattrs', 'is_default']

connector.get_object() needs improvment

When I try to create a network view on a CP member, the objects module first checks if the network view exists.

When you make this call to the CP member, CPM does not proxy the call automatically because it is a GET operation. No proxying on GET.

So the connector needs to detect this case and should perform proxying.

get_object() in connector already has this logic however this does not work currently because the first call will fail from _parse_reply().

The reason is that the response on the first call will return HTML, not JSON, as below.

Click here if page does not refresh in 10 seconds.

Rather than failing this, we need to check if this is REFRESH HTTP request and treat it as a valid request but returns an empty object so that the 2nd call can be made to GM.

Take this as a high priority.

Do not fail in delete_fixed_address if no fixed ip was found

Need to update delete_fixed_address to check if fixed_ip is found before trying to delete it.

Error message:

``

2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/ipam/driver.py", line 318, in deallocate
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource ipam_controller.deallocate_ip(ip_addr)
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/neutron/common/ipam.py", line 355, in deallocate_ip
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource ip_address)
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/neutron/common/ip_allocator.py", line 182, in deallocate_ip
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource self.manager.delete_fixed_address(network_view, ip)
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/object_manager.py", line 227, in delete_fixed_address
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource fixed_address.delete()
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource AttributeError: 'NoneType' object has no attribute 'delete'
2015-12-14 15:01:41.482 TRACE neutron.api.v2.resource

ib_objects.FixedAddress.search fails

While xecuting the following code from deallocate(), I got errors below.

fa = ib_objects.FixedAddress.search(self._ib_context.connector,
network_view=mapped_netview,
ip=ip_address)

2015-11-24 10:36:25.421 ERROR neutron.api.v2.resource [req-52422d03-c7f5-48d7-9c8f-91be7be0df17 admin 4befcd541d594ac6a60389243a0b0ef6] delete failed
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource Traceback (most recent call last):
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/api/v2/resource.py", line 83, in resource
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource result = method(request=request, *_args)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_db/api.py", line 136, in wrapper
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource return f(_args, *kwargs)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 119, in exit
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource six.reraise(self.type
, self.value, self.tb)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_db/api.py", line 136, in wrapper
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource return f(_args, *_kwargs)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/api/v2/base.py", line 521, in delete
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource obj_deleter(request.context, id, *_kwargs)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/plugins/ml2/plugin.py", line 808, in delete_network
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self._delete_ports(context, port_ids)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/plugins/ml2/plugin.py", line 714, in delete_ports
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.delete_port(context, port_id)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 119, in exit
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource six.reraise(self.type
, self.value, self.tb)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/plugins/ml2/plugin.py", line 714, in _delete_ports
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.delete_port(context, port_id)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/plugins/ml2/plugin.py", line 1367, in delete_port
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource super(Ml2Plugin, self).delete_port(context, id)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/db_base_plugin_v2.py", line 1237, in delete_port
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.ipam.delete_port(context, id)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 351, in delete_port
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource port['fixed_ips'])
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 57, in ipam_deallocate_ips
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource ipam_subnet.deallocate(ip['ip_address'])
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 119, in exit
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource six.reraise(self.type
, self.value, self.tb)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/opt/stack/neutron/neutron/db/ipam_pluggable_backend.py", line 57, in _ipam_deallocate_ips
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource ipam_subnet.deallocate(ip['ip_address'])
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/networking_infoblox/ipam/driver.py", line 320, in deallocate
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource ip=ip_address)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 250, in search
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource connector, *_kwargs)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 231, in _search
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource ib_obj_for_search = cls(connector, *_kwargs)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 135, in new
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource cls).new(cls.get_class_from_args(kwargs))
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/bdb.py", line 53, in trace_dispatch
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource return self.dispatch_return(frame, arg)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/bdb.py", line 88, in dispatch_return
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.user_return(frame, arg)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/pdb.py", line 190, in user_return
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.interaction(frame, None)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/pdb.py", line 209, in interaction
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource self.print_stack_entry(self.stack[self.curindex])
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/pdb.py", line 900, in print_stack_entry
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource prompt_prefix)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/bdb.py", line 381, in format_stack_entry
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource s = s + repr.repr(rv)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/repr.py", line 24, in repr
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource return self.repr1(x, self.maxlevel)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/lib/python2.7/repr.py", line 34, in repr1
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource s = builtin.repr(x)
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 69, in repr
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource for field in self._fields + self._shadow_fields
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 70, in
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource if getattr(self, field) is not None}
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource File "/usr/local/lib/python2.7/dist-packages/infoblox_client/objects.py", line 59, in getattr
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource raise AttributeError
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource AttributeError
2015-11-24 10:36:25.421 TRACE neutron.api.v2.resource

New class needed for Tenant Object

There is a ticket field in jira: OPENSTACK-786, regarding “Tenant Name” support under Cloud->Tenants tab in NIOS GUI.

In order to populate this we need to call a new api:

https://10.39.12.179/wapidoc/objects/grid.cloudapi.tenant.html?highlight=tenant%20name#grid:cloudapi:tenant.name

It seems that the way to update the Tenant Name is to do a put to the Tenant object.

E.g.

curl -k -u cloud:infoblox -H "Content-Type: application/json" -X POST https://10.39.19.152//wapi/v2.2/record:host?_return_fields=ipv4addrs -d '{"ipv4addrs":[{"ipv4addr": "10.10.10.3"}],"name": "test","configure_for_dns": false,"extattrs": {"Tenant ID": {"value": "1013"},"VM ID": {"value": "355"},"Cloud API Owned": {"value": "True"},"VM Name": {"value": "SomeVM2"},"CMP Type":{"value":"OpenStack"},"Tenant Name": {"value": "SomeTenant"}}}'

then

curl -k -u cloud:infoblox -H "Content-Type: application/json" -X GET https://10.39.19.152/wapi/v2.2/grid:cloudapi:tenant?id=1013

to get the object handle

then

curl -k -u cloud:infoblox -H "Content-Type: application/json" -X PUT https://10.39.19.152/wapi/v2.2/grid:cloudapi:tenant/ZG5zLnRlbmFudCQxMDEx:1013/1013 -d '{"name":"Some Tenant Name"}'

to update the Tenant Name on the Tenant Object.

Cloud API User needs to have RW permission on "All Tenant" permissions.

_ref attribute error

I created a dhcp member like this.

    ib_dhcp_members = []
    for m in dhcp_members:
        ib_dhcp_members.append(ib_objects.AnyMember(_struct='dhcpmember',
                                                    name=m.member_name))

Then I call the following to restart dhcp members.

    for ib_member in self.ib_cxt.mapping.ib_dhcp_members:
        self.ib_cxt.ibom.restart_all_services(ib_member)

Then this fails because the following method checks _ref property which is not created.

def restart_all_services(self, member):
    if not member._ref:             <== FAILURE
        member.fetch()
    self.connector.call_func('restartservices', member._ref,
                             {'restart_option': 'RESTART_IF_NEEDED',
                              'service_option': 'ALL'})

You either need to create all the mandatory fields with default values when an object is created or
you can change the logic above to

    if not hasattr(member, '_ref:  '):

It is inconvenient if API user has to create fields with default values without knowing which fields are referenced.

Need to change update_network_options not to overwrite the existing EAs.

When the admin created a shared network in NIOS and added custom EAs, creating the shared subnet in Openstack removes the custom EAs because we overwrite the existing ib_network.extattrs with newly generated extattrs as below.

    if extattrs:
        ib_network.extattrs = extattrs

So we need to actually check if EA key exists in the ib_network.extattrs and just update value on the existing key.

This way we will not remove the existing EAs that were added from NIOS side.

'configure_for_dhcp' does not work.

I used the following options to create ip allocator.

options['use_host_record'] = True
options['configure_for_dhcp'] = False
ip_allocator.IPAllocator(self.ibom, options)

But when I allocated ip using allocate_ip_from_range call, configure_for_dhcp option was not working correctly.

This is the trace from the api call.

Infoblox record:host was created: HostRecordV4: extattrs="EAs:Account=None,Port ID=None,VM ID=dhcpa3da5f21-e3f1-5842-947d-21228419109c-d2d41e33-6717-48ba-bbb0-0ff25d74d22e,IP Type=Fixed,CMP Type=OpenStack,Port Attached Device - Device Owner=network:dhcp,Port Attached Device - Device ID=dhcpa3da5f21-e3f1-5842-947d-21228419109c-d2d41e33-6717-48ba-bbb0-0ff25d74d22e,Cloud API Owned=True,Tenant ID=4befcd541d594ac6a60389243a0b0ef6", ipv4addr="func:nextavailableip:9.9.1.2-9.9.1.254,default", name="98dfeac1-ca46-44c4-a343-0096e0d4b62c.s2.cloud.global.com", ipv4addrs="[IPv4: configure_for_dhcp="True", ip="func:nextavailableip:9.9.1.2-9.9.1.254,default", mac="fa:16:3e:2f:5d:08", ipv4addr="func:nextavailableip:9.9.1.2-9.9.1.254,default"]", view="default"

Multivalued String List EA is not supported

An EA definition allows a string type with multi-valued.
Then it accepts list of string data like

Last Grid Sync Time = ['controller-1': '2016-01-15 23:02:59', 'controller-2': '2016-01-15 23:03:03']

However this is not allowed in ib_objects.EA because all the data is converted to string like this:

Last Grid Sync Time = "['controller-1': '2016-01-15 23:02:59', 'controller-2': '2016-01-15 23:03:03']"

We should support EA multi-valued.

Introduce push/pull(fetch) concept for infoblox-client objects.

Currently two way mechanism for exanging data between infoblox-client object instances and nios objects exists:

  • fetch - data stream from nios to local object, reference can be present in object, or object can be searched by search fields in opposite case;
  • update - data stream from local object to nios, send fields updates to remote object, requires to have reference set in local object and object on nios side should already exists;

And I propose to extend this concept to push - pull, where having reference and object on nios side is not required to data stream from local object to nios:

  • pull - data stream from nios to local object, it would be just an allias for 'fetch', since it already allows to get objects with or without reference;
  • push - this one will do what 'update' does if reference is set, but if reference is not set, then it would try to create object on remote. It would be almost analog of current 'create' class method but for instance.

So next code would be possible:

network = object.Network(connector, network='192.168.1.0', networkview='default')
# wapi call for create/update fields on nios side are done in push method
network.push()

A new exception needed when a delegation member or a dhcp member has already been assigned.

When a next available member is sent to NIOS for network creation, the following error message is returned.

{ "Error": "AdmConDataError: None (IBDataConflictError: IB.Data.Conflict:Member 10.39.12.91 is assigned to another network view 'test2')",
"code": "Client.Ibap.Data.Conflict",
"text": "Member 10.39.12.91 is assigned to another network view 'test2'"
}
The Response Code:400

The connector should capture this specific case and raise an infoblox exception like
InfobloxMemberAlreadyAssigned.

'configure_for_dhcp' does not work.

I used the following options to create ip allocator.

options['use_host_record'] = True
options['configure_for_dhcp'] = False
ip_allocator.IPAllocator(self.ibom, options)

But when I allocated ip using allocate_ip_from_range call, configure_for_dhcp option was not working correctly.

This is the trace from the api call.

Infoblox record:host was created: HostRecordV4: extattrs="EAs:Account=None,Port ID=None,VM ID=dhcpa3da5f21-e3f1-5842-947d-21228419109c-d2d41e33-6717-48ba-bbb0-0ff25d74d22e,IP Type=Fixed,CMP Type=OpenStack,Port Attached Device - Device Owner=network:dhcp,Port Attached Device - Device ID=dhcpa3da5f21-e3f1-5842-947d-21228419109c-d2d41e33-6717-48ba-bbb0-0ff25d74d22e,Cloud API Owned=True,Tenant ID=4befcd541d594ac6a60389243a0b0ef6", ipv4addr="func:nextavailableip:9.9.1.2-9.9.1.254,default", name="98dfeac1-ca46-44c4-a343-0096e0d4b62c.s2.cloud.global.com", ipv4addrs="[IPv4: configure_for_dhcp="True", ip="func:nextavailableip:9.9.1.2-9.9.1.254,default", mac="fa:16:3e:2f:5d:08", ipv4addr="func:nextavailableip:9.9.1.2-9.9.1.254,default"]", view="default"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.