示例#1
0
 def add_addr(addr, family):
     if not addr:
         return
     if addr.version != family:
         raise RuntimeError(f"Wrong family for {a}")
     try:
         a = IPAddress.objects.get(
             address=addr,
             vrf=data.get("vrf"),
         )
         result = "Assigned"
     except ObjectDoesNotExist:
         a = IPAddress(
             address=addr,
             vrf=data.get("vrf"),
         )
         result = "Created"
     a.status = IPAddressStatusChoices.STATUS_ACTIVE
     a.dns_name = data["dns_name"]
     if a.assigned_object:
         raise RuntimeError(f"Address {addr} is already assigned")
     a.assigned_object = vminterface
     a.tenant = data.get("tenant")
     a.full_clean()
     a.save()
     #a.tags.set(data[f"primary_ip{family}_tags"])
     self.log_info(f"{result} IP address {a.address} {a.vrf or ''}")
     setattr(vm, f"primary_ip{family}", a)
示例#2
0
 def add_addr(addr, expect_family):
     if not addr:
         return
     if addr.version != expect_family:
         raise RuntimeError("Wrong family for %r" % a)
     try:
         a = IPAddress.objects.get(
             address=addr,
             vrf=data.get("vrf"),
         )
         result = "Assigned"
     except ObjectDoesNotExist:
         a = IPAddress(
             address=addr,
             vrf=data.get("vrf"),
         )
         result = "Created"
     a.status = IPAddressStatusChoices.STATUS_ACTIVE
     a.dns_name = data["dns_name"]
     if a.interface:
         raise RuntimeError("Address %s is already assigned" % addr)
     a.interface = interface
     a.tenant = data.get("tenant")
     a.save()
     self.log_info("%s IP address %s %s" %
                   (result, a.address, a.vrf or ""))
     setattr(vm, "primary_ip%d" % a.family, a)
    def _add_ip_to_interface(self, device, interface):
        # determine prefix appropriate to site of device
        try:
            prefix = Prefix.objects.get(site=device.site,
                                        role__slug="management",
                                        tenant=device.tenant)
        except ObjectDoesNotExist:
            message = "Can't find prefix for site {} on device {}".format(
                device.site.slug, device.name)
            self.log_failure(message)
            return message
        self.log_info("Selecting address from network {}".format(
            prefix.prefix))
        available_ips = iter(prefix.get_available_ips())

        # disable 0net skipping on frack
        if device.tenant and device.tenant.slug == 'fr-tech':
            zeroth_net = None
        else:
            # skip the first /24 net as this is reserved for network devices
            zeroth_net = list(
                ipaddress.ip_network(prefix.prefix).subnets(new_prefix=24))[0]

        ip = None
        for ip in available_ips:
            address = ipaddress.ip_address(ip)
            if zeroth_net is None or address not in zeroth_net:
                break
            else:
                ip = None

        if ip:
            # create IP address as child of appropriate prefix
            newip = IPAddress(
                address="{}/{}".format(ip, prefix.prefix.prefixlen),
                status=IPADDRESS_STATUS_ACTIVE,
                family=prefix.family,
            )
            # save ASAP
            newip.save()
            newip.vrf = prefix.vrf.pk if prefix.vrf else None
            # assign ip to interface
            newip.interface = interface
            newip.tenant = device.tenant
            newip.save()

            message = "Created ip {} for mgmt on device {}".format(
                newip, device.name)
            self.log_success(message)
            return message

        # fall through to failure
        message = "Not enough IPs to allocate one on prefix {}".format(
            prefix.prefix)
        self.log_failure(message)
        return message
示例#4
0
def host_get_mac_consumer(host_id, is_virtual):
    if not is_virtual:
        host = Device.objects.get(id=host_id)
    else:
        host = VirtualMachine.objects.get(id=host_id)

    ip, secret = host.management_access
    resp = HostByCli(ip, secret.name, secret.password).get_mac()

    # Sample output:
    #
    # 8: ens4f1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT qlen 1000
    #     link/ether 90:e2:ba:e3:bc:d5 brd ff:ff:ff:ff:ff:ff
    # 9: ens5f0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT qlen 1000
    #     link/ether 90:e2:ba:e3:ba:80 brd ff:ff:ff:ff:ff:ff
    #
    # We are to parse this to extract interface name and mac address
    if not resp:
        host.status = DEVICE_STATUS_OFFLINE
        host.save()
        return
    else:
        host.status = DEVICE_STATUS_ACTIVE
        host.save()

    for (name, mac, ip) in resp:
        # There are 3 scenarios interface may have been generated:
        #
        # 1. MAC could have been seen by switch. In this case, we know the MAC
        #    but doesn't know its name or host. So matching the MAC is the only option.
        #    ASSUMPTION: MAC is unique of the entire inventory.
        # 2. a repeated scan of either switch host. In this case, we should
        #    have had either a full match (name,mac,host) or None.
        #
        # Since (device,name) is unique, we have to check
        # interface carefully before creating a new one.

        # handle case #2, we have either seen a full match or none.
        aa = Interface.objects.filter(device=host, name=name, mac_address=mac)
        if aa:
            interface = aa[0]

        else:
            # search by (device,name)
            bb = Interface.objects.filter(device=host, name=name)
            if bb:
                bb.update(mac_address=mac)
            else:
                # search by (device,mac)
                cc = Interface.objects.filter(device=host, mac_address=mac)

                if cc:
                    cc.update(name=name)
                else:
                    interface = Interface(device=host,
                                          name=name,
                                          mac_address=mac)
                    interface.save()

        # create IP
        # Note that IP can be duplicate, eg. 192.168.x.x is a private
        # address, thus can be available in multiple host. So we only
        # create new IPAddress if all existing one of this address has
        # already an Interface associated w/ it.
        if ip:

            # TODO: we have to iterate all IP because
            # manual input may have used wrong **mask*.
            for e in IPAddress.objects.all():
                if ip == str(e.address.ip):
                    if e.primary_ip4_for_set.all():
                        # if it's tied to a device
                        for d in e.primary_ip4_for_set.all():
                            if d == host:
                                e.address = ip
                                e.save()

            existing_ip = IPAddress.objects.filter(address=ip,
                                                   interface=interface)
            if existing_ip:
                my_ip = existing_ip[0]
            else:
                # we have create this IP, but has not associated it w/ anyone
                existing_ip = IPAddress.objects.filter(address=ip,
                                                       interface__isnull=True)
                if existing_ip:
                    my_ip = existing_ip[0]
                    my_ip.interface = interface
                    my_ip.save()
                else:
                    my_ip = IPAddress(address=IPNetwork(ip),
                                      interface=interface)
                    my_ip.save()
