class Bridge(Model): interface = models.OneToOneField( Interfaces, verbose_name=_("Interface"), on_delete=models.CASCADE, ) members = ListField( verbose_name=_("Members"), default=[], ) class Meta: verbose_name = _("Bridge") verbose_name_plural = _("Bridges") ordering = ["interface"] def __str__(self): return str(self.interface)
class Task(Model): task_dataset = models.CharField( max_length=150, verbose_name=_("Volume/Dataset"), ) task_recursive = models.BooleanField( default=False, verbose_name=_("Recursive"), ) task_exclude = ListField(verbose_name=_("Exclude child datasets"), ) task_lifetime_value = models.PositiveIntegerField( default=2, verbose_name=_("Snapshot lifetime value"), ) task_lifetime_unit = models.CharField( default='WEEK', max_length=120, choices=choices.RetentionUnit_Choices, verbose_name=_("Snapshot lifetime unit"), ) task_naming_schema = models.CharField( default='auto-%Y-%m-%d_%H-%M', max_length=150, verbose_name=_("Naming schema"), ) task_minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_("Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), ) task_hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), ) task_daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), ) task_month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), ) task_dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), ) task_begin = models.TimeField( default=time(hour=9), verbose_name=_("Begin"), help_text=_("Do not snapshot before"), ) task_end = models.TimeField( default=time(hour=18), verbose_name=_("End"), help_text=_("Do not snapshot after"), ) task_allow_empty = models.BooleanField( default=True, verbose_name=_("Allow taking empty snapshots"), ) task_enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), ) def __str__(self): return '%s - %s - %d %s' % ( self.task_dataset, self.task_naming_schema, self.task_lifetime_value, self.task_lifetime_unit.lower(), ) class Meta: verbose_name = _("Periodic Snapshot Task") verbose_name_plural = _("Periodic Snapshot Tasks") ordering = ["task_dataset"]
class Replication(Model): repl_name = models.CharField(max_length=120, verbose_name=_("Name")) repl_direction = models.CharField( max_length=120, choices=[("PUSH", "Push"), ("PULL", "Pull")], default="PUSH", verbose_name=_("Direction"), ) repl_transport = models.CharField( max_length=120, choices=[("SSH", "SSH"), ("SSH+NETCAT", "SSH+netcat"), ("LOCAL", "Local"), ("LEGACY", "Legacy")], default="SSH", verbose_name=_("Transport"), ) repl_ssh_credentials = models.ForeignKey( SSHCredentialsKeychainCredential, blank=True, null=True, verbose_name=_("SSH Connection"), ) repl_netcat_active_side = models.CharField( max_length=120, choices=[("LOCAL", "Local"), ("REMOTE", "Remote")], default=None, null=True, verbose_name=_("Netcat Active Side"), ) repl_netcat_active_side_listen_address = models.CharField( max_length=120, default=None, null=True, verbose_name=_("Netcat Active Side Listen Address"), ) repl_netcat_active_side_port_min = models.PositiveIntegerField( null=True, verbose_name=_("Netcat Active Side Min Port"), ) repl_netcat_active_side_port_max = models.PositiveIntegerField( null=True, verbose_name=_("Netcat Active Side Max Port"), ) repl_netcat_passive_side_connect_address = models.CharField( max_length=120, default=None, null=True, verbose_name=_("Netcat Passive Side Connect Address"), ) repl_source_datasets = ListField(verbose_name=_("Source Datasets"), ) repl_target_dataset = models.CharField( max_length=120, verbose_name=_("Target Dataset"), help_text=_( "This should be the name of the ZFS filesystem on " "remote side. eg: Volumename/Datasetname not the mountpoint or " "filesystem path"), ) repl_recursive = models.BooleanField( default=False, verbose_name=_("Recursively replicate child dataset's snapshots"), ) repl_exclude = ListField(verbose_name=_("Exclude child datasets"), ) repl_properties = models.BooleanField( default=True, verbose_name=_("Send dataset properties along with snapshots"), ) repl_periodic_snapshot_tasks = models.ManyToManyField( "Task", related_name="replication_tasks", verbose_name=_("Periodic snapshot tasks"), blank=True, ) repl_naming_schema = ListField( verbose_name=_("Also replicate snapshots matching naming schema"), ) repl_auto = models.BooleanField( default=True, verbose_name=_("Run automatically"), ) repl_schedule_minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_("Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), null=True, ) repl_schedule_hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), null=True, ) repl_schedule_daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), null=True, ) repl_schedule_month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), null=True, ) repl_schedule_dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), null=True, ) repl_schedule_begin = models.TimeField( default=time(hour=0), verbose_name=_("Begin"), help_text=_("Do not start replication before"), null=True, ) repl_schedule_end = models.TimeField( default=time(hour=23, minute=45), verbose_name=_("End"), help_text=_("Do not start replication after"), null=True, ) repl_restrict_schedule_minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_("Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), null=True, ) repl_restrict_schedule_hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), null=True, ) repl_restrict_schedule_daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), null=True, ) repl_restrict_schedule_month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), null=True, ) repl_restrict_schedule_dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), null=True, ) repl_restrict_schedule_begin = models.TimeField( default=time(hour=0), verbose_name=_("Begin"), help_text=_("Do not start replication before"), null=True, ) repl_restrict_schedule_end = models.TimeField( default=time(hour=23, minute=45), verbose_name=_("End"), help_text=_("Do not start replication after"), null=True, ) repl_only_matching_schedule = models.BooleanField( verbose_name=_("Only replicate snapshots matching schedule"), ) repl_allow_from_scratch = models.BooleanField(verbose_name=_( "Replicate from scratch if incremental is not possible"), ) repl_hold_pending_snapshots = models.BooleanField( verbose_name=_("Hold pending snapshots"), ) repl_retention_policy = models.CharField( max_length=120, choices=[("SOURCE", "Same as source"), ("CUSTOM", "Custom"), ("NONE", "None")], default="NONE", verbose_name=_("Snapshot retention policy"), ) repl_lifetime_value = models.PositiveIntegerField( null=True, default=2, verbose_name=_("Snapshot lifetime value"), ) repl_lifetime_unit = models.CharField( null=True, default='WEEK', max_length=120, choices=choices.RetentionUnit_Choices, verbose_name=_("Snapshot lifetime unit"), ) repl_compression = models.CharField( null=True, blank=True, max_length=120, choices=choices.Repl_CompressionChoices, default="LZ4", verbose_name=_("Stream Compression"), ) repl_speed_limit = models.IntegerField( null=True, blank=True, default=None, verbose_name=_("Limit (kbps)"), help_text=_("Limit the replication speed. Unit in " "kilobits/second. 0 = unlimited."), ) repl_dedup = models.BooleanField( default=False, verbose_name=_('Send deduplicated stream'), help_text=_( 'Blocks which would have been ' 'sent multiple times in the send stream will only be sent ' 'once. The receiving system must also support this feature to ' 'receive a deduplicated stream. This flag can be used regard-' 'less of the dataset\'s dedup property, but performance will be ' 'much better if the filesystem uses a dedup-capable checksum ' '(eg. sha256).'), ) repl_large_block = models.BooleanField( default=True, verbose_name=_('Allow blocks larger than 128KB'), help_text=_( 'Generate a stream which may contain blocks larger than 128KB. ' 'This flag has no effect if the large_blocks pool feature is ' 'disabled, or if the recordsize property of this filesystem ' 'has never been set above 128KB. The receiving system must ' 'have the large_blocks pool feature enabled as well. See ' 'zpool-features(7) for details on ZFS feature flags and the ' 'large_blocks feature.'), ) repl_embed = models.BooleanField( default=False, verbose_name=_('Allow WRITE_EMBEDDED records'), help_text=_( 'Generate a more compact stream by using WRITE_EMBEDDED ' 'records for blocks which are stored more compactly on disk by ' 'the embedded_data pool feature. This flag has no effect if ' 'the embedded_data feature is disabled. The receiving system ' 'must have the embedded_data feature enabled. If the ' 'lz4_compress feature is active on the sending system, then ' 'the receiving system must have that feature enabled as well. ' 'See zpool-features(7) for details on ZFS feature flags and ' 'the embedded_data feature.'), ) repl_compressed = models.BooleanField( default=True, verbose_name=_('Allow compressed WRITE records'), help_text=_( 'Generate a more compact stream by using compressed WRITE ' 'records for blocks which are compressed on disk and in memory ' '(see the compression property for details). If the ' 'lz4_compress feature is active on the sending system, then ' 'the receiving system must have that feature enabled as well. ' 'If the large_blocks feature is enabled on the sending system ' 'but the -L option is not supplied in conjunction with -c then ' 'the data will be decompressed before sending so it can be ' 'split into smaller block sizes. '), ) repl_retries = models.PositiveIntegerField( default=5, verbose_name=_("Number of retries for failed replications"), ) repl_logging_level = models.CharField( null=True, blank=True, max_length=120, choices=[ ("", "Default"), ("DEBUG", "Debug"), ("INFO", "Info"), ("WARNING", "Warning"), ("ERROR", "Error"), ], default=None, verbose_name=_("Logging Level"), ) repl_enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), help_text=_( 'Disabling will not stop any replications which are in progress.'), ) repl_state = models.TextField( default="{}", editable=False, ) class Meta: verbose_name = _("Replication Task") verbose_name_plural = _("Replication Tasks") def __str__(self): return self.repl_name
class Settings(Model): stg_guiprotocol = models.CharField( max_length=120, choices=choices.PROTOCOL_CHOICES, default="http", verbose_name=_("Protocol") ) stg_guicertificate = models.ForeignKey( "Certificate", verbose_name=_("Certificate"), limit_choices_to={'cert_type__in': [CERT_TYPE_EXISTING, CERT_TYPE_INTERNAL]}, on_delete=models.SET_NULL, blank=True, null=True ) stg_guiaddress = ListField( blank=True, default=['0.0.0.0'], verbose_name=_("WebGUI IPv4 Address") ) stg_guiv6address = ListField( blank=True, default=['::'], verbose_name=_("WebGUI IPv6 Address") ) stg_guiport = models.IntegerField( verbose_name=_("WebGUI HTTP Port"), validators=[MinValueValidator(1), MaxValueValidator(65535)], default=80, ) stg_guihttpsport = models.IntegerField( verbose_name=_("WebGUI HTTPS Port"), validators=[MinValueValidator(1), MaxValueValidator(65535)], default=443, ) stg_guihttpsredirect = models.BooleanField( verbose_name=_('WebGUI HTTP -> HTTPS Redirect'), default=True, help_text=_( 'Redirect HTTP (port 80) to HTTPS when only the HTTPS protocol is ' 'enabled' ), ) stg_language = models.CharField( max_length=120, choices=settings.LANGUAGES, default="en", verbose_name=_("Language") ) stg_kbdmap = models.CharField( max_length=120, choices=choices.KBDMAP_CHOICES(), verbose_name=_("Console Keyboard Map"), blank=True, ) stg_timezone = models.CharField( max_length=120, choices=choices.TimeZoneChoices(), default="America/Los_Angeles", verbose_name=_("Timezone") ) stg_sysloglevel = models.CharField( max_length=120, choices=choices.SYS_LOG_LEVEL, default="f_info", verbose_name=_("Syslog level"), help_text=_("Specifies which messages will be logged by " "server. INFO and VERBOSE log transactions that " "server performs on behalf of the client. " "f_is_debug specify higher levels of debugging output. " "The default is f_info."), ) stg_syslogserver = models.CharField( default='', blank=True, max_length=120, verbose_name=_("Syslog server"), help_text=_("Specifies the server and port syslog messages " "will be sent to. The accepted format is hostname:port " "or ip:port, if :port is not specified it will default to " "port 514 (this field currently only takes IPv4 addresses)"), ) stg_wizardshown = models.BooleanField( editable=False, default=False, ) stg_pwenc_check = models.CharField( max_length=100, editable=False, ) class Meta: verbose_name = _("General")
class CloudSync(Model): description = models.CharField( max_length=150, verbose_name=_('Description'), ) direction = models.CharField( max_length=10, verbose_name=_("Direction"), help_text=_( "Push - From local to remote. Pull - From " "remote to local." ), default='PUSH', choices=( ('PUSH', _('Push')), ('PULL', _('Pull')), ) ) path = PathField( verbose_name=_("Path"), abspath=False, ) credential = models.ForeignKey( 'system.CloudCredentials', verbose_name=_('Credential'), ) transfer_mode = models.CharField( verbose_name=_('Transfer Mode'), default='sync', choices=( ('SYNC', _('Sync')), ('COPY', _('Copy')), ('MOVE', _('Move')), ), max_length=20, ) attributes = DictField( editable=False, ) snapshot = models.BooleanField( verbose_name=_("Take snapshot"), help_text=_( "Take dataset snapshot before pushing data.", ), ) pre_script = models.TextField( blank=True, verbose_name=_("Pre-script"), help_text=_( "Script to execute before running sync.", ), ) post_script = models.TextField( blank=True, verbose_name=_("Post-script"), help_text=_( "Script to execute after running sync.", ), ) encryption = models.BooleanField( verbose_name=_("Remote encryption"), help_text=_( "This option will push encrypted files and decrypt pulled files.", ), ) filename_encryption = models.BooleanField( default=True, verbose_name=_("Filename encryption"), help_text=_( "Also encrypt filenames.", ), ) encryption_password = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption password"), ) encryption_salt = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption salt"), ) args = models.TextField( blank=True, max_length=255, verbose_name=_("Auxiliary arguments"), help_text=_( "These arguments will be passed to rclone." "<br>See <a href=\"https://rclone.org/docs/\">https://rclone.org/docs/</a> for help"), ) minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_( "Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), ) hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), ) daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), ) month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), ) dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), ) follow_symlinks = models.BooleanField( verbose_name=_("Follow symlinks"), help_text=_( "Follow symlinks and copy the pointed to item.", ), ) transfers = models.IntegerField( null=True, ) bwlimit = ListField( editable=False, ) exclude = ListField( editable=False, ) enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), help_text=_( 'Disabling will not stop any syncs which are in progress.' ), ) class Meta: verbose_name = _("Cloud Sync") verbose_name_plural = _("Cloud Syncs") ordering = ["description"] def __str__(self): return self.description def run(self): with client as c: jid = c.call('cloudsync.sync', self.id) return jid