diff --git a/.gitignore b/.gitignore index 9a78f649015be92c89c3536059bd0a7280f5dfb7..ee695dd721e6054695f3aa7ee42e9ac35b296158 100644 --- a/.gitignore +++ b/.gitignore @@ -16,22 +16,14 @@ netaxe/logs netaxe/__pycahe__ netaxe/netboost/conf.py netaxe/netboost/__pycache__/ -netaxe/apps/users/migrations/00*.py netaxe/apps/users/__pycache__/ -netaxe/apps/system/migrations/00*.py netaxe/apps/system/__pycache__/ -netaxe/apps/asset/migrations/00*.py netaxe/apps/asset/__pycache__/ -netaxe/apps/automation/migrations/00*.py netaxe/apps/automation/__pycache__/ netaxe/apps/automation/tools/__pycache__/ -netaxe/apps/config_center/migrations/00*.py netaxe/apps/config_center/__pycache__/ -netaxe/apps/route_backend/migrations/00*.py -netaxe/apps/int_utilization/migrations/00*.py netaxe/apps/route_backend/__pycache__/ netaxe/__pycache__/ -netaxemedia netaxe/media/automation netaxe/media/device_config/current-configuration docker/server/logs/ @@ -54,14 +46,7 @@ netaxe/apps/int_utilization/__pycache__/ netaxe/apps/route_backend/__pycache__/ netaxe/apps/system/__pycache__/ netaxe/apps/users/__pycache__/ -netaxe/apps/api/migrations/ -netaxe/apps/asset/migrations/ -netaxe/apps/automation/migrations/ -netaxe/apps/config_center/migrations/ -netaxe/apps/int_utilization/migrations/ -netaxe/apps/route_backend/migrations/ -netaxe/apps/system/migrations/ -netaxe/apps/users/migrations/ docker/server/conf/apisix_log/access.log docker/server/conf/apisix_log/error.log -docker/server/conf/apisix_conf/config.yaml \ No newline at end of file +docker/server/conf/apisix_conf/config.yaml +netaxe_alert/ \ No newline at end of file diff --git a/docker/server/docker-compose.yml b/docker/server/docker-compose.yml index 0584bfe90f86856839c293a48b9501197f7150ff..56c982c1ef4f09920b748cc545140ff8da0f012a 100644 --- a/docker/server/docker-compose.yml +++ b/docker/server/docker-compose.yml @@ -8,7 +8,7 @@ networks: services: netaxe-server: - image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.7 + image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.8 container_name: netaxe-server ports: - "8001:8001" @@ -50,7 +50,7 @@ services: - netops-axe celery-default: - image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.7 + image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.8 container_name: celery-default command: sh start.sh default depends_on: @@ -61,7 +61,7 @@ services: networks: - netops-axe celery-netaxe_ipam: - image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.7 + image: registry.cn-hangzhou.aliyuncs.com/netaxe/netaxe-backend:1.0.8 container_name: celery-netaxe_ipam command: sh start.sh netaxe_ipam depends_on: diff --git a/docker/server/nginx.conf b/docker/server/nginx.conf index dd38dc3581b83ef27e43406249e0a8f08495d420..eb45cca5f52a459a963810d0617f6c143d98daa6 100644 --- a/docker/server/nginx.conf +++ b/docker/server/nginx.conf @@ -39,4 +39,10 @@ server { add_header Cache-Control private; alias /home/netaxe/static/; } + location /media/ { + expires 2d; + autoindex off; + add_header Cache-Control private; + alias /home/netaxe/media/; + } } \ No newline at end of file diff --git a/netaxe/apps/asset/migrations/0001_initial.py b/netaxe/apps/asset/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..a887ff9eb3ee4e05a053228e7f9c4d820df4fced --- /dev/null +++ b/netaxe/apps/asset/migrations/0001_initial.py @@ -0,0 +1,397 @@ +# Generated by Django 3.2.17 on 2023-02-27 15:53 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('automation', '__first__'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='AdminRecord', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('admin_server', models.CharField(max_length=32, verbose_name='登录主机')), + ('admin_remote_ip', models.GenericIPAddressField(verbose_name='远程地址')), + ('admin_start_time', models.CharField(max_length=64, verbose_name='开始时间')), + ('admin_login_status_time', models.CharField(max_length=16, verbose_name='登录时长')), + ('admin_record_file', models.CharField(max_length=256, verbose_name='操作记录')), + ('admin_record_mode', models.CharField(choices=[('ssh', 'ssh'), ('guacamole', 'guacamole')], default='ssh', max_length=10, verbose_name='登录协议')), + ], + options={ + 'verbose_name': '登录管理用户记录表', + 'verbose_name_plural': '登录管理用户记录表', + 'db_table': 'asset_admin_record', + }, + ), + migrations.CreateModel( + name='AssetAccount', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='', max_length=50, unique=True, verbose_name='管理账户')), + ('username', models.CharField(blank=True, default='', max_length=50, null=True, verbose_name='登录用户名')), + ('password', models.CharField(blank=True, default='', max_length=200, null=True, verbose_name='登录密码')), + ('protocol', models.CharField(choices=[('ssh', 'ssh'), ('telnet', 'telnet'), ('netconf', 'netconf')], default='ssh', max_length=20, verbose_name='协议名')), + ('port', models.IntegerField(default=22, verbose_name='端口号')), + ('role', models.CharField(choices=[('3', '超级管理员'), ('2', '管理员'), ('1', '普通用户'), ('0', '查看')], default=3, max_length=20, verbose_name='用户角色')), + ('en_pwd', models.CharField(blank=True, default='', max_length=200, null=True, verbose_name='特权密码')), + ], + options={ + 'verbose_name_plural': '设备管理账户', + 'db_table': 'asset_account', + }, + ), + migrations.CreateModel( + name='AssetIpInfo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=200, null=True, verbose_name='标识名')), + ('ipaddr', models.GenericIPAddressField(verbose_name='IP')), + ], + options={ + 'verbose_name_plural': '设备关联IP表', + 'db_table': 'asset_ip', + }, + ), + migrations.CreateModel( + name='Attribute', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='网络属性')), + ], + options={ + 'verbose_name_plural': '网络属性表', + 'db_table': 'asset_attribute', + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='设备类型')), + ], + options={ + 'verbose_name_plural': '设备类型表', + 'db_table': 'asset_category', + }, + ), + migrations.CreateModel( + name='Framework', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True, verbose_name='网络架构')), + ], + options={ + 'verbose_name_plural': '网络架构表', + 'db_table': 'asset_framework', + }, + ), + migrations.CreateModel( + name='Idc', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True, verbose_name='机房名称')), + ('address', models.CharField(default='', max_length=100, verbose_name='机房地址')), + ('tel', models.CharField(default='', max_length=30, verbose_name='机房电话')), + ], + options={ + 'verbose_name_plural': '数据中心表', + 'db_table': 'asset_idc', + }, + ), + migrations.CreateModel( + name='IdcModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='', max_length=30, verbose_name='模块名')), + ('floor', models.CharField(default='', max_length=30, verbose_name='楼层号')), + ('area', models.CharField(default='', max_length=30, verbose_name='区域号')), + ], + options={ + 'verbose_name_plural': '机房模块表', + 'db_table': 'asset_idc_model', + }, + ), + migrations.CreateModel( + name='Model', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='硬件型号')), + ], + options={ + 'verbose_name_plural': '硬件型号表', + 'db_table': 'asset_model', + }, + ), + migrations.CreateModel( + name='NetworkDevice', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('serial_num', models.CharField(max_length=200, unique=True, verbose_name='序列号')), + ('manage_ip', models.GenericIPAddressField(default='0.0.0.0', verbose_name='管理地址')), + ('name', models.CharField(default='', max_length=100, verbose_name='资产名称')), + ('soft_version', models.CharField(default='', max_length=200, verbose_name='软件版本')), + ('patch_version', models.CharField(default='', max_length=200, null=True, verbose_name='补丁版本')), + ('u_location_start', models.IntegerField(default=0, validators=[django.core.validators.MaxValueValidator(50), django.core.validators.MinValueValidator(1)], verbose_name='机架位起始')), + ('u_location_end', models.IntegerField(default=0, validators=[django.core.validators.MaxValueValidator(50), django.core.validators.MinValueValidator(1)], verbose_name='机架位结束')), + ('uptime', models.DateField(default=django.utils.timezone.now, null=True, verbose_name='上线时间')), + ('expire', models.DateField(blank=True, null=True, verbose_name='维保日期')), + ('memo', models.TextField(default='', null=True, verbose_name='备注')), + ('status', models.PositiveSmallIntegerField(choices=[(0, '在线'), (1, '下线'), (2, '挂牌'), (3, '备用')], default=0, verbose_name='状态')), + ('ha_status', models.PositiveSmallIntegerField(choices=[(1, '主设备'), (2, '从设备'), (0, '独立设备')], default=0, verbose_name='HA状态')), + ('chassis', models.IntegerField(default=0, verbose_name='机框编号')), + ('slot', models.IntegerField(default=0, verbose_name='槽位编号')), + ('auto_enable', models.BooleanField(default=True, verbose_name='自动化纳管')), + ], + options={ + 'verbose_name': '网络设备表', + 'verbose_name_plural': '网络设备表', + 'db_table': 'asset_networkdevice', + }, + ), + migrations.CreateModel( + name='NetZone', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='', max_length=20, unique=True, verbose_name='区域名')), + ], + options={ + 'verbose_name_plural': '网络区域表', + 'db_table': 'asset_netzone', + }, + ), + migrations.CreateModel( + name='Rack', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='', max_length=30, verbose_name='机柜编号')), + ('rack_row', models.CharField(default='', max_length=30, verbose_name='机柜排')), + ], + options={ + 'verbose_name_plural': '机柜表', + 'db_table': 'rack', + }, + ), + migrations.CreateModel( + name='Role', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='', max_length=30, unique=True, verbose_name='设备角色')), + ], + options={ + 'verbose_name_plural': '设备角色表', + 'db_table': 'asset_role', + }, + ), + migrations.CreateModel( + name='Vendor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='供应商')), + ('alias', models.CharField(default='', max_length=30, unique=True, verbose_name='别名')), + ], + options={ + 'verbose_name_plural': '设备供应商表', + 'db_table': 'asset_vendor', + }, + ), + migrations.AddIndex( + model_name='vendor', + index=models.Index(fields=['name'], name='asset_vendo_name_1285d0_idx'), + ), + migrations.AddIndex( + model_name='role', + index=models.Index(fields=['name'], name='asset_role_name_69d477_idx'), + ), + migrations.AddField( + model_name='rack', + name='idc_model', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='asset.idcmodel', verbose_name='关联模块'), + ), + migrations.AddIndex( + model_name='netzone', + index=models.Index(fields=['name'], name='asset_netzo_name_c26a83_idx'), + ), + migrations.AddField( + model_name='networkdevice', + name='account', + field=models.ManyToManyField(blank=True, to='asset.AssetAccount', verbose_name='管理账户'), + ), + migrations.AddField( + model_name='networkdevice', + name='attribute', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attribute_asset', to='asset.attribute', verbose_name='网络属性'), + ), + migrations.AddField( + model_name='networkdevice', + name='category', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='category_asset', to='asset.category', verbose_name='设备类型'), + ), + migrations.AddField( + model_name='networkdevice', + name='framework', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='framework_asset', to='asset.framework', verbose_name='网络架构'), + ), + migrations.AddField( + model_name='networkdevice', + name='idc', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='idc_asset', to='asset.idc', verbose_name='所属机房'), + ), + migrations.AddField( + model_name='networkdevice', + name='idc_model', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='idc_model_asset', to='asset.idcmodel', verbose_name='模块'), + ), + migrations.AddField( + model_name='networkdevice', + name='model', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='model_asset', to='asset.model', verbose_name='硬件型号'), + ), + migrations.AddField( + model_name='networkdevice', + name='plan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='releate_device', to='automation.collectionplan', verbose_name='采集方案'), + ), + migrations.AddField( + model_name='networkdevice', + name='rack', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rack_asset', to='asset.rack', verbose_name='机柜编号'), + ), + migrations.AddField( + model_name='networkdevice', + name='role', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='role_asset', to='asset.role', verbose_name='设备角色'), + ), + migrations.AddField( + model_name='networkdevice', + name='vendor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='vendor_asset', to='asset.vendor', verbose_name='供应商'), + ), + migrations.AddField( + model_name='networkdevice', + name='zone', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='zone_asset', to='asset.netzone', verbose_name='网络区域'), + ), + migrations.AddField( + model_name='model', + name='vendor', + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='asset.vendor', verbose_name='供应商'), + ), + migrations.AddField( + model_name='idcmodel', + name='idc', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='asset.idc', verbose_name='所属机房'), + ), + migrations.AddIndex( + model_name='idc', + index=models.Index(fields=['name'], name='asset_idc_name_187da9_idx'), + ), + migrations.AddIndex( + model_name='framework', + index=models.Index(fields=['name'], name='asset_frame_name_7528f7_idx'), + ), + migrations.AddIndex( + model_name='category', + index=models.Index(fields=['name'], name='asset_categ_name_cb6153_idx'), + ), + migrations.AddIndex( + model_name='attribute', + index=models.Index(fields=['name'], name='asset_attri_name_5328a7_idx'), + ), + migrations.AddField( + model_name='assetipinfo', + name='device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bind_ip', to='asset.networkdevice', verbose_name='关联设备'), + ), + migrations.AddIndex( + model_name='assetaccount', + index=models.Index(fields=['name'], name='asset_accou_name_5b4ba2_idx'), + ), + migrations.AddField( + model_name='adminrecord', + name='admin_login_user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='admin_record', to=settings.AUTH_USER_MODEL, verbose_name='用户'), + ), + migrations.AddIndex( + model_name='rack', + index=models.Index(fields=['name'], name='rack_name_2a7200_idx'), + ), + migrations.AlterUniqueTogether( + name='rack', + unique_together={('name', 'idc_model')}, + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['manage_ip'], name='asset_netwo_manage__7c873a_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['serial_num'], name='asset_netwo_serial__f349e5_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['name'], name='asset_netwo_name_7b8151_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['soft_version'], name='asset_netwo_soft_ve_f5cb8c_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['patch_version'], name='asset_netwo_patch_v_6b2281_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['uptime'], name='asset_netwo_uptime_da13a6_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['expire'], name='asset_netwo_expire_587d66_idx'), + ), + migrations.AddIndex( + model_name='networkdevice', + index=models.Index(fields=['status'], name='asset_netwo_status_a07fec_idx'), + ), + migrations.AlterUniqueTogether( + name='networkdevice', + unique_together={('rack', 'u_location_start', 'u_location_end')}, + ), + migrations.AlterIndexTogether( + name='networkdevice', + index_together={('manage_ip', 'name')}, + ), + migrations.AddIndex( + model_name='model', + index=models.Index(fields=['name'], name='asset_model_name_c7c498_idx'), + ), + migrations.AlterUniqueTogether( + name='model', + unique_together={('name', 'vendor')}, + ), + migrations.AddIndex( + model_name='idcmodel', + index=models.Index(fields=['name'], name='asset_idc_m_name_570a3b_idx'), + ), + migrations.AlterUniqueTogether( + name='idcmodel', + unique_together={('name', 'idc')}, + ), + migrations.AddIndex( + model_name='assetipinfo', + index=models.Index(fields=['name'], name='asset_ip_name_6c7b10_idx'), + ), + migrations.AlterUniqueTogether( + name='assetipinfo', + unique_together={('name', 'device')}, + ), + ] diff --git a/netaxe/apps/asset/migrations/0002_historicalnetworkdevice.py b/netaxe/apps/asset/migrations/0002_historicalnetworkdevice.py new file mode 100644 index 0000000000000000000000000000000000000000..8c61934e5873e584e20ea5ea3cef6bf83897005f --- /dev/null +++ b/netaxe/apps/asset/migrations/0002_historicalnetworkdevice.py @@ -0,0 +1,64 @@ +# Generated by Django 3.2.17 on 2023-02-27 15:53 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('automation', '__first__'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('asset', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalNetworkDevice', + fields=[ + ('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('serial_num', models.CharField(db_index=True, max_length=200, verbose_name='序列号')), + ('manage_ip', models.GenericIPAddressField(default='0.0.0.0', verbose_name='管理地址')), + ('name', models.CharField(default='', max_length=100, verbose_name='资产名称')), + ('soft_version', models.CharField(default='', max_length=200, verbose_name='软件版本')), + ('patch_version', models.CharField(default='', max_length=200, null=True, verbose_name='补丁版本')), + ('u_location_start', models.IntegerField(default=0, validators=[django.core.validators.MaxValueValidator(50), django.core.validators.MinValueValidator(1)], verbose_name='机架位起始')), + ('u_location_end', models.IntegerField(default=0, validators=[django.core.validators.MaxValueValidator(50), django.core.validators.MinValueValidator(1)], verbose_name='机架位结束')), + ('uptime', models.DateField(default=django.utils.timezone.now, null=True, verbose_name='上线时间')), + ('expire', models.DateField(blank=True, null=True, verbose_name='维保日期')), + ('memo', models.TextField(default='', null=True, verbose_name='备注')), + ('status', models.PositiveSmallIntegerField(choices=[(0, '在线'), (1, '下线'), (2, '挂牌'), (3, '备用')], default=0, verbose_name='状态')), + ('ha_status', models.PositiveSmallIntegerField(choices=[(1, '主设备'), (2, '从设备'), (0, '独立设备')], default=0, verbose_name='HA状态')), + ('chassis', models.IntegerField(default=0, verbose_name='机框编号')), + ('slot', models.IntegerField(default=0, verbose_name='槽位编号')), + ('auto_enable', models.BooleanField(default=True, verbose_name='自动化纳管')), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField(db_index=True)), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('attribute', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.attribute', verbose_name='网络属性')), + ('category', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.category', verbose_name='设备类型')), + ('framework', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.framework', verbose_name='网络架构')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('idc', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.idc', verbose_name='所属机房')), + ('idc_model', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.idcmodel', verbose_name='模块')), + ('model', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.model', verbose_name='硬件型号')), + ('plan', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='automation.collectionplan', verbose_name='采集方案')), + ('rack', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.rack', verbose_name='机柜编号')), + ('role', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.role', verbose_name='设备角色')), + ('vendor', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.vendor', verbose_name='供应商')), + ('zone', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='asset.netzone', verbose_name='网络区域')), + ], + options={ + 'verbose_name': 'historical 网络设备表', + 'verbose_name_plural': 'historical 网络设备表', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': ('history_date', 'history_id'), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/README.rst b/netaxe/apps/asset/migrations/__init__.py similarity index 100% rename from README.rst rename to netaxe/apps/asset/migrations/__init__.py diff --git a/netaxe/apps/asset/models.py b/netaxe/apps/asset/models.py index b9650f6d18215ca371c39c47b8e014a5ce75ce1b..b5fe2b2a6e8e984f8d8f39bfe76f8d46cf135c7b 100644 --- a/netaxe/apps/asset/models.py +++ b/netaxe/apps/asset/models.py @@ -2,6 +2,7 @@ from django.db import models from django.core.validators import MaxValueValidator, MinValueValidator from django.utils import timezone from utils.crypt_pwd import CryptPwd +from simple_history.models import HistoricalRecords # Create your models here. @@ -420,6 +421,7 @@ class NetworkDevice(models.Model): plan = models.ForeignKey("automation.CollectionPlan", verbose_name='采集方案', blank=True, null=True, related_name='releate_device', on_delete=models.SET_NULL) # bgbu = models.ManyToManyField("users.BgBu", verbose_name='BGBU', blank=True) + history = HistoricalRecords() def __str__(self): return '{}_{}_{}'.format(self.manage_ip, self.name, self.idc.name) diff --git a/netaxe/apps/asset/views.py b/netaxe/apps/asset/views.py index 1e92443b8309ce54af1c0536034088204733117c..bb775e89844c1911c8c84ee0ec715dfdf83a6bd1 100644 --- a/netaxe/apps/asset/views.py +++ b/netaxe/apps/asset/views.py @@ -7,7 +7,6 @@ from django.views import View from django.http import JsonResponse, FileResponse, Http404 from django_filters.rest_framework import DjangoFilterBackend from rest_framework.views import APIView -from rest_framework_tracking.mixins import LoggingMixin from rest_framework import viewsets, permissions, filters from netboost.settings import MEDIA_ROOT @@ -368,11 +367,10 @@ class NetworkDeviceFilter(django_filters.FilterSet): fields = '__all__' -class NetworkDeviceViewSet(LoggingMixin, viewsets.ModelViewSet): +class NetworkDeviceViewSet(viewsets.ModelViewSet): """ 处理 GET POST , 处理 /api/post// GET PUT PATCH DELETE """ - logging_methods = ['POST', 'PUT', 'PATCH', 'DELETE'] queryset = NetworkDevice.objects.all().order_by('-id') queryset = NetworkDeviceSerializer.setup_eager_loading(queryset) serializer_class = NetworkDeviceSerializer @@ -417,30 +415,3 @@ class NetworkDeviceViewSet(LoggingMixin, viewsets.ModelViewSet): print('更新', super().update(request, *args, **kwargs)) return super().update(request, *args, **kwargs) - # 拼接log记录中data字段前后变化 - def handle_log(self): - # Do some stuff before saving. - print('before', self.log['data']) - # print(self.request) - if self.request.POST.get('serial_num'): - # print('PUT记录写入') - for key in self.request.POST.keys(): - if key == 'serial_num': - continue - self.log['data'][key] += " => " + str(self.request.POST[key]) - self.log['data'].pop('serial_num') - if self.log['data'].get('id'): - self.log['data'].pop('id') - if self.log['view_method'] == 'create': - tmp = json.loads(self.log['response']) - if isinstance(tmp['data'], dict): - if 'id' in tmp['data'].keys(): - self.log['path'] += str(tmp['data']['id']) + '/' - elif self.request.data.get('serial_num'): - print('PATCH记录写入') - for key in self.request.data.keys(): - if key == 'serial_num': - continue - self.log['data'][key] += " => " + str(self.request.data[key]) - self.log['data'].pop('serial_num') - super(NetworkDeviceViewSet, self).handle_log() diff --git a/netaxe/apps/automation/views.py b/netaxe/apps/automation/views.py index e5320ab24c313dc4181a5f36ebd34d6a1fb0dc94..fd3df25a89206bea55abcf6605197057fac7a620 100644 --- a/netaxe/apps/automation/views.py +++ b/netaxe/apps/automation/views.py @@ -1,7 +1,6 @@ import django_filters from django_filters.rest_framework import DjangoFilterBackend -from rest_framework_tracking.mixins import LoggingMixin from rest_framework import viewsets, permissions, filters, pagination from apps.route_backend.views import LimitSet @@ -23,11 +22,10 @@ class CollectionPlanFilter(django_filters.FilterSet): fields = '__all__' -class CollectionPlanViewSet(LoggingMixin, CustomViewBase): +class CollectionPlanViewSet(CustomViewBase): """ 处理 GET POST , 处理 /api/post// GET PUT PATCH DELETE """ - logging_methods = ['POST', 'PUT', 'PATCH', 'DELETE'] queryset = CollectionPlan.objects.all().order_by('-id') queryset = CollectionPlanSerializer.setup_eager_loading(queryset) serializer_class = CollectionPlanSerializer diff --git a/netaxe/apps/config_center/migrations/0001_initial.py b/netaxe/apps/config_center/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..2edc2c54fb8d9065b3f7303ab0248ead30b60bbd --- /dev/null +++ b/netaxe/apps/config_center/migrations/0001_initial.py @@ -0,0 +1,93 @@ +# Generated by Django 3.2.15 on 2022-11-08 10:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ConfigCompliance', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True, verbose_name='名称')), + ('vendor', models.CharField(choices=[('H3C', 'H3C'), ('Huawei', 'Huawei'), ('Cisco', 'Cisco')], default='H3C', max_length=50, verbose_name='厂商')), + ('category', models.CharField(choices=[('switch', 'switch'), ('firewall', 'firewall'), ('router', 'router')], default='交换机', max_length=50, verbose_name='类型')), + ('pattern', models.CharField(choices=[('match-compliance', 'match-compliance'), ('mismatch-compliance', 'mismatch-compliance')], default='match-compliance', max_length=50, verbose_name='模式')), + ('regex', models.TextField(default='', verbose_name='表达式')), + ('is_repair', models.BooleanField(default=False, verbose_name='是否修正')), + ('repair_cmds', models.TextField(default='', verbose_name='修复命令')), + ('datetime', models.DateTimeField(auto_now=True, verbose_name='创建日期')), + ], + options={ + 'verbose_name': '配置合规表', + 'verbose_name_plural': '配置合规表', + 'db_table': 'config_compliance', + }, + ), + migrations.CreateModel( + name='ConfigTemplate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vendor', models.CharField(choices=[('H3C', 'H3C'), ('HUAWEI', 'HUAWEI'), ('CISCO', 'CISCO'), ('Ruijie', 'Ruijie'), ('Hillstone', 'Hillstone')], default='H3C', max_length=100, verbose_name='厂商')), + ('name', models.CharField(max_length=100, unique=True, verbose_name='配置项名称')), + ('config_yaml', models.TextField(blank=True, default='', verbose_name='yaml内容')), + ('config_jinja2', models.TextField(blank=True, default='', verbose_name='jinja2内容')), + ('config_text', models.TextField(blank=True, default='', verbose_name='配置命令')), + ('datetime', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ], + options={ + 'verbose_name': '配置片段表', + 'verbose_name_plural': '配置片段表', + 'db_table': 'config_template', + }, + ), + migrations.CreateModel( + name='TTPTemplate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vendor', models.CharField(choices=[('H3C', 'H3C'), ('HUAWEI', 'HUAWEI'), ('CISCO', 'CISCO'), ('Ruijie', 'Ruijie'), ('Hillstone', 'Hillstone')], default='H3C', max_length=100, verbose_name='厂商')), + ('name', models.CharField(max_length=100, unique=True, verbose_name='名称')), + ('ttp_content', models.TextField(blank=True, default='', verbose_name='模板内容')), + ('datetime', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ], + options={ + 'verbose_name': '配置片段表', + 'verbose_name_plural': '配置片段表', + 'db_table': 'ttp_template', + }, + ), + migrations.AddIndex( + model_name='ttptemplate', + index=models.Index(fields=['name', 'vendor'], name='ttp_templat_name_1944b9_idx'), + ), + migrations.AlterUniqueTogether( + name='ttptemplate', + unique_together={('vendor', 'name')}, + ), + migrations.AddIndex( + model_name='configtemplate', + index=models.Index(fields=['name', 'vendor'], name='config_temp_name_09cec8_idx'), + ), + migrations.AlterUniqueTogether( + name='configtemplate', + unique_together={('vendor', 'name')}, + ), + migrations.AddIndex( + model_name='configcompliance', + index=models.Index(fields=['vendor'], name='config_comp_vendor_292331_idx'), + ), + migrations.AddIndex( + model_name='configcompliance', + index=models.Index(fields=['category'], name='config_comp_categor_4829f4_idx'), + ), + migrations.AddIndex( + model_name='configcompliance', + index=models.Index(fields=['datetime'], name='config_comp_datetim_5e0126_idx'), + ), + ] diff --git a/netaxe/apps/config_center/migrations/0002_auto_20230227_1057.py b/netaxe/apps/config_center/migrations/0002_auto_20230227_1057.py new file mode 100644 index 0000000000000000000000000000000000000000..47d6837fcaed11342711e28b50ac53b7a3483905 --- /dev/null +++ b/netaxe/apps/config_center/migrations/0002_auto_20230227_1057.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.17 on 2023-02-27 10:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('config_center', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='configtemplate', + name='vendor', + field=models.CharField(choices=[('H3C', 'H3C'), ('HUAWEI', 'HUAWEI'), ('Cisco_ios', 'Cisco_ios'), ('Ruijie', 'Ruijie'), ('Hillstone', 'Hillstone')], default='H3C', max_length=100, verbose_name='厂商'), + ), + migrations.AlterField( + model_name='ttptemplate', + name='vendor', + field=models.CharField(choices=[('H3C', 'H3C'), ('HUAWEI', 'HUAWEI'), ('Cisco_ios', 'Cisco_ios'), ('Ruijie', 'Ruijie'), ('Hillstone', 'Hillstone')], default='H3C', max_length=100, verbose_name='厂商'), + ), + ] diff --git a/index.rst b/netaxe/apps/config_center/migrations/__init__.py similarity index 100% rename from index.rst rename to netaxe/apps/config_center/migrations/__init__.py diff --git a/netaxe/apps/open_ipam/migrations/0001_initial.py b/netaxe/apps/open_ipam/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..a6d3747db5f2a69a11acdc7867f5682f353a9528 --- /dev/null +++ b/netaxe/apps/open_ipam/migrations/0001_initial.py @@ -0,0 +1,92 @@ +# Generated by Django 3.2.17 on 2023-02-27 10:57 + +import cidrfield.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='TagsModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('bg_color', models.CharField(blank=True, max_length=100, verbose_name='bg_color')), + ('compress', models.CharField(blank=True, max_length=100, verbose_name='compress')), + ('fg_color', models.CharField(blank=True, max_length=100, verbose_name='fgcolor')), + ('locked', models.CharField(blank=True, max_length=100, verbose_name='locked')), + ('type', models.CharField(blank=True, max_length=100, verbose_name='type')), + ('show_tag', models.BooleanField(verbose_name='showtag')), + ], + options={ + 'verbose_name': '网络地址标签表', + 'verbose_name_plural': '网络地址标签表', + 'db_table': 'ipam_tags', + }, + ), + migrations.CreateModel( + name='Subnet', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('subnet_id', models.IntegerField(default=0, verbose_name='网段ID')), + ('name', models.CharField(db_index=True, max_length=100, verbose_name='名称')), + ('subnet', cidrfield.models.IPNetworkField(db_index=True, unique=True, verbose_name='子网段')), + ('mask', models.IntegerField(default=24, verbose_name='掩码')), + ('freehosts_percent', models.FloatField(blank=True, default=0, null=True, verbose_name='空闲率')), + ('description', models.CharField(blank=True, max_length=300, null=True, verbose_name='描述')), + ('master_subnet', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_subnet_set', to='open_ipam.subnet', verbose_name='上一级子网段')), + ], + options={ + 'verbose_name': '子网网段表', + 'verbose_name_plural': '子网网段表', + 'db_table': 'ipam_subnet', + 'ordering': ['subnet'], + }, + ), + migrations.CreateModel( + name='IpAddress', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ip_address', models.GenericIPAddressField(unique=True, verbose_name='IP地址')), + ('description', models.CharField(blank=True, max_length=500, null=True, verbose_name='描述信息')), + ('tag', models.PositiveSmallIntegerField(choices=[(1, '空闲'), (2, '已分配已使用'), (3, '保留'), (4, '未分配已使用'), (6, '已分配未使用'), (7, '自定义空闲')], default=1, verbose_name='状态标签')), + ('editDate', models.DateField(auto_now=True, null=True, verbose_name='编辑时间')), + ('lastScan', models.DateField(auto_now=True, null=True)), + ('lastDiscovery', models.DateField(auto_now=True, null=True)), + ('lastOnlineTime', models.DateField(auto_now=True, null=True, verbose_name='最近在线时间')), + ('subnet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='open_ipam.subnet', verbose_name='归属子网段')), + ], + options={ + 'verbose_name': '网络地址表', + 'verbose_name_plural': '网络地址表', + 'db_table': 'ipam_ip_address', + 'ordering': ['ip_address'], + }, + ), + migrations.AddIndex( + model_name='subnet', + index=models.Index(fields=['subnet'], name='subnet_idx'), + ), + migrations.AddIndex( + model_name='subnet', + index=models.Index(fields=['name'], name='name'), + ), + migrations.AddIndex( + model_name='ipaddress', + index=models.Index(fields=['ip_address'], name='ipam_ip_add_ip_addr_20df1b_idx'), + ), + migrations.AddIndex( + model_name='ipaddress', + index=models.Index(fields=['description'], name='ipam_ip_add_descrip_ad47a9_idx'), + ), + migrations.AddIndex( + model_name='ipaddress', + index=models.Index(fields=['lastOnlineTime'], name='ipam_ip_add_lastOnl_d2352c_idx'), + ), + ] diff --git a/netaxe/apps/open_ipam/views.py b/netaxe/apps/open_ipam/views.py index ed14d8b74a8fd4fcc21f032e90a5bbf05638cffd..3bb3a76ed6574d0aaed7ebed64ad32e79496f7ec 100644 --- a/netaxe/apps/open_ipam/views.py +++ b/netaxe/apps/open_ipam/views.py @@ -363,7 +363,7 @@ class IpAmHandelView(APIView): return JsonResponse(res, safe=True) if description: - Subnet.objects.update(description=description) + Subnet.objects.filter(id=subnet_id).update(description=description) res = {'message': '网段描述更新成功', 'code': 200, } return JsonResponse(res, safe=True) diff --git a/netaxe/apps/topology/__init__.py b/netaxe/apps/topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/netaxe/apps/topology/admin.py b/netaxe/apps/topology/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..7a814b4324ba49eae2c8a20145021613bb4e87ad --- /dev/null +++ b/netaxe/apps/topology/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin +from .models import Topology +# Register your models here. + + +class AdminTopology(admin.ModelAdmin): + """拓扑图总表""" + list_display = ['name', 'bgbu_list'] + search_fields = ['name', 'bgbu_list'] + + +admin.site.register(Topology, AdminTopology) \ No newline at end of file diff --git a/netaxe/apps/topology/apps.py b/netaxe/apps/topology/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..762bfcbfb47172bf8a78e9cb1c310a3415e75bad --- /dev/null +++ b/netaxe/apps/topology/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TopologyConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.topology' diff --git a/netaxe/apps/topology/icon_manage.py b/netaxe/apps/topology/icon_manage.py new file mode 100644 index 0000000000000000000000000000000000000000..34a5dd43ea6f4890d0677627c85a1bc2e3746793 --- /dev/null +++ b/netaxe/apps/topology/icon_manage.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +""" +------------------------------------------------- + File Name: icon_manage + Description: + Author: Lijiamin + date: 2022/11/21 20:19 +------------------------------------------------- + Change Activity: + 2022/11/21 20:19 +------------------------------------------------- +""" +from pathlib import Path + +from netboost.settings import BASE_DIR + +ICON_PATH = BASE_DIR + '/media/topology/img/' + + +class IconTree: + def __init__(self): + self.tree_data = {} + self.tree_final = [] + self.pathname = Path(BASE_DIR + '/media/topology/img/') + self.tree_str = '' + self.key = 0 + self.root_path = 'img/' + + def _second_path(self, root_name, pathname): + # self.tree_data[root_name]['children'] = [] + self.key += 1 + data = { + 'id': self.key, + 'key': root_name + '/' + pathname.name, + # 'children': [], + 'label': pathname.name, + } + if pathname.is_dir(): + data['children'] = [] + for cp in pathname.iterdir(): + self.key += 1 + if cp.name.endswith('.png'): + sub_data = { + 'id': self.key, + 'key': data['key'] + cp.name, + 'label': cp.name, + } + data['children'].append(sub_data) + self.tree_data[root_name]['children'].append(data) + + def root_tree(self): + black_list = ['.git', '__pycache__', 'favicon.ico', '.DS_Store', 'background.css'] + # 遍历根目录下所有文件 + for root in self.pathname.iterdir(): + if root.name not in black_list: + self.key += 1 + data = { + 'id': self.key, + 'key': root.name, + # 'children': [], + 'label': root.name, + } + self.tree_data[root.name] = data + if root.is_dir(): + self.tree_data[root.name]['children'] = [] + for cp in root.iterdir(): + if cp.name.endswith('.png'): + self._second_path(root.name, cp) + + def produce_tree(self): + self.root_tree() + self.tree_final = [self.tree_data[k] for k in self.tree_data.keys()] diff --git a/netaxe/apps/topology/migrations/0001_initial.py b/netaxe/apps/topology/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..25b09dcfae0b939cc103ca82cb0601e542572e36 --- /dev/null +++ b/netaxe/apps/topology/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.17 on 2023-02-27 20:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0002_userprofile_jwt_secret'), + ] + + operations = [ + migrations.CreateModel( + name='Topology', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True, verbose_name='名称')), + ('memo', models.TextField(blank=True, null=True, verbose_name='描述')), + ('bgbu', models.ManyToManyField(blank=True, related_name='bgbu_topology_group', to='users.BgBu', verbose_name='关联业务')), + ], + options={ + 'verbose_name_plural': '拓扑表', + 'db_table': 'topology', + }, + ), + migrations.AddIndex( + model_name='topology', + index=models.Index(fields=['name'], name='topology_name_89fd82_idx'), + ), + ] diff --git a/netaxe/apps/topology/migrations/__init__.py b/netaxe/apps/topology/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/netaxe/apps/topology/models.py b/netaxe/apps/topology/models.py new file mode 100644 index 0000000000000000000000000000000000000000..4fc93d6e5732484532e59686049793e47ba1ef73 --- /dev/null +++ b/netaxe/apps/topology/models.py @@ -0,0 +1,43 @@ +from django.db import models +# import mongoengine +# Create your models here. +# from django.core.exceptions import ValidationError +# from django.core.validators import MaxValueValidator, MinValueValidator +""" +------------------------------------------------- + Description: Topology + Author: jmli12 + date: 2021/12/17 + Soft: PyCharm + CodeStyle: PEP8 + +------------------------------------------------- + Change Activity: + +------------------------------------------------- +""" + + +class Topology(models.Model): + """ + 拓扑表 + Topology + """ + name = models.CharField( + verbose_name='名称', + max_length=50, + null=False, + unique=True) + bgbu = models.ManyToManyField("users.BgBu", verbose_name='关联业务', blank=True, related_name='bgbu_topology_group') + memo = models.TextField(verbose_name='描述', null=True, blank=True) + + def bgbu_list(self): + return ','.join([i.name for i in self.bgbu.all()]) + + def __str__(self): + return self.name + + class Meta: + verbose_name_plural = '拓扑表' + db_table = 'topology' # 通过db_table自定义数据表名 + indexes = [models.Index(fields=['name'])] \ No newline at end of file diff --git a/netaxe/apps/topology/serializers.py b/netaxe/apps/topology/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..293141b5c7559f2d8387332e065ccb6ac569c7fd --- /dev/null +++ b/netaxe/apps/topology/serializers.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +""" +------------------------------------------------- + File Name: serializers + Description: + Author: Lijiamin + date: 2023/2/27 20:24 +------------------------------------------------- + Change Activity: + 2023/2/27 20:24 +------------------------------------------------- +""" +import json +from rest_framework import serializers +from .models import Topology + + +# bgbu field +class BgBuField(serializers.StringRelatedField): + + def to_internal_value(self, value): + # print(value, type(value)) + # value = value[1:-1] + value = json.loads(value) + # print('解码后', value, type(value)) + # print(value, type(value)) + if isinstance(value, list): + return value + else: + raise serializers.ValidationError("BGBU with name: %s not found" % value) + + +# 拓扑表 +class TopologySerializer(serializers.ModelSerializer): + add_datetime = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S') + bgbu = BgBuField(many=True) + + class Meta: + model = Topology + fields = '__all__' + + def create(self, validated_data): + """ + 重写 create + """ + bgbu = validated_data.get('bgbu') + validated_data.pop('bgbu') + instance = Topology.objects.create(**validated_data) + if bgbu: + if isinstance(bgbu[0], list) and instance: + dev_obj = Topology.objects.get(id=instance.id) + dev_obj.bgbu.set(bgbu[0]) + return instance + + def update(self, instance, validated_data): + """ + 重写 update + """ + instance.name = validated_data.get('name', instance.name) + instance.memo = validated_data.get('memo', instance.memo) + instance.save() + bgbu = validated_data.get('bgbu', instance.bgbu) + if bgbu: + if isinstance(bgbu[0], list): + dev_obj = Topology.objects.get(id=instance.id) + # dev_obj.bgbu.clear() + dev_obj.bgbu.set(bgbu[0]) + return instance \ No newline at end of file diff --git a/netaxe/apps/topology/tasks.py b/netaxe/apps/topology/tasks.py new file mode 100644 index 0000000000000000000000000000000000000000..60a4d33ad76048a97e1c74fe3e9823582fdf94d1 --- /dev/null +++ b/netaxe/apps/topology/tasks.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +# @Time : 2021/12/21 16:02 +# @Author : jmli12 +# @Site : +# @File : tasks.py +# @Software: PyCharm +# redis-json more : https://github.com/RedisJSON/redisjson-py + +from __future__ import absolute_import, unicode_literals +import math +from apps.topology.models import Topology +from utils.db.mongo_ops import MongoOps, MongoNetOps + +# import json + +# graph_mongo = MongoOps(db='Topology', coll='graph') +lldp_mongo = MongoOps(db='Automation', coll='LLDPTable') +interface_mongo = MongoOps(db='Automation', coll='layer2interface') +layer3int_mongo = MongoOps(db='Automation', coll='layer3interface') +cmdb_mongo = MongoOps(db='XunMiData', coll='networkdevice') +lagg_mongo = MongoOps(db='Automation', coll='AggreTable') + + +# 拓扑数据生成 +class TopologyTask: + def __init__(self, name): + # 初始化待处理的数据模型 + self.topology = Topology.objects.get(name=name) + self.host_q = MongoNetOps.get_topology(self.topology.name) + self.NODE_HIERARCHY = [ + ('^.*.AS..*', "1", "AC.png"), + ('^.*.AR..*', "4", "L3.png") + ] + self.speed_map = { + "1G": 1, + "10G": 10, + "25G": 25, + "40G": 40, + "100G": 100, + } + + # 获取拓扑 + def get_graph(self): + return MongoNetOps.get_topology(self.topology.name) + + # 删除拓扑 + def del_graph(self): + self.topology.delete() + MongoNetOps.del_topology(self.topology.name) + return + + # 保存拓扑 + def save_graph(self, obj): + MongoNetOps.topology_ops(**obj) + + # 根据设备IP和接口返回接口速率 + def foo_speed(self, hostip, interface_name): + tmp = interface_mongo.find(query_dict={"hostip": hostip, "interface": interface_name}, fileds={"_id": 0}) + speed = tmp[0]['speed'] if tmp else '1G' + return self.speed_map[speed] if speed in self.speed_map.keys() else 1 + + # 根据IP 和接口返回当前接口三层IP信息 + def foo_layer3_ip(self, hostip, interface_name): + tmp = layer3int_mongo.find(query_dict={"hostip": hostip, "interface": interface_name}, fileds={"_id": 0}) + # 如果没有IP,则查询是否聚合口,再查聚合口IP + if not tmp: + tmp_1 = lagg_mongo.find(query_dict={"hostip": hostip, "memberports": {"$in": [interface_name]}}, + fileds={"_id": 0, "aggregroup": 1}) + if tmp: + aggre_interface = tmp_1[0]['aggregroup'] + tmp_2 = layer3int_mongo.find(query_dict={"hostip": hostip, "interface": aggre_interface}, + fileds={"_id": 0}) + if tmp_2: + return aggre_interface + ' ' + tmp_2[0]['ipaddress'] + '/' + tmp_2[0]['ipmask'] if tmp else '' + # print('tmp', tmp) + try: + return tmp[0]['ipaddress'] + '/' + tmp[0]['ipmask'] if tmp else '' + except Exception as e: + return tmp[0]['ipaddress'] + '/32' + + # 生成连线 + def foo_link(self, nodes, manual_links, strict=True): + """ + { + "highest_utilization": 0, + "source": "B3.MG.OB.DS.X01S", + "source_interfaces": [ + "Ten-GigabitEthernet1/0/1" + ], + "source_interfaces_indes": [ + 1 + ], + "speed": "10", + "target": "B3.MG.OB.AS.G12A", + "target_interfaces": [ + "Ten-GigabitEthernet1/0/52", + "Ten-GigabitEthernet1/0/51" + ], + "target_interfaces_indes": [ + 52, + 51 + ] + }, + :return: + """ + + # 排除重复连线 + def is_duplicate(links): + tmp_result = [] + for a in links: + source = a['source_manage_ip'] + a['source_interfaces'] + target = a['target_manage_ip'] + a['target_interfaces'] + # 正向和反向都去重 + if source + '-' + target not in [x['name'] for x in tmp_result] \ + and target + '-' + source not in [x['name'] for x in tmp_result]: + a['name'] = source + '-' + target + tmp_result.append(a) + # 节点信息补充多条连线信息 需要验证测试两个节点的数据 + # 计算两个节点之间的连线总数 + # 假设到这一步,已经不存在A-B B-A的重复连线数据 + result = [] # 最终数据 + for out_link in tmp_result: + # 两个节点之间的连线总数 + out_link['sameTotal'] = 0 + out_link['sameIndex'] = 0 + for in_link in tmp_result: + if in_link['source_manage_ip'] == out_link['source_manage_ip'] and in_link['target_manage_ip'] == \ + out_link['target_manage_ip']: + out_link['sameTotal'] += 1 + tmp_index = [x['sameIndex'] for x in result + if x['source_manage_ip'] == out_link['source_manage_ip'] + and x['target_manage_ip'] == out_link['target_manage_ip']] + if tmp_index: + out_link['sameIndex'] = max(tmp_index) + 1 + else: + out_link['sameIndex'] += 1 + + out_link['sameTotalHalf'] = out_link['sameTotal'] / 2 + out_link['sameUneven'] = True if out_link['sameTotal'] % 2 else False + out_link['sameMiddleLink'] = out_link['sameUneven'] and math.ceil(out_link['sameTotal']) == out_link[ + 'sameIndex'] + out_link['sameLowerHalf'] = out_link['sameIndex'] <= out_link['sameTotalHalf'] + out_link['sameArcDirection'] = 0 if out_link['sameLowerHalf'] else 1 + out_link['sameIndexCorrected'] = out_link['sameIndex'] \ + if out_link['sameLowerHalf'] else out_link['sameIndex'] - math.ceil(out_link['sameTotalHalf']) + result.append(out_link) + return result + + links = [] + # 遍历节点 + for node in nodes: + neighbor_q = lldp_mongo.find(query_dict={"hostip": node['manage_ip']}, fileds={"_id": 0}) + if neighbor_q: + # 遍历节点的LLDP信息 + for _neighbor in neighbor_q: + if strict: # 严格模式 只计算相关 + # 排除自己连接自己 + if _neighbor['neighbor_ip'] == node['manage_ip']: + continue + if _neighbor['neighbor_ip'] in [x['manage_ip'] for x in nodes]: + data = { + "highest_utilization": 0, + "source": node['id'], + "source_manage_ip": node['manage_ip'], + "source_interface_ip": self.foo_layer3_ip(node['manage_ip'], + _neighbor['local_interface']), + "source_interfaces": _neighbor['local_interface'], + "source_interfaces_indes": '', + "speed": self.foo_speed(node['manage_ip'], _neighbor['local_interface']), + "target": _neighbor['neighborsysname'], + "target_manage_ip": _neighbor['neighbor_ip'], + "target_interfaces": _neighbor['neighbor_port'], + "target_interfaces_indes": '', + "target_interface_ip": self.foo_layer3_ip(_neighbor['neighbor_ip'], + _neighbor['neighbor_port']), + "method": "auto" # 自动计算标识 手动添加的连线为 manual + } + links.append(data) + else: # 开放模式 计算不相关 + data = { + "highest_utilization": 0, + "source": node['id'], + "source_manage_ip": node['manage_ip'], + "source_interfaces": '', + "source_interfaces_indes": '', + "speed": self.foo_speed(node['manage_ip'], _neighbor['local_interface']), + "target": _neighbor['neighborsysname'], + "target_manage_ip": _neighbor['neighbor_ip'], + "target_interfaces": _neighbor['neighbor_port'], + "target_interfaces_indes": '', + "method": "auto" # 自动计算标识 手动添加的连线为 manual + } + links.append(data) + return is_duplicate(links + manual_links) + + # 排除重复的设备和接口 + def is_link_duplicate(self, source_ip, source_interface, target_ip, target_interface): + for link in self.host_q['links']: + if source_ip == link['source_manage_ip'] and source_interface == link['source_interfaces']: + return False + elif source_ip == link['target_manage_ip'] and source_interface == link['target_interfaces']: + return False + elif target_ip == link['source_manage_ip'] and target_interface == link['source_interfaces']: + return False + elif target_ip == link['target_manage_ip'] and target_interface == link['target_interfaces']: + return False + return True + + # 增加手动连线 + def add_manual_link(self, source_ip, source_name, source_interface, target_ip, target_name, target_interface): + result = { + "links": self.host_q['links'], + "nodes": self.host_q['nodes'], + "name": self.topology.name, + "cmdb": '', + "interface": [] + } + if self.is_link_duplicate(source_ip, source_interface, target_ip, target_interface): + data = { + "highest_utilization": 0, + "source": source_name, + "source_manage_ip": source_ip, + "source_interface_ip": self.foo_layer3_ip(source_ip, source_interface), + "source_interfaces": source_interface, + "source_interfaces_indes": '', + "speed": self.foo_speed(source_ip, source_interface), + "target": target_name, + "target_manage_ip": target_ip, + "target_interfaces": target_interface, + "target_interfaces_indes": '', + "target_interface_ip": self.foo_layer3_ip(target_ip, target_interface), + "method": "manual" # 自动计算标识 手动添加的连线为 manual + } + result['links'].append(data) + # 严格模式,只匹配相关的连线, strict 用来开关严格模式, strict=False则是开放模式 + result['links'] = self.foo_link(result['nodes'], result['links'], strict=True) + # 存储拓扑计算结果 + MongoNetOps.topology_ops(**result) + return True + return False + + # 本地计算生成拓扑 + def local_graph(self): + # 最终结果格式 + result = { + "links": [], + "nodes": self.host_q['nodes'], + "name": self.topology.name, + "cmdb": '', + "interface": [] + } + # 保留手动连线 + if self.host_q['links']: + for link in self.host_q['links']: + if link['method'] == 'manual': + result['links'].append(link) + # 完善/更新节点信息 + for host in self.host_q['nodes']: + host['image'] = "AC.png" + tmp_info = cmdb_mongo.find(query_dict={"manage_ip": host['manage_ip']}, fileds={"_id": 0}) + if tmp_info: + tmp_info = tmp_info[0] + host['name'] = tmp_info['name'] + host['id'] = tmp_info['name'] + host['device_id'] = tmp_info['id'] + host['serial_num'] = tmp_info['serial_num'] + host['location'] = tmp_info['idc_name'] + '_' + tmp_info['idc_model_name'] + '_' + tmp_info[ + 'rack_name'] + '_' + str(tmp_info['u_location_start']) + '_' + str(tmp_info['u_location_end']) + host['vendor_model'] = tmp_info['vendor_name'] + '_' + tmp_info.get('model_name', ' ') + host['expire'] = tmp_info['expire'] + # tmp_node = { + # "id": host.name, # 设备名 + # "manage_ip": host.host, # 设备IP + # "image": self.hostname_to_image(host.name) # 设备图标 + # } + + result['links'] += self.foo_link(result['nodes'], result['links'], strict=True) + + MongoNetOps.topology_ops(**result) + + self.topology.save() + return result + + # 增加节点 + def add_node(self, add_nodes: list): + # 先把原有的node变成IP为key的列表用于判断是否重复 + node_ip_dict = dict() + if self.host_q is not None and isinstance(self.host_q, dict): + # if 'nodes' in self.host_q.keys(): + node_ip_dict = {x['manage_ip']: x for x in self.host_q['nodes']} + else: + self.host_q = { + "links": [], + "nodes": [], + "name": self.topology.name, + "cmdb": '', + "interface": [] + } + # 开始添加新节点,并判断去重 + for node in add_nodes: + if node['manage_ip'] not in node_ip_dict.keys(): + self.host_q['nodes'] += [node] + # 重新计算 + self.local_graph() + return + + # 删除节点 + def del_node(self, del_nodes: list): + for del_node in del_nodes: + for node in self.host_q['nodes']: + if del_node['manage_ip'] == node['manage_ip']: + self.host_q['nodes'].remove(node) + # 重新计算 + self.local_graph() + + # 删除连线 只能删除手动连线 + def del_link(self, del_link: dict): + links = [x for x in self.host_q['links'] if x['method'] == 'manual'] + for link in links: + if del_link['source_manage_ip'] == link['source_manage_ip'] \ + and del_link['source_interfaces'] == link['source_interfaces'] \ + and del_link['target_manage_ip'] == link['target_manage_ip'] \ + and del_link['target_interfaces'] == link['target_interfaces']: + self.host_q['links'].remove(link) + # 重新计算 + self.local_graph() + diff --git a/netaxe/apps/topology/tests.py b/netaxe/apps/topology/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/netaxe/apps/topology/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/netaxe/apps/topology/urls.py b/netaxe/apps/topology/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..f09492717dfcec44c476c4af502e3c5a83693aba --- /dev/null +++ b/netaxe/apps/topology/urls.py @@ -0,0 +1,17 @@ +from django.contrib.auth.decorators import login_required +from django.urls import path, include +from rest_framework.routers import DefaultRouter +from .views import * + +app_name = 'topology' +router = DefaultRouter() + + +router.register(r'index', TopologyViewSet) + + +urlpatterns = [ + path(r'', include(router.urls)), + path('show/', TopologyShow.as_view(), name='show'), + path('topology_icon/', IconView.as_view(), name='topology_icon'), +] diff --git a/netaxe/apps/topology/views.py b/netaxe/apps/topology/views.py new file mode 100644 index 0000000000000000000000000000000000000000..96abdc1252ed7864d3bb960519f94553336f2128 --- /dev/null +++ b/netaxe/apps/topology/views.py @@ -0,0 +1,265 @@ +import json +import os +from collections import OrderedDict +from datetime import datetime, date +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage +from django.http import JsonResponse +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework.views import APIView +from rest_framework import viewsets, permissions, filters +from django.shortcuts import render +from django.views import View +from rest_framework.permissions import IsAuthenticated +from rest_framework.views import APIView +from apps.topology.icon_manage import IconTree +from apps.topology.tasks import TopologyTask +from apps.topology.models import Topology +from .serializers import TopologySerializer +from utils.db.mongo_ops import MongoOps, MongoNetOps +from utils.tools.custom_pagination import LargeResultsSetPagination + +# Create your views here. +# 设备二层接口表 +interface_mongo = MongoOps(db='Automation', coll='layer2interface') + +ICON_PATH = 'topology/img/' + + +class DateEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, datetime): + return obj.strftime('%Y-%m-%d %H:%M:%S') + elif isinstance(obj, date): + return obj.strftime("%Y-%m-%d") + else: + return json.JSONEncoder.default(self, obj) + + +# 拓扑清单 +class TopologyViewSet(viewsets.ModelViewSet): + """ + 处理 GET POST , 处理 /api/post// GET PUT PATCH DELETE + """ + queryset = Topology.objects.all().order_by('-id') + # queryset = TopologySerializer.setup_eager_loading(queryset) + serializer_class = TopologySerializer + permission_classes = (permissions.IsAuthenticated,) + # 配置搜索功能 + filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) + filter_fields = '__all__' + pagination_class = LargeResultsSetPagination + + +# 拓扑显示 +class TopologyShow(APIView): + permission_classes = (IsAuthenticated,) + + def get(self, request): + get_param = request.GET.dict() + if get_param.get('graph'): + content = MongoNetOps.get_topology(get_param['graph']) + if content: + return JsonResponse(dict(code=200, data=content, msg='获取拓扑数据成功'), content_type="application/json", + safe=False) + else: + return JsonResponse(dict(code=400, msg='没有拓扑数据'), content_type="application/json", safe=False) + if get_param.get('get_interface_by_manage_ip'): + content = interface_mongo.find(query_dict={"hostip": get_param['get_interface_by_manage_ip']}, + fileds={"_id": 0}) + if content: + return JsonResponse(dict(code=200, data=content, msg='success'), content_type="application/json", + safe=False) + else: + return JsonResponse(dict(code=400, data='没有匹配的数据', msg='success'), content_type="application/json", + safe=False) + + data = { + "code": 400, + "data": [], + "msg": "没有匹配的操作" + } + return JsonResponse(data) + + def post(self, request): + # post_param = request.body + post_param = request.data + # print(post_param, type(post_param)) + # 保存拓扑图 + if all(k in post_param for k in ("name", "graph")): + _TopologyTask = TopologyTask(post_param['name']) + graph_data = post_param['graph'] + # 只有link 连线需要重写source 和 target ,d3.js会把source和target改成对应node的字典格式, 默认给到前端是字符串格式的设备ID + for i in graph_data['links']: + i['target'] = i['target']['id'] + i['source'] = i['source']['id'] + _TopologyTask.save_graph(graph_data) + MongoNetOps.topology_ops(**graph_data) + data = { + "code": 200, + "data": [], + "msg": "保存拓扑图成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + # 新建节点 + if all(k in post_param for k in ("name", "add_nodes")): + _TopologyTask = TopologyTask(post_param['name']) + graph_data = _TopologyTask.get_graph() + if not graph_data: + nodes = post_param['add_nodes'] + result = OrderedDict() + # 多字典合并去重 + for item in nodes: + result.setdefault(item['manage_ip'], {**item}) + result = list(result.values()) + # print(result) + _TopologyTask.add_node(result) + else: + _TopologyTask.add_node(post_param['add_nodes']) + data = { + "code": 200, + "data": [], + "msg": "新建节点成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + # 删除节点 + if all(k in post_param for k in ("name", "del_nodes")): + _TopologyTask = TopologyTask(post_param['name']) + del_nodes = json.loads(post_param['del_nodes']) + _TopologyTask.del_node(del_nodes) + data = { + "code": 200, + "data": [], + "msg": "删除节点成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + # 删除拓扑图 + if all(k in post_param for k in ("name", "del_graph")): + _TopologyTask = TopologyTask(post_param['name']) + _TopologyTask.del_graph() + data = { + "code": 200, + "data": [], + "msg": "删除拓扑图成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + # 增加手动连线 + if all(k in post_param for k in + ("name", "a_name", "b_name", "a_device", "b_device", "a_interface", "b_interface")): + _TopologyTask = TopologyTask(post_param['name']) + tmp = dict(source_ip=post_param['a_device'], + source_name=post_param['a_name'], + source_interface=post_param['a_interface'], + target_ip=post_param['b_device'], + target_name=post_param['b_name'], + target_interface=post_param['b_interface']) + res = _TopologyTask.add_manual_link(**tmp) + if res: + data = { + "code": 200, + "data": [], + "msg": "增加手动连线成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + data = { + "code": 400, + "data": [], + "msg": "增加手动连线失败" + } + return JsonResponse(data, content_type="application/json", safe=False) + # 删除手动连线 + if all(k in post_param for k in ("name", "del_link")): + _TopologyTask = TopologyTask(post_param['name']) + _TopologyTask.del_link(post_param['del_link']) + data = { + "code": 200, + "data": [], + "msg": "删除手动连线成功" + } + return JsonResponse(data, content_type="application/json", safe=False) + # # 修改单个节点信息(比如图标) + # if all(k in post_param for k in ("name", "edit_node")): + # _TopologyTask = TopologyTask(post_param['name']) + # data = { + # "code": 200, + # "data": [], + # "msg": "删除手动连线成功" + # } + # return JsonResponse(data, content_type="application/json", safe=False) + + data = { + "code": 400, + "data": [], + "msg": "删除手动连线失败" + } + return JsonResponse(data, content_type="application/json", safe=False) + + +# 图标库 +class IconView(APIView): + permission_classes = (IsAuthenticated,) + + def get(self, request): + get_param = request.GET.dict() + # print(get_param) + if get_param.get('get_tree'): + _tree = IconTree() + _tree.produce_tree() + res = _tree.tree_final + if res: + return JsonResponse(dict(code=200, data=res, msg='获取图标库成功'), content_type="application/json", + safe=False) + else: + return JsonResponse(dict(code=400, msg='没有数据'), content_type="application/json", safe=False) + data = { + "code": 400, + "data": [], + "msg": "没有匹配的操作" + } + return JsonResponse(data) + + def post(self, request): + post_param = request.data + # print(post_param) + # 新建目录 + if all(k in post_param for k in ("dir_name", "current_path")): + data = { + "code": 400, + "data": [], + "msg": "" + } + if post_param['current_path'] == '/': + # print('根目录新建') + if os.path.exists(ICON_PATH + post_param['dir_name']): + data['msg'] = '已经存在该目录' + else: + os.mkdir(ICON_PATH + post_param['dir_name']) + data['code'] = 200 + data['msg'] = '新建完成' + else: + if os.path.exists(ICON_PATH + post_param['current_path'] + '/' + post_param['dir_name']): + data['msg'] = '已经存在该目录' + else: + os.mkdir(ICON_PATH + post_param['current_path'] + '/' + post_param['dir_name']) + data['code'] = 200 + data['msg'] = '新建完成' + return JsonResponse(data, content_type="application/json", safe=False) + # 上传图标 + if post_param.get('upload_path'): + icons = request.FILES['icons'] + # print(ICON_PATH + post_param['upload_path'] + post_param['filename']) + path = default_storage.save(ICON_PATH + post_param['upload_path'] + '/' + post_param['filename'], + ContentFile(icons.read())) + # print(path) + data = { + "code": 200, + "data": [], + "msg": "上传完成" + } + return JsonResponse(data, content_type="application/json", safe=False) + data = { + "code": 400, + "data": [], + "msg": "没有匹配的动作" + } + return JsonResponse(data, content_type="application/json", safe=False) diff --git a/netaxe/apps/users/migrations/0001_initial.py b/netaxe/apps/users/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..5408d6c22f19ed5bebd3ea1ac79082fbd4ba44af --- /dev/null +++ b/netaxe/apps/users/migrations/0001_initial.py @@ -0,0 +1,73 @@ +# Generated by Django 3.2.17 on 2023-02-21 16:01 + +import django.contrib.auth.models +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='UserProfile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('username', models.CharField(db_index=True, help_text='用户账号', max_length=150, unique=True, verbose_name='用户账号')), + ('nick_name', models.CharField(blank=True, max_length=30, null=True, verbose_name='昵称')), + ('mobile', models.CharField(blank=True, max_length=11, null=True, verbose_name='手机号码')), + ('email', models.EmailField(blank=True, help_text='邮箱', max_length=255, null=True, verbose_name='邮箱')), + ('image', models.ImageField(default='images/default.png', upload_to='images/%Y/%m/%d/')), + ('login_status', models.SmallIntegerField(choices=[(0, '在线'), (1, '离线'), (2, '忙碌')], default=0, verbose_name='登录状态')), + ('gender', models.IntegerField(blank=True, choices=[(0, '未知'), (1, '男'), (2, '女')], default=0, help_text='性别', null=True, verbose_name='性别')), + ('user_type', models.IntegerField(blank=True, choices=[(0, '后台用户'), (1, '前台用户')], default=0, help_text='用户类型', null=True, verbose_name='用户类型')), + ], + options={ + 'verbose_name': '用户表', + 'verbose_name_plural': '用户表', + 'db_table': 'ops_user', + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='BgBu', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=20, unique=True, verbose_name='业务名称')), + ], + options={ + 'verbose_name': '业务表', + 'verbose_name_plural': '业务表', + 'db_table': 'bgbu', + }, + ), + migrations.AddIndex( + model_name='bgbu', + index=models.Index(fields=['name'], name='bgbu_name_7454a1_idx'), + ), + migrations.AddField( + model_name='userprofile', + name='groups', + field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'), + ), + migrations.AddField( + model_name='userprofile', + name='user_permissions', + field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'), + ), + ] diff --git a/netaxe/apps/users/migrations/0002_userprofile_jwt_secret.py b/netaxe/apps/users/migrations/0002_userprofile_jwt_secret.py new file mode 100644 index 0000000000000000000000000000000000000000..ebbb16aa9a1c8f852070d1b385beb87dd36a0ea5 --- /dev/null +++ b/netaxe/apps/users/migrations/0002_userprofile_jwt_secret.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.17 on 2023-02-21 16:01 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='jwt_secret', + field=models.UUIDField(default=uuid.uuid4), + ), + ] diff --git a/netaxe/apps/users/migrations/__init__.py b/netaxe/apps/users/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/netaxe/apps/users/models.py b/netaxe/apps/users/models.py index fa2059022e4228a3c16a608ec2bb71922dcc2740..7208adb9dac28afad9594a4bf3c788be0b1c1c08 100644 --- a/netaxe/apps/users/models.py +++ b/netaxe/apps/users/models.py @@ -1,6 +1,7 @@ import hashlib from django.db import models from django.contrib.auth.models import AbstractUser +import uuid class UserProfile(AbstractUser): @@ -36,6 +37,10 @@ class UserProfile(AbstractUser): user_type = models.IntegerField( choices=USER_TYPE, default=0, verbose_name="用户类型", null=True, blank=True, help_text="用户类型" ) + jwt_secret = models.UUIDField(default=uuid.uuid4) + + def jwt_get_secret_key(self): + return self.jwt_secret # post = models.ManyToManyField( # to="system.Post", blank=True, verbose_name="关联岗位", db_constraint=False, help_text="关联岗位") # role = models.ManyToManyField( diff --git a/netaxe/apps/users/serializers.py b/netaxe/apps/users/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..369fd95e64a5712c60f402eba1d95099da3ca3c0 --- /dev/null +++ b/netaxe/apps/users/serializers.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +""" +------------------------------------------------- + File Name: serializers + Description: + Author: Lijiamin + date: 2023/2/27 20:25 +------------------------------------------------- + Change Activity: + 2023/2/27 20:25 +------------------------------------------------- +""" +import json +from rest_framework import serializers +from .models import BgBu + + +class BgBuSerializer(serializers.ModelSerializer): + """bgbu表,用于运营平台数据对应关系""" + + class Meta: + model = BgBu + fields = ('id', 'name',) + diff --git a/netaxe/apps/users/urls.py b/netaxe/apps/users/urls.py index 79380ee46ff593496bd4cdd08d2de66d77668017..546e8c6019f5f30d6011c1450250eb1f96d775ae 100644 --- a/netaxe/apps/users/urls.py +++ b/netaxe/apps/users/urls.py @@ -1,11 +1,13 @@ from django.urls import path, include -from rest_framework import routers +from rest_framework.routers import SimpleRouter from apps.users.views.user import UserViewSet +from apps.users.views.user import BgBuViewSet -router = routers.SimpleRouter() +router = SimpleRouter() router.register(r'user', UserViewSet) +router.register(r'bgbu', BgBuViewSet) urlpatterns = [ path(r'', include(router.urls)), diff --git a/netaxe/apps/users/views.py b/netaxe/apps/users/views.py deleted file mode 100644 index 60f00ef0ef347811e7b0c0921b7fda097acd9fcc..0000000000000000000000000000000000000000 --- a/netaxe/apps/users/views.py +++ /dev/null @@ -1 +0,0 @@ -# Create your views here. diff --git a/netaxe/apps/users/views/user.py b/netaxe/apps/users/views/user.py index 40363f28770323d79ff68cfe44ebb8024b480dc5..5f79600fe4cd534d7d2857d7ac1c0d71df47e93f 100644 --- a/netaxe/apps/users/views/user.py +++ b/netaxe/apps/users/views/user.py @@ -1,10 +1,12 @@ from django.contrib.auth.hashers import make_password from django_restql.fields import DynamicSerializerMethodField -from rest_framework import serializers +from rest_framework import serializers, permissions, filters, viewsets from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated - -from apps.users.models import UserProfile +from django_filters.rest_framework import DjangoFilterBackend +from utils.tools.custom_pagination import LargeResultsSetPagination +from apps.users.models import UserProfile, BgBu +from apps.users.serializers import BgBuSerializer from apps.system.views.role import RoleSerializer from utils.custom.json_response import ErrorResponse, DetailResponse from utils.custom.serializers import CustomModelSerializer @@ -213,3 +215,19 @@ class UserViewSet(CustomModelViewSet): return DetailResponse(data=None, msg="修改成功") else: return ErrorResponse(msg="未获取到用户") + + +class BgBuViewSet(viewsets.ModelViewSet): + """ + BgBu表---处理 GET POST , 处理 /api/post// GET PUT PATCH DELETE + """ + queryset = BgBu.objects.all().order_by('name') + serializer_class = BgBuSerializer + permission_classes = (permissions.IsAuthenticated,) + # pagination_class = LimitSet + pagination_class = LargeResultsSetPagination + # 配置搜索功能 + filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) + # 如果要允许对某些字段进行过滤,可以使用filter_fields属性。 + # filterset_class = DeviceBackupConfigFilter + filter_fields = '__all__' \ No newline at end of file diff --git a/netaxe/init.sh b/netaxe/init.sh index 4e0fe1d697f4e7a01720c973fe36376d598ef212..d338afd02948c629e1e03d81548fe2b6bf35527a 100644 --- a/netaxe/init.sh +++ b/netaxe/init.sh @@ -44,6 +44,10 @@ python3 manage.py makemigrations rest_framework_tracking python3 manage.py migrate rest_framework_tracking +python3 manage.py makemigrations topology + +python3 manage.py migrate topology + python3 manage.py init_asset # 资产初始化 python3 manage.py init_collect # 采集方案初始化 python3 manage.py init_system_menu # 系统菜单初始化 diff --git a/netaxe/media/topology/img/AC.png b/netaxe/media/topology/img/AC.png new file mode 100644 index 0000000000000000000000000000000000000000..9cf78b7e1ec31722ba4c52674b4c4e6ea723dcde Binary files /dev/null and b/netaxe/media/topology/img/AC.png differ diff --git a/netaxe/media/topology/img/DS.png b/netaxe/media/topology/img/DS.png new file mode 100644 index 0000000000000000000000000000000000000000..3486b04b5ba618f82566f53b79399a8c199bacbc Binary files /dev/null and b/netaxe/media/topology/img/DS.png differ diff --git a/netaxe/media/topology/img/L2.png b/netaxe/media/topology/img/L2.png new file mode 100644 index 0000000000000000000000000000000000000000..db3db274c4874c657490fc0e9167e16416a9891c Binary files /dev/null and b/netaxe/media/topology/img/L2.png differ diff --git a/netaxe/media/topology/img/L3.png b/netaxe/media/topology/img/L3.png new file mode 100644 index 0000000000000000000000000000000000000000..88984ff1bbb63f709aa2c7a2391723ec2fe5ca62 Binary files /dev/null and b/netaxe/media/topology/img/L3.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_mango.svg b/netaxe/media/topology/img/bridge/bridge_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..2a016b1834fe16579a844c313e8d775a61b891b7 --- /dev/null +++ b/netaxe/media/topology/img/bridge/bridge_mango.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/netaxe/media/topology/img/bridge/bridge_mango_large.png b/netaxe/media/topology/img/bridge/bridge_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..472c30808bcd0ed68818589a873e1ce1e55746b5 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_mango_large.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_mango_medium.png b/netaxe/media/topology/img/bridge/bridge_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..c23ef2da0465d8ce4aceb47fc8b91698c5329519 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_mango_medium.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_mango_small.png b/netaxe/media/topology/img/bridge/bridge_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..1cfd871d369248db73f7dc47351c3ddf1ca96aaf Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_mango_small.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_pool.svg b/netaxe/media/topology/img/bridge/bridge_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..be8fd151b586a2f4a80d3602b5f3581740d7ffc3 --- /dev/null +++ b/netaxe/media/topology/img/bridge/bridge_pool.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/netaxe/media/topology/img/bridge/bridge_pool_large.png b/netaxe/media/topology/img/bridge/bridge_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..947e31afc0ab386a637e083afe51015a876de271 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_pool_large.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_pool_medium.png b/netaxe/media/topology/img/bridge/bridge_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..c3ce4891991fe13ff20c3e51405e8df38b047f38 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_pool_medium.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_pool_small.png b/netaxe/media/topology/img/bridge/bridge_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..aacbbf6740d661796eb328bdf271d578b03dcce6 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_pool_small.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_red.svg b/netaxe/media/topology/img/bridge/bridge_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..0fc50c225988c5b6e6937d2f42f0f26735929d25 --- /dev/null +++ b/netaxe/media/topology/img/bridge/bridge_red.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/netaxe/media/topology/img/bridge/bridge_red_large.png b/netaxe/media/topology/img/bridge/bridge_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..cbea19dbfd59630f6bf69c0c1ca282bebfdcb16f Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_red_large.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_red_medium.png b/netaxe/media/topology/img/bridge/bridge_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..70a348c9d8150341e198c9cf31183d9ed31ccac7 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_red_medium.png differ diff --git a/netaxe/media/topology/img/bridge/bridge_red_small.png b/netaxe/media/topology/img/bridge/bridge_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..80002a2a395806a7f5dc87bda65abf1e3d3c3c26 Binary files /dev/null and b/netaxe/media/topology/img/bridge/bridge_red_small.png differ diff --git a/netaxe/media/topology/img/cisco/test.png b/netaxe/media/topology/img/cisco/test.png new file mode 100644 index 0000000000000000000000000000000000000000..a060798b321afddaf538be2cb10d7af14c28dfda Binary files /dev/null and b/netaxe/media/topology/img/cisco/test.png differ diff --git a/netaxe/media/topology/img/default.png b/netaxe/media/topology/img/default.png new file mode 100644 index 0000000000000000000000000000000000000000..6b09ff509ee2b1d434146e70a7293de3d746dd65 Binary files /dev/null and b/netaxe/media/topology/img/default.png differ diff --git a/netaxe/media/topology/img/firewall.png b/netaxe/media/topology/img/firewall.png new file mode 100644 index 0000000000000000000000000000000000000000..6c0567c924d0e8eda2bc9f35f72da414dd42dd9d Binary files /dev/null and b/netaxe/media/topology/img/firewall.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_mango.svg b/netaxe/media/topology/img/firewall/firewall_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..cbf14af07a687f6c86c6cfbe12092e42a84d532b --- /dev/null +++ b/netaxe/media/topology/img/firewall/firewall_mango.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/firewall/firewall_mango_large.png b/netaxe/media/topology/img/firewall/firewall_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..696fb18b342f9cc27d4e0265bcd8c3ffef962f31 Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_mango_large.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_mango_medium.png b/netaxe/media/topology/img/firewall/firewall_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..ac3bdd124687f893cad3b41be2c4697c39839129 Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_mango_medium.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_mango_small.png b/netaxe/media/topology/img/firewall/firewall_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..3d257b1983ba14df97670fc0afaa8e808c50b797 Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_mango_small.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_pool.svg b/netaxe/media/topology/img/firewall/firewall_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..3be3ec9c0a904077a449133f30e11451720dbe29 --- /dev/null +++ b/netaxe/media/topology/img/firewall/firewall_pool.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/firewall/firewall_pool_large.png b/netaxe/media/topology/img/firewall/firewall_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..858e835f54c7e8d1b5dc3ca780a768b4151e34ac Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_pool_large.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_pool_medium.png b/netaxe/media/topology/img/firewall/firewall_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..c44e90b4113c6e87fe0b5af684916c6c8ab4d0dc Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_pool_medium.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_pool_small.png b/netaxe/media/topology/img/firewall/firewall_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..2afe3206259ec37a2830cacab1f8be3a3591535f Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_pool_small.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_red.svg b/netaxe/media/topology/img/firewall/firewall_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..f4369f1f9a225541ba63f49b45a627d3a73f605a --- /dev/null +++ b/netaxe/media/topology/img/firewall/firewall_red.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/firewall/firewall_red_large.png b/netaxe/media/topology/img/firewall/firewall_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..31c6b5aca9f0d88d326b003b6a4420cbcc080d28 Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_red_large.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_red_medium.png b/netaxe/media/topology/img/firewall/firewall_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7a377a1d4a2906ed9a714daa805b4a16d2350e Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_red_medium.png differ diff --git a/netaxe/media/topology/img/firewall/firewall_red_small.png b/netaxe/media/topology/img/firewall/firewall_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..140c5b134bc2557340baca8ca5450901cf91ee7c Binary files /dev/null and b/netaxe/media/topology/img/firewall/firewall_red_small.png differ diff --git a/netaxe/media/topology/img/group4.png b/netaxe/media/topology/img/group4.png new file mode 100644 index 0000000000000000000000000000000000000000..3486b04b5ba618f82566f53b79399a8c199bacbc Binary files /dev/null and b/netaxe/media/topology/img/group4.png differ diff --git a/netaxe/media/topology/img/leaf.png b/netaxe/media/topology/img/leaf.png new file mode 100644 index 0000000000000000000000000000000000000000..20a9f22ffc6a4cc8b1f6802e0e9bf52e56b49eed Binary files /dev/null and b/netaxe/media/topology/img/leaf.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_mango.svg b/netaxe/media/topology/img/load_balancer/load_balancer_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..c6f0059971a5ab5e84bbc934127a9311560e1078 --- /dev/null +++ b/netaxe/media/topology/img/load_balancer/load_balancer_mango.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_mango_large.png b/netaxe/media/topology/img/load_balancer/load_balancer_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..9f1907148c72515607e35ef371f9479b13bac3bc Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_mango_large.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_mango_medium.png b/netaxe/media/topology/img/load_balancer/load_balancer_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..f67b564f38a679a1af421dfe56ed1dc754861413 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_mango_medium.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_mango_small.png b/netaxe/media/topology/img/load_balancer/load_balancer_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..b747b49262b46a934c60dbcb726f7817466445bc Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_mango_small.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_pool.svg b/netaxe/media/topology/img/load_balancer/load_balancer_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..82867520a8bfdc688e9871af00727a8ecf59fede --- /dev/null +++ b/netaxe/media/topology/img/load_balancer/load_balancer_pool.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_pool_large.png b/netaxe/media/topology/img/load_balancer/load_balancer_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..9c76f2c5f66cff921a48cfd0734a246e81653cb8 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_pool_large.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_pool_medium.png b/netaxe/media/topology/img/load_balancer/load_balancer_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..79e632cda8f231c050cc74b58c8852bc9900d9a0 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_pool_medium.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_pool_small.png b/netaxe/media/topology/img/load_balancer/load_balancer_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..389e6a320c478a7e488aba1adf95f158eeb42bbd Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_pool_small.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_red.svg b/netaxe/media/topology/img/load_balancer/load_balancer_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..983840fee7b165dc542c7afd1721d863365865cb --- /dev/null +++ b/netaxe/media/topology/img/load_balancer/load_balancer_red.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_red_large.png b/netaxe/media/topology/img/load_balancer/load_balancer_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..93176d692322efb59100e8929a7f103a67dbd099 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_red_large.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_red_medium.png b/netaxe/media/topology/img/load_balancer/load_balancer_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..de7f753966eff38e90ebb067d701a557ea570bc8 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_red_medium.png differ diff --git a/netaxe/media/topology/img/load_balancer/load_balancer_red_small.png b/netaxe/media/topology/img/load_balancer/load_balancer_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..fb95285c610db0ecb9cf7a7d408a124a50840748 Binary files /dev/null and b/netaxe/media/topology/img/load_balancer/load_balancer_red_small.png differ diff --git a/netaxe/media/topology/img/logo/h3c.png b/netaxe/media/topology/img/logo/h3c.png new file mode 100644 index 0000000000000000000000000000000000000000..ce01685a405b4c01c94abd6943bc46f6f40cb878 Binary files /dev/null and b/netaxe/media/topology/img/logo/h3c.png differ diff --git a/netaxe/media/topology/img/logo/huawei.png b/netaxe/media/topology/img/logo/huawei.png new file mode 100644 index 0000000000000000000000000000000000000000..735c9ceb7aa91c8df0479c4366d3849fa12c1b79 Binary files /dev/null and b/netaxe/media/topology/img/logo/huawei.png differ diff --git a/netaxe/media/topology/img/routers/router_mango.svg b/netaxe/media/topology/img/routers/router_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..d97d743a5311eb5cfe203416c8305fd4eb3f210f --- /dev/null +++ b/netaxe/media/topology/img/routers/router_mango.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/routers/router_mango_large.png b/netaxe/media/topology/img/routers/router_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..1d88f7de4ee15b5e3f7745f9e691c9e275a20748 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_mango_large.png differ diff --git a/netaxe/media/topology/img/routers/router_mango_medium.png b/netaxe/media/topology/img/routers/router_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..8df3065ee4b3d36c6babc07b46bebf19b87ed846 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_mango_medium.png differ diff --git a/netaxe/media/topology/img/routers/router_mango_small.png b/netaxe/media/topology/img/routers/router_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..937d4397f405955fe683d3efe69b58b97a8fcf36 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_mango_small.png differ diff --git a/netaxe/media/topology/img/routers/router_pool.svg b/netaxe/media/topology/img/routers/router_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..2fffe7e878cf09e85e88df47610aa6fcf5a53070 --- /dev/null +++ b/netaxe/media/topology/img/routers/router_pool.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/routers/router_pool_large.png b/netaxe/media/topology/img/routers/router_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..a2b8b24b3fc5fb25ce51ec8f1d8422373fe3bc88 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_pool_large.png differ diff --git a/netaxe/media/topology/img/routers/router_pool_medium.png b/netaxe/media/topology/img/routers/router_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..593c81f2f04cbbddbc8db4f057695820e24cc475 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_pool_medium.png differ diff --git a/netaxe/media/topology/img/routers/router_pool_small.png b/netaxe/media/topology/img/routers/router_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..145c9ae3f08ad11f95ad185521bd875e69922aa3 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_pool_small.png differ diff --git a/netaxe/media/topology/img/routers/router_red.svg b/netaxe/media/topology/img/routers/router_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..9e167c429752e9d27e79326c0e73ae6662ee7028 --- /dev/null +++ b/netaxe/media/topology/img/routers/router_red.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/routers/router_red_large.png b/netaxe/media/topology/img/routers/router_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..9fdc4d0386963754f4ac63e27e20bf72106b30ca Binary files /dev/null and b/netaxe/media/topology/img/routers/router_red_large.png differ diff --git a/netaxe/media/topology/img/routers/router_red_medium.png b/netaxe/media/topology/img/routers/router_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2ee92bbd033e53a2f16e1b0b0a1eede1c69dec Binary files /dev/null and b/netaxe/media/topology/img/routers/router_red_medium.png differ diff --git a/netaxe/media/topology/img/routers/router_red_small.png b/netaxe/media/topology/img/routers/router_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..1fdc4f0e37aad1b8e48e1a9445f6c1d40a0e3b06 Binary files /dev/null and b/netaxe/media/topology/img/routers/router_red_small.png differ diff --git a/netaxe/media/topology/img/servers/server_mango.svg b/netaxe/media/topology/img/servers/server_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..95b68dc362a741a7ccdbbe9c6c142d94d15fa309 --- /dev/null +++ b/netaxe/media/topology/img/servers/server_mango.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/servers/server_pool.svg b/netaxe/media/topology/img/servers/server_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..5b998035d0d3bd05da80bf6e356a6ea2bbd4c6cf --- /dev/null +++ b/netaxe/media/topology/img/servers/server_pool.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/servers/server_rack_mango.svg b/netaxe/media/topology/img/servers/server_rack_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..499dfc5b5edad1fb4f1cbf49e52d21cce5b2708a --- /dev/null +++ b/netaxe/media/topology/img/servers/server_rack_mango.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/servers/server_rack_mango_large.png b/netaxe/media/topology/img/servers/server_rack_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..12379723d115ce8bcdf0a90f97841ca447530b7c Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_mango_large.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_mango_medium.png b/netaxe/media/topology/img/servers/server_rack_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..43014613fb87ba547702422a08fa0806ac492c4f Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_mango_medium.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_mango_small.png b/netaxe/media/topology/img/servers/server_rack_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..c79849d2733baa73d7d99506d9ed2da0f929e343 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_mango_small.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_pool.svg b/netaxe/media/topology/img/servers/server_rack_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..3f19fcd6460b5566f97355fc321273bee2efafa6 --- /dev/null +++ b/netaxe/media/topology/img/servers/server_rack_pool.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/servers/server_rack_pool_large.png b/netaxe/media/topology/img/servers/server_rack_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..f147e121ff44e942be7d7427f95d47ee22924dc8 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_pool_large.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_pool_medium.png b/netaxe/media/topology/img/servers/server_rack_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2c17c233e4f4e178fb4b1610192542ba17042f Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_pool_medium.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_pool_small.png b/netaxe/media/topology/img/servers/server_rack_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..fcf379f0b953ceeed371c751616d30d4be1a5763 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_pool_small.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_red.svg b/netaxe/media/topology/img/servers/server_rack_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..6aa9870754267b70ddbb58a7094a8622eee94cfd --- /dev/null +++ b/netaxe/media/topology/img/servers/server_rack_red.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/servers/server_rack_red_large.png b/netaxe/media/topology/img/servers/server_rack_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..734f114ca0a38d24569f91dac94d541a968d1a50 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_red_large.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_red_medium.png b/netaxe/media/topology/img/servers/server_rack_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..05892cb5b6f29d67721002391cf980cefef0dde4 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_red_medium.png differ diff --git a/netaxe/media/topology/img/servers/server_rack_red_small.png b/netaxe/media/topology/img/servers/server_rack_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..0c4ca938ab1986ffe81323b94de6a45099419429 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_rack_red_small.png differ diff --git a/netaxe/media/topology/img/servers/server_red.png b/netaxe/media/topology/img/servers/server_red.png new file mode 100644 index 0000000000000000000000000000000000000000..a55137c84c9dd87f64e0575540a59c187d57eac7 Binary files /dev/null and b/netaxe/media/topology/img/servers/server_red.png differ diff --git a/netaxe/media/topology/img/servers/server_red.svg b/netaxe/media/topology/img/servers/server_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..aed1dcdb0de0f703ef56c3d8f1b7403c89f89f08 --- /dev/null +++ b/netaxe/media/topology/img/servers/server_red.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/netaxe/media/topology/img/spine.png b/netaxe/media/topology/img/spine.png new file mode 100644 index 0000000000000000000000000000000000000000..9ba053ab81cc58b9280fe9e484c5a6091b9190c7 Binary files /dev/null and b/netaxe/media/topology/img/spine.png differ diff --git a/netaxe/media/topology/img/switches/switch_mango.svg b/netaxe/media/topology/img/switches/switch_mango.svg new file mode 100644 index 0000000000000000000000000000000000000000..4149f9cb6e207208d57be96f7a0b349ca8653f04 --- /dev/null +++ b/netaxe/media/topology/img/switches/switch_mango.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/switches/switch_mango_large.png b/netaxe/media/topology/img/switches/switch_mango_large.png new file mode 100644 index 0000000000000000000000000000000000000000..28775cd0775614cf1971cbaf2dd7cf46beb1f70a Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_mango_large.png differ diff --git a/netaxe/media/topology/img/switches/switch_mango_medium.png b/netaxe/media/topology/img/switches/switch_mango_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..454bdbcd8e384a5f70a214be58eab8baf4fef780 Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_mango_medium.png differ diff --git a/netaxe/media/topology/img/switches/switch_mango_small.png b/netaxe/media/topology/img/switches/switch_mango_small.png new file mode 100644 index 0000000000000000000000000000000000000000..9ba053ab81cc58b9280fe9e484c5a6091b9190c7 Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_mango_small.png differ diff --git a/netaxe/media/topology/img/switches/switch_pool.svg b/netaxe/media/topology/img/switches/switch_pool.svg new file mode 100644 index 0000000000000000000000000000000000000000..cabf1103a3335d827b3969365ef20c27516a7078 --- /dev/null +++ b/netaxe/media/topology/img/switches/switch_pool.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/switches/switch_pool_large.png b/netaxe/media/topology/img/switches/switch_pool_large.png new file mode 100644 index 0000000000000000000000000000000000000000..69ef94060114437b38b45e0f77eb92520b85792e Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_pool_large.png differ diff --git a/netaxe/media/topology/img/switches/switch_pool_medium.png b/netaxe/media/topology/img/switches/switch_pool_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..5bffbc90131fc40fa82fc6eb46756423164d3aac Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_pool_medium.png differ diff --git a/netaxe/media/topology/img/switches/switch_pool_small.png b/netaxe/media/topology/img/switches/switch_pool_small.png new file mode 100644 index 0000000000000000000000000000000000000000..20a9f22ffc6a4cc8b1f6802e0e9bf52e56b49eed Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_pool_small.png differ diff --git a/netaxe/media/topology/img/switches/switch_red.svg b/netaxe/media/topology/img/switches/switch_red.svg new file mode 100644 index 0000000000000000000000000000000000000000..bc7179856b3d6b994bc717c02658f29114efbbca --- /dev/null +++ b/netaxe/media/topology/img/switches/switch_red.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/netaxe/media/topology/img/switches/switch_red_large.png b/netaxe/media/topology/img/switches/switch_red_large.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c10603a82cf7dd5d585dc547b6143debd8731d Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_red_large.png differ diff --git a/netaxe/media/topology/img/switches/switch_red_medium.png b/netaxe/media/topology/img/switches/switch_red_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..b2943701806a85e7a29315a653c6d999b44e8873 Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_red_medium.png differ diff --git a/netaxe/media/topology/img/switches/switch_red_small.png b/netaxe/media/topology/img/switches/switch_red_small.png new file mode 100644 index 0000000000000000000000000000000000000000..e2a842fabf8acee6601f701858f33c16c2d80691 Binary files /dev/null and b/netaxe/media/topology/img/switches/switch_red_small.png differ diff --git a/netaxe/media/topology/img/test.png b/netaxe/media/topology/img/test.png new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/netaxe/media/topology/img/tor/Ansible-Networking-Switches-01.png b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-01.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc9037e7237ae4e3590504034b6bc8a7d527840 Binary files /dev/null and b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-01.png differ diff --git a/netaxe/media/topology/img/tor/Ansible-Networking-Switches-02.png b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-02.png new file mode 100644 index 0000000000000000000000000000000000000000..cba8d4ef489b5d4c0968eeb85cddeae8e66111ca Binary files /dev/null and b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-02.png differ diff --git a/netaxe/media/topology/img/tor/Ansible-Networking-Switches-03.png b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-03.png new file mode 100644 index 0000000000000000000000000000000000000000..cdfaa1caefe9ee3350f8c33cb1b1635b56a64232 Binary files /dev/null and b/netaxe/media/topology/img/tor/Ansible-Networking-Switches-03.png differ diff --git a/netaxe/netboost/settings.py b/netaxe/netboost/settings.py index 0402f344b7f904c3a1677116e474f41923a1b0d0..3f0670c09e06b7dffbe46852e12e0329624c40a8 100644 --- a/netaxe/netboost/settings.py +++ b/netaxe/netboost/settings.py @@ -54,13 +54,13 @@ INSTALLED_APPS = [ "django_celery_beat", "django_celery_results.apps.CeleryResultConfig", "rest_framework", - "rest_framework_tracking", + "simple_history", + # "rest_framework_tracking", # "rest_framework.authtoken", # "rest_framework.apps.RestFrameworkConfig", - "apps.users.apps.UsersConfig", "apps.system.apps.SystemConfig", - + "apps.topology.apps.TopologyConfig", "apps.asset.apps.AssetConfig", "apps.automation.apps.AutomationConfig", "apps.config_center.apps.ConfigCenterConfig", @@ -127,7 +127,6 @@ AUTH_USER_MODEL = "users.UserProfile" # Internationalization # https://docs.djangoproject.com/en/4.0/topics/i18n/ -# LANGUAGE_CODE = "en-us" LANGUAGE_CODE = "zh-hans" TIME_ZONE = "Asia/Shanghai" @@ -276,9 +275,13 @@ STATICFILES_FINDERS = ( DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # simple jwt 设置 SIMPLE_JWT = { - "ACCESS_TOKEN_LIFETIME": timedelta(days=1), # access token 有效期 30分钟 - "REFRESH_TOKEN_LIFETIME": timedelta(days=2), # refresh token 有效期 2 天 + "ACCESS_TOKEN_LIFETIME": timedelta(hours=1), # access token 有效期 30分钟 + "REFRESH_TOKEN_LIFETIME": timedelta(days=1), # refresh token 有效期 2 天 "ROTATE_REFRESH_TOKENS": True, + 'ALGORITHM': 'HS256', + 'SIGNING_KEY': SECRET_KEY, + 'VERIFYING_KEY': None, + 'AUTH_HEADER_TYPES': ('Bearer',), } # restful api 配置 @@ -298,7 +301,7 @@ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( # "rest_framework.authentication.BasicAuthentication", # "rest_framework.authentication.SessionAuthentication", - "rest_framework.authentication.TokenAuthentication", + # "rest_framework.authentication.TokenAuthentication", "rest_framework_simplejwt.authentication.JWTAuthentication", # "apps.api.authentication.ExpiringTokenAuthentication", ), @@ -347,7 +350,8 @@ CACHES = { # 认证配置 AUTHENTICATION_BACKENDS = ( # "django_auth_ldap.backend.LDAPBackend", - "utils.custom.backends.CustomBackend", + # "utils.custom.backends.CustomBackend", + "django.contrib.auth.backends.ModelBackend", "guardian.backends.ObjectPermissionBackend", # 这是guardian的 ) diff --git a/netaxe/netboost/urls.py b/netaxe/netboost/urls.py index 4750889319fd84f9ab8e06ad584839b4a0aa22ae..9a372dde912711be79bd6e01a7cd6c24b4d3b595 100644 --- a/netaxe/netboost/urls.py +++ b/netaxe/netboost/urls.py @@ -63,4 +63,5 @@ urlpatterns = [ path(r'api/config_center/', include('apps.config_center.urls')), path(r'api/int_utilization/', include('apps.int_utilization.urls')), path(r'api/open_ipam/', include('apps.open_ipam.urls')), + path(r'api/topology/', include('apps.topology.urls')), ] diff --git a/netaxe/requirements.txt b/netaxe/requirements.txt index cbbbcd9d82f0c8dcdd6bbeda9842cff75143c001..940745aa673596c34a31b8641bd6a950fa471ba1 100644 --- a/netaxe/requirements.txt +++ b/netaxe/requirements.txt @@ -87,8 +87,6 @@ wrapt==1.14.1 zipp==3.8.0 zope.interface==5.4.0 pymongo==3.10.1 -# rest api 日志记录模块 -drf-api-tracking==1.8.0 xmltodict==0.13.0 requests==2.28.1 pycryptodome==3.15.0 @@ -119,4 +117,5 @@ django-restql==0.15.2 user-agents==2.2.0 drf-yasg==1.21.4 xlrd==1.2.0 - +django-restql==0.15.2 +django-simple-history==3.2.0 diff --git a/netaxe/utils/custom/exception.py b/netaxe/utils/custom/exception.py index fb867d649566baa93d7dac5a13d9e948ac850bf7..227ddfdb291754a3c5f22adc41e81e2a71fffe59 100644 --- a/netaxe/utils/custom/exception.py +++ b/netaxe/utils/custom/exception.py @@ -1,9 +1,6 @@ # -*- coding: utf-8 -*- """ -@author: 猿小天 -@contact: QQ:1638245306 -@Created on: 2021/6/2 002 16:06 @Remark: 自定义异常处理 """ import logging diff --git a/netaxe/utils/custom/nacos.py b/netaxe/utils/custom/nacos.py index 2cd8f0634293d045710211d15a2f62e739bf7ed8..79884e97be18c0caa391752313e278a52111e19e 100644 --- a/netaxe/utils/custom/nacos.py +++ b/netaxe/utils/custom/nacos.py @@ -3,13 +3,13 @@ import urllib import logging import hashlib import threading -import requests,time +import requests, time logger = logging.getLogger('server') class nacos: - def __init__(self,ip="127.0.0.1",port=8848): + def __init__(self, ip="127.0.0.1", port=8848): self.ip = ip self.port = port self.__registerDict = {} @@ -17,7 +17,7 @@ class nacos: def __healthyCheckThreadRun(self): while True: - #检查registerThread + # 检查registerThread try: time.sleep(5) serviceIp = self.__registerDict["serviceIp"] @@ -30,20 +30,22 @@ class nacos: metadata = self.__registerDict["metadata"] weight = self.__registerDict["weight"] enabled = self.__registerDict["enabled"] - self.registerService(serviceIp,servicePort,serviceName, - namespaceId,groupName,clusterName, - ephemeral,metadata,weight,enabled) + self.registerService(serviceIp, servicePort, serviceName, + namespaceId, groupName, clusterName, + ephemeral, metadata, weight, enabled) except: - logging.exception("服务注册心跳进程健康检查失败",exc_info=True) + logging.exception("服务注册心跳进程健康检查失败", exc_info=True) def healthyCheck(self): t = threading.Thread(target=self.__healthyCheckThreadRun) t.start() logging.info("健康检查线程已启动") - def registerService(self,serviceIp,servicePort,serviceName,namespaceId="public", - groupName="DEFAULT_GROUP",clusterName="DEFAULT", - ephemeral=True,metadata={},weight=1,enabled=True): + def registerService(self, serviceIp, servicePort, serviceName, namespaceId="public", + groupName="DEFAULT_GROUP", clusterName="DEFAULT", + ephemeral=True, metadata=None, weight=1, enabled=True): + if metadata is None: + metadata = {} self.__registerDict["serviceIp"] = serviceIp self.__registerDict["servicePort"] = servicePort self.__registerDict["serviceName"] = serviceName @@ -56,7 +58,6 @@ class nacos: self.__registerDict["enabled"] = enabled self.__registerDict["healthy"] = int(time.time()) - registerUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/ns/instance" params = { "ip": serviceIp, @@ -72,14 +73,29 @@ class nacos: } try: re = requests.post(registerUrl, params=params) - if (re.text == "ok"): + if re.text == "ok": logging.info("服务注册成功。") else: - logging.error("服务注册失败 "+re.text) + logging.error("服务注册失败 " + re.text) except: - logging.exception("服务注册失败",exc_info=True) + logging.exception("服务注册失败", exc_info=True) + def fallbackFun(): return "request Error" + + def timeOutFun(): - return "request time out" \ No newline at end of file + return "request time out" + + +# class NacosManage: +# def __init__(self, server_addr,name_space, data_id, group): +# self.SERVER_ADDRESS = server_addr +# self.NAMESPACE = name_space +# self.data_id = data_id +# self.group = group +# +# def getNacosConf(self): +# try: +# client = nacos.NacosClietn \ No newline at end of file diff --git a/netaxe/utils/db/mongo_ops.py b/netaxe/utils/db/mongo_ops.py index b6dfec4decbfb131f4e259c1c4241de2d165996a..ed9a358989f7f3fa03934d8c5b6e9e24940f11ae 100644 --- a/netaxe/utils/db/mongo_ops.py +++ b/netaxe/utils/db/mongo_ops.py @@ -270,9 +270,32 @@ class MongoOps: xunmi_mongo = MongoOps(db='netops', coll='XunMi') lagg_mongo = MongoOps(db='Automation', coll='AggreTable') compliance_mongo = MongoOps(db='Automation', coll='ConfigCompliance') +topology_mongo = MongoOps(db='Automation', coll='topology') class MongoNetOps(object): + @staticmethod + def del_topology(name): + topology_mongo.delete_many(query={'name': name}) + return + + @staticmethod + def get_topology(name): + _query = topology_mongo.find(query_dict={'name': name}, fileds={'_id': 0}) + if _query: + return _query[0] + return [] + + @staticmethod + def topology_ops(**data): + _query = topology_mongo.find(query_dict={'name': data['name']}, fileds={'_id': 0}) + if _query: + topology_mongo.delete_many(query={'name': data['name']}) + topology_mongo.insert(data) + else: + topology_mongo.insert(data) + return + @staticmethod def compliance_result(**kwargs): res = compliance_mongo.find(query_dict=kwargs, fileds={'_id': 0}) diff --git a/netaxe/utils/init_system_menu.json b/netaxe/utils/init_system_menu.json index 867ba76631f557c2b751b3de026ce63119bbd0f1..78015b91612407e298714db07a0cb863431ddb9c 100644 --- a/netaxe/utils/init_system_menu.json +++ b/netaxe/utils/init_system_menu.json @@ -143,6 +143,33 @@ "web_path": "/task_center/task_list", "sort": 2, "id": 10021 + }, + { + "name": "拓扑管理", + "status": "True", + "parent_id": null, + "visible": "True", + "web_path": "/net_topology", + "sort": 6, + "id": 20006 + }, + { + "name": "拓扑展示", + "status": "True", + "parent_id": 20006, + "visible": "True", + "web_path": "/net_topology/show", + "sort": 1, + "id": 20011 + }, + { + "name": "图标库", + "status": "True", + "parent_id": 20006, + "visible": "True", + "web_path": "/net_topology/topology_icon", + "sort": 2, + "id": 20012 } ] } \ No newline at end of file diff --git a/web/README.md b/web/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f2a81e246a2b05c052d4a21f9607dcedfe88d939 100644 --- a/web/README.md +++ b/web/README.md @@ -0,0 +1 @@ +NetAxe 前端模块 diff --git a/web/index.html b/web/index.html index 99cc008e9cf9e3e4269cdc4a3d9f6b94f00d4460..a7d1375d2b144b44081cf53a277358ae6176ebf9 100644 --- a/web/index.html +++ b/web/index.html @@ -6,10 +6,10 @@ - Net-axe + NetAxe
@@ -24,7 +24,7 @@
-
Net-Axe
+
NetAxe
diff --git a/web/nginx.conf b/web/nginx.conf index 2cdb5b80cf71df492ae64b6e04e8eb88cddc2300..12f45c17dcdd2f948d1465a14d65cfda9a8e2766 100644 --- a/web/nginx.conf +++ b/web/nginx.conf @@ -24,7 +24,9 @@ server { location /ipam { proxy_pass http://apisix:9080/ipam; } - + # location /media { + # proxy_pass http://apisix:9080/media; + # } # location /api { # proxy_pass http://netaxe-nginx:9999/api; # } diff --git a/web/src/api/url.ts b/web/src/api/url.ts index 3c99bc3d378401623555b53596c69e0c94ccc047..36db3d8b8fa337c51deab9b81a82dfc02c804f48 100644 --- a/web/src/api/url.ts +++ b/web/src/api/url.ts @@ -11,25 +11,28 @@ export const getMenuList = '/api/system/menu/' export const getDepartmentList = '/api/system/dept/' export const getMenuListByRole = '/api/system/menu/web_router/' -// export const test = '/test' -// export const BackendApi = '/api/' -// export const captcha = '/net_backend/captcha' -// export const device_import_template = '/api/asset/excel/' // 调度管理 export const getdispach = '/api/backend/dispatch_page/' // 任务列表 export const jobcenterTaskUrl = '/api/backend/jobCenter/' -// 未知 +// 网络设备 export const get_device_expand = '/api/backend/networklist/' +// 采集方案 export const deviceCollect = '/api/backend/deviceCollect/' -// 未知 -export const networkDeviceUrl = '/api/backend/networkDevice/' +// webssh export const deviceWebSshLogin = '/api/backend/deviceWebSsh/' export const automation_chart = '/api/backend/automationChart/' // 未知 export const deviceInfoChange = '/api/backend/deviceInfoChange/' export const getperiodic_taskList = '/api/backend/periodic_task/' -// 未知 +// 拓扑图 +export const get_topology = '/api/topology/index/' +export const topology_show = '/api/topology/show/' +export const topology_media_img = '/media/topology/img/' +export const topology_icon = '/api/topology/topology_icon/' +// 获取业务对应表 +export const getBgbuList = '/api/users/bgbu/' +// 获取变更路径(废弃ing) export const get_api_request_log = '/api/backend/api_request_log/' export const getinterval_schedule = '/api/backend/interval_schedule/' diff --git a/web/src/assets/logo.png b/web/src/assets/logo.png index 450eab97f01b0fbe2e43980b3228829cd6127ffc..76d42e8b8b3d5b5670380d85762913ac580c9105 100644 Binary files a/web/src/assets/logo.png and b/web/src/assets/logo.png differ diff --git a/web/src/components/footer/index.vue b/web/src/components/footer/index.vue index 3bdf776a958d7051240ff01d784a8497ea57b569..62ffeb2a2495094a2b2460579832a4fb760435de 100644 --- a/web/src/components/footer/index.vue +++ b/web/src/components/footer/index.vue @@ -1,5 +1,5 @@ diff --git a/web/src/views/ip_manage/ipam.vue b/web/src/views/ip_manage/ipam.vue index 5efc9d1eb0e829f8229f5d00851fa442d10b8c4a..4456b48c89b9b5e5a376d6508f7361d2c50c96a3 100644 --- a/web/src/views/ip_manage/ipam.vue +++ b/web/src/views/ip_manage/ipam.vue @@ -4,32 +4,30 @@ - + 搜索 清除
导出网段 - + >导出网段 + 新增网段 - + >新增网段 + @@ -39,13 +37,14 @@
详情
-
因ipv6网段地址较多,下图仅展示单次请求结果数据-可滚动查询下一分页 +
因ipv6网段地址较多,下图仅展示单次请求结果数据-可滚动查询下一分页
@@ -70,7 +69,7 @@ {{ subnet_info.desc }} - +
@@ -106,73 +105,67 @@
{{ ip_info.address }}
- -
@@ -180,61 +173,54 @@ @@ -245,19 +231,19 @@ 选中网段即为父节点网段,若需要新建一级网段则需要选择空白处 - + @@ -276,19 +262,19 @@ - + @@ -306,16 +292,16 @@ @@ -324,759 +310,691 @@ \ No newline at end of file + .roll_div { + height: calc(100% - 191px); + padding: 10px 24px; + position: relative; + background-color: #fbfcfe; + overflow-y: auto; + } + + .bold-attribute { + font-weight: bold; + padding-right: 5px; + } + + .used { + background-color: #409eff; + } + + .reserved { + background: #22dd22; + } + + .dist_and_used { + /*已分配已使用*/ + background: #e6b600; + } + + .not_dist_and_used { + /*未分配已使用*/ + background: #1695c4; + } + + .free { + background-color: #67c23a; + } + + .empty { + background-color: #f4f4f4; + } + + .dist_and_not_used { + background-color: #11eec2; + } + + .custom_empty { + background: #f4f4f4; + } + + .chart-item { + //height: 500px; + width: 400px; + //padding-left:300px; + //padding-top: 30px; + height: 300px; + } + + .button_border { + border: 1px solid black; + } + diff --git a/web/src/views/login/LoginComponent.vue b/web/src/views/login/LoginComponent.vue index 927cfbfdc75ad931036f1945946251d4d8bfa85f..cd7ba96969244d625ebe04f9772508c9e6bb6f62 100644 --- a/web/src/views/login/LoginComponent.vue +++ b/web/src/views/login/LoginComponent.vue @@ -1,397 +1,399 @@ diff --git a/web/src/views/net_topology/show.vue b/web/src/views/net_topology/show.vue new file mode 100644 index 0000000000000000000000000000000000000000..f96ea8af30313cea697a789bf40c92434f054ed3 --- /dev/null +++ b/web/src/views/net_topology/show.vue @@ -0,0 +1,1658 @@ + + + diff --git a/web/src/views/net_topology/topology_icon.vue b/web/src/views/net_topology/topology_icon.vue new file mode 100644 index 0000000000000000000000000000000000000000..5928768e552ac89a14833dd66cf8da254c06158f --- /dev/null +++ b/web/src/views/net_topology/topology_icon.vue @@ -0,0 +1,273 @@ + + + + diff --git a/web/vite.config.ts b/web/vite.config.ts index b1b3fd7384004e0abdfb90a115240cef33b368cc..66fce2a7a7758c5eea994405d28ec5bbbd17a8e6 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -48,6 +48,12 @@ export default ({ mode }) => { changeOrigin: true, // 虚拟的站点需要更管origin rewrite: (path: string) => path.replace(/^\/ipam/, '/ipam'), }, + '/media': { + target: env.VITE_BASIC_URL, + ws: true, //代理websockets + changeOrigin: true, // 虚拟的站点需要更管origin + rewrite: (path: string) => path.replace(/^\/media/, '/media'), + }, '/ws': { target: env.VITE_BASIC_URL, timeout: 60000,