Esempio n. 1
0
class ObjectPermission(BaseModel):
    """
    A mapping of view, add, change, and/or delete permission for users and/or groups to an arbitrary set of objects
    identified by ORM query parameters.
    """

    name = models.CharField(max_length=100)
    description = models.CharField(max_length=200, blank=True)
    enabled = models.BooleanField(default=True)
    object_types = models.ManyToManyField(
        to=ContentType,
        limit_choices_to=Q(
            ~Q(app_label__in=[
                "admin",
                "auth",
                "contenttypes",
                "sessions",
                "taggit",
                "users",
            ])
            | Q(app_label="auth", model__in=["group", "user"])
            | Q(app_label="users", model__in=["objectpermission", "token"])),
        related_name="object_permissions",
    )
    groups = models.ManyToManyField(to=Group,
                                    blank=True,
                                    related_name="object_permissions")
    users = models.ManyToManyField(to=User,
                                   blank=True,
                                   related_name="object_permissions")
    actions = ArrayField(
        base_field=models.CharField(max_length=30),
        help_text="The list of actions granted by this permission",
    )
    constraints = models.JSONField(
        encoder=DjangoJSONEncoder,
        blank=True,
        null=True,
        help_text=
        "Queryset filter matching the applicable objects of the selected type(s)",
    )

    objects = RestrictedQuerySet.as_manager()

    class Meta:
        ordering = ["name"]
        verbose_name = "permission"

    def __str__(self):
        return self.name

    def list_constraints(self):
        """
        Return all constraint sets as a list (even if only a single set is defined).
        """
        if type(self.constraints) is not list:
            return [self.constraints]
        return self.constraints
Esempio n. 2
0
class EoxNotice(ChangeLoggedModel, BaseModel):
    # Assign permissions to model
    objects = RestrictedQuerySet.as_manager()

    # Set model columns
    devices = models.ManyToManyField(Device)
    device_type = models.ForeignKey(to="dcim.DeviceType",
                                    on_delete=models.CASCADE,
                                    verbose_name="Device Type")
    end_of_sale = models.DateField(null=True,
                                   blank=True,
                                   verbose_name="End of Sale")
    end_of_support = models.DateField(null=True,
                                      blank=True,
                                      verbose_name="End of Support")
    end_of_sw_releases = models.DateField(
        null=True, blank=True, verbose_name="End of Software Releases")
    end_of_security_patches = models.DateField(
        null=True, blank=True, verbose_name="End of Security Patches")
    notice_url = models.URLField(blank=True, verbose_name="Notice URL")

    class Meta:
        ordering = ("end_of_support", "end_of_sale")
        constraints = [
            models.UniqueConstraint(fields=["device_type"],
                                    name="unique_device_type")
        ]

    def __str__(self):
        if self.end_of_support:
            msg = f"{self.device_type} - End of support: {self.end_of_support}"
        else:
            msg = f"{self.device_type} - End of sale: {self.end_of_sale}"
        return msg

    def get_absolute_url(self):
        return reverse("plugins:eox_notices:eoxnotice", kwargs={"pk": self.pk})

    def save(self, signal=False):
        # Update the model with related devices that are of the specific device type
        if not signal:
            related_devices = Device.objects.filter(
                device_type=self.device_type)
            for device in related_devices:
                self.devices.add(device)
        super().save()

    def clean(self):
        super().clean()

        if not self.end_of_sale and not self.end_of_support:
            raise ValidationError(
                _("End of Sale or End of Support must be specified."))