示例#5
0
    def handle(self, *args, **options):
        # First, query for the device by name.
        try:
            device = Device.objects.get(name=options['name'])
        except Device.DoesNotExist:
            self.stdout.write(f"Unable to find device: {options['name']}")
            return

        # If an IP address was specified, then configure the device with it.
        _ip = options['ip']
        if _ip is not None:
            # Make sure there's an interface named "mgmt"
            # If there isn't, then create one.
            mgmt_iface = next(
                (True
                 for iface in device.vc_interfaces() if iface.name == 'mgmt'),
                None)
            if not mgmt_iface:
                if options['dry_run']:
                    self.stdout.write(
                        'Would have created a managment interface called mgmt')
                else:
                    mgmt_iface = Interface(
                        device=device,
                        name='mgmt',
                        type=InterfaceTypeChoices.TYPE_VIRTUAL)
                    mgmt_iface.save()

            # Make sure the specific IP address exists and is on the mgmt interface.
            try:
                _ip = options['ip']
                mgmt_ip = IPAddress.objects.get(address=_ip)

                # If the IP exists, make sure it's currently not assigned to another interface.
                if mgmt_ip.interface is not None:
                    if mgmt_ip.interface.name != 'mgmt' and mgmt_ip.interface.device.id != device.id:
                        self.stdout.write(
                            f"IP Address {_ip} is already assigned to {mgmt_ip.interface.device.name}"
                        )
                        return
                # Otherwise, add the IP to the interface.
                else:
                    if options['dry_run']:
                        self.stdout.write(
                            f"Would have added {mgmt_ip} to the mgmt interface"
                        )
                    else:
                        mgmt_ip.interface = mgmt_iface
                        mgmt_ip.save()
            except IPAddress.DoesNotExist:
                # If the IP doesn't exist, create it and link it to the mgmt interfae.
                if options['dry_run']:
                    self.stdout.write(
                        f"Would have created IP address {options['ip']} and assigned it to the mgmt interface"
                    )
                else:
                    mgmt_ip = IPAddress(address=options['ip'],
                                        interface=mgmt_iface)
                    mgmt_ip.save()

            # Ensure the primary IP address of the device is set to the mgmt IP.
            if device.primary_ip4 is None or device.primary_ip4.id != mgmt_ip.id:
                if options['dry_run']:
                    self.stdout.write(
                        f"Would have assigned {mgmt_ip} as the primary IP of the device"
                    )
                else:
                    device.primary_ip4 = mgmt_ip
                    device.save()
    def run(self, data, commit):
        # Create the device
        device = Device(name=data['business_name'],
                        device_role_id=self.DEVICE_ROLE_ID,
                        device_type_id=data["hardware_choice"],
                        platform_id=self.PLATFORM_ID,
                        site_id=self.SITE_ID)
        device.save()

        interfaces = Interface.objects.filter(device_id=device.id)
        enabled_interfaces = []
        mgmt_intf = interfaces.get(name="b107")
        enabled_interfaces.append(mgmt_intf)
        uplk_intf = interfaces.get(name="ether10")
        enabled_interfaces.append(uplk_intf)
        uplk_intf.mode = "tagged"
        uplk_intf.tagged_vlans.set([self.INET_VLAN, self.MGMT_VLAN])
        uplk_intf.description = "Uplink"
        uplk_intf.save()
        inet_intf = interfaces.get(name="ether1")
        enabled_interfaces.append(inet_intf)
        inet_intf.description = "Internet"
        inet_intf.mode = "access"
        inet_intf.untagged_vlan = self.INET_VLAN
        inet_intf.save()
        mgmt_intf.save()
        for intf in interfaces:
            intf.enabled = False
            intf.save()
        for intf in enabled_interfaces:
            intf.enabled = True
            intf.mtu = 1500
            intf.save()
        available_ip = Prefix.objects.get(
            vlan=self.MGMT_VLAN).get_first_available_ip()
        ip = IPAddress(
            address=available_ip,
            assigned_object_type=ContentType.objects.get_for_model(Interface),
            assigned_object_id=mgmt_intf.id)
        ip.save()
        device.primary_ip4_id = ip.id
        device.primary_ip_id = ip.id
        device.comments = data['comments']
        device.save()

        # ############
        if (not data["skip_zabbix"] and commit):

            # Post to Zabbix API to create host in mikrotik group and ICMP
            # template
            try:
                hostid = self.ZAPI.host.create(
                    host=data["business_name"],
                    interfaces=dict(type=2,
                                    main=1,
                                    useip=1,
                                    ip=available_ip.replace("/24", ""),
                                    port=161,
                                    dns="",
                                    details=dict(
                                        version="1",
                                        bulk="0",
                                        community=self.SNMP_COMMUNITY)),
                    groups=dict(groupid=15),
                    templates=dict(templateid=10186))
                self.log_info("zabbix configured successfully")
            except Exception as e:
                self.log_info("failed to configure zabbix {0}".format(e))

        if (not data["skip_uplink_port"] and commit):
            try:
                agg_switches = Device.objects.filter(
                    site=data["uplink_site"],
                    device_role_id=self.AGG_ROLE_ID,
                    status="active")
                selected_interface = ""
                for agg_switch in agg_switches:
                    interfaces = Interface.objects.filter(
                        device_id=agg_switch.id)
                    for interface in interfaces:
                        if (interface.connection_status is not True
                                and interface.enabled is True
                                and interface.description == ''
                                and interface.type == '1000base-x-sfp'):
                            selected_interface = interface
                            break
                    if selected_interface != "":
                        selected_interface.enabled = True
                        selected_interface.description = device.name
                        selected_interface.mode = "tagged"
                        selected_interface.tagged_vlans.set(
                            [self.INET_VLAN, self.MGMT_VLAN])
                        selected_interface.save()
                        cable = Cable(
                            termination_a=uplk_intf,
                            termination_b=selected_interface,
                        )
                        cable.save()
                        self.log_info(
                            "uplink switch chosen. Port {0} on {1}".format(
                                selected_interface.name, agg_switch.name))
                        break
                if selected_interface == "":
                    self.log_failure("No available aggregate port found. \
                        No aggregate port assigned.")

            except BaseException:
                self.log("failed to document uplink switch")

        self.log_success("Created {0}".format(device.name))
