<commit_before>from __future__ import unicode_literals

import logging
from decimal import Decimal

from django.contrib.contenttypes import generic as ct_generic
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator, URLValidator
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django_fsm import FSMIntegerField
from django_fsm import transition

from nodeconductor.core import models as core_models
from nodeconductor.iaas.backend import CloudBackendError
from nodeconductor.structure import models as structure_models


logger = logging.getLogger(__name__)


def validate_known_keystone_urls(value):
    from nodeconductor.iaas.backend.openstack import OpenStackBackend

    backend = OpenStackBackend()
    try:
        backend.get_credentials(value)
    except CloudBackendError:
        raise ValidationError('%s is not a known OpenStack deployment.' % value)


@python_2_unicode_compatible
class Cloud(core_models.UuidMixin, core_models.SynchronizableMixin, models.Model):
    """
    A cloud instance information.

    Represents parameters set that are necessary to connect to a particular cloud,
    such as connection endpoints, credentials, etc.
    """

    class Meta(object):
        unique_together = (
            ('customer', 'name'),
        )

    class Permissions(object):
        customer_path = 'customer'
        project_path = 'projects'
        project_group_path = 'customer__projects__project_groups'

    name = models.CharField(max_length=100)
    customer = models.ForeignKey(structure_models.Customer, related_name='clouds')
    projects = models.ManyToManyField(
        structure_models.Project, related_name='clouds', through='CloudProjectMembership')

    # OpenStack backend specific fields
    auth_url = models.CharField(max_length=200, help_text='Keystone endpoint url',
                                validators=[URLValidator(), validate_known_keystone_urls])

    def get_backend(self):
        # TODO: Support different clouds instead of hard-coding
        # Importing here to avoid circular imports hell
        from nodeconductor.iaas.backend.openstack import OpenStackBackend

        return OpenStackBackend()

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class CloudProjectMembership(core_models.SynchronizableMixin, models.Model):
    """
    This model represents many to many relationships between project and cloud
    """

    cloud = models.ForeignKey(Cloud)
    project = models.ForeignKey(structure_models.Project)

    # OpenStack backend specific fields
    username = models.CharField(max_length=100, blank=True)
    password = models.CharField(max_length=100, blank=True)

    tenant_id = models.CharField(max_length=64, blank=True)

    availability_zone = models.CharField(max_length=100, blank=True)

    class Meta(object):
        unique_together = ('cloud', 'tenant_id')

    class Permissions(object):
        customer_path = 'cloud__customer'
        project_path = 'project'
        project_group_path = 'project__project_groups'

    def __str__(self):
        return '{0} | {1}'.format(self.cloud.name, self.project.name)

    def update_resource_quota_usage(self, field, value):
        try:
            resource_quota_usage = ResourceQuotaUsage.objects.get(cloud_project_membership=self)
        except ResourceQuotaUsage.DoesNotExist:
            resource_quota_usage = ResourceQuotaUsage(cloud_project_membership=self)<commit_msg>Add help_text to availability zone field (nc-327)<commit_after>from __future__ import unicode_literals

import logging
from decimal import Decimal

from django.contrib.contenttypes import generic as ct_generic
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator, URLValidator
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django_fsm import FSMIntegerField
from django_fsm import transition

from nodeconductor.core import models as core_models
from nodeconductor.iaas.backend import CloudBackendError
from nodeconductor.structure import models as structure_models


logger = logging.getLogger(__name__)


def validate_known_keystone_urls(value):
    from nodeconductor.iaas.backend.openstack import OpenStackBackend

    backend = OpenStackBackend()
    try:
        backend.get_credentials(value)
    except CloudBackendError:
        raise ValidationError('%s is not a known OpenStack deployment.' % value)


@python_2_unicode_compatible
class Cloud(core_models.UuidMixin, core_models.SynchronizableMixin, models.Model):
    """
    A cloud instance information.

    Represents parameters set that are necessary to connect to a particular cloud,
    such as connection endpoints, credentials, etc.
    """

    class Meta(object):
        unique_together = (
            ('customer', 'name'),
        )

    class Permissions(object):
        customer_path = 'customer'
        project_path = 'projects'
        project_group_path = 'customer__projects__project_groups'

    name = models.CharField(max_length=100)
    customer = models.ForeignKey(structure_models.Customer, related_name='clouds')
    projects = models.ManyToManyField(
        structure_models.Project, related_name='clouds', through='CloudProjectMembership')

    # OpenStack backend specific fields
    auth_url = models.CharField(max_length=200, help_text='Keystone endpoint url',
                                validators=[URLValidator(), validate_known_keystone_urls])

    def get_backend(self):
        # TODO: Support different clouds instead of hard-coding
        # Importing here to avoid circular imports hell
        from nodeconductor.iaas.backend.openstack import OpenStackBackend

        return OpenStackBackend()

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class CloudProjectMembership(core_models.SynchronizableMixin, models.Model):
    """
    This model represents many to many relationships between project and cloud
    """

    cloud = models.ForeignKey(Cloud)
    project = models.ForeignKey(structure_models.Project)

    # OpenStack backend specific fields
    username = models.CharField(max_length=100, blank=True)
    password = models.CharField(max_length=100, blank=True)

    tenant_id = models.CharField(max_length=64, blank=True)

    availability_zone = models.CharField(
        max_length=100, blank=True,
        help_text='Optional availability group. Will be used for all instances provisioned in this tenant')

    class Meta(object):
        unique_together = ('cloud', 'tenant_id')

    class Permissions(object):
        customer_path = 'cloud__customer'
        project_path = 'project'
        project_group_path = 'project__project_groups'

    def __str__(self):
        return '{0} | {1}'.format(self.cloud.name, self.project.name)

    def update_resource_quota_usage(self, field, value):
        try:
            resource_quota_usage = ResourceQuotaUsage.objects.get(cloud_project_membership=self)
        except ResourceQuotaUsage.DoesNotExist:
            resource_quota_usage = ResourceQuotaUsage(cloud_project_membership=self)
{'fraction_non_alphanumeric': 0.07236208556885404, 'fraction_numerical': 0.006465813729536387, 'mean_word_length': 4.038115038115038, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '95346', 'n_tokens_mistral': 2005, 'n_tokens_neox': 1906, 'n_words': 485}