Beispiel #1
0
 def handle(self, filename, fields='', delimiter=b',', **options):
     fields = [field.strip() for field in fields.split(',')]
     with open(filename, 'rb') as f:
         for row in UnicodeReader(f, delimiter=delimiter):
             data = dict(zip(fields, row))
             try:
                 dev_id = int(data['id'])
             except (ValueError, KeyError):
                 continue
             if not dev_id:
                 continue
             try:
                 dev = Device.objects.get(id=dev_id)
             except Device.DoesNotExist:
                 sys.stderr.write("Device with id=%r doesn't exist!\n" %
                                  dev_id)
                 continue
             for field, value in data.iteritems():
                 if field in ('id', ''):
                     continue
                 if value in ('None', ''):
                     value = None
                 if value is None and field in ('remarks', ):
                     value = ''
                 print('%r.%s = %r' % (dev, field, value))
                 setattr(dev, field, value)
                 dev.save(priority=50)
Beispiel #2
0
 def clean_csv(self):
     csv_string = self.cleaned_data['csv'].strip().lower()
     rows = UnicodeReader(cStringIO.StringIO(csv_string))
     parsed_macs = set()
     for row_number, cols in enumerate(rows, start=1):
         _validate_cols_count(6, cols, row_number)
         mac = cols[0].strip()
         _validate_mac(mac, parsed_macs, row_number)
         _validate_deploy_children(mac, row_number)
         parsed_macs.add(mac)
         management_ip = cols[1].strip()
         _validate_management_ip(management_ip, row_number)
         network_name = cols[2].strip()
         if not (is_mac_address_known(mac) and network_name == ''):
             # Allow empty network when the device already exists.
             _validate_network_name(network_name, row_number)
         venture_symbol = cols[3].strip()
         venture_role = cols[4].strip()
         _validate_venture_and_role(
             venture_symbol,
             venture_role,
             row_number,
         )
         preboot = cols[5].strip()
         _validate_preboot(preboot, row_number)
     return csv_string
Beispiel #3
0
 def handle_single(self, filename):
     print('Importing Network from {}...'.format(filename))
     with open(filename, 'rb') as f:
         for i, value in enumerate(UnicodeReader(f), 1):
             if len(value) != 6:
                 raise IncorrectLengthRowError(
                     'CSV row {} have {} elements, should be 6'.format(
                         i, len(value)))
             (name, address, terminator_name, data_center_name,
              environment_name, rack_name) = value
             if not all((
                     name,
                     address,
                     terminator_name,
                     data_center_name,
                     environment_name,
                     rack_name,
             )):
                 raise EmptyRecordValueError(
                     'Record fields can not be empty', )
             self.create_network(
                 name,
                 address,
                 terminator_name,
                 data_center_name,
                 environment_name,
                 rack_name,
                 i,
             )
Beispiel #4
0
    def clean_csv(self):
        csv_string = self.cleaned_data['csv'].strip().lower()
        rows = UnicodeReader(cStringIO.StringIO(csv_string))
        parsed_macs = set()

        for row_number, cols in enumerate(rows, start=1):
            _validate_cols_count(8, cols, row_number,
                                 1 if self.assets_enabled else 0)
            mac = cols[0].strip()
            _validate_mac(mac, parsed_macs, row_number)
            _validate_deploy_children(mac, row_number)
            parsed_macs.add(mac)
            management_ip = cols[1].strip()
            _validate_management_ip(management_ip, row_number)
            network_name = cols[2].strip()
            if not (is_mac_address_known(mac) and network_name == ''):
                # Allow empty network when the device already exists.
                _validate_network_name(network_name, row_number)
            venture_symbol = cols[3].strip()
            venture_role = cols[4].strip()
            _validate_venture_and_role(
                venture_symbol,
                venture_role,
                row_number,
            )
            service = cols[5].strip()
            _validate_service(service, row_number)
            environment = cols[6].strip()
            _validate_environment(environment, row_number)
            preboot = cols[7].strip()
            _validate_preboot(preboot, row_number)
            if self.assets_enabled and len(cols) == 9:
                asset_identity = cols[8].strip()
                _validate_asset_identity(asset_identity, row_number, mac)
        return csv_string