示例#7
0
def sync_interfaces(device, interfaces):
    """ Syncing interfaces

        :param device: object NetBox Device
        :param interfaces: list of lists

        interfaces:
            interface['NAME'] - Name of interface
            interface['MAC'] - Mac-Address
            interface['IP'] - List of IP-address
            interface['MTU'] - MTU
            interface['DESCR'] - Description of interfaces
            interface['TYPE'] - Physical type of interface (Default 1G-cooper - cannot get from linux)
            interface['STATE'] - UP|DOWN

        :return: status: bool, message: string
    """
    # Updated interface counter
    count = 0

    # Init interfaces filter
    iface_filter = device.cf().get('Interfaces filter')
    try:
        iface_regex = re.compile(iface_filter)
    except Exception as e:
        logger.warning("Cannot parse regex for interface filter: {}".format(e))
        iface_regex = re.compile('.*')

    for interface in interfaces:
        name = interface.get('NAME')
        mac = interface.get('MAC')
        ips = interface.get('IP')
        mtu = interface.get('MTU')
        description = interface.get('DESCR')
        iface_type = interface.get('TYPE')
        iface_state = interface.get('STATE')
        # TODO: add a bonding support
        iface_master = interface.get('BOND')

        # Check interface filter
        if not iface_regex.match(name):
            logger.debug("Iface {} not match with regex".format(name))
            continue

        # Get interface from device - for check if exist
        ifaces = device.interfaces.filter(name=name)
        if ifaces:
            logger.info(
                "Interface {} is exist on device {}, will update".format(
                    name, device.name))
            # TODO: I think, that only one item will be in filter, but need to add check for it
            iface = ifaces[0]
        else:
            logger.info(
                "Interface {} is not exist on device {}, will create new".
                format(name, device.name))
            iface = Interface(name=name)
            iface.device = device

        logger.info(
            "Will be save next parameters: Name:{name}, MAC: {mac}, MTU: {mtu}, Descr: {description}"
            .format(name=name, mac=mac, mtu=mtu, description=description))
        if description:
            iface.description = description
        else:
            iface.description = ''
        iface.mac_address = mac

        # MTU should be less 32767
        if int(mtu) < MAX_MTU:
            iface.mtu = mtu

        logger.info("Interface state is {}".format(iface_state))
        iface.enabled = 'up' in iface_state.lower()
        iface.form_factor = _get_interface_type(name)

        try:
            iface.save()
        except Exception as e:
            logger.error("Cannot save interface, error is {}".format(e))
        else:
            count += 1
            logger.info("Interface {} was succesfully saved".format(
                name, device.name))

        try:
            _connect_interface(iface)
        except:
            logger.error("Problem with connection function")

        # IP syncing
        if len(ips) > 0:
            for address in ips:
                addr = IPAddress()
                addr.interface = iface
                logger.info("Address is: {}".format(addr))
                # TODO: Need a test ipv6 addresses
                try:
                    # tries to determine is this address exist
                    if iface.ip_addresses.filter(address=address):
                        continue
                    addr.address = IPNetwork(address)
                    addr.save()
                except:
                    logger.warning(
                        "Cannot set address {} on interface".format(address))

    if count == 0:
        return False, "Can't update any interface, see a log for details"
    return True, "Successfully updated {} interfaces".format(count)
