feat: Supports running adhoc,playbook with variable (#14417)

* perf:Create a job that supports adding node parameters

* feat: add variable model

* feat: Modify Variable and AdHoc models,

* feat: Parameters can be set when running job

* feat: Supports setting  variable type

* feat: Supports running adhoc with parameters

* feat: Supports running playbook with parameters

* fix: Translate

* feat: Support setting variables for scheduled tasks

* perf: Translate

---------

Co-authored-by: wangruidong <940853815@qq.com>
This commit is contained in:
fit2bot
2024-11-07 10:38:34 +08:00
committed by GitHub
parent 8f11167db0
commit c96ae1022b
30 changed files with 565 additions and 141 deletions

View File

@@ -5,3 +5,4 @@ from .adhoc import *
from .celery import *
from .playbook import *
from .job import *
from .variable import *

View File

@@ -29,6 +29,7 @@ from ops.ansible.exception import CommandInBlackListException
from ops.mixin import PeriodTaskModelMixin
from ops.variables import *
from ops.const import Types, RunasPolicies, JobStatus, JobModules
from ops.utils import merge_nodes_and_assets
from orgs.mixins.models import JMSOrgBaseModel
from perms.models import AssetPermission
from perms.utils import UserPermAssetUtil
@@ -50,11 +51,13 @@ def get_parent_keys(key, include_self=True):
class JMSPermedInventory(JMSInventory):
def __init__(self,
assets,
nodes,
account_policy='privileged_first',
account_prefer='root,Administrator',
module=None,
host_callback=None,
user=None):
assets = merge_nodes_and_assets(list(nodes), list(assets), user)
super().__init__(assets, account_policy, account_prefer, host_callback, exclude_localhost=True)
self.user = user
self.module = module
@@ -149,9 +152,11 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
playbook = models.ForeignKey('ops.Playbook', verbose_name=_("Playbook"), null=True, on_delete=models.SET_NULL)
type = models.CharField(max_length=128, choices=Types.choices, default=Types.adhoc, verbose_name=_("Type"))
creator = models.ForeignKey('users.User', verbose_name=_("Creator"), on_delete=models.SET_NULL, null=True)
assets = models.ManyToManyField('assets.Asset', verbose_name=_("Assets"))
assets = models.ManyToManyField('assets.Asset', blank=True, verbose_name=_("Assets"))
nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Node"))
use_parameter_define = models.BooleanField(default=False, verbose_name=(_('Use Parameter Define')))
parameters_define = models.JSONField(default=dict, verbose_name=_('Parameters define'))
periodic_variable = models.JSONField(default=dict, verbose_name=_('Periodic variable'))
runas = models.CharField(max_length=128, default='root', verbose_name=_('Run as'))
runas_policy = models.CharField(max_length=128, choices=RunasPolicies.choices, default=RunasPolicies.skip,
verbose_name=_('Run as policy'))
@@ -203,7 +208,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
@property
def inventory(self):
return JMSPermedInventory(self.assets.all(),
return JMSPermedInventory(self.assets.all(), self.nodes.all(),
self.runas_policy, self.runas,
user=self.creator, module=self.module)
@@ -220,7 +225,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
class Meta:
verbose_name = _("Job")
unique_together = [('name', 'org_id', 'creator')]
unique_together = [('name', 'org_id', 'creator', 'type')]
ordering = ['date_created']
@@ -328,7 +333,7 @@ class JobExecution(JMSOrgBaseModel):
if isinstance(self.parameters, str):
extra_vars = json.loads(self.parameters)
else:
extra_vars = {}
extra_vars = self.parameters if self.parameters else {}
static_variables = self.gather_static_variables()
extra_vars.update(static_variables)
@@ -349,7 +354,8 @@ class JobExecution(JMSOrgBaseModel):
runner = PlaybookRunner(
self.inventory_path,
self.current_job.playbook.entry,
self.private_dir
self.private_dir,
extra_vars=extra_vars,
)
elif self.current_job.type == Types.upload_file:
job_id = self.current_job.id

View File

@@ -23,8 +23,6 @@ dangerous_keywords = (
)
class Playbook(JMSBaseModel):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name'), null=True)

View File

@@ -0,0 +1,50 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from common.db.models import JMSBaseModel
from ops.const import FieldType
class Variable(JMSBaseModel):
name = models.CharField(max_length=1024, verbose_name=_('Name'), null=True)
var_name = models.CharField(
max_length=1024, null=True, verbose_name=_('Variable name'),
help_text=_("The variable name used in the script has a fixed prefix 'jms_' followed by the input variable "
"name. For example, if the variable name is 'name,' the final generated environment variable will "
"be 'jms_name'.")
)
default_value = models.CharField(max_length=2048, verbose_name=_('Default Value'), null=True)
creator = models.ForeignKey('users.User', verbose_name=_("Creator"), on_delete=models.SET_NULL, null=True)
type = models.CharField(max_length=64, default=FieldType.text, verbose_name=_('Variable type'))
tips = models.CharField(max_length=1024, default='', verbose_name=_('Tips'), null=True, blank=True)
required = models.BooleanField(default=False, verbose_name=_('Required'))
extra_args = models.JSONField(default=dict, verbose_name=_('ExtraVars'))
playbook = models.ForeignKey(
'ops.Playbook', verbose_name=_("Playbook"), null=True, on_delete=models.CASCADE, related_name='variable'
)
adhoc = models.ForeignKey(
'ops.AdHoc', verbose_name=_("Adhoc"), null=True, on_delete=models.CASCADE, related_name='variable'
)
job = models.ForeignKey('ops.Job', verbose_name=_("Job"), null=True, on_delete=models.CASCADE,
related_name='variable')
def __str__(self):
return self.name
@property
def form_data(self):
return {
'var_name': self.var_name,
'label': self.name,
'help_text': self.tips,
'read_only': False,
'required': self.required,
'type': self.type,
'write_only': False,
'default': self.default_value,
'extra_args': self.extra_args,
}
class Meta:
verbose_name = _("Variable")
ordering = ['date_created']