def test_site(): s1 = Site( name='site1', description='test site 1' ) s1.config_values = {} s1.full_clean() s1.save() now = datetime.now( timezone.utc ) tmp = getConfig( s1 ) assert now - tmp[ '__last_modified' ] < timedelta( seconds=5 ) assert now - tmp[ '__timestamp' ] < timedelta( seconds=5 ) del tmp[ '__last_modified' ] del tmp[ '__timestamp' ] del tmp[ '__pxe_template_location' ] assert tmp == { '__contractor_host': 'http://contractor/', '__pxe_location': 'http://static/pxe/', '_site': 'site1' } assert _strip_base( getConfig( s1 ) ) == { '_site': 'site1' } s2 = Site( name='site2', description='test site 2', parent=s1 ) s2.config_values = { 'myval': 'this is a test', 'stuff': 'this is only a test' } s2.full_clean() s2.save() assert _strip_base( getConfig( s2 ) ) == { '_site': 'site2', 'myval': 'this is a test', 'stuff': 'this is only a test' } s1.config_values = { 'under': 'or over' } s1.full_clean() s1.save() assert _strip_base( getConfig( s2 ) ) == { '_site': 'site2', 'myval': 'this is a test', 'stuff': 'this is only a test', 'under': 'or over' } s2.config_values[ '>under' ] = ' here' s2.config_values[ '<under' ] = 'going ' s2.full_clean() s2.save() assert _strip_base( getConfig( s2 ) ) == { '_site': 'site2', 'myval': 'this is a test', 'stuff': 'this is only a test', 'under': 'going or over here' }
def getValues( self ): config = getConfig( self.target ) result = {} for key in config: result[ key ] = ( lambda key=key: getWrapper( self.target, key ), None ) return result
def updateRecord(target): db = collection(target) if target.__class__.__name__ in ('StructureBluePrint', 'FoundationBluePrint'): item = getConfig(target) else: item = mergeValues(getConfig(target)) for i in ('__contractor_host', '__pxe_template_location', '__pxe_location'): # these are the same everywhere del item[i] key = {'_id': target.pk} prepConfig(item) db.update(key, item, upsert=True)
def _containerSpec( foundation ): result = {} structure_config = getConfig( foundation.structure ) structure_config = mergeValues( structure_config ) result[ 'image' ] = structure_config[ 'docker_image' ] result[ 'port_list' ] = structure_config.get( 'port_list', [] ) result[ 'environment_map' ] = structure_config.get( 'environment_map', {} ) result[ 'command' ] = structure_config.get( 'docker_command', None ) return result
def _vmSpec(foundation): result = {} structure_config = getConfig(foundation.structure) structure_config = mergeValues(structure_config) result['vmid'] = foundation.proxmox_vmid result['core_count'] = structure_config.get('cpu_count', 1) result['memory_size'] = structure_config.get('memory_size', 1024) # in MiB # result[ 'swap_size' ] = structure_config.get( 'swap_size', 1024 ) # for lxc result['disk_size'] = structure_config.get('disk_size', 10) # in GiB result['type'] = 'qemu' # only support quemu right now return result
def _vmSpec(foundation): result = {} structure_config = getConfig(foundation.structure) structure_config = mergeValues(structure_config) result['azure_size'] = structure_config.get('azure_size', 'Standard_D1_v2') for key in ('azure_admin_username', 'azure_admin_password', 'azure_image'): try: result[key] = structure_config[key] except KeyError: pass return result
def _vmSpec(foundation): result = {} structure_config = getConfig(foundation.structure) structure_config = mergeValues(structure_config) result['cpu_count'] = structure_config.get('cpu_count', 1) result['memory_size'] = structure_config.get('memory_size', 1024) result['disk_size'] = structure_config.get('disk_size', 10) if 'ova' in structure_config: result['ova'] = structure_config['ova'] for key in ('vcenter_property_map', 'vcenter_deployment_option', 'vcenter_ip_protocol'): try: result[key] = structure_config[key] except KeyError: pass if 'template' in structure_config: result['template'] = structure_config['template'] for key in ('vcenter_hostname', 'vcenter_domain', 'vcenter_dnsserver_list', 'vcenter_dnssuffix_list', 'vcenter_property_map'): try: result[key] = structure_config[key] except KeyError: pass else: result['vcenter_guest_id'] = structure_config.get( 'vcenter_guest_id', 'otherGuest') for key in ('vcenter_virtual_exec_usage', 'vcenter_virtual_mmu_usage', 'vcenter_virtual_vhv', 'vcenter_network_interface_class', 'vcenter_property_map'): try: result[key] = structure_config[key] except KeyError: pass return result
def _vmSpec( foundation ): result = {} structure_config = getConfig( foundation.structure ) structure_config = mergeValues( structure_config ) result[ 'cpu_count' ] = structure_config.get( 'cpu_count', 1 ) result[ 'memory_size' ] = structure_config.get( 'memory_size', 1024 ) # in MiB result[ 'disk_size' ] = structure_config.get( 'disk_size', 10 ) # in GiB result[ 'virtualbox_guest_type' ] = structure_config.get( 'virtualbox_guest_type', 'Other' ) for key in ( 'virtualbox_network_adapter_type', ): try: result[ key ] = structure_config[ key ] except KeyError: pass return result
def getDynamicPools(site): result = [] site_config = getConfig(site) try: dns_server = site_config['dns_servers'][0] except (KeyError, IndexError): dns_server = '1.1.1.1' domain_name = site_config.get('domain_name', '') # without the distinct we get an AddressBlock for each DynamicAddress for addr_block in AddressBlock.objects.filter( site=site, baseaddress__dynamicaddress__isnull=False).distinct(): item = { 'address_map': {}, 'gateway': addr_block.gateway, 'name': addr_block.pk, 'netmask': addr_block.netmask, 'dns_server': dns_server, 'domain_name': domain_name } for addr in addr_block.baseaddress_set.filter( dynamicaddress__isnull=False): addr = addr.subclass try: # TODO: this needs to be retought a bit, really should be passing in the bootfile addr.pxe.name item['address_map'][ addr.ip_address] = 'undionly_console.kpxe' except AttributeError: item['address_map'][addr.ip_address] = None result.append(item) return result
def getConfig( self ): """ returns the computed config for this foundation """ return mergeValues( getConfig( self.subclass ) )
def handler(request): match = url_regex.match(request.uri.lower()) if not match: return Response(400, data='Invalid config uri', content_type='text') (request_type, _, config_uuid, structure_id, foundation_locator, ip_address, _, _, _) = match.groups() target = None if config_uuid is not None: try: target = Structure.objects.get(config_uuid=config_uuid[2:]) except Structure.DoesNotExist: return Response(404, data='Config UUID Not Found', content_type='text') elif structure_id is not None: try: target = Structure.objects.get(pk=int(structure_id[2:])) except Structure.DoesNotExist: return Response(404, data='Structure Not Found', content_type='text') elif foundation_locator is not None: try: target = Foundation.objects.get(pk=foundation_locator[2:]).subclass except Foundation.DoesNotExist: return Response(404, data='Foundation Not Found', content_type='text') else: if ip_address is not None: address = BaseAddress.lookup(ip_address[2:]) else: address = BaseAddress.lookup(request.remote_addr) if address is None: return Response(404, data='Address Not Found', content_type='text') address = address.subclass if address.type == 'Address': target = address.networked.subclass else: target = address if target is None: return Response(500, data='Target is missing', content_type='text') data = None config = getConfig(target) if request_type in ('boot_script', 'pxe_template'): pxe = None if isinstance(target, Structure): pxe = target.provisioning_interface.pxe elif isinstance(target, Foundation): pxe = target.structure.provisioning_interface.pxe elif isinstance(target, DynamicAddress): pxe = target.pxe if pxe is None: return Response(200, data='', content_type='text') if request_type == 'boot_script': template = '#!ipxe\n\n' + pxe.boot_script elif request_type == 'pxe_template': template = pxe.template data = renderTemplate(template, config) return Response(200, data=data, content_type='text') elif request_type == 'config': _fromPythonMap( config ) # this does not go out CInP's converter, we need to make the python dict JSON encodable our selves return Response(200, data=mergeValues(config)) return Response(400, data='Invalid request type', content_type='text')
def test_blueprint(): fb1 = FoundationBluePrint( name='fdnb1', description='Foundation BluePrint 1' ) fb1.foundation_type_list = [ 'Unknown' ] fb1.full_clean() fb1.save() now = datetime.now( timezone.utc ) tmp = getConfig( fb1 ) assert now - tmp[ '__last_modified' ] < timedelta( seconds=5 ) assert now - tmp[ '__timestamp' ] < timedelta( seconds=5 ) del tmp[ '__last_modified' ] del tmp[ '__timestamp' ] del tmp[ '__pxe_template_location' ] assert tmp == { '__contractor_host': 'http://contractor/', '__pxe_location': 'http://static/pxe/', '_blueprint': 'fdnb1' } assert _strip_base( getConfig( fb1 ) ) == { '_blueprint': 'fdnb1' } fb2 = FoundationBluePrint( name='fdnb2', description='Foundation BluePrint 2' ) fb2.foundation_type_list = [ 'Unknown' ] fb2.config_values = { 'the': 'Nice value' } fb2.full_clean() fb2.save() fb2.parent_list.add( fb1 ) assert _strip_base( getConfig( fb2 ) ) == { '_blueprint': 'fdnb2', 'the': 'Nice value' } fb1.config_values = { 'from': 'inside the house' } fb1.full_clean() fb1.save() assert _strip_base( getConfig( fb2 ) ) == { '_blueprint': 'fdnb2', 'the': 'Nice value', 'from': 'inside the house' } sb1 = StructureBluePrint( name='strb1', description='Structure BluePrint 1' ) sb1.full_clean() sb1.save() now = datetime.now( timezone.utc ) tmp = getConfig( sb1 ) assert now - tmp[ '__last_modified' ] < timedelta( seconds=5 ) assert now - tmp[ '__timestamp' ] < timedelta( seconds=5 ) del tmp[ '__last_modified' ] del tmp[ '__timestamp' ] del tmp[ '__pxe_template_location' ] assert tmp == { '__contractor_host': 'http://contractor/', '__pxe_location': 'http://static/pxe/', '_blueprint': 'strb1' } assert _strip_base( getConfig( sb1 ) ) == { '_blueprint': 'strb1' } sb2 = StructureBluePrint( name='strb2', description='Structure BluePrint 2' ) sb2.full_clean() sb2.save() sb2.parent_list.add( sb1 ) assert _strip_base( getConfig( sb2 ) ) == { '_blueprint': 'strb2' } sb2.foundation_blueprint_list.add( fb2 ) assert _strip_base( getConfig( sb2 ) ) == { '_blueprint': 'strb2' }
def test_foundation(): s1 = Site( name='site1', description='test site 1' ) s1.config_values = {} s1.full_clean() s1.save() fb1 = FoundationBluePrint( name='fdnb1', description='Foundation BluePrint 1' ) fb1.foundation_type_list = [ 'Unknown' ] fb1.full_clean() fb1.save() f1 = Foundation( site=s1, locator='fdn1', blueprint=fb1 ) f1.full_clean() f1.save() now = datetime.now( timezone.utc ) tmp = getConfig( f1 ) assert now - tmp[ '__last_modified' ] < timedelta( seconds=5 ) assert now - tmp[ '__timestamp' ] < timedelta( seconds=5 ) del tmp[ '__last_modified' ] del tmp[ '__timestamp' ] del tmp[ '__pxe_template_location' ] assert tmp == { '__contractor_host': 'http://contractor/', '__pxe_location': 'http://static/pxe/', '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_blueprint': 'fdnb1', '_site': 'site1' } assert _strip_base( getConfig( f1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_blueprint': 'fdnb1', '_site': 'site1' } fb1.config_values[ 'lucky' ] = 'blueprint' fb1.full_clean() fb1.save() assert _strip_base( getConfig( f1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_blueprint': 'fdnb1', '_site': 'site1', 'lucky': 'blueprint' } s1.config_values[ 'lucky' ] = 'site' s1.full_clean() s1.save() assert _strip_base( getConfig( f1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_blueprint': 'fdnb1', '_site': 'site1', 'lucky': 'site' }
def getConfig( self ): return mergeValues( getConfig( self.subclass ) )
def updateConfig( self, config_value_map ): # TODO: this is a bad Idea, need to figure out a better way to do this, at least restrict it to accounts that can create/updatre structures self.config_values.update( config_value_map ) self.full_clean() self.save() return mergeValues( getConfig( self ) )
def test_structure(): s1 = Site( name='site1', description='test site 1' ) s1.full_clean() s1.save() fb1 = FoundationBluePrint( name='fdnb1', description='Foundation BluePrint 1' ) fb1.foundation_type_list = [ 'Unknown' ] fb1.full_clean() fb1.save() f1 = Foundation( site=s1, locator='fdn1', blueprint=fb1 ) f1.full_clean() f1.save() sb1 = StructureBluePrint( name='strb1', description='Structure BluePrint 1' ) sb1.full_clean() sb1.save() sb1.foundation_blueprint_list.add( fb1 ) str1 = Structure( foundation=f1, site=s1, hostname='struct1', blueprint=sb1 ) str1.full_clean() str1.save() now = datetime.now( timezone.utc ) tmp = getConfig( str1 ) assert now - tmp[ '__last_modified' ] < timedelta( seconds=5 ) assert now - tmp[ '__timestamp' ] < timedelta( seconds=5 ) del tmp[ '__last_modified' ] del tmp[ '__timestamp' ] del tmp[ '_structure_config_uuid' ] del tmp[ '__pxe_template_location' ] assert tmp == { '__contractor_host': 'http://contractor/', '__pxe_location': 'http://static/pxe/', '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_provisioning_address': None, '_primary_interface': None, '_primary_interface_mac': None, '_primary_address': None, '_structure_id': str1.pk, '_structure_state': 'planned', '_fqdn': 'struct1', '_hostname': 'struct1', '_domain_name': None, '_interface_map': {}, '_blueprint': 'strb1', '_site': 'site1' } assert _strip_base( getConfig( str1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_provisioning_address': None, '_primary_interface': None, '_primary_interface_mac': None, '_primary_address': None, '_structure_id': str1.pk, '_structure_state': 'planned', '_fqdn': 'struct1', '_hostname': 'struct1', '_domain_name': None, '_interface_map': {}, '_blueprint': 'strb1', '_site': 'site1' } fb1.config_values[ 'bob' ] = 'foundation blueprint' fb1.full_clean() fb1.save() assert _strip_base( getConfig( str1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_provisioning_address': None, '_primary_interface': None, '_primary_interface_mac': None, '_primary_address': None, '_structure_id': str1.pk, '_structure_state': 'planned', '_fqdn': 'struct1', '_hostname': 'struct1', '_domain_name': None, '_interface_map': {}, '_blueprint': 'strb1', '_site': 'site1' } sb1.config_values[ 'bob' ] = 'structure blueprint' sb1.full_clean() sb1.save() assert _strip_base( getConfig( str1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_provisioning_address': None, '_primary_interface': None, '_primary_interface_mac': None, '_primary_address': None, '_structure_id': str1.pk, '_structure_state': 'planned', '_fqdn': 'struct1', '_hostname': 'struct1', '_domain_name': None, '_interface_map': {}, '_blueprint': 'strb1', '_site': 'site1', 'bob': 'structure blueprint' } str1.config_values[ 'bob' ] = 'structure' str1.full_clean() str1.save() assert _strip_base( getConfig( str1 ) ) == { '_foundation_class_list': [], '_foundation_id': 'fdn1', '_foundation_id_map': None, '_foundation_interface_list': [], '_foundation_locator': 'fdn1', '_foundation_state': 'planned', '_foundation_type': 'Unknown', '_provisioning_interface': None, '_provisioning_interface_mac': None, '_provisioning_address': None, '_primary_interface': None, '_primary_interface_mac': None, '_primary_address': None, '_structure_id': str1.pk, '_structure_state': 'planned', '_fqdn': 'struct1', '_hostname': 'struct1', '_domain_name': None, '_interface_map': {}, '_blueprint': 'strb1', '_site': 'site1', 'bob': 'structure' }
def getConfig(self): return getConfig(self)
def getWrapper( target, key ): # TODO: find a way to make this less expensive, mabey something that can detect if the target has changed, without calling getConfig config = getConfig( target ) return config[ key ]
def handler( request ): if not re.match( '^/config/[a-z_]+/([sf][0-9]+)?$', request.uri ): return Response( 400, data='Invalid config uri', content_type='text' ) ( _, _, request_type, target_id ) = request.uri.split( '/' ) target = None interface = None if len( target_id ) > 0: if target_id[0] == 's': try: target = Structure.objects.get( pk=int( target_id[ 1: ] ) ) except Structure.DoesNotExist: return Response( 404, data='Structure Not Found', content_type='text' ) elif target_id[0] == 'f': try: target = Foundation.objects.get( pk=int( target_id[ 1: ] ) ) except Foundation.DoesNotExist: return Response( 404, data='Foundation Not Found', content_type='text' ) else: return Response( 500, data='Target Confusion', content_type='text' ) interface = target.provisioning_interface else: print( 'Getting config goodies for "{0}"'.format( request.remote_addr ) ) address = BaseAddress.lookup( request.remote_addr ) if address is None: return Response( 404, data='Address Not Found', content_type='text' ) address = address.subclass if address.type != 'Address': return Response( 404, data='Address Not Valid', content_type='text' ) target = address.networked.subclass try: if isinstance( target, Structure ): interface = target.foundation.interfaces.get( name=address.interface_name ) else: interface = target.interfaces.get( name=address.interface_name ) except NetworkInterface.DoesNotExist: return Response( 404, data='Interface Not Found', content_type='text' ) if target is None or interface is None: return Response( 500, data='Target/Interface is missing', content_type='text' ) data = None config = getConfig( target ) if request_type in ( 'boot_script', 'pxe_template' ): pxe = interface.pxe if pxe is None: return Response( 200, data='', content_type='text' ) if request_type == 'boot_script': template = Template( '#!ipxe\n\n' + pxe.boot_script ) elif request_type == 'pxe_template': template = Template( pxe.template ) data = template.render( Context( config ) ) print( 'config_handler sending "{0}" to "{1}"\n ----------- '.format( request_type, request.remote_addr ) ) print( data ) print( ' ----------- ') return Response( 200, data=data, content_type='text' ) elif request_type == 'config': _fromPythonMap( config ) return Response( 200, data=json.dumps( config ) ) return Response( 400, data='Invalid request type', content_type='text' )
def __init__( self, target ): super().__init__() if isinstance( target, dict ): self.config = target else: self.config = getConfig( target )
def getConfig( self ): return mergeValues( getConfig( self ) )
def getConfig(self): return getConfig(self.subclass)
def test_getconfig(): with pytest.raises( ValueError ): getConfig( object() )