示例#8
0
    def handle(self, *args, **options):
        # First, query for the device by name.
        try:
            device = Device.objects.get(name=options['device_name'])
        except Device.DoesNotExist:
            self.stdout.write(f"Unable to find device: {options['device_name']}")
            return

        # Determine the information needed to connect to the device.
        mgmt_ip = device.primary_ip4
        onepw_host = settings.PLUGINS_CONFIG['sidekick'].get('1pw_connect_host', None)
        onepw_token_path = settings.PLUGINS_CONFIG['sidekick'].get('1pw_connect_token_path', None)
        onepw_vault = settings.PLUGINS_CONFIG['sidekick'].get('1pw_connect_readonly_vault', None)

        # If all of the connection information was found,
        # attempt to decrypt the connection credentials,
        # connect to the device, and inventory the interfaces.
        if mgmt_ip is not None and \
           onepw_host is not None and \
           onepw_token_path is not None and \
           onepw_vault is not None:

            _mgmt_ip = "%s" % (mgmt_ip.address.ip)

            try:
                snmp = decrypt_1pw_secret(onepw_token_path, onepw_host, onepw_vault, f"{device}", 'snmp')
            except Exception as e:
                self.stdout.write(f"Unable to decrypt snmp secret: {e}")

            if snmp is None:
                self.stdout.write(f"Unable to find snmp secret for {device}")
                return

            try:
                device_info = snmpwalk_bulk(_mgmt_ip, snmp)
                # device_info = get_device_info_via_snmp(_mgmt_ip, snmp)
            except Exception as e:
                self.stdout.write(f"Error querying device {device}: {e}")
                return

            # If we're able to connect,
            # build a list of interface names already on the device.
            existing_interfaces = {}
            for i in device.vc_interfaces():
                existing_interfaces[i.name] = i

            # Obtain the list of interfaces.
            # For each device that is not supposed to be ignored,
            # add that interface to the device if it doesn't already exist.
            for iface_index, iface_details in device_info.items():
                iface_name = iface_details.get('ifName', None)
                if iface_name is None:
                    continue
                # self.stdout.write(f"{iface_details['name']}: {iface_details['oper_status']}")
                # continue

                if not any(i in iface_details['ifName'] for i in VALID_INTERFACE_NAMES):
                    continue

                iface_type = InterfaceTypeChoices.TYPE_VIRTUAL
                if iface_details['ifHighSpeed'] == 1000:
                    iface_type = InterfaceTypeChoices.TYPE_1GE_FIXED
                if iface_details['ifHighSpeed'] == 10000:
                    iface_type = InterfaceTypeChoices.TYPE_10GE_FIXED
                if iface_details['ifHighSpeed'] == 'ieee8023adLag':
                    iface_type = InterfaceTypeChoices.TYPE_LAG

                # TODO: VLAN management is incomplete right now.
                # _vlan = None
                iface_mode = InterfaceModeChoices.MODE_TAGGED
                if '.' in iface_name:
                    iface_mode = InterfaceModeChoices.MODE_ACCESS
                    # _vlan = iface_name.split('.')[1]
                if 'Vlan' in iface_name:
                    iface_mode = InterfaceModeChoices.MODE_ACCESS
                #     m = RE_ARISTA_VLAN.search(iface_name)
                #     if m:
                #         _vlan = m.group(1)

                iface_untagged_vlan = None
                # if _vlan is not None:
                #     try:
                #         iface_untagged_vlan = VLAN.objects.get(vid=_vlan)
                #     except VLAN.MultipleObjectsReturned:
                #         self.stdout.write(f"WARNING: Multiple results found for VLAN {_vlan}. Not setting VLAN.")
                #     except VLAN.DoesNotExist:
                #         self.stdout.write(f"WARNING: No results found for VLAN {_vlan}. Not setting VLAN.")

                # If the interface already exists, update a few fields.
                # We do not update the interface type because that could have
                # been updated in NetBox directly to something more specific/better
                # than what SNMP can can determine.
                if iface_name in existing_interfaces.keys():
                    existing_interface = existing_interfaces[iface_name]

                    changed = False
                    _descr = iface_details['ifAlias'].strip()
                    if existing_interface.description != _descr:
                        existing_interface.description = _descr
                        changed = True

                    admin_status = f"{iface_details['ifAdminStatus']}"
                    if admin_status == "up":
                        admin_status = 1
                    if admin_status == "down":
                        admin_status = 0

                    iface_status = False
                    oper_status = iface_details['ifOperStatus']
                    if admin_status == 1 and oper_status == 1:
                        iface_status = True
                    if existing_interface.enabled != iface_status:
                        existing_interface.enabled = iface_status
                        changed = True

                    if existing_interface.untagged_vlan != iface_untagged_vlan:
                        existing_interface.untagged_vlan = iface_untagged_vlan
                        changed = True

                    if changed is True:
                        if options['dry_run']:
                            self.stdout.write(f"Would have updated {iface_name}")
                        else:
                            existing_interface.save()

                if iface_name not in existing_interfaces.keys():
                    if options['dry_run']:
                        self.stdout.write(f"Would have added {iface_name}")
                    else:
                        admin_status = f"{iface_details['ifAdminStatus']}"
                        if admin_status == "down":
                            admin_status = False
                        if admin_status == "up":
                            admin_status = True

                        mtu = iface_details.get('ifMtu', 0)
                        if 'No more variables' in f"{mtu}":
                            mtu = 0

                        iface = Interface(
                            device=device,
                            description=iface_details.get('ifDescr', None),
                            name=iface_name,
                            type=iface_type,
                            enabled=admin_status,
                            mac_address=iface_details.get('ifPhysAddress', None),
                            mtu=mtu,
                            mode=iface_mode,
                            untagged_vlan=iface_untagged_vlan,
                        )
                        iface.save()

            # To account for one or more new interfaces being added,
            # build a list of interface names already on the device.
            existing_interfaces = {}
            for i in device.vc_interfaces():
                existing_interfaces[i.name] = i

            # Obtain the list of IP addresses on each interface.
            # For each interface that is not supposed to be ignored,
            # add the IP address to the interface if it doesn't already exist.
            for iface_index, iface_details in device_info.items():
                iface_name = iface_details.get('ifName', None)
                if iface_name is None:
                    continue

                if not any(i in iface_name for i in VALID_INTERFACE_NAMES):
                    continue

                if iface_name not in existing_interfaces.keys():
                    continue

                existing_interface = existing_interfaces[iface_name]
                existing_ip_addresses = existing_interface.ip_addresses.all()

                for version, family in IP_VERSIONS.items():
                    if version not in iface_details.keys():
                        continue

                    if iface_details[version] is None:
                        continue

                    # Check if an IP was removed from the device.
                    # If so, then delete it from NetBox.
                    for existing_ip in existing_ip_addresses:
                        if existing_ip.family == family:
                            if f"{existing_ip}" not in iface_details[version]:
                                if options['dry_run']:
                                    self.stdout.write(
                                        f"Would have removed {existing_ip} from {iface_name}")
                                else:
                                    existing_ip.assigned_object = None
                                    existing_ip.description = f"Previously assigned to {options['device_name']} on interface {iface_name}"
                                    existing_ip.save()

                    # Check if an IP needs to be added to NetBox.
                    for interface_ip in iface_details[version]:
                        # If the IP polled from the device is not in the NetBox device interface...
                        if not any(interface_ip == f"{_ip}" for _ip in existing_ip_addresses):
                            try:
                                ip = IPAddress.objects.get(address=interface_ip)
                                if ip.assigned_object is not None and ip.assigned_object.id != existing_interface.id:
                                    # If the IP being reported is the management IP, then ignore.
                                    # This is because we want to standardize on the name of the
                                    # management interface, even if the IP address is on a different
                                    # interface. This isn't ideal and should be improved in the
                                    # future.
                                    if ip == mgmt_ip:
                                        continue

                                    # Also ignore private IP addresses since they can be
                                    # reused in different locations. Again, this isn't ideal and
                                    # should be improved in the future.
                                    if f"{ip}".startswith("10.") or f"{ip}".startswith("172.") or f"{ip}".startswith("192."):
                                        continue

                                    # If the IP assignment is on the same device, we will assume
                                    # a reconfiguration was made. In this case, we reassign the
                                    # IP.
                                    if ip.assigned_object.device.name == existing_interface.device.name:
                                        ip.assigned_object = existing_interface
                                        ip.save()
                                        continue

                                    self.stdout.write(
                                        f"IP Address {interface_ip} is already assigned to "
                                        f"{ip.assigned_object.name} on {ip.assigned_object.device.name}. "
                                        f"Will not assign to {existing_interface.name} on "
                                        f"{existing_interface.device.name}")
                                    continue
                                # Otherwise, add the IP to the interface.
                                else:
                                    if options['dry_run']:
                                        self.stdout.write(
                                            f"Would have added {interface_ip} to {existing_interface.name}")
                                    else:
                                        if ip.description != existing_interface.description:
                                            ip.description = existing_interface.description
                                        ip.assigned_object = existing_interface
                                        ip.save()
                            except IPAddress.MultipleObjectsReturned:
                                self.stdout.write(f"WARNING: Multiple results found for IP {interface_ip}. Skipping.")
                                continue
                            except IPAddress.DoesNotExist:
                                if options['dry_run']:
                                    self.stdout.write(
                                        f"Would have created IP address {interface_ip} and added it to " +
                                        f"{existing_interface.name}")
                                else:
                                    ip = IPAddress(
                                        address=interface_ip,
                                        description=existing_interface.description)
                                    ip.save()

                                    existing_interface.ip_address = ip
                                    existing_interface.save()

            # Obtain the counters on each interface.
            # For each interface that is not supposed to be ignored,
            # store the counters as a NIC object.
            for iface_index, iface_details in device_info.items():
                iface_name = iface_details.get('ifName', None)
                if iface_name is None:
                    continue

                if not any(i in iface_name for i in VALID_INTERFACE_NAMES):
                    continue

                if iface_name not in existing_interfaces.keys():
                    continue

                existing_interface = existing_interfaces[iface_name]
                if options['dry_run']:
                    self.stdout.write(f"Would have updated counters for {existing_interface.name}: {iface_details}")
                else:
                    admin_status = iface_details.get('ifAdminStatus', 0)
                    if 'No more variables' in f"{admin_status}":
                        admin_status = 0

                    oper_status = iface_details.get('ifOperStatus', 0)
                    if 'No more variables' in f"{oper_status}":
                        oper_status = 0

                    out_octets = iface_details.get('ifHCOutOctets', 0)
                    if 'No more variables' in f"{out_octets}":
                        out_octets = 0

                    in_octets = iface_details.get('ifHCInOctets', 0)
                    if 'No more variables' in f"{in_octets}":
                        in_octets = 0

                    out_unicast_packets = iface_details.get('ifHCOutUcastPkts', 0)
                    if 'No more variables' in f"{out_unicast_packets}":
                        out_unicast_packets = 0

                    in_unicast_packets = iface_details.get('ifHCInUcastPkts', 0)
                    if 'No more variables' in f"{in_unicast_packets}":
                        in_unicast_packets = 0

                    out_nunicast_packets = iface_details.get('ifOutNUcastPkts', 0)
                    if 'No more variables' in f"{out_nunicast_packets}":
                        out_nunicast_packets = 0

                    in_nunicast_packets = iface_details.get('ifInNUcastPkts', 0),
                    if 'No more variables' in f"{in_nunicast_packets}":
                        in_nunicast_packets = 0

                    out_errors = iface_details.get('ifOutErrors', 0)
                    if 'No more variables' in f"{out_errors}":
                        out_errors = 0

                    in_errors = iface_details.get('ifInErrors', 0)
                    if 'No more variables' in f"{in_errors}":
                        in_errors = 0

                    nic = NIC(
                        interface=existing_interface,
                        interface_id=existing_interface.id,
                        admin_status=admin_status,
                        oper_status=oper_status,
                        out_octets=out_octets,
                        in_octets=in_octets,
                        out_unicast_packets=out_unicast_packets,
                        in_unicast_packets=in_unicast_packets,
                        out_nunicast_packets=out_nunicast_packets,
                        in_nunicast_packets=in_unicast_packets,
                        out_errors=out_errors,
                        in_errors=in_errors,
                    )

                    if 'in_rate' in iface_details:
                        nic.in_rate = iface_details['in_rate']
                    if 'out_rate' in iface_details:
                        nic.out_rate = iface_details['out_rate']

                    nic.save()

                # Send the metrics to Graphite if graphite_host has been set.
                graphite_host = settings.PLUGINS_CONFIG['sidekick'].get('graphite_host', None)
                if graphite_host is not None:
                    graphyte.init(graphite_host)

                    # Determine the difference between the last two updates.
                    # This is because Cybera's metrics were previously stored in RRD
                    # files which only retains the derivative and not what the actual
                    # counters were.
                    previous_entries = NIC.objects.filter(
                        interface_id=existing_interface.id).order_by('-last_updated')
                    if len(previous_entries) < 2:
                        continue

                    e1 = previous_entries[0]
                    e2 = previous_entries[1]
                    total_seconds = (e1.last_updated - e2.last_updated).total_seconds()

                    graphite_prefix = "{}.{}".format(
                        e1.graphite_device_name(), e1.graphite_interface_name())

                    for cat in METRIC_CATEGORIES:
                        m1 = getattr(e1, cat, None)
                        m2 = getattr(e2, cat, None)
                        if m1 is not None and m2 is not None:
                            diff = (m1 - m2)

                            if diff != 0:
                                diff = diff / total_seconds
                            graphite_name = f"{graphite_prefix}.{cat}"
                            if options['dry_run']:
                                self.stdout.write(f"{graphite_name} {diff} {total_seconds}")
                            else:
                                graphyte.send(graphite_name, diff)

                    # Determine if the interface is part of a member's network service.
                    # If so, send a second set of metrics to Graphite with a prefix
                    # dedicated to that service.
                    try:
                        nsd = NetworkServiceDevice.objects.get(
                            device=device, interface=existing_interface.name,
                            network_service__active=True)
                    except NetworkServiceDevice.MultipleObjectsReturned:
                        self.stdout.write(f"Multiple results found for network service using "
                                          f"{device} {existing_interface.name}")
                        continue
                    except NetworkServiceDevice.DoesNotExist:
                        continue

                    ns = nsd.network_service
                    service_prefix = f"{ns.graphite_service_name()}.{graphite_prefix}"

                    for cat in ['in_octets', 'out_octets']:
                        graphite_name = f"{service_prefix}.{cat}"
                        m1 = getattr(e1, cat, None)
                        m2 = getattr(e2, cat, None)
                        if m1 is not None and m2 is not None:
                            diff = (m1 - m2)

                            if diff != 0:
                                diff = diff / total_seconds
                            graphyte.send(graphite_name, diff)
