Hi, not a Python expert but cobbled this together. Maybe contains something useful.
It starts the cifs/nfs services.
called from shell
Code:
echo "Enable services..."
python3 "${bin}/truenas_services.py" --action "start"
truenas_services.py
Code:
import argparse
import sys
import requests
import json
import yaml
import os
import logging
import logging.config
from pathlib import Path
from requests.auth import HTTPBasicAuth
failure = False
script_folder = os.path.dirname(os.path.realpath(__file__))
log_config_path = os.path.abspath(os.path.join(script_folder, '..', 'bin_var', 'logging.yaml'))
config_path = os.path.abspath(os.path.join(script_folder, '..', 'bin_var', 'config_truenas_services.json'))
config = yaml.safe_load(open(log_config_path, 'r'))
logging.config.dictConfig(config)
logger = logging.getLogger()
with open(config_path) as json_data_file:
  config = json.load(json_data_file)
# http://<host>/api/docs/
def service_action(host, service, api_key, action):
  global failure
  api_call = 'http://{}/api/v2.0/service/{}'.format(host, action)
  headers = {"Content-Type":"application/json", "Authorization": "Bearer " + api_key}
  json_string = r'{"service": "' + service + r'","service-control": {"ha_propagate": false}}'
 
  try:
    resp = requests.post(api_call, json=json.loads(json_string), headers=headers)
    if resp.status_code != 200:
      logger.error('Action "{}" on host "{}" for service "{}" failed with error: {}'.format(action, host, service, resp.status_code))
      failure = True
    else:
      logger.info('Action "{}" on host "{}" for service "{}" successful'.format(action, host, service))
  except Exception as e:
    logger.error('Action "{}" on host "{}" for service "{}" failed with error: {}'.format(action, host, service, e))
    failure = True
  
  
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--action', required=True, type=str)
args = parser.parse_args(sys.argv[1:])
action = args.action
for nas in config:
  host = config[nas]["host"]
  api_key = config[nas]["api_key"]
  skip = config[nas]["skip"]
  if skip:
    logger.info('Ignoring actions for host "{}"'.format(host))
  else:
    service_action(host, 'cifs', api_key, action)
    service_action(host, 'nfs', api_key, action)
if failure:
  raise Exception('Some or all commands failed')
config_truenas_services.json
Code:
{
    "nas":{
        "host":"nas",
        "api_key":"<key>",
        "skip": false
    },
    "nas2":{
        "host":"nas2",
        "api_key":"<key2>",
        "skip": false
    }
}
logging.yaml. Filename is full path. If i remember correctly this was really necessary.
Code:
version: 1
disable_existing_loggers: False
formatters:
    console_formatter:
        format: "%(levelname)s - %(message)s"
       
    file_formatter:
        format: "[%(asctime)s] [%(levelname)s] [%(funcName)s] - %(message)s"
       
filters: []
handlers:
    console:
        class: logging.StreamHandler
        level: INFO
        formatter: console_formatter
        stream: ext://sys.stdout
    file_handler:
        class: logging.FileHandler
        level: DEBUG
        formatter: file_formatter
        filename: "/home/test/bin_var/logging.log"
       
#    session_handler:
#        class: logging.FileHandler
#        level: DEBUG
#        formatter: file_formatter
#        filename: "session.log"
#        mode: 'w'
root:
    level: DEBUG
    handlers: [console, file_handler]
    #handlers: [console, file_handler, session_handler]