Esempio n. 3
0
class BaseModel(models.Model):
    """
    Base model class that all models should inherit from.

    This abstract base provides globally common fields and functionality.

    Here we define the primary key to be a UUID field and set its default to
    automatically generate a random UUID value. Note however, this does not
    operate in the same way as a traditional auto incrementing field for which
    the value is issued by the database upon initial insert. In the case of
    the UUID field, Django creates the value upon object instantiation. This
    means the canonical pattern in Django of checking `self.pk is None` to tell
    if an object has been created in the actual database does not work because
    the object will always have the value populated prior to being saved to the
    database for the first time. An alternate pattern of checking `not self.present_in_database`
    can be used for the same purpose in most cases.
    """

    id = models.UUIDField(primary_key=True,
                          default=uuid.uuid4,
                          unique=True,
                          editable=False)

    objects = RestrictedQuerySet.as_manager()

    @property
    def present_in_database(self):
        """
        True if the record exists in the database, False if it does not.
        """
        return not self._state.adding

    class Meta:
        abstract = True

    def validated_save(self):
        """
        Perform model validation during instance save.

        This is a convenience method that first calls `self.full_clean()` and then `self.save()`
        which in effect enforces model validation prior to saving the instance, without having
        to manually make these calls seperately. This is a slight departure from Django norms,
        but is intended to offer an optional, simplified interface for performing this common
        workflow. The indended use is for user defined Jobs and scripts run via the `nbshell`
        command.
        """
        self.full_clean()
        self.save()
Esempio n. 4
0
class TokenViewSet(ModelViewSet):
    queryset = RestrictedQuerySet(model=Token).prefetch_related("user")
    serializer_class = serializers.TokenSerializer
    filterset_class = filters.TokenFilterSet

    @property
    def authentication_classes(self):
        """Inherit default authentication_classes and basic authentication."""
        classes = super().authentication_classes
        return classes + [BasicAuthentication]

    def get_queryset(self):
        """
        Limit users to their own Tokens.
        """
        queryset = super().get_queryset()
        return queryset.filter(user=self.request.user)
Esempio n. 5
0
class GroupViewSet(ModelViewSet):
    queryset = RestrictedQuerySet(model=Group).annotate(user_count=Count("user")).order_by("name")
    serializer_class = serializers.GroupSerializer
    filterset_class = filters.GroupFilterSet
Esempio n. 6
0
class UserViewSet(ModelViewSet):
    queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related("groups").order_by("username")
    serializer_class = serializers.UserSerializer
    filterset_class = filters.UserFilterSet
class OnboardingTask(BaseModel, ChangeLoggedModel):
    """The status of each onboarding Task is tracked in the OnboardingTask table."""

    created_device = models.ForeignKey(to="dcim.Device",
                                       on_delete=models.SET_NULL,
                                       blank=True,
                                       null=True)

    ip_address = models.CharField(
        max_length=255,
        help_text="primary ip address for the device",
        null=True)

    site = models.ForeignKey(to="dcim.Site",
                             on_delete=models.SET_NULL,
                             blank=True,
                             null=True)

    role = models.ForeignKey(to="dcim.DeviceRole",
                             on_delete=models.SET_NULL,
                             blank=True,
                             null=True)

    device_type = models.CharField(
        null=True,
        max_length=255,
        help_text="Device Type extracted from the device (optional)")

    platform = models.ForeignKey(to="dcim.Platform",
                                 on_delete=models.SET_NULL,
                                 blank=True,
                                 null=True)

    status = models.CharField(max_length=255,
                              choices=OnboardingStatusChoices,
                              help_text="Overall status of the task")

    failed_reason = models.CharField(
        max_length=255,
        choices=OnboardingFailChoices,
        help_text="Raison why the task failed (optional)",
        null=True)

    message = models.CharField(max_length=511, blank=True)

    port = models.PositiveSmallIntegerField(
        help_text="Port to use to connect to the device", default=22)
    timeout = models.PositiveSmallIntegerField(
        help_text=
        "Timeout period in sec to wait while connecting to the device",
        default=30)

    def __str__(self):
        """String representation of an OnboardingTask."""
        return f"{self.site} : {self.ip_address}"

    def get_absolute_url(self):
        """Provide absolute URL to an OnboardingTask."""
        return reverse("plugins:nautobot_device_onboarding:onboardingtask",
                       kwargs={"pk": self.pk})

    objects = RestrictedQuerySet.as_manager()