示例#9
0
    def run(self, data):
        host = data['vcenter_host']
        user = data['vcenter_user']
        password = data['vcenter_password']
        vmCount = 0
        ipCount = 0
        intCount = 0

        si = SmartConnectNoSSL(host=host,
                               user=user,
                               pwd=password,
                               port=int(443))
        if si:
            self.log_success("Connected to vCenter!")

        if not si:
            self.log_failure(
                "Couldn't connect to vCenter with the given credentials.")
            return -1

        atexit.register(Disconnect, si)

        content = si.RetrieveContent()
        children = content.rootFolder.childEntity
        for child in children:
            dc = child
            vmdata[dc.name] = {}
            clusters = dc.hostFolder.childEntity
            for cluster in clusters:
                self.log_info(f"Found Cluster: {cluster}")
                vmdata[dc.name][cluster.name] = {}
                hosts = cluster.host
                for host in hosts:
                    self.log_info(f"Found Host: {host}")
                    hostname = host.summary.config.name
                    vmdata[dc.name][cluster.name][hostname] = {}
                    vms = host.vm
                    self.log_info(f"DC Name: {vmdata[dc.name]}")
                    self.log_info(
                        f"Cluster Name: {vmdata[dc.name][cluster.name]}")
                    for vm in vms:
                        newVM = VirtualMachine(
                            name=vm.summary.config.name,
                            cluster=data['cluster'],
                            status=DEVICE_STATUS_ACTIVE,
                            vcpus=str(vm.summary.config.numCpu),
                            memory=vm.summary.config.memorySizeMB,
                            disk=str(
                                int(
                                    float("%.2f" %
                                          (vm.summary.storage.committed /
                                           1024**3)))))
                        newVM.save()
                        vmResult = VirtualMachine.objects.get(
                            name=vm.summary.config.name)
                        self.log_success("Created new VM: {}".format(newVM))
                        vmCount = vmCount + 1
                        nics = {}
                        num = 1
                        for nic in vm.guest.net:
                            if nic.network:
                                if nic.ipConfig is not None and nic.ipConfig.ipAddress is not None:
                                    ipconf = nic.ipConfig.ipAddress
                                    i = 0
                                    for ip in ipconf:
                                        if ":" not in ip.ipAddress:
                                            ipv4c = f"{ip.ipAddress}/{ip.prefixLength}"
                                            nicDescription = nic.network
                                            nicName = f"NIC{num}"
                                            newInt = Interface(
                                                virtual_machine=vmResult,
                                                name=nicName,
                                                description=nicDescription,
                                                type=IFACE_TYPE_VIRTUAL,
                                                mac_address=nic.macAddress)
                                            newInt.save()
                                            intCount = intCount + 1
                                            intResult = Interface.objects.get(
                                                name=nicName,
                                                mac_address=nic.macAddress)
                                            self.log_info(
                                                f"Created new interface: {newInt} - {nic.macAddress}"
                                            )
                                            newIP = IPAddress(
                                                family='4',
                                                address=ipv4c,
                                                description=
                                                f"{vm.summary.config.name} - {nicName}",
                                                interface=intResult)
                                            newIP.save()
                                            ipCount = ipCount + 1
                                            num = num + 1
                                            self.log_info(
                                                f"Created new IP: {newIP} - {nicName} - {nicDescription}"
                                            )
                                    i = i + 1

        self.log_info(
            f"Created {vmCount} VMs, {ipCount} IPs, and {intCount} interfaces."
        )
