Esempio n. 1
0
def groups_populate(group_name: Optional[str] = None):
    if group_name:
        tmpgroups: dict = {group_name: []}
    else:
        tmpgroups: dict = {key: [] for key in get_groups()}
    with sqla_session() as session:
        devices: List[Device] = session.query(Device).all()
        for dev in devices:
            groups = get_groups(dev.hostname)
            for group in groups:
                if group in tmpgroups:
                    tmpgroups[group].append(dev.hostname)
    return tmpgroups
Esempio n. 2
0
 def __init__(self, **kwargs):
     hosts = {}
     with cnaas_nms.db.session.sqla_session() as session:
         instance: Device
         for instance in session.query(Device):
             hosts[instance.hostname] = {
                 'platform':
                 instance.platform,
                 'groups': [
                     'T_' + instance.device_type.name,
                     'S_' + instance.state.name
                 ],
                 'data': {
                     'synchronized':
                     instance.synchronized,
                     'managed': (True if instance.state
                                 == DeviceState.MANAGED else False)
                 }
             }
             for group in get_groups(instance.hostname):
                 hosts[instance.hostname]['groups'].append(group)
             hostname = self._get_management_ip(instance.management_ip,
                                                instance.dhcp_ip)
             if hostname:
                 hosts[instance.hostname]['hostname'] = hostname
     groups = {'global': {'data': {'k': 'v'}}}
     for device_type in list(DeviceType.__members__):
         groups['T_' + device_type] = {}
     for device_type in list(DeviceState.__members__):
         groups['S_' + device_type] = {}
     for group in get_groups():
         groups[group] = {}
     groups['S_DHCP_BOOT']['username'] = '******'
     groups['S_DHCP_BOOT']['password'] = '******'
     groups['S_DISCOVERED']['username'] = '******'
     groups['S_DISCOVERED']['password'] = '******'
     groups['S_INIT']['username'] = '******'
     groups['S_INIT']['password'] = '******'
     groups['S_MANAGED']['username'] = '******'
     groups['S_MANAGED']['password'] = '******'
     defaults = {'data': {'k': 'v'}}
     super().__init__(hosts=hosts,
                      groups=groups,
                      defaults=defaults,
                      **kwargs)
Esempio n. 3
0
def groups_populate(group_name: Optional[str] = None):
    tmpgroups: dict = {}
    with sqla_session() as session:
        devices: List[Device] = session.query(Device).all()
        for dev in devices:
            groups = get_groups(dev.hostname)
            if not groups:
                continue
            for group in groups:
                if group_name and group != group_name:
                    continue
                if group not in tmpgroups:
                    tmpgroups[group] = []
                tmpgroups[group].append(dev.hostname)
    return tmpgroups
Esempio n. 4
0
    def post(self):
        """ Start sync of device(s) """
        json_data = request.get_json()
        # default args
        kwargs: dict = {
            'dry_run': True,
            'auto_push': False,
            'force': False,
            'resync': False
        }

        if 'dry_run' in json_data and isinstance(json_data['dry_run'], bool) \
                and not json_data['dry_run']:
            kwargs['dry_run'] = False
        if 'force' in json_data and isinstance(json_data['force'], bool):
            kwargs['force'] = json_data['force']
        if 'auto_push' in json_data and isinstance(json_data['auto_push'],
                                                   bool):
            kwargs['auto_push'] = json_data['auto_push']
        if 'resync' in json_data and isinstance(json_data['resync'], bool):
            kwargs['resync'] = json_data['resync']
        if 'comment' in json_data and isinstance(json_data['comment'], str):
            kwargs['job_comment'] = json_data['comment']
        if 'ticket_ref' in json_data and isinstance(json_data['ticket_ref'],
                                                    str):
            kwargs['job_ticket_ref'] = json_data['ticket_ref']

        total_count: Optional[int] = None
        nr = cnaas_init()

        if 'hostname' in json_data:
            hostname = str(json_data['hostname'])
            if not Device.valid_hostname(hostname):
                return empty_result(
                    status='error',
                    data=f"Hostname '{hostname}' is not a valid hostname"), 400
            _, total_count, _ = inventory_selector(nr, hostname=hostname)
            if total_count != 1:
                return empty_result(
                    status='error',
                    data=
                    f"Hostname '{hostname}' not found or is not a managed device"
                ), 400
            kwargs['hostnames'] = [hostname]
            what = hostname
        elif 'device_type' in json_data:
            devtype_str = str(json_data['device_type']).upper()
            if DeviceType.has_name(devtype_str):
                kwargs['device_type'] = devtype_str
            else:
                return empty_result(
                    status='error',
                    data=
                    f"Invalid device type '{json_data['device_type']}' specified"
                ), 400
            what = f"{json_data['device_type']} devices"
            _, total_count, _ = inventory_selector(nr,
                                                   resync=kwargs['resync'],
                                                   device_type=devtype_str)
        elif 'group' in json_data:
            group_name = str(json_data['group'])
            if group_name not in get_groups():
                return empty_result(
                    status='error',
                    data='Could not find a group with name {}'.format(
                        group_name))
            kwargs['group'] = group_name
            what = 'group {}'.format(group_name)
            _, total_count, _ = inventory_selector(nr,
                                                   resync=kwargs['resync'],
                                                   group=group_name)
        elif 'all' in json_data and isinstance(json_data['all'],
                                               bool) and json_data['all']:
            what = "all devices"
            _, total_count, _ = inventory_selector(nr, resync=kwargs['resync'])
        else:
            return empty_result(
                status='error',
                data=f"No devices to synchronize were specified"), 400

        scheduler = Scheduler()
        job_id = scheduler.add_onetime_job(
            'cnaas_nms.confpush.sync_devices:sync_devices',
            when=1,
            scheduled_by=get_jwt_identity(),
            kwargs=kwargs)

        res = empty_result(data=f"Scheduled job to synchronize {what}")
        res['job_id'] = job_id

        resp = make_response(json.dumps(res), 200)
        if total_count:
            resp.headers['X-Total-Count'] = total_count
        resp.headers['Content-Type'] = "application/json"
        return resp
