Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Signed-off-by: Liu, Xiaopeng (133) <[email protected]>
  • Loading branch information
Liu, Xiaopeng (133) committed May 25, 2020
1 parent fc45b9e commit 2b285c6
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 36 deletions.
22 changes: 11 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# Changelog

## [0.1.1][]
## [0.1.3]

### Changed

- Bugfix: kill process now passes correct parameter
- Refactory: abstract core workflow into one common function to reduce duplicates
- Refactory: [Issue #4](https://github.com/chaostoolkit-incubator/chaostoolkit-saltstack/issues/4) Salt API accepts eauth method as parameter in configuration

### Added

- Network experiments now accepts device name to adapt different os
- Add experiment action of kill processes by name
- Add experiment action of kill process by PID
- Add experiment probe to check process PID by name
- Add experiment action: run customized command line with run_cmd method

## [0.1.1]

### Changed

- Refactory: abstract core workflow into one common function to reduce duplicates
- Bugfix: kill process now passes correct parameter
- Refactory: abstract core workflow into one common function to reduce duplicates

### Added

- Add experiment action of kill processes by name
- Add experiment action of kill process by PID
- Add experiment probe to check process PID by name
- Network experiments now accepts device name to adapt different os
- Add experiment action of kill processes by name
- Add experiment action of kill process by PID
- Add experiment probe to check process PID by name

## [0.1.0][]

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,15 @@ There are two ways of doing this:
```

* or you inject the secrets explicitly to the experiment definition:
SALTMASTER_EAUTH is optional and default to pam

```json
{
"saltstack": {
"SALTMASTER_HOST": "https://172.10.20.666",
"SALTMASTER_USER": "username",
"SALTMASTER_PASSWORD": "password"
"SALTMASTER_EAUTH": "sharedsecret"
}
}
```
Expand Down
7 changes: 5 additions & 2 deletions chaossaltstack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ def __init__(self, configuration):
elif 'username' in configuration:
self.username = configuration['username']
self.password = configuration['password']
self.eauth = configuration['eauth']
# Default settings for Salt Master
self.headers = {"Content-type": "application/json"}
self.params = {'client': 'local', 'fun': '', 'tgt': ''}
# Use User/Pass
self.login_url = self.url + "/login"
self.login_params = {
'username': self.username, 'password': self.password,
'eauth': 'pam'
'eauth': self.eauth
}

def run_cmd(self, tgt, method: str, arg=None):
Expand Down Expand Up @@ -164,9 +165,10 @@ def saltstack_api_client(secrets: Secrets = None) -> salt_api_client:
* SALTMASTER_HOST: Salt Master API address
You can authenticate with user / password via:
You can authenticate with user / password / eauth via:
* SALTMASTER_USER: the user name
* SALTMASTER_PASSWORD: the password
* SALTMASTER_EAUTH: the auth method, default to pam
Or via a token:
* SALTMASTER_TOKEN
Expand Down Expand Up @@ -197,6 +199,7 @@ def lookup(k: str, d: str = None) -> str:
if "SALTMASTER_USER" in env or "SALTMASTER_USER" in secrets:
configuration['username'] = lookup("SALTMASTER_USER", "")
configuration['password'] = lookup("SALTMASTER_PASSWORD", "")
configuration['eauth'] = lookup("SALTMASTER_EAUTH", "pam")
elif "SALTMASTER_TOKEN" in env or "SALTMASTER_TOKEN" in secrets:
configuration['token'] = lookup("SALTMASTER_TOKEN")
else:
Expand Down
104 changes: 87 additions & 17 deletions chaossaltstack/machine/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
from ..types import SaltStackResponse
from .constants import OS_LINUX, OS_WINDOWS
from .constants import BURN_CPU, FILL_DISK, NETWORK_UTIL, \
BURN_IO, KILLALL_PROCESSES, KILL_PROCESS
BURN_IO, KILLALL_PROCESSES, KILL_PROCESS, RUN_CMD


__all__ = ["burn_cpu", "fill_disk", "network_latency", "burn_io",
"network_loss", "network_corruption", "network_advanced",
"killall_processes", "kill_process"]
"killall_processes", "kill_process", "run_cmd"]


def burn_cpu(instance_ids: List[str] = None,
Expand Down Expand Up @@ -209,7 +209,7 @@ def network_loss(instance_ids: List[str] = None,
param["duration"] = execution_duration
param["param"] = "loss " + loss_ratio
param["device"] = device

return __default_salt_experiment__(instance_ids=instance_ids,
execution_duration=execution_duration,
param=param,
Expand Down Expand Up @@ -253,7 +253,6 @@ def network_corruption(instance_ids: List[str] = None,
param["param"] = "corrupt " + corruption_ratio
param["device"] = device


return __default_salt_experiment__(instance_ids=instance_ids,
execution_duration=execution_duration,
param=param,
Expand Down Expand Up @@ -341,7 +340,7 @@ def killall_processes(instance_ids: List[str] = None,
Chaostoolkit Secrets
"""
logger.debug(
"Start network_latency: configuration='{}', instance_ids='{}'".format(
"Start killall_process: configuration='{}', instance_ids='{}'".format(
configuration, instance_ids))

param = dict()
Expand Down Expand Up @@ -389,7 +388,7 @@ def kill_process(instance_ids: List[str] = None,
Chaostoolkit Secrets
"""
logger.debug(
"Start network_latency: configuration='{}', instance_ids='{}'".format(
"Start kill_process: configuration='{}', instance_ids='{}'".format(
configuration, instance_ids))

param = dict()
Expand All @@ -406,6 +405,50 @@ def kill_process(instance_ids: List[str] = None,
)


def run_cmd(instance_ids: List[str] = None,
execution_duration: str = "60",
cmd: List[str] = None,
configuration: Configuration = None,
secrets: Secrets = None) -> SaltStackResponse:
"""
run cmd
Linus -> Shell
Windows -> PowerShell
Parameters
----------
instance_ids : List[str]
Filter the virtual machines. If the filter is omitted all machines in
the subscription will be selected as potential chaos candidates.
execution_duration : str, optional default to 1 second
This is not technically not useful as the process usually is killed
without and delay, however you can set more seconds here to let the
thread wait for more time to extend your experiment execution in case
you need to watch more on the observation metrics.
cmd : List[str]
Lines of your commands
configuration : Configuration
Chaostoolkit Configuration
secrets : Secrets
Chaostoolkit Secrets
"""
logger.debug(
"Start run_cmd: configuration='{}', instance_ids='{}'".format(
configuration, instance_ids))

param = dict()
param["duration"] = execution_duration
param["cmd"] = cmd

return __default_salt_experiment__(instance_ids=instance_ids,
execution_duration=execution_duration,
param=param,
experiment_type=RUN_CMD,
configuration=configuration,
secrets=secrets
)


###############################################################################
# Private helper functions
###############################################################################
Expand Down Expand Up @@ -459,25 +502,52 @@ def __default_salt_experiment__(instance_ids: List[str] = None,
)


def __construct_script_content__(action, os_type, parameters):
def __construct_script_content__(action: str = None,
os_type: str = None,
parameters: dict = None):
"""
As for now, no Windows action supported except burn CPU
:param action:
:param os_type: { OS_LINUX | OS_WINDOWS }
:param parameters:
:return:
"""

if os_type == OS_WINDOWS:
script_name = action+".ps1"
# TODO in ps1
cmd_param = '\n'.join(
['='.join([k, "'"+v+"'"]) for k, v in parameters.items()])
elif os_type == OS_LINUX:
script_name = action+".sh"
cmd_param = '\n'.join(
['='.join([k, "'"+v+"'"]) for k, v in parameters.items()])
cmd_param = ""
if os_type == OS_LINUX:
file_suffix = ".sh"
p_delimiter = ""
cmdline_delimiter = " && "
elif os_type == OS_WINDOWS:
file_suffix = ".ps1"
p_delimiter = "$"
cmdline_delimiter = "\n"
else:
raise FailedActivity(
"Cannot find corresponding script for {} on OS: {}".format(
action, os_type))

if action == "run_cmd":
cmdline_param = cmdline_delimiter.join(parameters['cmd'])
# parameters.pop('cmd')
del parameters['cmd']
else:
cmdline_param = ""

if parameters is not None:
param_list = list()
for k, v in parameters.items():
param_list.append('='.join([p_delimiter + k, "'" + v + "'"]))
cmd_param = '\n'.join(param_list)
else:
logger.info("No parameter parsed, return default script content")

script_name = action + file_suffix

with open(os.path.join(os.path.dirname(__file__),
"scripts", script_name)) as file:
script_content = file.read()
# merge duration
script_content = cmd_param + "\n" + script_content
script_content = cmd_param + "\n" + cmdline_param + "\n" + script_content
return script_content
1 change: 1 addition & 0 deletions chaossaltstack/machine/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
NETWORK_UTIL = "network_advanced"
KILLALL_PROCESSES = "killall_processes"
KILL_PROCESS = "kill_process"
RUN_CMD = "run_cmd"
4 changes: 2 additions & 2 deletions chaossaltstack/machine/scripts/burn_io.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ done
EOF

chmod +x /tmp/loop.sh
timeout --preserve-status $duration /tmp/loop.sh
timeout $duration /tmp/loop.sh

# while true;
# do
# dd if=/dev/urandom of=/experiment_burnio bs=1M count=1024 iflag=fullblock status=none
# done &

ret=$?
if [ $ret -eq 0 ]; then
if [[ $ret -eq 0 || $ret -eq 124 ]]; then
echo "experiment burnio -> <$instance_id>: success"
else
echo "experiment brunio -> <$instance_id>: fail"
Expand Down
8 changes: 4 additions & 4 deletions chaossaltstack/machine/scripts/network_advanced.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ fi
experiment=$(tc qdisc add dev $device root netem $param)
ret=$?
if [ $ret -eq 0 ]; then
echo "experiment network_latency -> <$instance_id>: success"
echo "experiment network:[$param] -> <$instance_id>: success"
else
echo "experiment network_latency -> <$instance_id>: fail"
echo "experiment network:[$param] -> <$instance_id>: fail"
fi

#Sleep $duration
Expand All @@ -38,7 +38,7 @@ fi
tc -s qdisc show dev $device |grep pfifo_fast 2>&1 >/dev/null
ret2=$?
if [ $ret2 -eq 0 ]; then
echo "recover network_latency -> <$instance_id>: success"
echo "recover network:[$param] -> <$instance_id>: success"
else
echo "recover network_latency -> <$instance_id>: fail"
echo "recover network:[$param] -> <$instance_id>: fail"
fi
12 changes: 12 additions & 0 deletions chaossaltstack/machine/scripts/run_cmd.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Try
{

}
Catch
{

}
Finally
{

}
7 changes: 7 additions & 0 deletions chaossaltstack/machine/scripts/run_cmd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

ret=$?
if [ $ret -eq 0 ]; then
echo "experiment run_cmd -> <$instance_id>: success"
else
echo "experiment run_cmd -> <$instance_id>: fail"
fi

0 comments on commit 2b285c6

Please sign in to comment.