diff --git a/apps/assets/api/asset/__init__.py b/apps/assets/api/asset/__init__.py index 0f1d81825..75c314df7 100644 --- a/apps/assets/api/asset/__init__.py +++ b/apps/assets/api/asset/__init__.py @@ -3,6 +3,7 @@ from .cloud import * from .custom import * from .database import * from .device import * +from .gpt import * from .host import * from .permission import * from .web import * diff --git a/apps/assets/api/asset/gpt.py b/apps/assets/api/asset/gpt.py new file mode 100644 index 000000000..ef9953a41 --- /dev/null +++ b/apps/assets/api/asset/gpt.py @@ -0,0 +1,16 @@ +from assets.models import GPT, Asset +from assets.serializers import GPTSerializer + +from .asset import AssetViewSet + +__all__ = ['GPTViewSet'] + + +class GPTViewSet(AssetViewSet): + model = GPT + perm_model = Asset + + def get_serializer_classes(self): + serializer_classes = super().get_serializer_classes() + serializer_classes['default'] = GPTSerializer + return serializer_classes diff --git a/apps/assets/const/category.py b/apps/assets/const/category.py index 8c4d387d8..9ccbb134e 100644 --- a/apps/assets/const/category.py +++ b/apps/assets/const/category.py @@ -12,6 +12,7 @@ class Category(ChoicesMixin, models.TextChoices): DATABASE = 'database', _("Database") CLOUD = 'cloud', _("Cloud service") WEB = 'web', _("Web") + GPT = 'gpt', "GPT" CUSTOM = 'custom', _("Custom type") @classmethod diff --git a/apps/assets/const/gpt.py b/apps/assets/const/gpt.py new file mode 100644 index 000000000..6a51dd3d6 --- /dev/null +++ b/apps/assets/const/gpt.py @@ -0,0 +1,54 @@ +from django.utils.translation import gettext_lazy as _ + +from .base import BaseType + + +class GPTTypes(BaseType): + CHATGPT = 'chatgpt', _('ChatGPT') + + @classmethod + def _get_base_constrains(cls) -> dict: + return { + '*': { + 'charset_enabled': False, + 'domain_enabled': False, + 'su_enabled': False, + } + } + + @classmethod + def _get_automation_constrains(cls) -> dict: + constrains = { + '*': { + 'ansible_enabled': False, + 'ping_enabled': False, + 'gather_facts_enabled': False, + 'verify_account_enabled': False, + 'change_secret_enabled': False, + 'push_account_enabled': False, + 'gather_accounts_enabled': False, + } + } + return constrains + + @classmethod + def _get_protocol_constrains(cls) -> dict: + return { + '*': { + 'choices': ['http'], + } + } + + @classmethod + def internal_platforms(cls): + return { + cls.CHATGPT: [ + {'name': 'ChatGPT'} + ], + } + + @classmethod + def get_community_types(cls): + return [ + cls.CHATGPT, + ] diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index e66dde209..be0dec4f2 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -26,6 +26,8 @@ class Protocol(ChoicesMixin, models.TextChoices): k8s = 'k8s', 'K8S' http = 'http', 'HTTP(s)' + chatgpt = 'chatgpt', 'ChatGPT' + @classmethod def device_protocols(cls): return { @@ -154,7 +156,6 @@ class Protocol(ChoicesMixin, models.TextChoices): cls.http: { 'port': 80, 'secret_types': ['password'], - 'label': 'HTTP(s)', 'setting': { 'autofill': { 'type': 'choice', @@ -180,12 +181,23 @@ class Protocol(ChoicesMixin, models.TextChoices): }, } + @classmethod + def gpt_protocols(cls): + return { + cls.chatgpt: { + 'port': 443, + 'required': True, + 'secret_types': ['token'], + } + } + @classmethod def settings(cls): return { **cls.device_protocols(), **cls.database_protocols(), - **cls.cloud_protocols() + **cls.cloud_protocols(), + **cls.gpt_protocols(), } @classmethod diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py index 1f0156b7f..2ce6082a8 100644 --- a/apps/assets/const/types.py +++ b/apps/assets/const/types.py @@ -10,6 +10,7 @@ from .cloud import CloudTypes from .custom import CustomTypes from .database import DatabaseTypes from .device import DeviceTypes +from .gpt import GPTTypes from .host import HostTypes from .web import WebTypes @@ -18,7 +19,7 @@ class AllTypes(ChoicesMixin): choices: list includes = [ HostTypes, DeviceTypes, DatabaseTypes, - CloudTypes, WebTypes, CustomTypes + CloudTypes, WebTypes, CustomTypes, GPTTypes ] _category_constrains = {} @@ -147,6 +148,7 @@ class AllTypes(ChoicesMixin): (Category.DATABASE, DatabaseTypes), (Category.CLOUD, CloudTypes), (Category.WEB, WebTypes), + (Category.GPT, GPTTypes), (Category.CUSTOM, CustomTypes), ) diff --git a/apps/assets/migrations/0120_auto_20230630_1613.py b/apps/assets/migrations/0120_auto_20230630_1613.py new file mode 100644 index 000000000..aa884a217 --- /dev/null +++ b/apps/assets/migrations/0120_auto_20230630_1613.py @@ -0,0 +1,39 @@ +# Generated by Django 3.2.19 on 2023-06-30 08:13 + +import django.db.models.deletion +from django.db import migrations, models + + +def add_chatgpt_platform(apps, schema_editor): + platform_cls = apps.get_model('assets', 'Platform') + automation_cls = apps.get_model('assets', 'PlatformAutomation') + platform = platform_cls.objects.create( + name='ChatGPT', internal=True, category='gpt', type='chatgpt', + domain_enabled=False, su_enabled=False, comment='ChatGPT', + created_by='System', updated_by='System', + ) + platform.protocols.create(name='chatgpt', port=443, primary=True) + automation_cls.objects.create(ansible_enabled=False, platform=platform) + + +class Migration(migrations.Migration): + dependencies = [ + ('assets', '0119_assets_add_default_node'), + ] + + operations = [ + migrations.CreateModel( + name='GPT', + fields=[ + ('asset_ptr', + models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, + primary_key=True, serialize=False, to='assets.asset')), + ('proxy', models.CharField(blank=True, default='', max_length=128, verbose_name='Proxy')), + ], + options={ + 'verbose_name': 'Web', + }, + bases=('assets.asset',), + ), + migrations.RunPython(add_chatgpt_platform) + ] diff --git a/apps/assets/models/asset/__init__.py b/apps/assets/models/asset/__init__.py index 0004bfbb5..7541f2f2e 100644 --- a/apps/assets/models/asset/__init__.py +++ b/apps/assets/models/asset/__init__.py @@ -3,5 +3,6 @@ from .common import * from .custom import * from .database import * from .device import * +from .gpt import * from .host import * from .web import * diff --git a/apps/assets/models/asset/gpt.py b/apps/assets/models/asset/gpt.py new file mode 100644 index 000000000..4522dfe93 --- /dev/null +++ b/apps/assets/models/asset/gpt.py @@ -0,0 +1,11 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from .common import Asset + + +class GPT(Asset): + proxy = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Proxy")) + + class Meta: + verbose_name = _("Web") diff --git a/apps/assets/serializers/asset/__init__.py b/apps/assets/serializers/asset/__init__.py index 8e3e14cf3..481e90863 100644 --- a/apps/assets/serializers/asset/__init__.py +++ b/apps/assets/serializers/asset/__init__.py @@ -4,5 +4,6 @@ from .common import * from .custom import * from .database import * from .device import * +from .gpt import * from .host import * from .web import * diff --git a/apps/assets/serializers/asset/gpt.py b/apps/assets/serializers/asset/gpt.py new file mode 100644 index 000000000..88e28ed60 --- /dev/null +++ b/apps/assets/serializers/asset/gpt.py @@ -0,0 +1,15 @@ +from assets.models import GPT +from .common import AssetSerializer + +__all__ = ['GPTSerializer'] + + +class GPTSerializer(AssetSerializer): + class Meta(AssetSerializer.Meta): + model = GPT + fields = AssetSerializer.Meta.fields + [ + 'proxy', + ] + extra_kwargs = { + **AssetSerializer.Meta.extra_kwargs, + } diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 1a1384fdf..983e077f0 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -14,6 +14,7 @@ router.register(r'devices', api.DeviceViewSet, 'device') router.register(r'databases', api.DatabaseViewSet, 'database') router.register(r'webs', api.WebViewSet, 'web') router.register(r'clouds', api.CloudViewSet, 'cloud') +router.register(r'gpts', api.GPTViewSet, 'gpt') router.register(r'customs', api.CustomViewSet, 'custom') router.register(r'platforms', api.AssetPlatformViewSet, 'platform') router.register(r'labels', api.LabelViewSet, 'label')