Esempio n. 5
0
    def post(self):
        """Execute certificate related actions on device"""
        json_data = request.get_json()
        # default args
        kwargs: dict = {}

        if 'action' in json_data and isinstance(json_data['action'], str):
            action = json_data['action'].upper()
        else:
            return empty_result(
                status='error',
                data=f"Required field 'action' was not specified"), 400

        if 'comment' in json_data and isinstance(json_data['comment'], str):
            kwargs['job_comment'] = json_data['comment']
        if 'ticket_ref' in json_data and isinstance(json_data['ticket_ref'],
                                                    str):
            kwargs['job_ticket_ref'] = json_data['ticket_ref']

        total_count: Optional[int] = None
        nr = cnaas_init()

        if 'hostname' in json_data:
            hostname = str(json_data['hostname'])
            if not Device.valid_hostname(hostname):
                return empty_result(
                    status='error',
                    data=f"Hostname '{hostname}' is not a valid hostname"), 400
            _, total_count, _ = inventory_selector(nr, hostname=hostname)
            if total_count != 1:
                return empty_result(
                    status='error',
                    data=
                    f"Hostname '{hostname}' not found or is not a managed device"
                ), 400
            kwargs['hostname'] = hostname
        elif 'group' in json_data:
            group_name = str(json_data['group'])
            if group_name not in get_groups():
                return empty_result(
                    status='error',
                    data='Could not find a group with name {}'.format(
                        group_name))
            kwargs['group'] = group_name
            _, total_count, _ = inventory_selector(nr, group=group_name)
        else:
            return empty_result(status='error',
                                data=f"No devices were specified"), 400

        if action == 'RENEW':
            scheduler = Scheduler()
            job_id = scheduler.add_onetime_job(
                'cnaas_nms.confpush.cert:renew_cert',
                when=1,
                scheduled_by=get_jwt_identity(),
                kwargs=kwargs)

            res = empty_result(data=f"Scheduled job to renew certificates")
            res['job_id'] = job_id

            resp = make_response(json.dumps(res), 200)
            if total_count:
                resp.headers['X-Total-Count'] = total_count
            resp.headers['Content-Type'] = "application/json"
            return resp
        else:
            return empty_result(
                status='error',
                data=f"Unknown action specified: {action}"), 400