Beispiel #5
0
 def import_csv(self, group, uploaded_file):
     if uploaded_file.size > 4 * 1024 * 1024:
         messages.error(self.request, "File too big to import.")
         return
     f = cStringIO.StringIO(uploaded_file.read())
     rows = iter(UnicodeReader(f))
     header = list(rows.next())
     if header[0].strip() != 'sn':
         messages.error(
             self.request,
             "The first row should have 'sn' followed by variable names."
         )
         return
     variables = [name.strip() for name in header[1:]]
     devices = {}
     try:
         for row in rows:
             if not row:
                 continue
             devices[row[0]] = dict(zip(
                 variables,
                 (decimal.Decimal(v) for v in row[1:]),
             ))
     except ValueError as e:
         messages.error(self.request, "Invalid value: %s." % e)
         return
     variable_dict = {}
     for name in variables:
         v = PricingVariable(name=name, group=group)
         v.save()
         variable_dict[name] = v
     for sn, values in devices.iteritems():
         try:
             device = Device.objects.get(sn=sn)
         except Device.DoesNotExist:
             messages.warning(
                 self.request,
                 "Serial number %s not found, skipping." % sn
             )
             continue
         group.devices.add(device)
         for name, value in values.iteritems():
             PricingValue(
                 variable=variable_dict[name],
                 device=device,
                 value=value,
             ).save()
     group.save()
 def handle_single(self, filename, **options):
     if options['create_ptr']:
         create_ptr = True
     else:
         create_ptr = False
     print('Importing DNS records from {}...'.format(filename))
     with open(filename, 'rb') as f:
         for i, value in enumerate(UnicodeReader(f), 1):
             if len(value) != 3:
                 raise IncorrectLengthRowError(
                     'CSV row {} has {} elements, should be 3'.format(
                         i,
                         len(value),
                     ))
             name, type, content = value
             if not all((name, type, content)):
                 raise EmptyRecordValueError(
                     'Record fields can not be empty', )
             if type not in RECORD_TYPES:
                 raise DisallowedRecordTypeError(
                     'Record type {} is not allowed. Use:\n {}'.format(
                         type,
                         RECORD_TYPES,
                     ), )
             if type == 'A':
                 try:
                     ipaddr.IPv4Address(content)
                 except ValueError:
                     raise InvalidAddressError(
                         'Record {} has invalid IP address ({}).'.format(
                             name,
                             content,
                         ))
             domain = get_domain(name)
             if not domain:
                 raise DomainDoesNotExistError(
                     'Domain for {} does not exist in Ralph.'.format(name))
             self.create_record(domain, name, type, content)
             if create_ptr:
                 if type != 'A':
                     raise DisallowedRecordTypeError(
                         'PTR record can only be created for record type A.'
                     )
                 revname = '.'.join(reversed(
                     content.split('.'))) + '.in-addr.arpa'
                 # we need to create SOA domain/record first
                 today = datetime.date.today().strftime('%Y%m%d')
                 soa_name = '.'.join(revname.split('.')[1:])
                 soa_domain, created = Domain.objects.get_or_create(
                     name=soa_name, )
                 if created:
                     # last 2 digits == version for a given day
                     soa_domain.notified_serial = today + '01'
                     soa_domain.type = 'MASTER'
                     soa_domain.save()
                     print('Domain {} of type {} created (sn: {}).'.format(
                         soa_domain.name,
                         soa_domain.type,
                         soa_domain.notified_serial,
                     ))
                 type = 'SOA'
                 if options['soa_content']:
                     content = options['soa_content']
                 else:
                     content = settings.DEFAULT_SOA_RECORD_CONTENT
                 self.create_record(soa_domain, soa_name, type, content)
                 type = 'PTR'
                 content = name
                 self.create_record(soa_domain, revname, type, content)
