diff --git a/apps/assets/migrations/0098_auto_20220430_2126.py b/apps/assets/migrations/0098_auto_20220430_2126.py index 53a18e33e..943e8241f 100644 --- a/apps/assets/migrations/0098_auto_20220430_2126.py +++ b/apps/assets/migrations/0098_auto_20220430_2126.py @@ -1,35 +1,8 @@ # Generated by Django 3.1.14 on 2022-04-30 14:41 - -from collections import namedtuple from django.db import migrations, models import django.db.models.deletion -def migrate_platform_set_ops(apps, *args): - platform_model = apps.get_model('assets', 'Platform') - - default_ok = { - 'su_enabled': True, - 'su_method': 'sudo', - 'domain_enabled': True, - 'change_password_enabled': True, - 'change_password_method': 'change_password_linux', - 'verify_account_enabled': True, - 'verify_account_method': 'verify_account_ansible', - } - - platform_ops_map = { - 'Linux': {**default_ok, 'change_password_method': 'change_password_linux'}, - 'Windows': {**default_ok, 'change_password_method': 'change_password_windows'}, - 'AIX': {**default_ok, 'change_password_method': 'change_password_aix'}, - } - platforms = platform_model.objects.all() - - for p in platforms: - p.set_ops = True - p.save() - - class Migration(migrations.Migration): dependencies = [ diff --git a/apps/assets/migrations/0100_auto_20220711_1413.py b/apps/assets/migrations/0100_auto_20220711_1413.py index aed674b36..7aad60e2c 100644 --- a/apps/assets/migrations/0100_auto_20220711_1413.py +++ b/apps/assets/migrations/0100_auto_20220711_1413.py @@ -2,6 +2,12 @@ import time from django.db import migrations +from assets.models import Platform + + +def migrate_platform_set_ops(apps, *args): + platform_model = apps.get_model('assets', 'Platform') + Platform.set_default_platforms_ops(platform_model) def migrate_accounts(apps, schema_editor): @@ -59,5 +65,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(migrate_accounts) + migrations.RunPython(migrate_accounts), + migrations.RunPython(migrate_platform_set_ops) ] diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py index 304b9c120..06bdc4de3 100644 --- a/apps/assets/models/platform.py +++ b/apps/assets/models/platform.py @@ -40,7 +40,7 @@ class Platform(models.Model): # Accounts # 这应该和账号有关 su_enabled = models.BooleanField(default=False, verbose_name=_("Su enabled")) - su_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("SU method")) + su_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("SU method")) ping_enabled = models.BooleanField(default=False) ping_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Ping method")) verify_account_enabled = models.BooleanField(default=False, verbose_name=_("Verify account enabled")) @@ -61,6 +61,74 @@ class Platform(models.Model): ) return linux.id + @staticmethod + def set_default_platforms_ops(platform_model): + default_ok = { + 'su_enabled': True, + 'su_method': 'sudo', + 'domain_enabled': True, + 'change_password_enabled': True, + 'change_password_method': 'change_password_linux', + 'verify_account_enabled': True, + 'verify_account_method': 'ansible_posix_ping', + } + db_default = { + 'su_enabled': False, + 'domain_enabled': True, + 'change_password_enabled': True, + 'verify_account_enabled': True, + } + + platform_ops_map = { + ('host', 'linux'): { + **default_ok, + 'change_password_method': 'change_password_linux', + 'verify_account_method': 'ansible_posix_ping' + }, + ('host', 'windows'): { + **default_ok, + 'su_enabled': False, + 'change_password_method': 'change_password_windows', + 'verify_account_method': 'ansible_win_ping' + }, + ('host', 'unix'): { + **default_ok, + 'verify_account_method': 'ansible_posix_ping', + 'change_password_method': 'change_password_aix' + }, + ('database', 'mysql'): { + **db_default, + 'verify_account_method': 'mysql_ping', + 'change_password_method': 'change_password_mysql' + }, + ('database', 'postgresql'): { + **db_default, + 'verify_account_method': 'postgresql_ping', + 'change_password_method': 'change_password_postgresql' + }, + ('database', 'oracle'): { + **db_default, + 'verify_account_method': 'oracle_ping', + 'change_password_method': 'change_password_oracle' + }, + ('database', 'sqlserver'): { + **db_default, + 'verify_account_method': 'mysql_ping', + 'change_password_method': 'change_password_sqlserver' + }, + } + platforms = platform_model.objects.all() + + updated = [] + for p in platforms: + attrs = platform_ops_map.get((p.category, p.type), {}) + if not attrs: + continue + for k, v in attrs.items(): + setattr(p, k, v) + updated.append(p) + platform_model.objects.bulk_update(updated, list(default_ok.keys())) + def __str__(self): return self.name diff --git a/apps/assets/playbooks/platform/__init__.py b/apps/assets/playbooks/platform/__init__.py index e19fb8a84..3f6be47d7 100644 --- a/apps/assets/playbooks/platform/__init__.py +++ b/apps/assets/playbooks/platform/__init__.py @@ -5,14 +5,23 @@ from functools import partial BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -def check_platform_method(manifest): - required_keys = ['category', 'method', 'name', 'id'] +def check_platform_method(manifest, manifest_path): + required_keys = ['category', 'method', 'name', 'id', 'type'] less_key = set(required_keys) - set(manifest.keys()) if less_key: - raise ValueError("Manifest missing keys: {}".format(less_key)) + raise ValueError("Manifest missing keys: {}, {}".format(less_key, manifest_path)) + if not isinstance(manifest['type'], list): + raise ValueError("Manifest type must be a list: {}".format(manifest_path)) return True +def check_platform_methods(methods): + ids = [m['id'] for m in methods] + for i, _id in enumerate(ids): + if _id in ids[i+1:]: + raise ValueError("Duplicate id: {}".format(_id)) + + def get_platform_methods(): methods = [] for root, dirs, files in os.walk(BASE_DIR, topdown=False): @@ -21,25 +30,25 @@ def get_platform_methods(): rel_path = path.replace(BASE_DIR, '.') if len(rel_path.split('/')) != 3: continue + manifest_path = os.path.join(path, 'manifest.yml') if not os.path.exists(manifest_path): continue with open(manifest_path, 'r') as f: manifest = yaml.safe_load(f) - check_platform_method(manifest) - + check_platform_method(manifest, manifest_path) methods.append(manifest) + + check_platform_methods(methods) return methods def filter_key(manifest, attr, value): manifest_value = manifest.get(attr, '') - if manifest_value == 'all': - return True if isinstance(manifest_value, str): manifest_value = [manifest_value] - return value in manifest_value + return value in manifest_value or 'all' in manifest_value def filter_platform_methods(category, tp, method): diff --git a/apps/assets/playbooks/platform/database/change_password_mysql/manifest.yml b/apps/assets/playbooks/platform/database/change_password_mysql/manifest.yml index 452269c3d..043549ec6 100644 --- a/apps/assets/playbooks/platform/database/change_password_mysql/manifest.yml +++ b/apps/assets/playbooks/platform/database/change_password_mysql/manifest.yml @@ -1,6 +1,6 @@ id: change_password_mysql name: Change password for MySQL category: database -type: mysql +type: + - mysql method: change_password - diff --git a/apps/assets/playbooks/platform/database/change_password_oracle/manifest.yml b/apps/assets/playbooks/platform/database/change_password_oracle/manifest.yml index 4e1f00af4..d3bab86e1 100644 --- a/apps/assets/playbooks/platform/database/change_password_oracle/manifest.yml +++ b/apps/assets/playbooks/platform/database/change_password_oracle/manifest.yml @@ -2,4 +2,5 @@ id: change_password_oracle name: Change password for Oracle method: change_password category: database -type: oracle +type: + - oracle diff --git a/apps/assets/playbooks/platform/database/change_password_postgresql/manifest.yml b/apps/assets/playbooks/platform/database/change_password_postgresql/manifest.yml index 7a84ef0b1..9abe184be 100644 --- a/apps/assets/playbooks/platform/database/change_password_postgresql/manifest.yml +++ b/apps/assets/playbooks/platform/database/change_password_postgresql/manifest.yml @@ -1,5 +1,6 @@ id: change_password_postgresql name: Change password for PostgreSQL category: database -type: postgresql +type: + - postgresql method: change_password diff --git a/apps/assets/playbooks/platform/database/change_password_sqlserver/manifest.yml b/apps/assets/playbooks/platform/database/change_password_sqlserver/manifest.yml index 6b4c31b32..b16a24dc9 100644 --- a/apps/assets/playbooks/platform/database/change_password_sqlserver/manifest.yml +++ b/apps/assets/playbooks/platform/database/change_password_sqlserver/manifest.yml @@ -2,6 +2,7 @@ id: change_password_sqlserver name: Change password for SQLServer version: 1 category: database -type: sqlserver +type: + - sqlserver method: change_password diff --git a/apps/assets/playbooks/platform/host/verifiy_account_ansible/main.yml b/apps/assets/playbooks/platform/host/ansible_posix_ping/main.yml similarity index 100% rename from apps/assets/playbooks/platform/host/verifiy_account_ansible/main.yml rename to apps/assets/playbooks/platform/host/ansible_posix_ping/main.yml diff --git a/apps/assets/playbooks/platform/host/ansible_posix_ping/manifest.yml b/apps/assets/playbooks/platform/host/ansible_posix_ping/manifest.yml new file mode 100644 index 000000000..6cd223f1c --- /dev/null +++ b/apps/assets/playbooks/platform/host/ansible_posix_ping/manifest.yml @@ -0,0 +1,10 @@ +id: ansible_posix_ping +name: Ansible posix ping +description: Ansible ping +category: host +type: + - linux + - unix + - macos + - bsd +method: verify_account diff --git a/apps/assets/playbooks/platform/host/ansible_win_ping/main.yml b/apps/assets/playbooks/platform/host/ansible_win_ping/main.yml new file mode 100644 index 000000000..726d04a53 --- /dev/null +++ b/apps/assets/playbooks/platform/host/ansible_win_ping/main.yml @@ -0,0 +1,13 @@ +- hosts: centos + gather_facts: no + vars: + account: + username: web + password: test123 + + tasks: + - name: Verify password + win_ping: + vars: + ansible_user: "{{ account.username }}" + ansible_pass: "{{ account.password }}" diff --git a/apps/assets/playbooks/platform/host/ansible_win_ping/manifest.yml b/apps/assets/playbooks/platform/host/ansible_win_ping/manifest.yml new file mode 100644 index 000000000..fe881de3b --- /dev/null +++ b/apps/assets/playbooks/platform/host/ansible_win_ping/manifest.yml @@ -0,0 +1,6 @@ +id: ansible_win_ping +name: Ansible win ping +category: host +type: + - windows +method: verify_account diff --git a/apps/assets/playbooks/platform/host/change_password_aix/manifest.yml b/apps/assets/playbooks/platform/host/change_password_aix/manifest.yml index 32f6f25c5..451c10f8e 100644 --- a/apps/assets/playbooks/platform/host/change_password_aix/manifest.yml +++ b/apps/assets/playbooks/platform/host/change_password_aix/manifest.yml @@ -1,4 +1,6 @@ id: change_password_aix name: Change password for AIX category: host +type: + - aix method: change_password diff --git a/apps/assets/playbooks/platform/host/change_password_local_windows/manifest.yml b/apps/assets/playbooks/platform/host/change_password_local_windows/manifest.yml index 5286a7b3f..7f34008e6 100644 --- a/apps/assets/playbooks/platform/host/change_password_local_windows/manifest.yml +++ b/apps/assets/playbooks/platform/host/change_password_local_windows/manifest.yml @@ -3,9 +3,5 @@ name: Change password local account for Windows version: 1 method: change_password category: host -type: windows -vars: - account: - username: test - password: teset123 - public_key: test +type: + - windows diff --git a/apps/assets/playbooks/platform/host/verifiy_account_ansible/manifest.yml b/apps/assets/playbooks/platform/host/verifiy_account_ansible/manifest.yml deleted file mode 100644 index f4dd3085e..000000000 --- a/apps/assets/playbooks/platform/host/verifiy_account_ansible/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: verify_account_ansible -name: Ansible ping -description: Ansible ping -category: host -type: all -method: verify_account diff --git a/apps/common/drf/fields.py b/apps/common/drf/fields.py index d925164da..30fd6ce05 100644 --- a/apps/common/drf/fields.py +++ b/apps/common/drf/fields.py @@ -54,3 +54,8 @@ class ChoiceDisplayField(ChoiceField): 'value': value, 'label': self.choice_mapper.get(six.text_type(value), value), } + + def to_internal_value(self, data): + if isinstance(data, dict): + return data.get('value') + return super(ChoiceDisplayField, self).to_internal_value(data) diff --git a/apps/common/drf/metadata.py b/apps/common/drf/metadata.py index 2210b222b..d1c771ffc 100644 --- a/apps/common/drf/metadata.py +++ b/apps/common/drf/metadata.py @@ -90,6 +90,8 @@ class SimpleMetadataWithFilters(SimpleMetadata): for choice_value, choice_name in dict(field.choices).items() ] + if field.__class__.__name__ == 'ChoiceDisplayField': + field_info['type'] = 'display_choice' return field_info def get_filters_fields(self, request, view):