mirror of https://github.com/jumpserver/jumpserver
Merge branch 'v3' of github.com:jumpserver/jumpserver into v3
commit
e3b138be3a
|
@ -52,7 +52,3 @@ class BaseType(TextChoices):
|
||||||
@classmethod
|
@classmethod
|
||||||
def internal_platforms(cls):
|
def internal_platforms(cls):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def create_or_update_internal_platforms(cls):
|
|
||||||
data = cls._internal_platforms()
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ class CloudTypes(BaseType):
|
||||||
def _get_automation_constrains(cls) -> dict:
|
def _get_automation_constrains(cls) -> dict:
|
||||||
constrains = {
|
constrains = {
|
||||||
'*': {
|
'*': {
|
||||||
|
'ansible_enabled': False,
|
||||||
|
'ansible_config': {},
|
||||||
'gather_facts_enabled': False,
|
'gather_facts_enabled': False,
|
||||||
'verify_account_enabled': False,
|
'verify_account_enabled': False,
|
||||||
'change_password_enabled': False,
|
'change_password_enabled': False,
|
||||||
|
|
|
@ -25,6 +25,10 @@ class DatabaseTypes(BaseType):
|
||||||
def _get_automation_constrains(cls) -> dict:
|
def _get_automation_constrains(cls) -> dict:
|
||||||
constrains = {
|
constrains = {
|
||||||
'*': {
|
'*': {
|
||||||
|
'ansible_enabled': True,
|
||||||
|
'ansible_config': {
|
||||||
|
'ansible_connection': 'local',
|
||||||
|
},
|
||||||
'gather_facts_enabled': True,
|
'gather_facts_enabled': True,
|
||||||
'gather_accounts_enabled': True,
|
'gather_accounts_enabled': True,
|
||||||
'verify_account_enabled': True,
|
'verify_account_enabled': True,
|
||||||
|
|
|
@ -31,6 +31,10 @@ class DeviceTypes(BaseType):
|
||||||
def _get_automation_constrains(cls) -> dict:
|
def _get_automation_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'*': {
|
'*': {
|
||||||
|
'ansible_enabled': True,
|
||||||
|
'ansible_config': {
|
||||||
|
'ansible_connection': 'local',
|
||||||
|
},
|
||||||
'ping_enabled': True,
|
'ping_enabled': True,
|
||||||
'gather_facts_enabled': False,
|
'gather_facts_enabled': False,
|
||||||
'gather_accounts_enabled': False,
|
'gather_accounts_enabled': False,
|
||||||
|
|
|
@ -40,13 +40,23 @@ class HostTypes(BaseType):
|
||||||
def _get_automation_constrains(cls) -> dict:
|
def _get_automation_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'*': {
|
'*': {
|
||||||
|
'ansible_enabled': True,
|
||||||
|
'ansible_config': {
|
||||||
|
'ansible_connection': 'smart',
|
||||||
|
},
|
||||||
'ping_enabled': True,
|
'ping_enabled': True,
|
||||||
'gather_facts_enabled': True,
|
'gather_facts_enabled': True,
|
||||||
'gather_accounts_enabled': True,
|
'gather_accounts_enabled': True,
|
||||||
'verify_account_enabled': True,
|
'verify_account_enabled': True,
|
||||||
'change_password_enabled': True,
|
'change_password_enabled': True,
|
||||||
'create_account_enabled': True,
|
'create_account_enabled': True,
|
||||||
}
|
},
|
||||||
|
cls.WINDOWS: {
|
||||||
|
'ansible_config': {
|
||||||
|
'ansible_shell_type': 'powershell',
|
||||||
|
'ansible_connection': 'ssh',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from common.db.models import IncludesTextChoicesMeta, ChoicesMixin
|
from common.db.models import ChoicesMixin
|
||||||
from common.tree import TreeNode
|
from common.tree import TreeNode
|
||||||
|
|
||||||
from .category import Category
|
from .category import Category
|
||||||
|
@ -11,7 +11,7 @@ from .web import WebTypes
|
||||||
from .cloud import CloudTypes
|
from .cloud import CloudTypes
|
||||||
|
|
||||||
|
|
||||||
class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
class AllTypes(ChoicesMixin):
|
||||||
choices: list
|
choices: list
|
||||||
includes = [
|
includes = [
|
||||||
HostTypes, DeviceTypes, DatabaseTypes,
|
HostTypes, DeviceTypes, DatabaseTypes,
|
||||||
|
@ -19,6 +19,13 @@ class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
]
|
]
|
||||||
_category_constrains = {}
|
_category_constrains = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def choices(cls):
|
||||||
|
choices = []
|
||||||
|
for tp in cls.includes:
|
||||||
|
choices.extend(tp.choices)
|
||||||
|
return choices
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_constraints(cls, category, tp):
|
def get_constraints(cls, category, tp):
|
||||||
types_cls = dict(cls.category_types()).get(category)
|
types_cls = dict(cls.category_types()).get(category)
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Migration(migrations.Migration):
|
||||||
name='PlatformAutomation',
|
name='PlatformAutomation',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('ansible_enabled', models.BooleanField(default=False, verbose_name='Enabled')),
|
||||||
|
('ansible_config', models.JSONField(default=dict, verbose_name='Ansible config')),
|
||||||
('ping_enabled', models.BooleanField(default=False, verbose_name='Ping enabled')),
|
('ping_enabled', models.BooleanField(default=False, verbose_name='Ping enabled')),
|
||||||
('ping_method', models.CharField(blank=True, max_length=32, null=True, verbose_name='Ping method')),
|
('ping_method', models.CharField(blank=True, max_length=32, null=True, verbose_name='Ping method')),
|
||||||
('gather_facts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
('gather_facts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
||||||
|
|
|
@ -31,6 +31,8 @@ class PlatformProtocol(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class PlatformAutomation(models.Model):
|
class PlatformAutomation(models.Model):
|
||||||
|
ansible_enabled = models.BooleanField(default=False, verbose_name=_("Enabled"))
|
||||||
|
ansible_config = models.JSONField(default=dict, verbose_name=_("Ansible config"))
|
||||||
ping_enabled = models.BooleanField(default=False, verbose_name=_("Ping enabled"))
|
ping_enabled = models.BooleanField(default=False, verbose_name=_("Ping enabled"))
|
||||||
ping_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("Ping method"))
|
ping_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("Ping method"))
|
||||||
gather_facts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
|
gather_facts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
|
||||||
|
|
|
@ -59,11 +59,9 @@ class AssetAccountSerializer(AccountSerializer):
|
||||||
fields = fields_mini + fields_write_only
|
fields = fields_mini + fields_write_only
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AssetSerializer(JMSWritableNestedModelSerializer):
|
class AssetSerializer(JMSWritableNestedModelSerializer):
|
||||||
category = LabeledChoiceField(choices=Category.choices, read_only=True, label=_('Category'))
|
category = LabeledChoiceField(choices=Category.choices, read_only=True, label=_('Category'))
|
||||||
type = LabeledChoiceField(choices=AllTypes.choices, read_only=True, label=_('Type'))
|
type = LabeledChoiceField(choices=AllTypes.choices(), read_only=True, label=_('Type'))
|
||||||
domain = ObjectRelatedField(required=False, queryset=Domain.objects, label=_('Domain'))
|
domain = ObjectRelatedField(required=False, queryset=Domain.objects, label=_('Domain'))
|
||||||
platform = ObjectRelatedField(required=False, queryset=Platform.objects, label=_('Platform'))
|
platform = ObjectRelatedField(required=False, queryset=Platform.objects, label=_('Platform'))
|
||||||
nodes = ObjectRelatedField(many=True, required=False, queryset=Node.objects, label=_('Nodes'))
|
nodes = ObjectRelatedField(many=True, required=False, queryset=Node.objects, label=_('Nodes'))
|
||||||
|
|
|
@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from common.drf.fields import LabeledChoiceField
|
from common.drf.fields import LabeledChoiceField
|
||||||
from common.drf.serializers import JMSWritableNestedModelSerializer
|
from common.drf.serializers import JMSWritableNestedModelSerializer
|
||||||
from ..models import Platform, PlatformProtocol, PlatformAutomation
|
from ..models import Platform, PlatformProtocol, PlatformAutomation
|
||||||
from ..const import Category, AllTypes, Protocol
|
from ..const import Category, AllTypes
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['PlatformSerializer', 'PlatformOpsMethodSerializer']
|
__all__ = ['PlatformSerializer', 'PlatformOpsMethodSerializer']
|
||||||
|
@ -36,7 +36,8 @@ class PlatformAutomationSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = PlatformAutomation
|
model = PlatformAutomation
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'ping_enabled', 'ping_method',
|
'id', 'ansible_enabled', 'ansible_config',
|
||||||
|
'ping_enabled', 'ping_method',
|
||||||
'gather_facts_enabled', 'gather_facts_method',
|
'gather_facts_enabled', 'gather_facts_method',
|
||||||
'create_account_enabled', 'create_account_method',
|
'create_account_enabled', 'create_account_method',
|
||||||
'change_password_enabled', 'change_password_method',
|
'change_password_enabled', 'change_password_method',
|
||||||
|
@ -68,7 +69,7 @@ class PlatformProtocolsSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class PlatformSerializer(JMSWritableNestedModelSerializer):
|
class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
type = LabeledChoiceField(choices=AllTypes.choices, label=_("Type"))
|
type = LabeledChoiceField(choices=AllTypes.choices(), label=_("Type"))
|
||||||
category = LabeledChoiceField(choices=Category.choices, label=_("Category"))
|
category = LabeledChoiceField(choices=Category.choices, label=_("Category"))
|
||||||
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
|
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
|
||||||
automation = PlatformAutomationSerializer(label=_('Automation'), required=False)
|
automation = PlatformAutomationSerializer(label=_('Automation'), required=False)
|
||||||
|
|
|
@ -15,36 +15,12 @@ import inspect
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import F, Value, ExpressionWrapper
|
from django.db.models import F, Value, ExpressionWrapper
|
||||||
from enum import _EnumDict
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.db.models.functions import Concat
|
from django.db.models.functions import Concat
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class IncludesTextChoicesMeta(type):
|
|
||||||
def __new__(metacls, classname, bases, classdict):
|
|
||||||
includes = classdict.pop('includes', None)
|
|
||||||
assert includes
|
|
||||||
|
|
||||||
attrs = _EnumDict()
|
|
||||||
attrs._cls_name = classname
|
|
||||||
for k, v in classdict.items():
|
|
||||||
attrs[k] = v
|
|
||||||
|
|
||||||
for cls in includes:
|
|
||||||
_member_names_ = cls._member_names_
|
|
||||||
_member_map_ = cls._member_map_
|
|
||||||
_value2label_map_ = cls._value2label_map_
|
|
||||||
|
|
||||||
for name in _member_names_:
|
|
||||||
value = str(_member_map_[name])
|
|
||||||
label = _value2label_map_[value]
|
|
||||||
attrs[name] = value, label
|
|
||||||
bases = (models.TextChoices,)
|
|
||||||
return type(classname, bases, attrs)
|
|
||||||
|
|
||||||
|
|
||||||
class BitOperationChoice:
|
class BitOperationChoice:
|
||||||
NONE = 0
|
NONE = 0
|
||||||
NAME_MAP: dict
|
NAME_MAP: dict
|
||||||
|
|
|
@ -83,7 +83,7 @@ class BaseInventory(InventoryManager):
|
||||||
用于生成动态构建Ansible Inventory. super().__init__ 会自动调用
|
用于生成动态构建Ansible Inventory. super().__init__ 会自动调用
|
||||||
host_list: [{
|
host_list: [{
|
||||||
"name": "",
|
"name": "",
|
||||||
"ip": "",
|
"address": "",
|
||||||
"port": "",
|
"port": "",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
|
@ -154,3 +154,14 @@ class BaseInventory(InventoryManager):
|
||||||
return self.get_hosts(pattern)
|
return self.get_hosts(pattern)
|
||||||
|
|
||||||
|
|
||||||
|
class JMSInventory:
|
||||||
|
def __init__(self, assets, account=None, ansible_connection='ssh',
|
||||||
|
account_policy='smart', host_var_callback=None):
|
||||||
|
"""
|
||||||
|
:param assets:
|
||||||
|
:param account: account username name if not set use account_policy
|
||||||
|
:param ansible_connection: ssh, local,
|
||||||
|
:param account_policy:
|
||||||
|
:param host_var_callback:
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import ansible_runner
|
||||||
|
|
||||||
|
|
||||||
|
class AnsibleInventory:
|
||||||
|
def __init__(self, assets, account=None, ansible_connection='ssh'):
|
||||||
|
self.assets = assets
|
||||||
|
self.account = account
|
||||||
|
|
||||||
|
|
||||||
|
class AdHocRunner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PlaybookRunner:
|
||||||
|
pass
|
Loading…
Reference in New Issue