Search code examples
pythonjinja2salt-project

calling python function within saltstack sls


I am new in saltstack and i have some troubles creating a python function to make some regex checks. i have this function

from re import sub, match, search
def app_instance_match(app):
  instance_no = 0
  m = search('^(.*)(-)(\d)$', app)
  if m is not None:
    app = m.group(1)
    instance_no = int(m.group(3))
  return app, instance_no

when i call it from console with

salt-ssh -i 'genesis-app-1' emod.app_instance_match test-14 

i get

$ salt-ssh -i 'genesis-app-1' emod.app_instance_match test-14
genesis-app-1: - test-14 - 0

When i try to use it inside a sls file like

    {% set app = salt['emod.app_instance_match'](app) %}

i cannot use the app anymore. i tried

{% for x,y in app %} 
test:
  cmd.run:
    - names: 
      - echo {{x} {{y}}

or like

cmd.run:
    - names: 
      - echo {{app}}

I know that it return to me a dictionary but i am unable to access the values of it. The only thing that i need is the 2 returns from the python function: test-14 and 0.

when i echo for testing the X from the loop fox x,y in app i saw values like retcode, stdout, stderror.

Is there any other way to syntax the

{% set app = salt['emod.app_instance_match'](app) %}

something like that so will have 2 set variables in sls

{% set app,no = salt['emod.app_instance_match'](app) %}

i also tried like

{% set app = salt['emod.app_instance_match'](app).items() %}

I am missing something in the syntax but i cannot find anything in the internet to help me continue. I have the values that i want inside app, but i am not able to access them to take the part that i want.


Solution

  • First, You are not getting a dict back, you are getting a tuple back. there is a big difference. second {% set app,no = salt['emod.app_instance_match'](app) %} is exactly what you should be using. that will split the variables into two parts app and no. I should note sometimes using salt-ssh actually makes debugging things in salt harder. I would suggest installing a local minion to at least test these basic things.

    Here is an example using your own code. I named it epp instead of emod.

    [root@salt00 tests]# cat tests.sls
    {% set x,y = salt['epp.app_instance_match']('test-14') %}
    x: {{x}}
    y: {{y}}
    [root@salt00 tests]# salt-call slsutil.renderer salt://tests/tests.sls default_render=jinja
    local:
        ----------
        x:
            test-14
        y:
            0
    [root@salt00 tests]# cat ../_modules/epp.py
    from re import sub, match, search
    def app_instance_match(app):
      instance_no = 0
      m = search('^(.*)(-)(\d)$', app)
      if m is not None:
        app = m.group(1)
        instance_no = int(m.group(3))
      return app, instance_no
    

    The second thing is you might want to look at https://docs.saltproject.io/en/latest/topics/jinja/index.html#regex-search which is already a regex search.

    And third. Your regex looks off. ^ and $ don't really work well with single strings. which would explain why test-14 didn't come back as ('test',1) but instead came back as ('test-14',0)

    I'm thinking you want '(.*)-(\d*)' as your real regex. which will return ('test',14) for test-14