Beispiel #7
0
 def get(self, *args, **kwargs):
     mass_deployment = get_object_or_404(
         MassDeploymentModel,
         id=kwargs.get('deployment'),
         is_done=False,
     )
     reserved_hostnames = []
     reserved_ip_addresses = []
     new_csv_rows = []
     csv_rows = UnicodeReader(
         cStringIO.StringIO(mass_deployment.csv.strip()))
     for raw_cols in csv_rows:
         cols = []
         for col in raw_cols:
             cols.append(" %s " % col.strip())
         hostname = ""
         ip = ""
         rack = None
         asset_identity = None
         if self.assets_enabled and len(cols) == 7:
             asset_identity = cols[6].strip()
         device = _find_device(cols[0], asset_identity)
         try:
             network, ip = _find_network_ip(
                 cols[2].strip(),
                 reserved_ip_addresses,
                 device,
             )
         except Network.DoesNotExist:
             pass
         else:
             hostname = _find_hostname(
                 network,
                 reserved_hostnames,
                 device,
                 ip,
             )
             for rack in network.racks.filter(
                     deleted=False).order_by('name')[:1]:
                 break
             cols[2] = " %s " % network.name
         cols.insert(0, " %s " % rack.sn if rack else " ")
         cols.insert(0, " %s " % ip)
         cols.insert(0, " %s " % hostname)
         new_csv_rows.append(cols)
         if device:
             self.actions.append((
                 'warning',
                 "An old device %s will be re-used. Make sure it's not "
                 "used in production anymore!" % device,
             ))
             if device.deleted:
                 self.actions.append((
                     'info',
                     "Device %s will be undeleted." % device,
                 ))
             if device.ipaddress_set.exists():
                 self.actions.append((
                     'info',
                     "All DNS entries for IP addresses [%s] will be "
                     "deleted." %
                     ', '.join(ip.address
                               for ip in device.ipaddress_set.all()),
                 ))
                 self.actions.append((
                     'info',
                     "All DHCP entries for IP addresses [%s] "
                     "will be deleted." %
                     (', '.join(ip.address
                                for ip in device.ipaddress_set.all()), ),
                 ))
             if device.ethernet_set.exists():
                 self.actions.append((
                     'info',
                     "All DHCP entries for  "
                     "MAC addresses [%s] will be deleted." %
                     (', '.join(eth.mac
                                for eth in device.ethernet_set.all()), ),
                 ))
             if device.disksharemount_set.exists():
                 self.actions.append((
                     'info',
                     "All disk shares mounted on %s will be disconnected "
                     "from it." % device,
                 ))
             self.actions.append((
                 'info',
                 "The uptime, operating system and software list for %s "
                 "will be reset." % device,
             ))
         else:
             if hostname:
                 self.actions.append((
                     'success',
                     "A new device %s will be created." % hostname,
                 ))
         if hostname and ip:
             self.actions.append((
                 'info',
                 "An A DNS entry for %s and %s will be created." %
                 (hostname, ip),
             ))
             self.actions.append((
                 'info',
                 "A PTR DNS entry for %s and %s will be created." %
                 (hostname, ip),
             ))
         if cols[0].strip() and ip:
             self.actions.append((
                 'info',
                 "A DHCP entry for %s and %s will be created." %
                 (cols[3], ip),
             ))
     csv_string = cStringIO.StringIO()
     UnicodeWriter(csv_string).writerows(new_csv_rows)
     self.form = MassDeploymentForm(initial={'csv': csv_string.getvalue()})
     return super(MassDeployment, self).get(*args, **kwargs)