示例#10
0
    def run(self, data, commit):

        services_list = [
            {
                'id_s': 's2',
                'port': 22,
                'name': 'SSHv2',
                'protocol': 'tcp'
            },
            {
                'id_s': 's1',
                'port': 22,
                'name': 'SSHv1',
                'protocol': 'tcp'
            },
            {
                'id_s': 't',
                'port': 23,
                'name': 'Telnet',
                'protocol': 'tcp'
            },
            {
                'id_s': 'y',
                'port': 443,
                'name': 'YANG',
                'protocol': 'tcp'
            },
            {
                'id_s': 'r',
                'port': 443,
                'name': 'REST',
                'protocol': 'tcp'
            },
        ]

        dev_role = DeviceRole.objects.get(slug='access-switch')
        device_new = Device(
            name=data['dev_name'],
            device_type=data['dev_model'],
            site=data['site'],
            rack=data['rack'],
            position=data['position'],
            device_role=dev_role,
            serial=data['dev_serial'],
        )
        device_new.save()

        device_new.custom_field_data['fMonitoring'] = data['monitoring']
        device_new.custom_field_data['fBackup'] = data['backup']
        device_new.save()

        output = []
        for iServ in data['services']:
            output.append(iServ)
            print(output)
            res = [row for row in services_list if row['id_s'] == iServ]
            s1 = Service(
                device=device_new,
                name=res[0]['name'],
                ports=[res[0]['port']],
                protocol=res[0]['protocol'],
            )
            s1.save()

        dev_mgmt_int = Interface(
            device=device_new,
            name=data['mgmt_int_name'],
            type='virtual',
        )
        dev_mgmt_int.save()

        ipa_type = ContentType.objects.get(app_label='dcim', model='interface')
        ipa = IPAddress(
            address=data['mgmt_int_ip'],
            assigned_object_id=dev_mgmt_int.id,
            assigned_object_type=ipa_type,
        )
        ipa.save()

        device_new.primary_ip4 = ipa

        device_new.save()

        self.log_success(f"Created new Juniper device: {device_new}")
        return ''.join(output)