Esempio n. 6
0
    def post(self):
        """ Upgrade firmware on device """
        json_data = request.get_json()

        kwargs = dict()
        seconds = 1
        date_format = "%Y-%m-%d %H:%M:%S"
        url = self.firmware_url()

        if 'url' not in json_data and url == '':
            return empty_result(status='error',
                                data='No external address configured for '
                                'HTTPD, please specify one with "url"')

        if 'url' not in json_data:
            kwargs['url'] = url
        else:
            if isinstance(json_data['url'], str):
                kwargs['url'] = json_data['url']
            else:
                return empty_result(status='error',
                                    data='url should be a string')

        if 'activate' in json_data:
            if isinstance(json_data['activate'], bool):
                kwargs['activate'] = json_data['activate']
            else:
                return empty_result(status='error',
                                    data='activate should be a boolean')

        if 'download' in json_data:
            if isinstance(json_data['download'], bool):
                kwargs['download'] = json_data['download']
            else:
                return empty_result(status='error',
                                    data='download should be a boolean')

        if 'reboot' in json_data:
            if isinstance(json_data['reboot'], bool):
                kwargs['reboot'] = json_data['reboot']
            else:
                return empty_result(status='error',
                                    data='reboot should be a boolean')

        if 'pre_flight' in json_data:
            if isinstance(json_data['pre_flight'], bool):
                kwargs['pre_flight'] = json_data['pre_flight']
            else:
                return empty_result(status='error',
                                    data='pre_flight should be a boolean')

        if 'post_flight' in json_data:
            if isinstance(json_data['post_flight'], bool):
                kwargs['post_flight'] = json_data['post_flight']
            else:
                return empty_result(status='error',
                                    data='post_flight should be a boolean')

        if 'post_waittime' in json_data:
            if isinstance(json_data['post_waittime'], int):
                kwargs['post_waittime'] = json_data['post_waittime']
            else:
                return empty_result(status='error',
                                    data='post_waittime should be an integer')

        if 'filename' in json_data:
            if isinstance(json_data['filename'], str):
                kwargs['filename'] = json_data['filename']
            else:
                return empty_result(status='error',
                                    data='filename should be a string')

        total_count: Optional[int] = None
        nr = cnaas_init()

        if 'hostname' in json_data:
            hostname = str(json_data['hostname'])
            if not Device.valid_hostname(hostname):
                return empty_result(
                    status='error',
                    data=f"Hostname '{hostname}' is not a valid hostname"
                ), 400
            _, total_count, _ = inventory_selector(nr, hostname=hostname)
            if total_count != 1:
                return empty_result(
                    status='error',
                    data=f"Hostname '{hostname}' not found or is not a managed device"
                ), 400
            kwargs['hostname'] = hostname
        elif 'group' in json_data:
            group_name = str(json_data['group'])
            if group_name not in get_groups():
                return empty_result(status='error', data='Could not find a group with name {}'.format(group_name))
            kwargs['group'] = group_name
            _, total_count, _ = inventory_selector(nr, group=group_name)
            kwargs['group'] = group_name
        else:
            return empty_result(
                status='error',
                data=f"No devices to upgrade were specified"
            ), 400

        if 'comment' in json_data and isinstance(json_data['comment'], str):
            kwargs['job_comment'] = json_data['comment']
        if 'ticket_ref' in json_data and isinstance(json_data['ticket_ref'], str):
            kwargs['job_ticket_ref'] = json_data['ticket_ref']

        if 'start_at' in json_data:
            try:
                time_start = datetime.strptime(json_data['start_at'],
                                               date_format)
                time_now = datetime.utcnow()

                if time_start < time_now:
                    return empty_result(status='error',
                                        data='start_at must be in the future')
                time_diff = time_start - time_now
                seconds = int(time_diff.total_seconds())
            except Exception as e:
                logger.exception(f'Exception when scheduling job: {e}')
                return empty_result(status='error',
                                    data=f'Invalid date format, should be: {date_format}')

        scheduler = Scheduler()
        job_id = scheduler.add_onetime_job(
            'cnaas_nms.confpush.firmware:device_upgrade',
            when=seconds,
            scheduled_by=get_jwt_identity(),
            kwargs=kwargs)
        res = empty_result(data='Scheduled job to upgrade devices')
        res['job_id'] = job_id

        resp = make_response(json.dumps(res), 200)
        if total_count:
            resp.headers['X-Total-Count'] = total_count
        resp.headers['Content-Type'] = "application/json"
        return resp
Esempio n. 7
0
    def load(self) -> Inventory:
        defaults = Defaults(
            connection_options={
                "napalm": ConnectionOptions(extras={
                    "optional_args": {
                        # args to eAPI HttpsEapiConnection for EOS
                        "enforce_verification": True,
                        "context": ssl_context
                    }
                })
            }
        )
        insecure_device_states = [
            DeviceState.INIT,
            DeviceState.DHCP_BOOT,
            DeviceState.PRE_CONFIGURED,
            DeviceState.DISCOVERED
        ]
        insecure_connection_options = {
            "napalm": ConnectionOptions(extras={
                "optional_args": {"enforce_verification": False}
            })
        }

        groups = Groups()
        for device_type in list(DeviceType.__members__):
            group_name = 'T_'+device_type
            groups[group_name] = Group(name=group_name, defaults=defaults)
        for device_state in list(DeviceState.__members__):
            username, password = self._get_credentials(device_state)
            group_name = 'S_'+device_state
            groups[group_name] = Group(
                name=group_name, username=username, password=password, defaults=defaults)
        for group_name in get_groups():
            groups[group_name] = Group(name=group_name, defaults=defaults)

        hosts = Hosts()
        with cnaas_nms.db.session.sqla_session() as session:
            instance: Device
            for instance in session.query(Device):
                hostname = self._get_management_ip(instance.management_ip,
                                                   instance.dhcp_ip)
                port = None
                if instance.port and isinstance(instance.port, int):
                    port = instance.port
                host_groups = [
                    'T_' + instance.device_type.name,
                    'S_' + instance.state.name
                ]
                for member_group in get_groups(instance.hostname):
                    host_groups.append(member_group)

                if instance.state in insecure_device_states:
                    host_connection_options = insecure_connection_options
                else:
                    host_connection_options = None
                hosts[instance.hostname] = Host(
                    name=instance.hostname,
                    hostname=hostname,
                    platform=instance.platform,
                    groups=ParentGroups(groups[g] for g in host_groups),
                    port=port,
                    data={
                        'synchronized': instance.synchronized,
                        'managed': (True if instance.state == DeviceState.MANAGED else False)
                    },
                    connection_options=host_connection_options,
                    defaults=defaults
                )

        return Inventory(hosts=hosts, groups=groups, defaults=defaults)