Beispiel #8
0
    def clean_csv(self):
        csv_string = self.cleaned_data['csv'].strip().lower()
        rows = UnicodeReader(cStringIO.StringIO(csv_string))
        cleaned_csv = []
        parsed_hostnames = set()
        parsed_ip_addresses = set()
        parsed_macs = set()
        for row_number, cols in enumerate(rows, start=1):
            _validate_cols_count(9, cols, row_number)
            _validate_cols_not_empty(cols, row_number)
            mac = cols[3].strip()
            _validate_mac(mac, parsed_macs, row_number)
            parsed_macs.add(mac)
            hostname = cols[0].strip()
            _validate_hostname(hostname, mac, parsed_hostnames, row_number)
            if not clean_hostname(hostname):
                raise forms.ValidationError("Invalid hostname")

            parsed_hostnames.add(hostname)
            network_name = cols[5].strip()
            try:
                network = Network.objects.get(name=network_name)
            except Network.DoesNotExist:
                raise forms.ValidationError(
                    "Row %s: Network '%s' doesn't exists." %
                    (row_number, network_name))
            rack_sn = cols[2].strip()
            if re.match(r"^[0-9]+$", rack_sn):
                rack_sn = "Rack %s %s" % (
                    rack_sn,
                    network.data_center.name.upper(),
                )
            if not rack_exists(rack_sn):
                raise forms.ValidationError(
                    "Row %s: Rack with serial number '%s' doesn't exists." %
                    (row_number, rack_sn))
            try:
                network.racks.get(sn=rack_sn)
            except Device.DoesNotExist:
                raise forms.ValidationError(
                    "Row %s: Rack '%s' isn't connected to "
                    "network '%s'." % (row_number, rack_sn, network.name))
            ip = cols[1].strip()
            _validate_ip_address(ip, network, parsed_ip_addresses, row_number)
            _validate_ip_owner(ip, mac, row_number)
            parsed_ip_addresses.add(ip)
            management_ip = cols[4].strip()
            _validate_management_ip(management_ip, row_number)
            try:
                venture_role = VentureRole.objects.get(
                    venture__symbol=cols[6].strip().upper(),
                    name=cols[7].strip())
                venture = venture_role.venture
            except VentureRole.DoesNotExist:
                raise forms.ValidationError(
                    "Row %s: "
                    "Couldn't find venture with symbol %s and role %s" %
                    (row_number, cols[6].strip(), cols[7].strip()))
            try:
                preboot = Preboot.objects.get(name=cols[8].strip())
            except Preboot.DoesNotExist:
                raise forms.ValidationError(
                    "Row %s: Couldn't find preboot %s" %
                    (row_number, cols[8].strip()))
            cleaned_csv.append({
                'hostname': hostname,
                'ip': ip,
                'mac': mac,
                'rack_sn': rack_sn,
                'venture': venture,
                'venture_role': venture_role,
                'preboot': preboot,
                'management_ip': management_ip,
                'network': network
            })
        return cleaned_csv
Beispiel #9
0
 def handle_single(self, filename, **options):
     if options['connect_business_segment']:
         connect_business_segment = True
     else:
         connect_business_segment = False
     print('Importing information from {}...'.format(filename))
     with open(filename, 'rb') as f:
         self.not_found_ventures = []
         self.not_found_profit_centers = set()
         self.not_found_business_segments = set()
         for i, value in enumerate(UnicodeReader(f), 1):
             if len(value) != 3:
                 raise IncorrectLengthRowError(
                     'CSV row {} have {} elements, should be 3'.format(
                         i, len(value)
                     )
                 )
             if not connect_business_segment:
                 venture_id, profit_center, description = value
                 venture = self.get_venture(venture_id, i)
                 if not venture:
                     continue
                 else:
                     profit_center, created = ProfitCenter.objects.get_or_create(  # noqa
                         name=profit_center or 'Other'
                     )
                     profit_center.description = description or 'Other'
                     profit_center.save()
                     venture.profit_center = profit_center
                     venture.save()
                     print(
                         'profit center {} joined to venture {}'.format(
                             profit_center, venture.name
                         )
                     )
             else:
                 venture_id, profit_center_name, business_segment_name = value   # noqa
                 venture = self.get_venture(venture_id, i)
                 if not venture:
                     continue
                 else:
                     profit_center = self.get_profit_center(
                         profit_center_name, i,
                     )
                     business_segment = self.get_business_segment(
                         business_segment_name, i,
                     )
                     if profit_center:
                         venture.profit_center = profit_center
                     if business_segment:
                         venture.business_segment = business_segment
                     venture.save()
         print("Ventures with ids {} don't exist".format(
             [v for v in self.not_found_ventures]
         ))
         if connect_business_segment:
             print("Business Segments with name {} does not exist".format(
                 [v for v in self.not_found_business_segments]
             ))
             print("Profit Center with name {} does not exist".format(
                 [v for v in self.not_found_profit_centers]
             ))