class CrScene(ResourceModel, models.Model): name = models.CharField(max_length=225) scene_config = models.OneToOneField(SceneConfig, on_delete=models.PROTECT) scene = models.ForeignKey(Scene, on_delete=models.SET_NULL, null=True, default=None) roles = models.TextField(default='[]') missions = models.ManyToManyField(Mission) traffic_events = models.ManyToManyField(TrafficEvent) cr_scene_config = models.TextField(default='{}') create_time = models.DateTimeField(default=timezone.now) # 实例状态 Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.name
class Traffic(ResourceModel, models.Model): title = models.CharField(max_length=64) introduction = models.TextField(null=True, default='', blank=True) Type = Enum( BACKGROUND=1, INTELLIGENT=2, ) type = models.PositiveIntegerField(default=Type.BACKGROUND) public = models.BooleanField(default=True) is_copy = models.BooleanField(default=False) hash = models.CharField(max_length=100, null=True, default=tool_hash) category = models.ForeignKey(TrafficCategory, on_delete=models.SET_NULL, null=True) create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='traffic_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='traffic_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) Status = Enum( DELETE=0, NORMAL=1 ) status = models.PositiveIntegerField(default=Status.NORMAL) parent = models.PositiveIntegerField(null=True) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.title
class CrEvent(Owner): name = models.CharField(max_length=225) logo = models.ImageField(upload_to='event_logo', default='event_logo/default_event_logo/img1.png') description = models.TextField(default='') hash = models.CharField(max_length=100, null=True, default=tool_hash) cr_scenes = models.ManyToManyField(CrScene, through='CrEventScene') # 实例进程 Process = Enum( INPROGRESS=0, COMING=1, OVER=2, ) start_time = models.DateTimeField() end_time = models.DateTimeField() # 实例状态 Status = Enum( DELETE=0, NORMAL=1, PAUSE=2, INPROGRESS=3, OVER=4, ) status = models.PositiveIntegerField(default=Status.NORMAL) # 实例正常 objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.name
class MonitorCategory(models.Model): Status = constant.Status cn_name = models.CharField(max_length=100) en_name = models.CharField(max_length=100) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class EvaluationReport(models.Model): report = models.OneToOneField(CheckReport, related_name='check_report') evaluation_status = models.PositiveIntegerField(default=EvaluationStatus.WAIT) evaluator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class TrafficCategory(models.Model): Status = Enum( DELETE=0, NORMAL=1, ) cn_name = models.CharField(max_length=64) en_name = models.CharField(max_length=64) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class MissionPeriod(models.Model): cr_scene = models.ForeignKey(CrScene, on_delete=models.CASCADE) period_name = models.CharField(max_length=100) period_index = models.PositiveIntegerField() Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class Scripts(ResourceModel, models.Model): Suffix = constant.Suffix Status = constant.Status Type = constant.ScriptType type = models.PositiveIntegerField(default=Type.REMOTE) public = models.BooleanField(default=True) status = models.PositiveIntegerField(default=Status.NORMAL) title = models.CharField(max_length=1024) desc = models.CharField(max_length=1024, null=True, blank=True) code = models.TextField() category = models.ForeignKey(MonitorCategory, on_delete=models.SET_NULL, null=True) checker = models.ForeignKey(StandardDevice, blank=True, null=True) # path = models.FileField(upload_to='scene/scripts', null=True, default=None) suffix = models.PositiveIntegerField(default=Suffix.PY) create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='script_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='script_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() @classmethod def get_script_id(cls, filename, type=Type.REMOTE): [title, suffix] = filename.split('.') suffix = cls.Suffix.PY if (suffix == 'py') else cls.Suffix.SH obj = cls.objects.filter(title=title, suffix=suffix, type=type, status=cls.Status.NORMAL) if obj and obj.count() == 1: return obj[0].id elif obj.count() > 1: raise Exception("Redundant Scripts") else: raise ValueError("No Matching Scripts") def __str__(self): return self.title
class UpgradeVersion(models.Model): upgrade_package = models.FileField(upload_to='upgrade') info = models.TextField(default='') create_time = models.DateTimeField(auto_now_add=True) upgrade_status = models.PositiveIntegerField(default=VersionStatus.SUCCESS) version = models.CharField(max_length=20, default='version') status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() class Meta: db_table = 'system_upgrade_info'
class Installer(Owner): name = models.CharField(max_length=100) type = models.ForeignKey(InstallerType, on_delete=models.PROTECT) resources = models.ManyToManyField(InstallerResource) Status = Enum( DELETE=0, NORMAL=1, ) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class ExamTask(models.Model): TopicProblem = constant.TopicProblem Status = constant.Status exam = models.ForeignKey(Mission, on_delete=models.CASCADE) task_title = models.CharField(max_length=100) task_content = models.CharField(max_length=1024) task_type = models.PositiveIntegerField(default=TopicProblem.SINGLE) option = models.TextField(null=True, blank=True) answer = models.CharField(max_length=100) task_index = models.IntegerField(null=True) task_score = models.IntegerField(default=0) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class Network(Owner): name = models.CharField(max_length=100, unique=True) company = models.CharField(max_length=100, default=None, null=True) cidr = models.CharField(max_length=1024, default=None, null=True) gateway = models.CharField(max_length=1024, default=None, null=True) dns = models.CharField(max_length=1024, default=None, null=True) dhcp = models.BooleanField(default=True) net_id = models.CharField(max_length=50, default=None, null=True) subnet_id = models.CharField(max_length=50, default=None, null=True) Status = Enum( DELETE=0, NORMAL=1, ) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class CrEventUserStandardDevice(Owner): cr_event_scene = models.ForeignKey(CrEventScene, on_delete=models.PROTECT) standard_device = models.CharField(max_length=100, null=True) # 某次启动的scene_id scene_id = models.PositiveIntegerField() Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() class Meta: unique_together = ('scene_id', 'standard_device')
class BaseNotice(models.Model): notice = models.CharField(max_length=1024) is_topped = models.BooleanField(default=False) create_time = models.DateTimeField(default=timezone.now) last_edit_time = models.DateTimeField(default=timezone.now) # 通知状态 Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() class Meta: abstract = True
class Disk(Owner): name = models.CharField(max_length=100, unique=True) size = models.PositiveIntegerField() used_size = models.FloatField(default=0) Format = Enum( NTFS='NTFS', EXT4='EXT4', FAT32='FAT32', ) format = models.CharField(max_length=100, default=Format.NTFS) disk_id = models.CharField(max_length=50, default=None, null=True) mnt_dir = models.CharField(max_length=1024, default=None, null=True) Status = Enum( DELETE=0, AVAILABLE=1, USING=2, DETACHING=3, ERROR=4, ) status = models.IntegerField(default=Status.AVAILABLE) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def sync(self): if self.status != Disk.Status.DELETE and self.disk_id: status_map = { 'available': Disk.Status.AVAILABLE, 'in-use': Disk.Status.USING, 'detaching': Disk.Status.DETACHING, 'error': Disk.Status.ERROR, } disk = cloud.volume.get(self.disk_id) self.name = disk.name self.size = disk.size self.modify_time = timezone.now() self.status = status_map.get(disk.status, Disk.Status.AVAILABLE) self.save()
class TrafficEvent(ResourceModel, models.Model): title = models.CharField(max_length=64) introduction = models.TextField(null=True, default='', blank=True) Type = Enum( BACKGROUND=1, INTELLIGENT=2, ) type = models.PositiveIntegerField(default=Type.BACKGROUND) StartUpMode = Enum( AUTO=1, DELAY=2 ) start_up_mode = models.PositiveIntegerField(default=StartUpMode.AUTO) delay_time = models.PositiveIntegerField(null=True) public = models.BooleanField(default=True) traffic = models.ForeignKey(Traffic, related_name='traffic_event') target = models.CharField(max_length=128, default=None, blank=True) runner = models.CharField(max_length=100, default=None) target_net = models.CharField(max_length=100, default=None) parameter = models.CharField(max_length=200, default='', blank=True) pid = models.CharField(max_length=128, default='') create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='event_traffic_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='event_traffic_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) Status = Enum( DELETE=0, NORMAL=1, RUNNING=2, ERROR=3, ) status = models.PositiveIntegerField(default=Status.NORMAL) error = models.TextField(max_length=2048, default=None, null=True) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class Mission(ResourceModel, models.Model): Type = constant.Type Status = constant.Status Difficulty = constant.Difficulty MissionStatus = constant.MissionStatus type = models.PositiveIntegerField() title = models.CharField(max_length=100) content = models.CharField(max_length=100, null=True, blank=True) score = models.IntegerField() status = models.IntegerField(default=Status.NORMAL) public = models.BooleanField(default=False) difficulty = models.IntegerField(default=Difficulty.INTRODUCTION) mission_status = models.IntegerField(default=MissionStatus.COMMING) create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='mission_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='mission_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) # instance period = models.IntegerField() # position objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.title
class StandardDevice(ResourceModel, Owner): name = models.CharField(max_length=100) description = models.TextField(default='') logo = models.ImageField(upload_to='standard_device_logo', null=True) # 设备角色:网关,网络,终端 Role = Enum( NETWORK=1, GATEWAY=2, TERMINAL=3, ) role = models.PositiveIntegerField() RoleNetworkType = Enum(NETWORK=1, ) RoleGatewayType = Enum( ROUTER=1, FIREWALL=2, TERMINAL_ROUTER=3, TERMINAL_FIREWALL=4, WAF=5, IPS=6, IDS=7, ) RoleTerminalType = Enum( OTHER=0, WEB_SERVER=1, DATABASE_SERVER=2, FILE_SERVER=3, BINARY_SERVER=4, MAIL_SERVER=5, OFFICE_EQUIPMENT=6, MOBILE_EQUIPMENT=7, INDUSTRIAL_CONTROL_EQUIPMENT=8, INTELLIGENT_EQUIPMENT=9, UAV=10, REMOTE_ADDRESS_SERVER=-1, DEVICE_PORT_SERVER=-2, WIRELESS_SERVER=-3, ) RoleType = { Role.NETWORK: RoleNetworkType, Role.GATEWAY: RoleGatewayType, Role.TERMINAL: RoleTerminalType, } role_type = models.IntegerField() is_real = models.BooleanField(default=False) # -- 路由属性 -- GatewayPortType = Enum( MANAGE=0, WAN=1, LAN=2, ) gateway_port_configs = models.TextField(default='[]') # -- 终端属性 -- # 镜像类型 ImageType = Enum( VM='vm', DOCKER='docker', REAL='real', ) image_type = models.CharField(max_length=100, null=True, default=None) # 系统类型 SystemType = Enum( LINUX='linux', WINDOWS='windows', OTHER='other', ) system_type = models.CharField(max_length=100, null=True, default=SystemType.OTHER) # 系统二级类型 SystemSubType = Enum( KALI_2='kali-2', UBUNTU_14='ubuntu-14', UBUNTU_16='ubuntu-16', CENTOS_7='centos-7', WINDOWS_XP='windows-xp', WINDOWS_7='windows-7', WINDOWS_8='windows-8', WINDOWS_10='windows-10', WINDOWS_SERVER_2012='windows-server-2012', WINDOWS_SERVER_2008='windows-server-2008', WINDOWS_SERVER_2003='windows-server-2003', WINDOWS_SERVER_2000='windows-server-2000', ANDROID='android', UBUNTUKYLIN_18='ubuntukylin-18', OPENSOLARIS_11='opensolaris-11', OPENSUSE_LEAP_42='opensuse-leap-42', DEBIAN_9='debian-9', DEEPOFIX='deepofix', REDHAT_7='redhat-7', BACKTRACK_5='backtrack-5', OTHER='other', ) SystemSubTypeMap = { SystemSubType.KALI_2: SystemType.LINUX, SystemSubType.UBUNTU_14: SystemType.LINUX, SystemSubType.UBUNTU_16: SystemType.LINUX, SystemSubType.CENTOS_7: SystemType.LINUX, SystemSubType.WINDOWS_XP: SystemType.WINDOWS, SystemSubType.WINDOWS_7: SystemType.WINDOWS, SystemSubType.WINDOWS_8: SystemType.WINDOWS, SystemSubType.WINDOWS_10: SystemType.WINDOWS, SystemSubType.WINDOWS_SERVER_2012: SystemType.WINDOWS, SystemSubType.WINDOWS_SERVER_2008: SystemType.WINDOWS, SystemSubType.WINDOWS_SERVER_2003: SystemType.WINDOWS, SystemSubType.WINDOWS_SERVER_2000: SystemType.WINDOWS, SystemSubType.ANDROID: SystemType.LINUX, SystemSubType.UBUNTUKYLIN_18: SystemType.LINUX, SystemSubType.OPENSOLARIS_11: SystemType.LINUX, SystemSubType.OPENSUSE_LEAP_42: SystemType.LINUX, SystemSubType.DEBIAN_9: SystemType.LINUX, SystemSubType.DEEPOFIX: SystemType.LINUX, SystemSubType.REDHAT_7: SystemType.LINUX, SystemSubType.BACKTRACK_5: SystemType.LINUX, SystemSubType.OTHER: SystemType.OTHER, } system_sub_type = models.CharField(max_length=100, null=True, default=SystemSubType.OTHER) # 来源基础镜像 source_image_name = models.CharField(max_length=100, null=True, default=None) # 镜像格式(上传) DiskFormat = Enum( QCOW2='qcow2', VMDK='vmdk', DOCKER='docker', VHD='vhd', VDI='vdi', AMI='ami', ARI='ari', ISO='iso', OVA='ova', RAW='raw', ) disk_format = models.CharField(max_length=100, null=True, default=None) # 镜像元数据 DiskController = Enum( NONE='', IDE='ide', VIRTIO='virtio', SCSI='scsi', UML='uml', XEN='xen', USB='usb', ) VirtualNetworkInterfaceDevice = Enum( NONE='', RTL8139='rtl8139', VIRTIO='virtio', E1000='e1000', NE2K_PCI='ne2k_pci', PCNET='pcnet', ) VideoImageDriver = Enum( NONE='', VGA='vga', CIRRUS='cirrus', VMVGA='vmvga', XEN='xen', QXL='qxl', ) meta_data = models.TextField(null=True, default=None) # 镜像大小 对应EnvTerminal.Flavor Flavor = Enum( M11C_05G_8G='m1.1c-0.5g-8g', M11C_1G_8G='m1.1c-1g-8g', M21C_05G_10G='m2.1c-0.5g-10g', M21C_1G_10G='m2.1c-1g-10g', M22C_2G_10G='m2.2c-2g-10g', M22C_4G_10G='m2.2c-4g-10g', M31C_1G_20G='m3.1c-1g-20g', M31C_2G_20G='m3.1c-2g-20g', M32C_4G_20G='m3.2c-4g-20g', M34C_4G_20G='m3.4c-4g-20g', M41C_1G_40G='m4.1c-1g-40g', M42C_2G_40G='m4.2c-2g-40g', M44C_4G_40G='m4.4c-4g-40g', M44C_8G_40G='m4.4c-8g-40g', M54C_4G_80G='m5.4c-4g-80g', M54C_8G_80G='m5.4c-8g-80g', ) flavor = models.CharField(max_length=100, null=True, default=None) # 默认访问方式 对应EnvTerminal.AccessMode access_mode = models.CharField(max_length=100, null=True, default=None) # 默认访问端口 access_port = models.CharField(max_length=32, default=None, null=True) # 默认连接模式 目前只针对rdp的guacamole连接的rdp/nla access_connection_mode = models.CharField(max_length=100, null=True, default=None) # 默认访问用户 对应EnvTerminal.AccessMode access_user = models.CharField(max_length=100, null=True, default=None) # 默认访问密码 对应EnvTerminal.AccessMode access_password = models.CharField(max_length=256, null=True, default=None) # 是否支持初始化 init_support = models.BooleanField(default=False) # 镜像状态 ImageStatus = Enum( NOT_APPLY=0, CREATING=1, CREATED=2, ERROR=3, ) image_status = models.PositiveIntegerField(default=ImageStatus.NOT_APPLY) image_status_updated = models.ForeignKey(Executor, on_delete=models.SET_NULL, default=None, null=True, related_name='+') error = models.CharField(max_length=2048, default=None, null=True) # 临时编辑的镜像场景 image_scene = models.ForeignKey(Scene, on_delete=models.SET_NULL, null=True, default=None) # type Type = Enum( NORMAL=0, TRM=1, TGM=2, CGM=3, ) type = models.PositiveIntegerField(default=Type.NORMAL) # 实体设备 port_map = models.TextField(default='[]') remote_address = models.CharField(max_length=128, null=True, default="") Status = Enum( DELETE=0, NORMAL=1, ) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()