Commit 2b3551f1 authored by ibuler's avatar ibuler

[Feature] 修改ansible和ops

parent e57121a7
...@@ -44,28 +44,18 @@ class Asset(models.Model): ...@@ -44,28 +44,18 @@ class Asset(models.Model):
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True) ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname')) hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
port = models.IntegerField(default=22, verbose_name=_('Port')) port = models.IntegerField(default=22, verbose_name=_('Port'))
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', verbose_name=_('Asset groups'))
verbose_name=_('Asset groups')) admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_("Admin user"))
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
on_delete=models.SET_NULL, verbose_name=_("Admin user")) idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('IDC'),)
system_users = models.ManyToManyField(SystemUser, blank=True,
related_name='assets',
verbose_name=_("System User"))
idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets',
on_delete=models.SET_NULL, verbose_name=_('IDC'),)
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, default='Server', verbose_name=_('Asset type'),)
default='Server', verbose_name=_('Asset type'),) env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, default='Prod', verbose_name=_('Asset environment'),)
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, status = models.CharField(choices=STATUS_CHOICES, max_length=12, null=True, blank=True, default='In use', verbose_name=_('Asset status'))
default='Prod', verbose_name=_('Asset environment'),)
status = models.CharField(choices=STATUS_CHOICES, max_length=12, null=True, blank=True,
default='In use', verbose_name=_('Asset status'))
# Some information # Some information
public_ip = models.GenericIPAddressField(max_length=32, blank=True, public_ip = models.GenericIPAddressField(max_length=32, blank=True, null=True, verbose_name=_('Public IP'))
null=True, verbose_name=_('Public IP')) remote_card_ip = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('Remote control card IP'))
remote_card_ip = models.CharField(max_length=16, null=True, blank=True,
verbose_name=_('Remote control card IP'))
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number')) cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position')) cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number')) number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
...@@ -114,22 +104,27 @@ class Asset(models.Model): ...@@ -114,22 +104,27 @@ class Asset(models.Model):
def _to_secret_json(self): def _to_secret_json(self):
"""Ansible use it create inventory""" """Ansible use it create inventory"""
return { data = {
'id': self.id, 'id': self.id,
'hostname': self.hostname, 'hostname': self.hostname,
'ip': self.ip, 'ip': self.ip,
'port': self.port, 'port': self.port,
'groups': [group.name for group in self.groups.all()], 'groups': [group.name for group in self.groups.all()],
'username': self.admin_user.username if self.admin_user else '',
'password': self.admin_user.password if self.admin_user else '',
'private_key': self.admin_user.private_key_file if self.admin_user else None,
'become': {
'method': self.admin_user.become_method,
'user': self.admin_user.become_user,
'pass': self.admin_user.become_pass,
} if self.admin_user and self.admin_user.become else {},
} }
if self.admin_user:
data.update({
'username': self.admin_user.username,
'password': self.admin_user.password,
'private_key': self.admin_user.private_key_file,
'become': {
'method': self.admin_user.become_method,
'user': self.admin_user.become_user,
'pass': self.admin_user.become_pass,
}
})
return data
class Meta: class Meta:
unique_together = ('ip', 'port') unique_together = ('ip', 'port')
......
...@@ -28,6 +28,9 @@ def private_key_validator(value): ...@@ -28,6 +28,9 @@ def private_key_validator(value):
class AdminUser(models.Model): class AdminUser(models.Model):
"""
Ansible use admin user as devops user to run adHoc and Playbook
"""
BECOME_METHOD_CHOICES = ( BECOME_METHOD_CHOICES = (
('sudo', 'sudo'), ('sudo', 'sudo'),
('su', 'su'), ('su', 'su'),
...@@ -35,24 +38,19 @@ class AdminUser(models.Model): ...@@ -35,24 +38,19 @@ class AdminUser(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username')) username = models.CharField(max_length=16, verbose_name=_('Username'))
_password = models.CharField( _password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password'))
max_length=256, blank=True, null=True, verbose_name=_('Password')) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator,])
_private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'),
validators=[private_key_validator,])
become = models.BooleanField(default=True) become = models.BooleanField(default=True)
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4) become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
become_user = models.CharField(default='root', max_length=64) become_user = models.CharField(default='root', max_length=64)
become_pass = models.CharField(default='', max_length=128) become_pass = models.CharField(default='', max_length=128)
_public_key = models.TextField( _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
max_length=4096, blank=True, verbose_name=_('SSH public key'))
comment = models.TextField(blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True) date_created = models.DateTimeField(auto_now_add=True, null=True)
created_by = models.CharField( created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by'))
max_length=32, null=True, verbose_name=_('Created by'))
def __unicode__(self): def __str__(self):
return self.name return self.name
__str__ = __unicode__
@property @property
def password(self): def password(self):
...@@ -134,33 +132,22 @@ class SystemUser(models.Model): ...@@ -134,33 +132,22 @@ class SystemUser(models.Model):
('K', 'Public key'), ('K', 'Public key'),
) )
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, unique=True, name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username')) username = models.CharField(max_length=16, verbose_name=_('Username'))
_password = models.CharField( _password = models.CharField(max_length=256, blank=True, verbose_name=_('Password'))
max_length=256, blank=True, verbose_name=_('Password')) protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
protocol = models.CharField( _private_key = models.TextField(max_length=8192, blank=True, verbose_name=_('SSH private key'))
max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol')) _public_key = models.TextField(max_length=8192, blank=True, verbose_name=_('SSH public key'))
_private_key = models.TextField( auth_method = models.CharField(choices=AUTH_METHOD_CHOICES, default='K', max_length=1, verbose_name=_('Auth method'))
max_length=8192, blank=True, verbose_name=_('SSH private key'))
_public_key = models.TextField(
max_length=8192, blank=True, verbose_name=_('SSH public key'))
auth_method = models.CharField(choices=AUTH_METHOD_CHOICES, default='K',
max_length=1, verbose_name=_('Auth method'))
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push')) auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
sudo = models.TextField( sudo = models.TextField(default='/sbin/ifconfig', verbose_name=_('Sudo'))
max_length=4096, default='/sbin/ifconfig', verbose_name=_('Sudo')) shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
shell = models.CharField(
max_length=64, default='/bin/bash', verbose_name=_('Shell'))
date_created = models.DateTimeField(auto_now_add=True) date_created = models.DateTimeField(auto_now_add=True)
created_by = models.CharField( created_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by'))
max_length=32, blank=True, verbose_name=_('Created by')) comment = models.TextField(max_length=128, blank=True, verbose_name=_('Comment'))
comment = models.TextField(
max_length=128, blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __str__(self):
return self.name return self.name
__str__ = __unicode__
@property @property
def password(self): def password(self):
...@@ -182,9 +169,24 @@ class SystemUser(models.Model): ...@@ -182,9 +169,24 @@ class SystemUser(models.Model):
def private_key(self, private_key_raw): def private_key(self, private_key_raw):
self._private_key = signer.sign(private_key_raw) self._private_key = signer.sign(private_key_raw)
@property
def private_key_file(self):
if not self.private_key:
return None
project_dir = settings.PROJECT_DIR
tmp_dir = os.path.join(project_dir, 'tmp')
key_name = md5(self._private_key.encode()).hexdigest()
key_path = os.path.join(tmp_dir, key_name)
if not os.path.exists(key_path):
self.private_key.write_private_key_file(key_path)
return key_path
@property @property
def public_key(self): def public_key(self):
return signer.unsign(self._public_key) if self._public_key:
return signer.unsign(self._public_key)
else:
return None
@public_key.setter @public_key.setter
def public_key(self, public_key_raw): def public_key(self, public_key_raw):
...@@ -213,7 +215,8 @@ class SystemUser(models.Model): ...@@ -213,7 +215,8 @@ class SystemUser(models.Model):
'shell': self.shell, 'shell': self.shell,
'sudo': self.sudo, 'sudo': self.sudo,
'password': self.password, 'password': self.password,
'public_key': self.public_key 'public_key': self.public_key,
'private_key_file': self.private_key_file,
} }
@property @property
......
...@@ -19,3 +19,32 @@ def test_admin_user_connective_manual(asset): ...@@ -19,3 +19,32 @@ def test_admin_user_connective_manual(asset):
def get_assets_by_id_list(id_list): def get_assets_by_id_list(id_list):
return Asset.objects.filter(id__in=id_list) return Asset.objects.filter(id__in=id_list)
def get_assets_by_hostname_list(hostname_list):
return Asset.objects.filter(hostname__in=hostname_list)
def get_asset_admin_user(user, asset):
if user.is_superuser:
return asset.admin_user
else:
msg = "{} have no permission for admin user".format(user.username)
raise PermissionError(msg)
def get_asset_system_user(user, asset, system_user_name):
from perms.utils import get_user_granted_assets
assets = get_user_granted_assets(user)
system_users = {system_user.name: system_user for system_user in assets.get(asset)}
if system_user_name in system_users:
return system_users[system_user_name]
else:
msg = "{} have no permission for {}".format(user.name, system_user_name)
raise PermissionError(msg)
def get_assets_with_admin_by_hostname_list(hostname_list):
assets = Asset.objects.filter(hostname__in=hostname_list)
return [(asset, asset.admin_user) for asset in assets]
# -*- coding: utf-8 -*-
#
...@@ -9,65 +9,85 @@ class AdHocResultCallback(CallbackBase): ...@@ -9,65 +9,85 @@ class AdHocResultCallback(CallbackBase):
""" """
def __init__(self, display=None): def __init__(self, display=None):
# result_raw example: { # result_raw example: {
# "ok": {"hostname": []}, # "ok": {"hostname": [{"task_name": {},...],..},
# "failed": {"hostname": []}, # "failed": {"hostname": ["task_name": {}..], ..},
# "unreachable: {"hostname": []}, # "unreachable: {"hostname": ["task_name": {}, ..]},
# "skipped": {"hostname": []}, # "skipped": {"hostname": ["task_name": {}, ..], ..},
# } # }
# results_summary example: { # results_summary example: {
# "contacted": {"hostname",...}, # "contacted": {"hostname",...},
# "dark": {"hostname": ["error",...],}, # "dark": {"hostname": [{"task_name": "error"},...],},
# } # }
self.results_raw = dict(ok={}, failed={}, unreachable={}, skipped={}) self.results_raw = dict(ok={}, failed={}, unreachable={}, skipped={})
self.results_summary = dict(contacted=set(), dark={}) self.results_summary = dict(contacted=set(), dark={})
super().__init__(display) super().__init__(display)
def gather_result(self, t, host, res): def gather_result(self, t, res):
host = res._host.get_name()
task_name = res.task_name
task_result = res._result
if self.results_raw[t].get(host): if self.results_raw[t].get(host):
self.results_raw[t][host].append(res) self.results_raw[t][host].append({task_name: task_result})
else: else:
self.results_raw[t][host] = [res] self.results_raw[t][host] = [{task_name: task_result}]
self.clean_result(t, host, res) self.clean_result(t, host, task_name, task_result)
def clean_result(self, t, host, res): def clean_result(self, t, host, task_name, task_result):
contacted = self.results_summary["contacted"] contacted = self.results_summary["contacted"]
dark = self.results_summary["dark"] dark = self.results_summary["dark"]
if t in ("ok", "skipped") and host not in dark: if t in ("ok", "skipped") and host not in dark:
contacted.add(host) contacted.add(host)
else: else:
dark[host].append(res) if dark.get(host):
dark[host].append({task_name: task_result})
else:
dark[host] = [{task_name: task_result}]
if host in contacted: if host in contacted:
contacted.remove(dark) contacted.remove(dark)
def runner_on_ok(self, host, res): def v2_runner_on_failed(self, result, ignore_errors=False):
self.gather_result("ok", host, res) self.gather_result("failed", result)
def runner_on_failed(self, host, res, ignore_errors=False): def v2_runner_on_ok(self, result):
self.gather_result("failed", host, res) self.gather_result("ok", result)
def runner_on_unreachable(self, host, res): def v2_runner_on_skipped(self, result):
self.gather_result("unreachable", host, res) self.gather_result("skipped", result)
def runner_on_skipped(self, host, item=None): def v2_runner_on_unreachable(self, result):
self.gather_result("skipped", host, item) self.gather_result("unreachable", result)
class CommandResultCallback(AdHocResultCallback): class CommandResultCallback(AdHocResultCallback):
"""
Command result callback
"""
def __init__(self, display=None): def __init__(self, display=None):
# results_command: {
# "cmd": "",
# "stderr": "",
# "stdout": "",
# "rc": 0,
# "delta": 0:0:0.123
# }
#
self.results_command = dict() self.results_command = dict()
super().__init__(display) super().__init__(display)
def gather_result(self, t, host, res): def gather_result(self, t, res):
super().gather_result(t, host, res) super().gather_result(t, res)
self.gather_cmd(t, host, res) self.gather_cmd(t, res)
def gather_cmd(self, t, host, res): def gather_cmd(self, t, res):
host = res._host.get_name()
cmd = {} cmd = {}
if t == "ok": if t == "ok":
cmd['cmd'] = res.get('cmd') cmd['cmd'] = res._result.get('cmd')
cmd['stderr'] = res.get('stderr') cmd['stderr'] = res._result.get('stderr')
cmd['stdout'] = res.get('stdout') cmd['stdout'] = res._result.get('stdout')
cmd['rc'] = res.get('rc') cmd['rc'] = res._result.get('rc')
cmd['delta'] = res._result.get('delta')
else: else:
cmd['err'] = "Error: {}".format(res) cmd['err'] = "Error: {}".format(res)
self.results_command[host] = cmd self.results_command[host] = cmd
......
...@@ -170,6 +170,10 @@ class AdHocRunner: ...@@ -170,6 +170,10 @@ class AdHocRunner:
"pattern: %s dose not match any hosts." % pattern "pattern: %s dose not match any hosts." % pattern
) )
def set_option(self, k, v):
kwargs = {k: v}
self.options = self.options._replace(**kwargs)
def run(self, tasks, pattern, play_name='Ansible Ad-hoc', gather_facts='no'): def run(self, tasks, pattern, play_name='Ansible Ad-hoc', gather_facts='no'):
""" """
:param tasks: [{'action': {'module': 'shell', 'args': 'ls'}, ...}, ] :param tasks: [{'action': {'module': 'shell', 'args': 'ls'}, ...}, ]
......
...@@ -24,8 +24,8 @@ class TestAdHocRunner(unittest.TestCase): ...@@ -24,8 +24,8 @@ class TestAdHocRunner(unittest.TestCase):
def test_run(self): def test_run(self):
tasks = [ tasks = [
{"action": {"module": "shell", "args": "ls"}}, {"action": {"module": "shell", "args": "ls"}, "name": "run_cmd"},
{"action": {"module": "shell", "args": "whoami"}}, {"action": {"module": "shell", "args": "whoami"}, "name": "run_whoami"},
] ]
ret = self.runner.run(tasks, "all") ret = self.runner.run(tasks, "all")
print(ret.results_summary) print(ret.results_summary)
...@@ -48,6 +48,7 @@ class TestCommandRunner(unittest.TestCase): ...@@ -48,6 +48,7 @@ class TestCommandRunner(unittest.TestCase):
def test_execute(self): def test_execute(self):
res = self.runner.execute('ls', 'all') res = self.runner.execute('ls', 'all')
print(res.results_command) print(res.results_command)
print(res.results_raw)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -4,12 +4,12 @@ ...@@ -4,12 +4,12 @@
from rest_framework import viewsets from rest_framework import viewsets
from .hands import IsSuperUser from .hands import IsSuperUser
from .models import Playbook from .models import AdHoc
from .serializers import TaskSerializer from .serializers import TaskSerializer
class TaskViewSet(viewsets.ModelViewSet): class TaskViewSet(viewsets.ModelViewSet):
queryset = Playbook.objects.all() queryset = AdHoc.objects.all()
serializer_class = TaskSerializer serializer_class = TaskSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import logging import logging
from collections import OrderedDict
import json import json
import uuid import uuid
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
__all__ = ["Playbook"] __all__ = ["AdHoc", "History"]
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AdHoc(models.Model): class AdHoc(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) name = models.CharField(max_length=128, blank=True, verbose_name=_('Name'))
tasks = models.TextField(verbose_name=_('Tasks')) # [{'name': 'task_name', 'module': '', 'args': ''}, ]
hosts = models.TextField(blank=True, null=True, verbose_name=_('Hosts')) # Asset inventory may be change @property
pattern = models.CharField(max_length=64, default='all', verbose_name=_('Playbook run pattern')) def short_id(self):
return str(self.id).split('-')[-1]
def __str__(self): def __str__(self):
return "%s" % self.name return self.name
def get_hosts_mapped_assets(self): class AdHocData(models.Model):
from assets.utils import get_assets_by_id_list BECOME_METHOD_CHOICES = (
assets_id = [i for i in self.hosts.split(',')] ('sudo', 'sudo'),
assets = get_assets_by_id_list(assets_id) ('su', 'su'),
return assets )
version = models.UUIDField(default=uuid.uuid4, primary_key=True)
subject = models.ForeignKey(AdHoc, on_delete=models.CASCADE)
_tasks = models.TextField(verbose_name=_('Tasks')) # [{'name': 'task_name', 'action': {'module': '', 'args': ''}, 'other..': ''}, ]
_hosts = models.TextField(blank=True, verbose_name=_('Hosts')) # ['hostname1', 'hostname2']
run_as_admin = models.BooleanField(default=False, verbose_name=_('Run as admin'))
run_as = models.CharField(max_length=128, verbose_name=_("Run as"))
become = models.BooleanField(default=False, verbose_name=_("Become"))
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
become_user = models.CharField(default='root', max_length=64)
become_pass = models.CharField(default='', max_length=128)
pattern = models.CharField(max_length=64, default='', verbose_name=_('Pattern'))
created_by = models.CharField(max_length=64, verbose_name=_('Create by'))
date_created = models.DateTimeField(auto_created=True)
@property @property
def inventory(self): def tasks(self):
return [asset._to_secret_json() for asset in self.get_hosts_mapped_assets()] return json.loads(self._tasks)
@tasks.setter
def tasks(self, item):
self._tasks = json.dumps(item)
@property @property
def module_args(self): def hosts(self):
task_tuple = [] return json.loads(self._hosts)
for module, args in json.loads(self._modules_args, object_pairs_hook=OrderedDict).items():
task_tuple.append((module, args))
return task_tuple
@module_args.setter @hosts.setter
def module_args(self, task_tuple): def hosts(self, item):
module_args_ = OrderedDict({}) self._hosts = json.dumps(item)
for module, args in task_tuple:
module_args_[module] = args
self._modules_args = json.dumps(module_args_)
@property
def short_version(self):
return str(self.version).split('-')[-1]
class History(models.Model): def __str__(self):
return "{} of {}".format(self.subject.name, self.short_version)
class AdHocHistory(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, primary_key=True) uuid = models.UUIDField(default=uuid.uuid4, primary_key=True)
adhoc = models.ForeignKey(AdHocData, on_delete=models.CASCADE)
date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time')) date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time'))
date_finished = models.DateTimeField(blank=True, null=True, verbose_name=_('End time')) date_finished = models.DateTimeField(blank=True, null=True, verbose_name=_('End time'))
timedelta = models.FloatField(default=0.0, verbose_name=_('Time'), null=True) timedelta = models.FloatField(default=0.0, verbose_name=_('Time'), null=True)
...@@ -58,3 +78,10 @@ class History(models.Model): ...@@ -58,3 +78,10 @@ class History(models.Model):
is_success = models.BooleanField(default=False, verbose_name=_('Is success')) is_success = models.BooleanField(default=False, verbose_name=_('Is success'))
result = models.TextField(blank=True, null=True, verbose_name=_('Playbook raw result')) result = models.TextField(blank=True, null=True, verbose_name=_('Playbook raw result'))
summary = models.TextField(blank=True, null=True, verbose_name=_('Playbook summary')) summary = models.TextField(blank=True, null=True, verbose_name=_('Playbook summary'))
@property
def short_id(self):
return str(self.id).split('-')[-1]
def __str__(self):
return self.short_id
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from rest_framework import serializers from rest_framework import serializers
from .models import Playbook from .models import AdHoc
class TaskSerializer(serializers.ModelSerializer): class TaskSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Playbook model = AdHoc
fields = '__all__' fields = '__all__'
...@@ -88,3 +88,14 @@ def is_uuid(s): ...@@ -88,3 +88,14 @@ def is_uuid(s):
else: else:
return False return False
def asset_to_dict(asset):
return asset.to_json()
def asset_to_dict_with_credential(asset):
return asset._to_secret_json()
def system_user_to_dict_with_credential(system_user):
return system_user._to_secret_json()
...@@ -9,13 +9,13 @@ from django.views.generic import ListView, DetailView, View ...@@ -9,13 +9,13 @@ from django.views.generic import ListView, DetailView, View
from django.utils import timezone from django.utils import timezone
from django.shortcuts import redirect, reverse from django.shortcuts import redirect, reverse
from .models import Playbook from .models import AdHoc, AdHocData, AdHocHistory
from ops.tasks import rerun_task from ops.tasks import rerun_task
class TaskListView(ListView): class TaskListView(ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
model = Playbook model = AdHoc
ordering = ('-date_start',) ordering = ('-date_start',)
context_object_name = 'task_list' context_object_name = 'task_list'
template_name = 'ops/task_list.html' template_name = 'ops/task_list.html'
...@@ -63,7 +63,7 @@ class TaskListView(ListView): ...@@ -63,7 +63,7 @@ class TaskListView(ListView):
class TaskDetailView(DetailView): class TaskDetailView(DetailView):
model = Playbook model = AdHocHistory
template_name = 'ops/task_detail.html' template_name = 'ops/task_detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
......
...@@ -53,79 +53,6 @@ def get_user_group_granted_assets(user_group): ...@@ -53,79 +53,6 @@ def get_user_group_granted_assets(user_group):
return assets return assets
# def get_user_granted_asset_groups_direct(user):
# """Return asset groups granted of the user direct nor inherit from user group
#
# :param user: Instance of :class: ``User``
# :return: {asset_group: {system_user1, },
# asset_group2: {system_user1, system_user2]}
# """
# asset_groups = {}
# asset_permissions_direct = user.asset_permissions.all()
#
# for asset_permission in asset_permissions_direct:
# if not asset_permission.is_valid:
# continue
# for asset_group in asset_permission.asset_groups.all():
# if asset_group in asset_groups:
# asset_groups[asset_group] |= set(asset_permission.system_users.all())
# else:
# setattr(asset_group, 'inherited', False)
# asset_groups[asset_group] = set(asset_permission.system_users.all())
#
# return asset_groups
# def get_user_granted_asset_groups_inherit_from_user_groups(user):
# """Return asset groups granted of the user and inherit from user group
#
# :param user: Instance of :class: ``User``
# :return: {asset_group: {system_user1, },
# asset_group2: {system_user1, system_user2]}
# """
# asset_groups = {}
# user_groups = user.groups.all()
# asset_permissions = set()
#
# # Get asset permission list of user groups for this user
# for user_group in user_groups:
# asset_permissions |= set(user_group.asset_permissions.all())
#
# # Get asset groups granted from user groups
# for asset_permission in asset_permissions:
# if not asset_permission.is_valid:
# continue
# for asset_group in asset_permission.asset_groups.all():
# if asset_group in asset_groups:
# asset_groups[asset_group] |= set(asset_permission.system_users.all())
# else:
# setattr(asset_group, 'inherited', True)
# asset_groups[asset_group] = set(asset_permission.system_users.all())
#
# return asset_groups
# def get_user_granted_asset_groups(user):
# """Get user granted asset groups all, include direct and inherit from user group
#
# :param user: Instance of :class: ``User``
# :return: {asset_group1: {system_user1, system_user2}, asset_group2: {...}}
# """
#
# asset_groups_inherit_from_user_groups = \
# get_user_granted_asset_groups_inherit_from_user_groups(user)
# asset_groups_direct = get_user_granted_asset_groups_direct(user)
# asset_groups = asset_groups_inherit_from_user_groups
#
# # Merge direct granted and inherit from user group
# for asset_group, system_users in asset_groups_direct.items():
# if asset_group in asset_groups:
# asset_groups[asset_group] |= asset_groups_direct[asset_group]
# else:
# asset_groups[asset_group] = asset_groups_direct[asset_group]
# return asset_groups
def get_user_granted_assets_direct(user): def get_user_granted_assets_direct(user):
"""Return assets granted of the user directly """Return assets granted of the user directly
...@@ -225,6 +152,22 @@ def get_user_asset_permissions(user): ...@@ -225,6 +152,22 @@ def get_user_asset_permissions(user):
return direct_permissions | user_group_permissions return direct_permissions | user_group_permissions
def get_user_granted_system_users(user):
"""
:param user: the user
:return: {"system_user": ["asset", "asset1"], "system_user": []}
"""
assets = get_user_granted_assets(user)
system_users_dict = {}
for asset, system_users in assets.items():
for system_user in system_users:
if system_user in system_users_dict:
system_users_dict[system_user].append(asset)
else:
system_users_dict[system_user] = [asset]
return system_users_dict
def get_user_groups_granted_in_asset(asset): def get_user_groups_granted_in_asset(asset):
pass pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment