class AddRouterRule(forms.SelfHandlingForm): source = RuleCIDRField(label=_("Source CIDR"), widget=forms.TextInput(), required=True) destination = RuleCIDRField(label=_("Destination CIDR"), widget=forms.TextInput(), required=True) action = forms.ChoiceField(label=_("Action"), required=True) nexthops = forms.MultiIPField(label=_("Optional: Next Hop " "Addresses (comma delimited)"), widget=forms.TextInput(), required=False) router_id = forms.CharField( label=_("Router ID"), widget=forms.TextInput(attrs={'readonly': 'readonly'})) failure_url = 'horizon:project:routers:detail' def __init__(self, request, *args, **kwargs): super(AddRouterRule, self).__init__(request, *args, **kwargs) self.fields['action'].choices = [('permit', _('Permit')), ('deny', _('Deny'))] def handle(self, request, data, **kwargs): try: if 'rule_to_delete' in request.POST: rulemanager.remove_rules(request, [request.POST['rule_to_delete']], router_id=data['router_id']) except Exception: exceptions.handle(request, _('Unable to delete router rule.')) try: if 'nexthops' not in data: data['nexthops'] = '' if data['source'] == '0.0.0.0/0': data['source'] = 'any' if data['destination'] == '0.0.0.0/0': data['destination'] = 'any' rule = { 'action': data['action'], 'source': data['source'], 'destination': data['destination'], 'nexthops': data['nexthops'].split(',') } rulemanager.add_rule(request, router_id=data['router_id'], newrule=rule) msg = _('Router rule added') LOG.debug(msg) messages.success(request, msg) return True except Exception as e: msg = _('Failed to add router rule %s') % e.message LOG.info(msg) messages.error(request, msg) redirect = reverse(self.failure_url, args=[data['router_id']]) exceptions.handle(request, msg, redirect=redirect)
def test_validate_multi_ip_field(self): GOOD_CIDRS_INPUT = ("192.168.1.1/16, 192.0.0.1/17", ) BAD_CIDRS_INPUT = ("1.2.3.4.5/41,0.0.0.0/99", "1.2.3.4.5/41;0.0.0.0/99", "1.2.3.4.5/41 0.0.0.0/99", "192.168.1.1/16 192.0.0.1/17") ip = forms.MultiIPField(mask=True, version=forms.IPv4) for cidr in GOOD_CIDRS_INPUT: self.assertIsNone(ip.validate(cidr)) for cidr in BAD_CIDRS_INPUT: self.assertRaises(ValidationError, ip.validate, cidr)
class AddAccessAction(workflows.Action): """Initialize the database access. This tab will honor the settings which should be a list of permissions required: * TROVE_ADD_USER_PERMS = [] * TROVE_ADD_DATABASE_PERMS = [] """ is_public = forms.BooleanField(label=_("Is Public"), required=False) allowed_cidrs = forms.MultiIPField(label=_("Allowed CIDRs"), required=False, version=forms.IPv4 | forms.IPv6, mask=True, widget=forms.TextInput(), help_text=_("Comma-separated CIDRs " "to connect through.")) class Meta(object): name = _("Database Access") permissions = TROVE_ADD_PERMS help_text_template = "project/databases/_launch_access_help.html"
class UpdateInstanceForm(forms.SelfHandlingForm): instance_id = forms.CharField(widget=forms.HiddenInput()) instance_name = forms.CharField(label=_("Name")) allowed_cidrs = forms.MultiIPField( label=_("Allowed CIDRs"), required=False, help_text=_("Classless Inter-Domain Routing " "(e.g. 192.168.0.0/24, or " "2001:db8::/128). Can enter multiple values separating" "by a comma"), version=forms.IPv4 | forms.IPv6, mask=True, widget=forms.TextInput()) def __init__(self, request, *args, **kwargs): super(UpdateInstanceForm, self).__init__(request, *args, **kwargs) instance_id = kwargs.get('initial', {}).get('instance_id') self.fields['instance_id'].initial = instance_id def handle(self, request, data): instance_id = data.get('instance_id') allowed_cidrs = data.get('allowed_cidrs') instance_name = data.get('instance_name') update_kwargs = {'name': instance_name} if allowed_cidrs: update_kwargs['allowed_cidrs'] = allowed_cidrs.split(',') try: api.trove.instance_update(request, instance_id, **update_kwargs) messages.success( request, _('Instance "%s" successfully updated.') % instance_name) except Exception: redirect = reverse("horizon:project:databases:index") exceptions.handle(request, _('Unable to update instance "%s".' % instance_id), redirect=redirect) return True
class UpdateIPSecSiteConnection(forms.SelfHandlingForm): name = forms.CharField(max_length=80, label=_("Name"), required=False) ipsecsiteconnection_id = forms.CharField( label=_("ID"), widget=forms.TextInput(attrs={'readonly': 'readonly'})) description = forms.CharField(required=False, max_length=80, label=_("Description")) peer_address = forms.IPField( label=_("Peer gateway public IPv4/IPv6 Address or FQDN"), help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for " "the VPN Connection"), version=forms.IPv4 | forms.IPv6, mask=False) peer_id = forms.IPField( label=_("Peer router identity for authentication (Peer ID)"), help_text=_("Peer router identity for authentication. " "Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"), version=forms.IPv4 | forms.IPv6, mask=False) peer_cidrs = forms.MultiIPField(label=_("Remote peer subnet(s)"), help_text=_( "Remote peer subnet(s) address(es) " "with mask(s) in CIDR format " "separated with commas if needed " "(e.g. 20.1.0.0/24, 21.1.0.0/24)"), version=forms.IPv4 | forms.IPv6, mask=True) psk = forms.CharField(widget=forms.PasswordInput(render_value=True), max_length=80, label=_("Pre-Shared Key (PSK) string")) mtu = forms.IntegerField( min_value=68, required=False, label=_("Maximum Transmission Unit size for the connection"), help_text=_("Equal to or greater than 68 if the local subnet is IPv4. " "Equal to or greater than 1280 if the local subnet " "is IPv6.")) dpd_action = forms.ChoiceField(label=_("Dead peer detection actions"), required=False, choices=[('hold', _('hold')), ('clear', _('clear')), ('disabled', _('disabled')), ('restart', _('restart')), ('restart-by-peer', _('restart-by-peer'))]) dpd_interval = forms.IntegerField( min_value=1, required=False, label=_("Dead peer detection interval"), help_text=_("Valid integer lesser than the DPD timeout")) dpd_timeout = forms.IntegerField( min_value=1, required=False, label=_("Dead peer detection timeout"), help_text=_("Valid integer greater than the DPD interval")) initiator = forms.ChoiceField(label=_("Initiator state"), required=False, choices=[ ('bi-directional', _('bi-directional')), ('response-only', _('response-only')) ]) admin_state_up = forms.ChoiceField(choices=[(True, _('UP')), (False, _('DOWN'))], label=_("Admin State"), required=False) failure_url = 'horizon:project:vpn:index' def clean(self): cleaned_data = super(UpdateIPSecSiteConnection, self).clean() interval = cleaned_data.get('dpd_interval') timeout = cleaned_data.get('dpd_timeout') if not interval < timeout: msg = _("DPD Timeout must be greater than DPD Interval") self._errors['dpd_timeout'] = self.error_class([msg]) return cleaned_data def handle(self, request, context): context['admin_state_up'] = (context['admin_state_up'] == 'True') try: data = { 'ipsec_site_connection': { 'name': context['name'], 'description': context['description'], 'peer_address': context['peer_address'], 'peer_id': context['peer_id'], 'peer_cidrs': context['peer_cidrs'].replace(" ", "").split(","), 'psk': context['psk'], 'mtu': context['mtu'], 'dpd': { 'action': context['dpd_action'], 'interval': context['dpd_interval'], 'timeout': context['dpd_timeout'] }, 'initiator': context['initiator'], 'admin_state_up': context['admin_state_up'], } } ipsecsiteconnection = api.vpn.ipsecsiteconnection_update( request, context['ipsecsiteconnection_id'], **data) msg = (_('IPSec Site Connection %s was successfully updated.') % context['name']) LOG.debug(msg) messages.success(request, msg) return ipsecsiteconnection except Exception as e: msg = (_('Failed to update IPSec Site Connection %s') % context['name']) LOG.info('%(msg)s: %(exception)s', {'msg': msg, 'exception': e}) redirect = reverse(self.failure_url) exceptions.handle(request, msg, redirect=redirect)
class AddIPSecSiteConnectionAction(workflows.Action): name = forms.CharField(max_length=80, label=_("Name")) description = forms.CharField( initial="", required=False, max_length=80, label=_("Description")) vpnservice_id = forms.ChoiceField( label=_("VPN Service associated with this connection")) ikepolicy_id = forms.ChoiceField( label=_("IKE Policy associated with this connection")) ipsecpolicy_id = forms.ChoiceField( label=_("IPSec Policy associated with this connection")) peer_address = forms.IPField( label=_("Peer gateway public IPv4/IPv6 Address or FQDN"), help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for " "the VPN Connection"), version=forms.IPv4 | forms.IPv6, mask=False) peer_id = forms.IPField( label=_("Peer router identity for authentication (Peer ID)"), help_text=_("Peer router identity for authentication. " "Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"), version=forms.IPv4 | forms.IPv6, mask=False) peer_cidrs = forms.MultiIPField( label=_("Remote peer subnet(s)"), help_text=_("Remote peer subnet(s) address(es) " "with mask(s) in CIDR format " "separated with commas if needed " "(e.g. 20.1.0.0/24, 21.1.0.0/24)"), version=forms.IPv4 | forms.IPv6, mask=True) psk = forms.CharField(max_length=80, label=_("Pre-Shared Key (PSK) string")) def populate_ikepolicy_id_choices(self, request, context): ikepolicy_id_choices = [('', _("Select IKE Policy"))] try: tenant_id = self.request.user.tenant_id ikepolicies = api.vpn.ikepolicy_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve IKE Policies list.')) ikepolicies = [] for p in ikepolicies: ikepolicy_id_choices.append((p.id, p.name)) self.fields['ikepolicy_id'].choices = ikepolicy_id_choices return ikepolicy_id_choices def populate_ipsecpolicy_id_choices(self, request, context): ipsecpolicy_id_choices = [('', _("Select IPSec Policy"))] try: tenant_id = self.request.user.tenant_id ipsecpolicies = api.vpn.ipsecpolicy_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve IPSec Policies list.')) ipsecpolicies = [] for p in ipsecpolicies: ipsecpolicy_id_choices.append((p.id, p.name)) self.fields['ipsecpolicy_id'].choices = ipsecpolicy_id_choices return ipsecpolicy_id_choices def populate_vpnservice_id_choices(self, request, context): vpnservice_id_choices = [('', _("Select VPN Service"))] try: tenant_id = self.request.user.tenant_id vpnservices = api.vpn.vpnservice_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve VPN Services list.')) vpnservices = [] for s in vpnservices: vpnservice_id_choices.append((s.id, s.name)) self.fields['vpnservice_id'].choices = vpnservice_id_choices return vpnservice_id_choices class Meta: name = _("Add New IPSec Site Connection") permissions = ('openstack.services.network',) help_text = _("Create IPSec Site Connection for current project.\n\n" "Assign a name and description for the " "IPSec Site Connection. " "All fields in this tab are required." )
class AddTenantPolicy(forms.SelfHandlingForm): priority = forms.ChoiceField(label=_("Priority"), help_text=_("Select a Priority for the " "policy. Lower value = higher " "priority.")) source = RuleCIDRField(label=_("Source CIDR"), widget=forms.TextInput()) source_port = PortField(required=False, initial=0) destination = RuleCIDRField(label=_("Destination CIDR"), widget=forms.TextInput()) destination_port = PortField(required=False, initial=0) action = forms.ChoiceField(label=_("Action")) protocol = forms.ChoiceField(label=_("Protocol"), help_text=_("Protocol is mandatory when " "specifying port for the policy " "traffic."), required=False) nexthops = forms.MultiIPField(label=_("Optional: Next Hop " "Addresses (comma delimited)"), help_text=_("Next Hop field is ignored for " "Deny action"), widget=forms.TextInput(), required=False) failure_url = 'horizon:project:connections:index' def __init__(self, request, *args, **kwargs): super(AddTenantPolicy, self).__init__(request, *args, **kwargs) self.fields['action'].choices = [('permit', _('Permit')), ('deny', _('Deny'))] self.fields['priority'].choices = self.populate_priority_choices( request) self.fields['protocol'].choices = [('', _('None')), ('tcp', 'TCP'), ('udp', 'UDP')] def populate_priority_choices(self, request): existing_priorities = [] all_policies = neutron.tenantpolicy_list( request, **{'tenant_id': request.user.project_id}) for policy in all_policies: existing_priorities.append(policy['priority']) priorities = [(prio, prio) for prio in range(3000, 0, -1) if prio not in existing_priorities] if priorities: priorities.insert(0, ("", _("Select a Priority"))) else: priorities.insert(0, ("", _("No Priorities available"))) return priorities def clean(self): cleaned_data = super(AddTenantPolicy, self).clean() if 'priority' not in cleaned_data: cleaned_data['priority'] = -1 if 'nexthops' not in cleaned_data: cleaned_data['nexthops'] = '' if 'source' in cleaned_data and cleaned_data['source'] == '0.0.0.0/0': cleaned_data['source'] = 'any' if ('destination' in cleaned_data and cleaned_data['destination'] == '0.0.0.0/0'): cleaned_data['destination'] = 'any' if 'action' in cleaned_data and cleaned_data['action'] == 'deny': cleaned_data['nexthops'] = '' return cleaned_data def _validate_protocol(self, data): if ((int(data['source_port']) > 0 or int(data['destination_port']) > 0) and data['protocol'] not in ['tcp', 'udp']): raise ValidationError('Protocol must be specified if either ' 'source or destination port is specified') def handle(self, request, data, **kwargs): try: self._validate_protocol(data) tenantpolicy = neutron.tenantpolicy_create(request, **data) msg = _("Tenant Policy was successfully created") LOG.debug(msg) messages.success(request, msg) return tenantpolicy except Exception as e: msg = _('Failed to add router rule %s') % e LOG.info(msg) messages.error(request, msg) redirect = reverse(self.failure_url) exceptions.handle(request, msg, redirect=redirect)
class AddIPsecSiteConnectionAction(workflows.Action): name = forms.CharField(max_length=80, label=_("Name"), required=False) description = forms.CharField(initial="", required=False, max_length=80, label=_("Description")) vpnservice_id = forms.ThemableChoiceField( label=_("VPN service associated with this connection")) local_ep_group_id = forms.ThemableChoiceField( required=False, label=_("Endpoint group for local subnet(s)"), help_text=_("Local subnets which the new IPsec connection is " "connected to. Required if no subnet is specified " "in a VPN service selected.")) ikepolicy_id = forms.ThemableChoiceField( label=_("IKE policy associated with this connection")) ipsecpolicy_id = forms.ThemableChoiceField( label=_("IPsec policy associated with this connection")) peer_address = forms.CharField( label=_("Peer gateway public IPv4/IPv6 Address or FQDN"), help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for " "the VPN Connection"), ) peer_id = forms.CharField( label=_("Peer router identity for authentication (Peer ID)"), help_text=_("Peer router identity for authentication. " "Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"), ) peer_ep_group_id = forms.ThemableChoiceField( required=False, label=_("Endpoint group for remote peer CIDR(s)"), help_text=_("Remote peer CIDR(s) connected to the new IPsec " "connection.")) peer_cidrs = forms.MultiIPField( required=False, label=_("Remote peer subnet(s)"), help_text=_("(Deprecated) Remote peer subnet(s) address(es) " "with mask(s) in CIDR format " "separated with commas if needed " "(e.g. 20.1.0.0/24, 21.1.0.0/24)"), version=forms.IPv4 | forms.IPv6, mask=True) psk = forms.CharField(max_length=80, label=_("Pre-Shared Key (PSK) string"), widget=forms.PasswordInput(render_value=False), help_text=_( "The pre-defined key string " "between the two peers of the VPN connection")) def populate_ikepolicy_id_choices(self, request, context): ikepolicy_id_choices = [('', _("Select IKE policy"))] try: tenant_id = self.request.user.tenant_id ikepolicies = api_vpn.ikepolicy_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve IKE policies list.')) ikepolicies = [] for p in ikepolicies: ikepolicy_id_choices.append((p.id, p.name_or_id)) self.fields['ikepolicy_id'].choices = ikepolicy_id_choices return ikepolicy_id_choices def populate_ipsecpolicy_id_choices(self, request, context): ipsecpolicy_id_choices = [('', _("Select IPsec Policy"))] try: tenant_id = self.request.user.tenant_id ipsecpolicies = api_vpn.ipsecpolicy_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve IPsec policies list.')) ipsecpolicies = [] for p in ipsecpolicies: ipsecpolicy_id_choices.append((p.id, p.name_or_id)) self.fields['ipsecpolicy_id'].choices = ipsecpolicy_id_choices return ipsecpolicy_id_choices def populate_vpnservice_id_choices(self, request, context): vpnservice_id_choices = [('', _("Select VPN service"))] try: tenant_id = self.request.user.tenant_id vpnservices = api_vpn.vpnservice_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve VPN services list.')) vpnservices = [] for s in vpnservices: vpnservice_id_choices.append((s.id, s.name_or_id)) self.fields['vpnservice_id'].choices = vpnservice_id_choices return vpnservice_id_choices def populate_local_ep_group_id_choices(self, request, context): try: tenant_id = self.request.user.tenant_id endpointgroups = api_vpn.endpointgroup_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve endpoint group list.')) endpointgroups = [] local_ep_group_ids = [(ep.id, ep.name_or_id) for ep in endpointgroups if ep.type == 'subnet'] local_ep_group_ids.insert(0, ('', _("Select local endpoint group"))) self.fields['local_ep_group_id'].choices = local_ep_group_ids return local_ep_group_ids def populate_peer_ep_group_id_choices(self, request, context): try: tenant_id = self.request.user.tenant_id endpointgroups = api_vpn.endpointgroup_list(request, tenant_id=tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve endpoint group list.')) endpointgroups = [] peer_ep_group_ids = [(ep.id, ep.name_or_id) for ep in endpointgroups if ep.type == 'cidr'] peer_ep_group_ids.insert(0, ('', _("Select peer endpoint group"))) self.fields['peer_ep_group_id'].choices = peer_ep_group_ids return peer_ep_group_ids class Meta(object): name = _("Add New IPsec Site Connection") permissions = ('openstack.services.network', ) help_text = _("Create IPsec site connection for current " "project. Assign a name and description for the " "IPsec site connection. " "All fields in this tab are required.")
class AddEndpointGroupAction(workflows.Action): name = forms.CharField(max_length=80, label=_("Name"), required=False) description = forms.CharField(initial="", required=False, max_length=80, label=_("Description")) type = forms.ThemableChoiceField( label=_("Type"), help_text=_("IPsec connection validation requires that local " "endpoints are subnets, and peer endpoints are CIDRs."), choices=[('cidr', _('CIDR (for external systems)')), ('subnet', _('Subnet (for local systems)'))], widget=forms.ThemableSelectWidget(attrs={ 'class': 'switchable', 'data-slug': 'type', })) cidrs = forms.MultiIPField( required=False, label=_("External System CIDRs"), widget=forms.TextInput( attrs={ 'class': 'switched', 'data-switch-on': 'type', 'data-type-cidr': _("External System CIDRs"), }), help_text=_("Remote peer subnet(s) address(es) " "with mask(s) in CIDR format " "separated with commas if needed " "(e.g. 20.1.0.0/24, 21.1.0.0/24). " "This field is valid if type is CIDR"), version=forms.IPv4 | forms.IPv6, mask=True) subnets = forms.MultipleChoiceField( required=False, label=_("Local System Subnets"), widget=forms.CheckboxSelectMultiple( attrs={ 'class': 'switched', 'data-switch-on': 'type', 'data-type-subnet': _("External System Subnets"), }), help_text=_("Local subnet(s). " "This field is valid if type is Subnet"), ) def populate_subnets_choices(self, request, context): subnets_choices = [] try: tenant_id = request.user.tenant_id networks = api.neutron.network_list_for_tenant(request, tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve networks list.')) networks = [] for n in networks: for s in n['subnets']: subnets_choices.append((s.id, s.cidr)) self.fields['subnets'].choices = subnets_choices return subnets_choices class Meta(object): name = _("Add New Endpoint Groups") permissions = ('openstack.services.network', ) help_text_template = "project/vpn/_add_endpoint_group_help.html"
class AddRouterRule(forms.SelfHandlingForm): priority = forms.IntegerField(label=_("Priority"), initial=-1, min_value=-1, max_value=3000, required=False, widget=forms.HiddenInput()) source = RuleCIDRField(label=_("Source CIDR"), widget=forms.TextInput()) destination = RuleCIDRField(label=_("Destination CIDR"), widget=forms.TextInput()) action = forms.ChoiceField(label=_("Action")) nexthops = forms.MultiIPField(label=_("Optional: Next Hop " "Addresses (comma delimited)"), help_text=_("Next Hop field is ignored for " "Deny action"), widget=forms.TextInput(), required=False) router_id = forms.CharField(label=_("Router ID"), widget=forms.HiddenInput()) router_name = forms.CharField( label=_("Router Name"), widget=forms.TextInput(attrs={'readonly': 'readonly'}), required=False) failure_url = 'horizon:project:connections:index' def __init__(self, request, *args, **kwargs): super(AddRouterRule, self).__init__(request, *args, **kwargs) self.fields['action'].choices = [('permit', _('Permit')), ('deny', _('Deny'))] def clean(self): cleaned_data = super(AddRouterRule, self).clean() if 'priority' not in cleaned_data: cleaned_data['priority'] = -1 if 'nexthops' not in cleaned_data: cleaned_data['nexthops'] = '' if 'source' in cleaned_data and cleaned_data['source'] == '0.0.0.0/0': cleaned_data['source'] = 'any' if ('destination' in cleaned_data and cleaned_data['destination'] == '0.0.0.0/0'): cleaned_data['destination'] = 'any' if 'action' in cleaned_data and cleaned_data['action'] == 'deny': cleaned_data['nexthops'] = '' return cleaned_data def handle(self, request, data, **kwargs): try: if 'rule_to_delete' in request.POST: rulemanager.remove_rules(request, request.POST['rule_to_delete'], router_id=data['router_id']) except Exception: exceptions.handle(request, _('Unable to delete router policy.')) try: rule = { 'priority': data['priority'], 'action': data['action'], 'source': data['source'], 'destination': data['destination'], 'nexthops': data['nexthops'].split(',') } rulemanager.add_rule(request, router_id=data['router_id'], newrule=rule) msg = _('Router policy action performed successfully.') LOG.debug(msg) messages.success(request, msg) return True except Exception as e: msg = _('Failed to add router rule %s') % e LOG.info(msg) messages.error(request, msg) redirect = reverse(self.failure_url) exceptions.handle(request, msg, redirect=redirect)