示例#11
0
    def setup_bbr(self, site, rack, vlan, site_no, node_id, asset_tag, sw):
        bbr_name = "bbr-%s.in.ffho.net" % site.slug

        try:
            bbr = Device.objects.get(name=bbr_name)
            self.log_info("Backbone router %s already present, carrying on." %
                          bbr_name)

            return bbr
        except Device.DoesNotExist:
            pass

        bbr_type = DeviceType.objects.get(manufacturer__name='PCEngines',
                                          model='APU2c4-19"')

        bbr = Device(
            device_type=bbr_type,
            device_role=DeviceRole.objects.get(name='Backbone router'),
            platform=Platform.objects.get(name='Linux'),
            name=bbr_name,
            asset_tag=asset_tag,
            status=DeviceStatusChoices.STATUS_PLANNED,
            site=site,
            rack=rack,
            position=rack.u_height - 4,
            face=DeviceFaceChoices.FACE_FRONT,
        )

        bbr.save()
        self.log_success("Created backbone router %s" % bbr)

        # Set bond0 mode to tagged-all, bundle enp<n>s0 into it and connect enp<n>s0  to switchport 10 + n
        bbr_bond0 = Interface.objects.get(device=bbr, name="bond0")
        bbr_bond0.mode = InterfaceModeChoices.MODE_TAGGED_ALL
        bbr_bond0.save()

        # Link enp1s0 and enp2s0 to switch port 10 and 11 respectivly
        for n in [1, 2]:
            bbr_port = Interface.objects.get(device=bbr, name="enp%ds0" % n)
            sw_port = Interface.objects.get(device=sw, name=str(10 + n))
            cable = Cable(termination_a=sw_port,
                          termination_b=bbr_port,
                          status=CableStatusChoices.STATUS_PLANNED)
            cable.save()

            bbr_port.lag = bbr_bond0
            bbr_port.save()

        self.log_success("Linked %s to %s" % (bbr, sw))

        # Disable enp3s0
        enp3s0 = Interface.objects.get(device=bbr, name="enp3s0")
        enp3s0.enabled = False
        enp3s0.save()

        # Set up Mgmt vlan interface + IP
        bbr_mgmt_iface = Interface(
            device=bbr,
            name="vlan%d" % vlan.vid,
            type=InterfaceTypeChoices.TYPE_VIRTUAL,
        )
        bbr_mgmt_iface.save()

        bbr_mgmt_ip = IPAddress(address="172.30.%d.1/24" % site_no,
                                interface=bbr_mgmt_iface)
        bbr_mgmt_ip.save()

        self.log_success("Configured %s on interface %s of %s" %
                         (bbr_mgmt_ip, bbr_mgmt_iface, bbr))

        # Set up loopback IPs
        bbr_lo_iface = Interface.objects.get(device=bbr, name="lo")
        ipv4 = IPAddress(address="10.132.255.%s/32" % node_id,
                         interface=bbr_lo_iface)
        ipv4.save()

        ipv6 = IPAddress(address="2a03:2260:2342:ffff::%s/128" % node_id,
                         interface=bbr_lo_iface)
        ipv6.save()

        bbr.primary_ip4 = ipv4
        bbr.primary_ip6 = ipv6
        bbr.save()
        self.log_success("Configured %s + %s on lo interface of %s" %
                         (ipv4, ipv6, bbr))
