def test_URLOrPPAFormField_catches_bad_PPA_hostname(self): bad_url = "ppa:%s/-%s" % ( factory.make_hostname(), factory.make_hostname()) error = self.assertRaises( ValidationError, URLOrPPAFormField().clean, bad_url) self.assertThat(error.messages[0], Equals( 'Enter a valid repository URL or PPA location.'))
def test_URLOrPPAFormField_catches_bad_scheme(self): bad_url = factory.make_url(scheme='bad_scheme') error = self.assertRaises(ValidationError, URLOrPPAFormField().clean, bad_url) self.assertThat( error.messages[0], Equals('Enter a valid repository URL or PPA location.'))
class PackageRepositoryForm(MAASModelForm): """Package Repository creation/edition form.""" class Meta: model = PackageRepository fields = ( 'name', 'url', 'distributions', 'disabled_pockets', 'disabled_components', 'components', 'arches', 'key', 'enabled', ) name = forms.CharField(label="Name", required=True, help_text=("The name of the Package Repository.")) url = URLOrPPAFormField(label="Package Repository URL", required=True, help_text="The Package Repository URL") # Use UnconstrainedMultipleChoiceField fields for multiple-choices # fields instead of the default (djorm-ext-pgarray's ArrayFormField): # ArrayFormField deals with comma-separated lists and here we want to # handle multiple-values submissions. distributions = UnconstrainedMultipleChoiceField(label="Distribution list") disabled_pockets = UnconstrainedMultipleChoiceField( label="Disabled Pocket list") disabled_components = UnconstrainedMultipleChoiceField( label="Disabled Component list") components = UnconstrainedMultipleChoiceField(label="Component list") arches = UnconstrainedMultipleChoiceField(label="Architecture list") key = forms.CharField( label="Key", required=False, help_text=("The key used to authenticate the Package Repository.")) enabled = forms.BooleanField( label="Enabled", required=False, help_text=("Whether or not the Package Repository is enabled.")) def __init__(self, data=None, instance=None, request=None, **kwargs): super().__init__(data=data, instance=instance, **kwargs) if self.instance.id is None: self.initial['enabled'] = True else: self.fields['url'].initial = self.instance.url def clean(self): cleaned_data = super().clean() if self.instance.default and not cleaned_data.get('enabled', False): raise ValidationError("Default repositories may not be disabled.") def clean_arches(self): arches = [] for value in self.cleaned_data.get('arches', []): arches.extend([s.strip() for s in value.split(',')]) known_arches = set(PackageRepository.objects.get_known_architectures()) for value in arches: if value not in known_arches: raise ValidationError( "'%s' is not a valid architecture. Known architectures: " "%s" % (value, ", ".join(sorted(known_arches)))) # If no arches provided, use MAIN_ARCHES. if len(arches) == 0: arches = PackageRepository.MAIN_ARCHES return arches def clean_distributions(self): values = [] for value in self.cleaned_data.get('distributions', []): values.extend([s.strip() for s in value.split(',')]) return values def clean_disabled_pockets(self): values = [] for value in self.cleaned_data.get('disabled_pockets', []): values.extend([s.strip() for s in value.split(',')]) # This allows to reset the values of disabled_pockets if one of the # following is passed over the API: # disabled_pockets= # disabled_pockets='' # disabled_pockets=None # disabled_pockets=[] if values == [''] or values == ['None'] or values == ['[]']: return [] # Check that a valid pocket is being disable. for pocket in values: if pocket not in PackageRepository.POCKETS_TO_DISABLE: raise ValidationError( "'%s' is not a valid Ubuntu archive pocket. You " "can only disable %s." % (pocket, PackageRepository.POCKETS_TO_DISABLE)) return values def clean_disabled_components(self): values = [] for value in self.cleaned_data.get('disabled_components', []): values.extend([s.strip() for s in value.split(',')]) # This allows to reset the values of disabled_components if one of the # following is passed over the API: # disabled_components= # disabled_components='' # disabled_components=None # disabled_components=[] if values == [''] or values == ['None'] or values == ['[]']: return [] if self.instance is not None and not self.instance.default and values: raise ValidationError( "This is a custom repository. Please update 'components' " "instead.") # Check that a valid component is being passed. for component in values: if component not in PackageRepository.COMPONENTS_TO_DISABLE: raise ValidationError( "'%s' is not a valid Ubuntu archive component. You " "can only disable %s." % (component, PackageRepository.COMPONENTS_TO_DISABLE)) return values def clean_components(self): values = [] for value in self.cleaned_data.get('components', []): values.extend([s.strip() for s in value.split(',')]) if self.instance is not None and self.instance.default and values: raise ValidationError( "This is a default Ubuntu repository. Please update " "'disabled_components' instead.") return values
def test_URLOrPPAFormField_validates_PPA(self): url = "ppa:%s/%s" % (factory.make_hostname(), factory.make_hostname()) self.assertEqual(url, URLOrPPAFormField().clean(url))
def test_URLOrPPAFormField_validates_URL(self): url = factory.make_url(scheme="http") self.assertEqual(url, URLOrPPAFormField().clean(url))
def test_rejects_none(self): error = self.assertRaises(ValidationError, URLOrPPAFormField().clean, None) self.assertThat(error.message, Equals("This field is required."))
class PackageRepositoryForm(MAASModelForm): """Package Repository creation/edition form.""" class Meta: model = PackageRepository fields = ( "name", "url", "distributions", "disabled_pockets", "disabled_components", "disable_sources", "components", "arches", "key", "enabled", ) name = forms.CharField( label="Name", required=True, help_text="The name of the Package Repository.", ) url = URLOrPPAFormField( label="Package Repository URL", required=True, help_text="The Package Repository URL", ) # Use UnconstrainedMultipleChoiceField fields for multiple-choices # fields instead of the default as we want to handle # multiple-values submissions. distributions = UnconstrainedMultipleChoiceField(label="Distribution list") disabled_pockets = UnconstrainedMultipleChoiceField( label="Disabled Pocket list") disabled_components = UnconstrainedMultipleChoiceField( label="Disabled Component list") disable_sources = forms.BooleanField( label="Disable Sources", required=False, help_text="Whether or not deb-src lines are disabled.", ) components = UnconstrainedMultipleChoiceField(label="Component list") arches = UnconstrainedMultipleChoiceField(label="Architecture list") key = forms.CharField( label="Key", required=False, help_text="The key used to authenticate the Package Repository.", ) enabled = forms.BooleanField( label="Enabled", required=False, help_text="Whether or not the Package Repository is enabled.", ) def __init__(self, data=None, instance=None, request=None, **kwargs): super().__init__(data=data, instance=instance, **kwargs) if self.instance.id is None: self.initial["enabled"] = True else: self.fields["url"].initial = self.instance.url def clean(self): cleaned_data = super().clean() if self.instance.default and not cleaned_data.get("enabled", False): raise ValidationError("Default repositories may not be disabled.") def clean_arches(self): arches = [] for value in self.cleaned_data.get("arches", []): arches.extend([s.strip() for s in value.split(",")]) known_arches = set(PackageRepository.objects.get_known_architectures()) for value in arches: if value not in known_arches: raise ValidationError( "'%s' is not a valid architecture. Known architectures: " "%s" % (value, ", ".join(sorted(known_arches)))) # If no arches provided, use MAIN_ARCHES. if len(arches) == 0: arches = PackageRepository.MAIN_ARCHES return arches def clean_distributions(self): values = [] for value in self.cleaned_data.get("distributions", []): values.extend([s.strip() for s in value.split(",")]) return values def clean_disabled_pockets(self): values = [] for value in self.cleaned_data.get("disabled_pockets", []): values.extend([s.strip() for s in value.split(",")]) # This allows to reset the values of disabled_pockets if one of the # following is passed over the API: # disabled_pockets= # disabled_pockets='' # disabled_pockets=None # disabled_pockets=[] if values == [""] or values == ["None"] or values == ["[]"]: return [] # Check that a valid pocket is being disable. for pocket in values: if pocket not in PackageRepository.POCKETS_TO_DISABLE: raise ValidationError( "'%s' is not a valid Ubuntu archive pocket. You " "can only disable %s." % (pocket, PackageRepository.POCKETS_TO_DISABLE)) return values def clean_disabled_components(self): values = [] for value in self.cleaned_data.get("disabled_components", []): values.extend([s.strip() for s in value.split(",")]) # This allows to reset the values of disabled_components if one of the # following is passed over the API: # disabled_components= # disabled_components='' # disabled_components=None # disabled_components=[] if values == [""] or values == ["None"] or values == ["[]"]: return [] if self.instance is not None and not self.instance.default and values: raise ValidationError( "This is a custom repository. Please update 'components' " "instead.") # Check that a valid component is being passed. for component in values: if component not in PackageRepository.COMPONENTS_TO_DISABLE: raise ValidationError( "'%s' is not a valid Ubuntu archive component. You " "can only disable %s." % (component, PackageRepository.COMPONENTS_TO_DISABLE)) return values def clean_components(self): values = [] for value in self.cleaned_data.get("components", []): values.extend([s.strip() for s in value.split(",")]) if self.instance is not None and self.instance.default and values: raise ValidationError( "This is a default Ubuntu repository. Please update " "'disabled_components' instead.") return values def save(self, endpoint, request): package_repository = super().save() create_audit_event( EVENT_TYPES.SETTINGS, endpoint, request, None, description=("%s package repository '%s'." % ( "Updated" if self.is_update else "Created", package_repository.name, )), ) return package_repository