示例#12
0
    def setup_swtich(self, site, rack, pp, panel_ports, vlan, site_no,
                     asset_tag):
        sw_name = "sw-%s-01.in.ffho.net" % site.slug

        try:
            sw = Device.objects.get(name=sw_name)
            self.log_info("Switch %s already present, carrying on." % sw_name)

            return sw
        except Device.DoesNotExist:
            pass

        sw_type = DeviceType.objects.get(manufacturer__name='Netonix',
                                         model='WS-12-250-AC')

        sw = Device(device_type=sw_type,
                    device_role=DeviceRole.objects.get(name='Switch'),
                    platform=Platform.objects.get(name='Netonix'),
                    name=sw_name,
                    asset_tag=asset_tag,
                    status=DeviceStatusChoices.STATUS_PLANNED,
                    site=site,
                    rack=rack,
                    position=rack.u_height - 2,
                    face=DeviceFaceChoices.FACE_FRONT)

        sw.save()
        self.log_success("Created switch %s" % sw)

        # Link switch ports for panel ports
        for n in range(1, int(panel_ports) + 1):
            cable = Cable(termination_a=Interface.objects.get(device=sw,
                                                              name=str(n)),
                          termination_b=FrontPort.objects.get(device=pp,
                                                              name=str(n)),
                          status=CableStatusChoices.STATUS_PLANNED)
            cable.save()

        # Disable interfaces which aren't connected
        unused_ifaces = [13, 14]
        if panel_ports < 10:
            unused_ifaces.extend(list(range(int(panel_ports + 1), 10)))
        unused_ifaces = [str(x) for x in sorted(unused_ifaces)]
        for n in unused_ifaces:
            iface = Interface.objects.get(device=sw, name=n)
            iface.enabled = False
            iface.save()

        self.log_success("Disabled switch unsued ports %s" %
                         ",".join(unused_ifaces))

        # Set up Mgmt port
        sw_mgmt_port = Interface.objects.get(device=sw, name="10")
        sw_mgmt_port.mode = InterfaceModeChoices.MODE_ACCESS
        sw_mgmt_port.untagged_vlan = vlan
        sw_mgmt_port.description = "Mgmt"
        sw_mgmt_port.save()

        self.log_success("Set mgmt interface 10 to untagged VLAN %s" % vlan)

        # Set po1 tagged-all and bundle ports 11 + 12 into it
        sw_po1 = Interface.objects.get(device=sw, name='po1')
        sw_po1.mode = InterfaceModeChoices.MODE_TAGGED_ALL
        sw_po1.save()

        for n in [11, 12]:
            sw_port = Interface.objects.get(device=sw, name=str(n))
            sw_port.lag = sw_po1
            sw_port.save()

        self.log_success("Linked first %s ports of %s to %s" %
                         (panel_ports, sw, pp))

        # Set up Mgmt vlan interface + IP
        sw_mgmt_iface = Interface(
            device=sw,
            name="vlan%d" % vlan.vid,
            type=InterfaceTypeChoices.TYPE_VIRTUAL,
        )
        sw_mgmt_iface.save()

        sw_mgmt_ip = IPAddress(address="172.30.%d.10/24" % site_no,
                               interface=sw_mgmt_iface)
        sw_mgmt_ip.save()

        sw.primary_ip4 = sw_mgmt_ip
        sw.save()

        self.log_success("Configured %s on interface %s of %s" %
                         (sw_mgmt_ip, sw_mgmt_iface, sw))

        return sw