stoobly-agent 1.9.6__py3-none-any.whl → 1.9.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. stoobly_agent/__init__.py +1 -1
  2. stoobly_agent/app/cli/scaffold/constants.py +1 -0
  3. stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py +4 -4
  4. stoobly_agent/app/cli/scaffold/service.py +6 -0
  5. stoobly_agent/app/cli/scaffold/service_command.py +8 -0
  6. stoobly_agent/app/cli/scaffold/service_update_command.py +70 -0
  7. stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +3 -2
  8. stoobly_agent/app/cli/scaffold/templates/app/.Makefile +34 -57
  9. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml +1 -0
  10. stoobly_agent/app/cli/scaffold/workflow_copy_command.py +1 -2
  11. stoobly_agent/app/cli/scaffold/workflow_create_command.py +1 -2
  12. stoobly_agent/app/cli/scaffold/workflow_run_command.py +2 -2
  13. stoobly_agent/app/cli/scaffold_cli.py +31 -13
  14. stoobly_agent/app/cli/validators/scaffold.py +5 -0
  15. {stoobly_agent-1.9.6.dist-info → stoobly_agent-1.9.8.dist-info}/METADATA +1 -1
  16. {stoobly_agent-1.9.6.dist-info → stoobly_agent-1.9.8.dist-info}/RECORD +32 -31
  17. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.disable → intercept/.disable} +0 -0
  18. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.enable → intercept/.enable} +0 -0
  19. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.down → scaffold/.down} +0 -0
  20. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.logs → scaffold/.logs} +0 -0
  21. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.mkcert → scaffold/.mkcert} +0 -0
  22. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.services → scaffold/.services} +0 -0
  23. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.up → scaffold/.up} +0 -0
  24. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.create → scenario/.create} +0 -0
  25. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.delete → scenario/.delete} +0 -0
  26. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.list → scenario/.list} +0 -0
  27. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.overwrite → scenario/.overwrite} +0 -0
  28. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.reset → scenario/.reset} +0 -0
  29. /stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/{.snapshot → scenario/.snapshot} +0 -0
  30. {stoobly_agent-1.9.6.dist-info → stoobly_agent-1.9.8.dist-info}/LICENSE +0 -0
  31. {stoobly_agent-1.9.6.dist-info → stoobly_agent-1.9.8.dist-info}/WHEEL +0 -0
  32. {stoobly_agent-1.9.6.dist-info → stoobly_agent-1.9.8.dist-info}/entry_points.txt +0 -0
stoobly_agent/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
1
  COMMAND = 'stoobly-agent'
2
- VERSION = '1.9.6'
2
+ VERSION = '1.9.8'
@@ -61,4 +61,5 @@ WORKFLOW_TEMPLATE = '${WORKFLOW_TEMPLATE}'
61
61
  WORKFLOW_TEMPLATE_ENV = 'WORKFLOW_TEMPLATE'
62
62
  WORKFLOW_TEST_TYPE = 'test'
63
63
 
64
+ CORE_WORKFLOWS = [WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE]
64
65
  WORKFLOW_TEMPLATE_OPTION = Literal[WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE]
@@ -10,7 +10,7 @@ from stoobly_agent.app.cli.scaffold.service_config import ServiceConfig
10
10
  from stoobly_agent.app.cli.scaffold.docker.constants import APP_INGRESS_NETWORK_NAME, APP_EGRESS_NETWORK_NAME, DOCKER_COMPOSE_BASE, DOCKER_COMPOSE_BASE_TEMPLATE
11
11
  from stoobly_agent.app.cli.scaffold.templates.constants import CORE_GATEWAY_SERVICE_NAME
12
12
 
13
- def configure_gateway(workflow_name, service_paths: List[str], no_publish = False):
13
+ def configure_gateway(namespace: str, service_paths: List[str], no_publish = False):
14
14
  if len(service_paths) == 0:
15
15
  return
16
16
 
@@ -36,7 +36,7 @@ def configure_gateway(workflow_name, service_paths: List[str], no_publish = Fals
36
36
  gateway_base['ports'] = ports
37
37
 
38
38
  app_dir_path = os.path.dirname(os.path.dirname(service_dir_path))
39
- __with_traefik_config(workflow_name, service_paths, app_dir_path, gateway_base)
39
+ __with_traefik_config(namespace, service_paths, app_dir_path, gateway_base)
40
40
  __with_networks(gateway_base, hostnames)
41
41
 
42
42
  with open(docker_compose_dest_path, 'w') as fp:
@@ -50,7 +50,7 @@ def __with_networks(config: dict, hostnames: List[str]):
50
50
  'aliases': hostnames
51
51
  }
52
52
 
53
- def __with_traefik_config(workflow_name: str, service_paths: List[str], app_dir_path: str, compose: dict):
53
+ def __with_traefik_config(namespace: str, service_paths: List[str], app_dir_path: str, compose: dict):
54
54
  config_dest = '/etc/traefik/traefik.yml'
55
55
 
56
56
  if not compose['volumes']:
@@ -98,7 +98,7 @@ def __with_traefik_config(workflow_name: str, service_paths: List[str], app_dir_
98
98
  })
99
99
 
100
100
  # Create traefik.yml in .stoobly/tmp
101
- traefik_template_relative_path = os.path.join(DATA_DIR_NAME, TMP_DIR_NAME, workflow_name, 'traefik.yml')
101
+ traefik_template_relative_path = os.path.join(DATA_DIR_NAME, TMP_DIR_NAME, namespace, 'traefik.yml')
102
102
  traefik_template_dest_path = os.path.join(app_dir_path, traefik_template_relative_path)
103
103
 
104
104
  if not os.path.exists(os.path.dirname(traefik_template_dest_path)):
@@ -20,5 +20,11 @@ class Service():
20
20
  def service_name(self):
21
21
  return self.__service_name
22
22
 
23
+ @property
24
+ def workflows(self):
25
+ # Each directory in the service directory path is a workflow
26
+ workflows = [ f.name for f in os.scandir(self.dir_path) if f.is_dir() ]
27
+ return workflows
28
+
23
29
  def workflow_dir_path(self, workflow_name: str):
24
30
  return os.path.join(self.dir_path, workflow_name)
@@ -18,6 +18,10 @@ class ServiceCommand(AppCommand):
18
18
  def service_config(self):
19
19
  return self.__config
20
20
 
21
+ @service_config.setter
22
+ def service_config(self, value):
23
+ self.__config = value
24
+
21
25
  @property
22
26
  def service_config_path(self):
23
27
  return self.__config.path
@@ -26,6 +30,10 @@ class ServiceCommand(AppCommand):
26
30
  def service_name(self):
27
31
  return self.__service_name
28
32
 
33
+ @service_name.setter
34
+ def service_name(self, value):
35
+ self.__service_name = value
36
+
29
37
  @property
30
38
  def service_exists(self):
31
39
  return os.path.exists(self.service_path)
@@ -0,0 +1,70 @@
1
+ import os
2
+ import pdb
3
+
4
+ from stoobly_agent.app.cli.scaffold.app import App
5
+ from stoobly_agent.app.cli.scaffold.constants import CORE_WORKFLOWS
6
+ from stoobly_agent.app.cli.scaffold.docker.workflow.decorators_factory import get_workflow_decorators
7
+ from stoobly_agent.app.cli.scaffold.service import Service
8
+ from stoobly_agent.app.cli.scaffold.service_command import ServiceCommand
9
+ from stoobly_agent.app.cli.scaffold.service_create_command import ServiceCreateCommand
10
+ from stoobly_agent.app.cli.scaffold.service_config import ServiceConfig
11
+ from stoobly_agent.app.cli.scaffold.workflow_config import WorkflowConfig
12
+ from stoobly_agent.app.cli.scaffold.workflow_create_command import WorkflowCreateCommand
13
+
14
+ from stoobly_agent.lib.logger import Logger
15
+
16
+
17
+ LOG_ID = 'ServiceUpdateCommand'
18
+
19
+ class ServiceUpdateCommand(ServiceCommand):
20
+
21
+ def __init__(self, app: App, **kwargs):
22
+ super().__init__(app, **kwargs)
23
+
24
+ def rename(self, new_service_name: str) -> Service:
25
+ self.__rename_service_dir(self.service_path, new_service_name)
26
+
27
+ self.service = Service(new_service_name, self.app)
28
+ self.service_config = ServiceConfig(self.service.dir_path)
29
+
30
+ self.__update_internal_container_specs(new_service_name)
31
+
32
+ return self.service
33
+
34
+ def __rename_service_dir(self, dir_path: str, new_name: str) -> None:
35
+ new_dir_path = os.path.join(self.app.scaffold_namespace_path, new_name)
36
+ os.rename(dir_path, new_dir_path)
37
+
38
+ def __update_internal_container_specs(self, new_service_name: str) -> None:
39
+ workflows = self.service.workflows
40
+
41
+ kwargs = {}
42
+ kwargs['app_dir_path'] = self.app.dir_path
43
+ kwargs['service_name'] = new_service_name
44
+ kwargs['workflow'] = workflows
45
+ command = ServiceCreateCommand(self.app, **kwargs)
46
+ command.build()
47
+
48
+ custom_workflows_set = set(workflows) - set(CORE_WORKFLOWS)
49
+ custom_workflows = list(custom_workflows_set)
50
+
51
+ for workflow in custom_workflows:
52
+ kwargs = {}
53
+ kwargs['app_dir_path'] = self.app.dir_path
54
+ kwargs['force'] = True
55
+ kwargs['service_name'] = new_service_name
56
+ kwargs['workflow_name'] = workflow
57
+
58
+ workflow_path = self.service.workflow_dir_path(workflow)
59
+ workflow_config = WorkflowConfig(workflow_path, **kwargs)
60
+ kwargs['template'] = workflow_config.template
61
+
62
+ command = WorkflowCreateCommand(self.app, **kwargs)
63
+
64
+ service_config = self.service_config
65
+ workflow_decorators = get_workflow_decorators(kwargs['template'], service_config)
66
+
67
+ command.build(
68
+ template=kwargs['template'],
69
+ workflow_decorators=workflow_decorators
70
+ )
@@ -116,12 +116,13 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
116
116
 
117
117
  def validate_internal_hostname(self, url: str) -> None:
118
118
  print(f"Validating hostname inside Docker network, url: {url}")
119
-
119
+
120
+ network = f"{self.workflow_name}.{self.app_config.network}"
120
121
  timeout_seconds = 1
121
122
  output = self.docker_client.containers.run(
122
123
  image='curlimages/curl:8.11.0',
123
124
  command=f"curl --max-time {timeout_seconds} {url} --verbose",
124
- network=APP_EGRESS_NETWORK_TEMPLATE.format(network=self.app_config.network),
125
+ network=APP_EGRESS_NETWORK_TEMPLATE.format(network=network),
125
126
  stderr=True,
126
127
  remove=True,
127
128
  )
@@ -1,20 +1,23 @@
1
1
  # Overridable Environment Variables
2
2
  #
3
- # STOOBLY_APP_DIR: path to the application source code directory
4
- # STOOBLY_CA_CERTS_DIR: path to folder where ca certs are stored
5
- # STOOBLY_CERTS_DIR: path to a folder to store certs
6
- # STOOBLY_CONTEXT_DIR: path to the folder containing the .stoobly folder
7
- # STOOBLY_WORKFLOW_SERVICE_OPTIONS: extra --service options to pass 'stoobly-agent scaffold workflow' commands
3
+ # STOOBLY_APP_DIR: path to the application source code directory, defaults to $(pwd)
4
+ # STOOBLY_CA_CERTS_DIR: path to folder where ca certs are stored, defaults to $(pwd)/.stoobly/ca_certs
5
+ # STOOBLY_CERTS_DIR: path to a folder to store certs, defaults to $(pwd)/.stoobly/certs
6
+ # STOOBLY_CONTEXT_DIR: path to the folder containing the .stoobly folder, defaults to $(pwd)
7
+ # STOOBLY_ENV_FILE: path to dotenv file, defaults to $(pwd)/.env
8
+ # STOOBLY_WORKFLOW_SERVICE_OPTIONS: extra --service options to pass 'stoobly-agent scaffold workflow' commands
8
9
 
9
10
  # Overridable Options
10
11
  #
11
- # workflow_down_extra_options: e.g. $(eval workflow_down_extra_options=<OPTIONS>)
12
- # workflow_log_extra_options: e.g. $(eval workflow_log_extra_options=<OPTIONS>)
13
- # workflow_up_extra_options: e.g. $(eval workflow_up_extra_options=<OPTIONS>)
12
+ # workflow_down_extra_options e.g. $(eval workflow_down_extra_options=<OPTIONS>)
13
+ # workflow_log_extra_options e.g. $(eval workflow_log_extra_options=<OPTIONS>)
14
+ # workflow_up_extra_options e.g. $(eval workflow_up_extra_options=<OPTIONS>)
15
+ #
16
+ # For full list, see targets with EXEC_OPTIONS
14
17
 
15
18
  # Constants
16
19
  DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
17
- EXEC_WORKFLOW_NAME := exec
20
+ DOCKER_BIN := docker
18
21
  PULL_OPTION := $(if $(STOOBLY_IMAGE_USE_LOCAL),,--pull)
19
22
  USER_ID := $(shell id -u)
20
23
 
@@ -25,6 +28,7 @@ app_dir=$$(realpath "$${STOOBLY_APP_DIR:-$(CONTEXT_DIR_DEFAULT)}")
25
28
  ca_certs_dir=$$(realpath "$${STOOBLY_CA_CERTS_DIR:-$(app_data_dir)/ca_certs}")
26
29
  certs_dir=$$(realpath "$${STOOBLY_CERTS_DIR:-$(app_data_dir)/certs}")
27
30
  context_dir=$$(realpath "$${STOOBLY_CONTEXT_DIR:-$(CONTEXT_DIR_DEFAULT)}")
31
+ env_file=$$(realpath "$${STOOBLY_ENV_FILE:-.env}")
28
32
  workflow=record
29
33
  workflow_service_options=$(shell echo $$STOOBLY_WORKFLOW_SERVICE_OPTIONS)
30
34
 
@@ -33,13 +37,11 @@ app_namespace_dir=$(app_data_dir)/docker
33
37
  app_tmp_dir=$(app_data_dir)/tmp
34
38
  dockerfile_path=$(app_namespace_dir)/.Dockerfile.context
35
39
  exec_docker_compose_file_path=$(app_namespace_dir)/stoobly-ui/exec/.docker-compose.exec.yml
36
- exec_namespace=$(shell echo "$(workflow_namespace).$(context_dir)" | (md5 2>/dev/null || md5sum 2>/dev/null || shasum 2>/dev/null) | awk '{print $$1}')
37
40
  workflow_namespace=$(if $(namespace),$(namespace),$(workflow))
38
41
  workflow_script=.stoobly/tmp/$(workflow_namespace)/run.sh
39
42
 
40
43
  # Options
41
44
  certs_dir_options=--ca-certs-dir-path $(ca_certs_dir) --certs-dir-path $(certs_dir)
42
- stoobly_exec_options=--profile $(EXEC_WORKFLOW_NAME) -p $(exec_namespace)
43
45
  working_dir_options=--app-dir-path $(app_dir) --context-dir-path $(context_dir)
44
46
 
45
47
  workflow_down_options=--user-id $(USER_ID) $(workflow_down_extra_options)
@@ -48,15 +50,12 @@ workflow_run_options=--namespace $(workflow_namespace) --script-path $(workflow_
48
50
  workflow_up_options=$(working_dir_options) $(certs_dir_options) --user-id $(USER_ID) $(workflow_up_extra_options)
49
51
 
50
52
  # Commands
51
- docker_command=docker
52
- docker_compose_command=$(docker_command) compose
53
- exec_down=$(docker_compose_command) -f "$(exec_docker_compose_file_path)" $(stoobly_exec_options) down
54
53
  exec_env=APP_DIR="$(app_dir)" CA_CERTS_DIR="$(ca_certs_dir)" USER_ID="$(USER_ID)"
55
- exec_up=$(docker_compose_command) -f "$(exec_docker_compose_file_path)" $(stoobly_exec_options) up --abort-on-container-exit --remove-orphans
56
- source_env=(set -a; [ -f .env ] && source .env; set +a)
54
+ exec_up=$(DOCKER_BIN) compose -f "$(exec_docker_compose_file_path)" run --rm stoobly_ui.command
55
+ source_env=[ -f "$(env_file)" ] && . "$(env_file)"
57
56
 
58
57
  # Build base image
59
- stoobly_exec_build=$(docker_command) build $(stoobly_exec_build_args) $(app_namespace_dir)
58
+ stoobly_exec_build=$(DOCKER_BIN) build $(stoobly_exec_build_args) $(app_namespace_dir) > /dev/null
60
59
  stoobly_exec_build_args=-f "$(dockerfile_path)" -t stoobly.$(USER_ID) --build-arg USER_ID=$(USER_ID) $(PULL_OPTION) --quiet
61
60
 
62
61
  # Exec any
@@ -64,8 +63,8 @@ stoobly_exec=$(stoobly_exec_build) && $(stoobly_exec_env) $(exec_up)
64
63
  stoobly_exec_env=$(source_env) && $(exec_env) CONTEXT_DIR="$(context_dir)"
65
64
 
66
65
  # Exec workflow run
67
- # Scaffold is stored in the application source code directory,
68
- # when running a scaffold command from within a container, it needs access to $(app_dir) rather than $(context_dir)
66
+ # Scaffold is stored in the application source code directory.
67
+ # When running a scaffold command from within a container, it needs access to $(app_dir) rather than $(context_dir)
69
68
  stoobly_exec_run=$(stoobly_exec_build) && $(stoobly_exec_run_env) $(exec_up)
70
69
  stoobly_exec_run_env=$(source_env) && $(exec_env) CONTEXT_DIR="$(app_dir)"
71
70
 
@@ -87,10 +86,8 @@ ca-cert/install: stoobly/install
87
86
  fi \
88
87
  fi
89
88
  certs:
90
- @export EXEC_COMMAND=.mkcert && \
89
+ @export EXEC_COMMAND=scaffold/.mkcert EXEC_OPTIONS="" EXEC_ARGS="" && \
91
90
  $(stoobly_exec)
92
- exec/down:
93
- @$(stoobly_exec_env) EXEC_COMMAND=- EXEC_ARGS=- EXEC_OPTIONS=- $(exec_down)
94
91
  nameservers: tmpdir
95
92
  @if [ -f /etc/resolv.conf ]; then \
96
93
  nameserver=$$(grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' /etc/resolv.conf) && \
@@ -103,16 +100,15 @@ nameservers: tmpdir
103
100
  echo "/etc/resolv.conf not found." >&2; \
104
101
  fi
105
102
  intercept/disable:
106
- @export EXEC_COMMAND=.disable && \
103
+ @export EXEC_COMMAND=intercept/.disable EXEC_OPTIONS="" EXEC_ARGS="" && \
107
104
  $(stoobly_exec)
108
105
  intercept/enable:
109
- @export EXEC_COMMAND=.enable && \
110
- export EXEC_ARGS=$(scenario_key) && \
106
+ @export EXEC_COMMAND=intercept/.enable EXEC_OPTIONS="" EXEC_ARGS=$(scenario_key) && \
111
107
  $(stoobly_exec)
112
108
  mock: workflow/mock ca-cert/install workflow/hostname/install nameservers workflow/up
113
109
  mock/services: workflow/mock workflow/services
114
110
  mock/logs: workflow/mock workflow/logs
115
- mock/down: workflow/mock workflow/down workflow/hostname/uninstall exec/down
111
+ mock/down: workflow/mock workflow/down workflow/hostname/uninstall
116
112
  pipx/install:
117
113
  @if ! command -v pipx >/dev/null 2>&1; then \
118
114
  echo "pipx is not installed. Installing pipx..."; \
@@ -124,43 +120,32 @@ python/validate:
124
120
  exit 1; \
125
121
  fi
126
122
  record: workflow/record ca-cert/install workflow/hostname/install nameservers workflow/up
127
- record/down: workflow/record workflow/down workflow/hostname/uninstall exec/down
123
+ record/down: workflow/record workflow/down workflow/hostname/uninstall
128
124
  record/services: workflow/record workflow/services
129
125
  record/logs: workflow/record workflow/logs
130
126
  scenario/create:
131
127
  # Create a scenario
132
- @export EXEC_COMMAND=.create && \
133
- export EXEC_OPTIONS="$(options)" && \
134
- export EXEC_ARGS="$(name)" && \
128
+ @export EXEC_COMMAND=scenario/.create EXEC_OPTIONS="$(options)" EXEC_ARGS="$(name)" && \
135
129
  $(stoobly_exec)
136
130
  scenario/delete:
137
131
  # Delete a scenario
138
- @export EXEC_COMMAND=.delete && \
139
- export EXEC_OPTIONS="$(options)" && \
140
- export EXEC_ARGS="$(key)" && \
132
+ @export EXEC_COMMAND=scenario/.delete EXEC_OPTIONS="$(options)" EXEC_ARGS="$(key)" && \
141
133
  $(stoobly_exec)
142
134
  scenario/list:
143
135
  # List scenarios
144
- @export EXEC_COMMAND=.list && \
145
- export EXEC_OPTIONS="$(options)" && \
136
+ @export EXEC_COMMAND=scenario/.list EXEC_OPTIONS="$(options)" EXEC_ARGS="" && \
146
137
  $(stoobly_exec)
147
138
  scenario/overwrite:
148
139
  # Overwrite a scenario
149
- @export EXEC_COMMAND=.overwrite && \
150
- export EXEC_OPTIONS="$(options)" && \
151
- export EXEC_ARGS="$(key)" && \
140
+ @export EXEC_COMMAND=scenario/.overwrite EXEC_OPTIONS="$(options)" EXEC_ARGS="$(key)" && \
152
141
  $(stoobly_exec)
153
142
  scenario/reset:
154
143
  # Resets a scenario to its last snapshot
155
- @export EXEC_COMMAND=.reset && \:
156
- export EXEC_OPTIONS="$(options)" && \
157
- export EXEC_ARGS="$(key)" && \
144
+ @export EXEC_COMMAND=scenario/.reset EXEC_OPTIONS="$(options)" EXEC_ARGS="$(key)" && \
158
145
  $(stoobly_exec)
159
146
  scenario/snapshot:
160
147
  # Create committable files for a scenario
161
- @export EXEC_COMMAND=.snapshot && \
162
- export EXEC_OPTIONS="$(options)" && \
163
- export EXEC_ARGS="$(key)" && \
148
+ @export EXEC_COMMAND=scenario/.snapshot EXEC_OPTIONS="$(options)" EXEC_ARGS="$(key)" && \
164
149
  $(stoobly_exec)
165
150
  stoobly/install: python/validate pipx/install
166
151
  @if ! pipx list 2> /dev/null | grep -q 'stoobly-agent'; then \
@@ -170,13 +155,11 @@ stoobly/install: python/validate pipx/install
170
155
  test: workflow/test workflow/up
171
156
  test/services: workflow/test workflow/services
172
157
  test/logs: workflow/test workflow/logs
173
- test/down: workflow/test workflow/down exec/down
158
+ test/down: workflow/test workflow/down
174
159
  tmpdir:
175
160
  @mkdir -p $(app_tmp_dir)
176
161
  workflow/down:
177
- @export EXEC_COMMAND=.down && \
178
- export EXEC_OPTIONS="$(workflow_down_options) $(workflow_run_options) $(options)" && \
179
- export EXEC_ARGS="$(workflow)" && \
162
+ @export EXEC_COMMAND=scaffold/.down EXEC_OPTIONS="$(workflow_down_options) $(workflow_run_options) $(options)" EXEC_ARGS="$(workflow)" && \
180
163
  $(stoobly_exec_run) && \
181
164
  $(workflow_run)
182
165
  workflow/hostname: stoobly/install
@@ -194,9 +177,7 @@ workflow/hostname: stoobly/install
194
177
  workflow/hostname/install: action/install workflow/hostname
195
178
  workflow/hostname/uninstall: action/uninstall workflow/hostname
196
179
  workflow/logs:
197
- @export EXEC_COMMAND=.logs && \
198
- export EXEC_OPTIONS="$(workflow_log_options) $(workflow_run_options) $(options)" && \
199
- export EXEC_ARGS="$(workflow)" && \
180
+ @export EXEC_COMMAND=scaffold/.logs EXEC_OPTIONS="$(workflow_log_options) $(workflow_run_options) $(options)" EXEC_ARGS="$(workflow)" && \
200
181
  $(stoobly_exec_run) && \
201
182
  $(workflow_run)
202
183
  workflow/mock:
@@ -204,15 +185,11 @@ workflow/mock:
204
185
  workflow/record:
205
186
  $(eval workflow=record)
206
187
  workflow/services:
207
- @export EXEC_COMMAND=.services && \
208
- export EXEC_OPTIONS="$(workflow_service_options) $(options)" && \
209
- export EXEC_ARGS="$(workflow)" && \
188
+ @export EXEC_COMMAND=scaffold/.services EXEC_OPTIONS="$(workflow_service_options) $(options)" EXEC_ARGS="$(workflow)" && \
210
189
  $(stoobly_exec_run)
211
190
  workflow/test:
212
191
  $(eval workflow=test) $(eval workflow_up_extra_options=$(workflow_up_extra_options) --no-publish)
213
192
  workflow/up:
214
- @export EXEC_COMMAND=.up && \
215
- export EXEC_OPTIONS="$(workflow_up_options) $(workflow_run_options) $(options)" && \
216
- export EXEC_ARGS="$(workflow)" && \
193
+ @export EXEC_COMMAND=scaffold/.up EXEC_OPTIONS="$(workflow_up_options) $(workflow_run_options) $(options)" EXEC_ARGS="$(workflow)" && \
217
194
  $(stoobly_exec_run) && \
218
195
  $(workflow_run)
@@ -7,5 +7,6 @@ services:
7
7
  file: ../.docker-compose.base.yml
8
8
  service: stoobly_ui.base
9
9
  image: stoobly.${USER_ID}
10
+ network_mode: none
10
11
  profiles:
11
12
  - exec
@@ -3,11 +3,10 @@ import pdb
3
3
  import shutil
4
4
 
5
5
  from .app import App
6
- from .constants import COMPOSE_TEMPLATE, WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE
6
+ from .constants import COMPOSE_TEMPLATE
7
7
  from .service_workflow import ServiceWorkflow
8
8
  from .workflow_command import WorkflowCommand
9
9
 
10
- CORE_WORKFLOWS = [WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE]
11
10
 
12
11
  class WorkflowCopyCommand(WorkflowCommand):
13
12
 
@@ -5,7 +5,7 @@ import shutil
5
5
  from typing import List, TypedDict, Union
6
6
 
7
7
  from .app import App
8
- from .constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE, WORKFLOW_TEMPLATE_OPTION
8
+ from .constants import WORKFLOW_TEMPLATE_OPTION
9
9
  from .docker.service.builder import ServiceBuilder
10
10
  from .docker.workflow.mock_decorator import MockDecorator
11
11
  from .docker.workflow.reverse_proxy_decorator import ReverseProxyDecorator
@@ -13,7 +13,6 @@ from .docker.workflow.builder import WorkflowBuilder
13
13
  from .templates.factory import custom_files, maintained_files
14
14
  from .workflow_command import WorkflowCommand
15
15
 
16
- CORE_WORKFLOWS = [WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE]
17
16
 
18
17
  class BuildOptions(TypedDict):
19
18
  builder_class: type
@@ -48,8 +48,8 @@ class WorkflowRunCommand(WorkflowCommand):
48
48
  self.__ca_certs_dir_path = kwargs.get('ca_certs_dir_path') or app.ca_certs_dir_path
49
49
  self.__certs_dir_path = kwargs.get('certs_dir_path') or app.certs_dir_path
50
50
  self.__context_dir_path = kwargs.get('context_dir_path') or app.context_dir_path
51
- self.__network = kwargs.get('network') or self.app_config.network
52
-
51
+ self.__network = f"{kwargs.get('network') or {self.workflow_name}}.{self.app_config.network}"
52
+
53
53
  @property
54
54
  def app_dir_path(self):
55
55
  return self.__app_dir_path
@@ -22,6 +22,7 @@ from stoobly_agent.app.cli.scaffold.service import Service
22
22
  from stoobly_agent.app.cli.scaffold.service_config import ServiceConfig
23
23
  from stoobly_agent.app.cli.scaffold.service_create_command import ServiceCreateCommand
24
24
  from stoobly_agent.app.cli.scaffold.service_delete_command import ServiceDeleteCommand
25
+ from stoobly_agent.app.cli.scaffold.service_update_command import ServiceUpdateCommand
25
26
  from stoobly_agent.app.cli.scaffold.service_workflow_validate_command import ServiceWorkflowValidateCommand
26
27
  from stoobly_agent.app.cli.scaffold.templates.constants import CORE_SERVICES
27
28
  from stoobly_agent.app.cli.scaffold.validate_exceptions import ScaffoldValidateException
@@ -145,10 +146,6 @@ def mkcert(**kwargs):
145
146
  def create(**kwargs):
146
147
  __validate_app_dir(kwargs['app_dir_path'])
147
148
 
148
- if '/' in kwargs['service_name']:
149
- print(f"Error: {kwargs['service_name']} is invalid. It cannot container '/", file=sys.stderr)
150
- sys.exit(1)
151
-
152
149
  if kwargs.get("proxy_mode"):
153
150
  __validate_proxy_mode(kwargs.get("proxy_mode"))
154
151
 
@@ -215,7 +212,7 @@ def delete(**kwargs):
215
212
  @click.option('--port', type=click.IntRange(1, 65535), help='Service port.')
216
213
  @click.option('--priority', default=5, type=click.FloatRange(1.0, 9.0), help='Determines the service run order. Lower values run first.')
217
214
  @click.option('--scheme', type=click.Choice(['http', 'https']), help='Defaults to https if hostname is set.')
218
- @click.option('--name', type=click.STRING, help='New name of the service to update to.')
215
+ @click.option('--name', callback=validate_service_name, type=click.STRING, help='New name of the service to update to.')
219
216
  @click.option('--proxy-mode', help='''
220
217
  Proxy mode can be "regular", "transparent", "socks5",
221
218
  "reverse:SPEC", or "upstream:SPEC". For reverse and
@@ -256,6 +253,19 @@ def update(**kwargs):
256
253
  if kwargs['scheme']:
257
254
  service_config.scheme = kwargs['scheme']
258
255
 
256
+ if kwargs['name']:
257
+ old_service_name = service.service_name
258
+ new_service_name = kwargs['name']
259
+
260
+ print(f"Renaming service from: {old_service_name}, to: {new_service_name}")
261
+
262
+ kwargs['service_path'] = service.dir_path
263
+ command = ServiceUpdateCommand(app, **kwargs)
264
+ service = command.rename(new_service_name)
265
+ service_config = command.service_config
266
+
267
+ print(f"Successfully renamed service to: {new_service_name}")
268
+
259
269
  if kwargs['proxy_mode']:
260
270
  __validate_proxy_mode(kwargs['proxy_mode'])
261
271
  service_config.proxy_mode = kwargs['proxy_mode']
@@ -337,9 +347,7 @@ def down(**kwargs):
337
347
  app = App(kwargs['app_dir_path'], DOCKER_NAMESPACE, **kwargs)
338
348
  __validate_app(app)
339
349
 
340
- # If namespace is set, default network to namespace
341
- if kwargs['namespace'] and not kwargs['network']:
342
- kwargs['network'] = kwargs['namespace']
350
+ __with_namespace_defaults(kwargs)
343
351
 
344
352
  services = __get_services(
345
353
  app, service=kwargs['service'], workflow=[kwargs['workflow_name']]
@@ -417,6 +425,8 @@ def logs(**kwargs):
417
425
  app = App(kwargs['app_dir_path'], DOCKER_NAMESPACE)
418
426
  __validate_app(app)
419
427
 
428
+ __with_namespace_defaults(kwargs)
429
+
420
430
  if len(kwargs['container']) == 0:
421
431
  kwargs['container'] = [WORKFLOW_CONTAINER_PROXY]
422
432
 
@@ -491,9 +501,7 @@ def up(**kwargs):
491
501
  app = App(app_dir_path, DOCKER_NAMESPACE, **kwargs)
492
502
  __validate_app(app)
493
503
 
494
- # If namespace is set, default network to namespace
495
- if kwargs['namespace'] and not kwargs['network']:
496
- kwargs['network'] = kwargs['namespace']
504
+ __with_namespace_defaults(kwargs)
497
505
 
498
506
  services = __get_services(
499
507
  app, service=kwargs['service'], workflow=[kwargs['workflow_name']]
@@ -505,7 +513,9 @@ def up(**kwargs):
505
513
 
506
514
  # Gateway ports are dynamically set depending on the workflow run
507
515
  workflow = Workflow(kwargs['workflow_name'], app)
508
- configure_gateway(workflow.workflow_name, workflow.service_paths_from_services(services), kwargs['no_publish'])
516
+ configure_gateway(
517
+ kwargs['namespace'] or workflow.workflow_name, workflow.service_paths_from_services(services), kwargs['no_publish']
518
+ )
509
519
 
510
520
  commands: List[WorkflowRunCommand] = []
511
521
  for service in services:
@@ -813,6 +823,14 @@ def __validate_proxy_mode(proxy_mode: str) -> None:
813
823
 
814
824
  # TODO: validate SPEC
815
825
 
826
+ def __with_namespace_defaults(kwargs):
827
+ if not kwargs.get('namespace'):
828
+ kwargs['namespace'] = kwargs.get('workflow_name')
829
+
830
+ # If network there was a network option, but it is not set, default network to namespace
831
+ if 'network' in kwargs and not kwargs['network']:
832
+ kwargs['network'] = kwargs['namespace']
833
+
816
834
  def __workflow_create(app, **kwargs):
817
835
  command = WorkflowCreateCommand(app, **kwargs)
818
836
 
@@ -822,4 +840,4 @@ def __workflow_create(app, **kwargs):
822
840
  command.build(
823
841
  template=kwargs['template'],
824
842
  workflow_decorators=workflow_decorators
825
- )
843
+ )
@@ -1,6 +1,8 @@
1
1
  import re
2
2
  import sys
3
3
 
4
+ from stoobly_agent.app.cli.scaffold.templates.constants import CORE_SERVICES
5
+
4
6
  def validate_app_name(ctx, param, app_name: str) -> str:
5
7
  app_name_regex = re.compile(r'^[a-zA-Z0-9._-]+$')
6
8
  if not re.search(app_name_regex, app_name):
@@ -27,6 +29,9 @@ def validate_namespace(ctx, param, namespace: str) -> str:
27
29
  return namespace
28
30
 
29
31
  def validate_service_name(ctx, param, service_name: str) -> str:
32
+ if service_name in CORE_SERVICES:
33
+ print(f"Error: {service_name} is a core service", file=sys.stderr)
34
+ sys.exit(1)
30
35
  service_name_regex = re.compile(r'^[a-zA-Z0-9._-]+$')
31
36
  if not re.search(service_name_regex, service_name):
32
37
  print(f"Error: service name {service_name} is invalid.", file=sys.stderr)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: stoobly-agent
3
- Version: 1.9.6
3
+ Version: 1.9.8
4
4
  Summary: Record, mock, and test HTTP(s) requests. CLI agent for Stoobly
5
5
  License: Apache-2.0
6
6
  Author: Matt Le
@@ -1,4 +1,4 @@
1
- stoobly_agent/__init__.py,sha256=UlQip9_Ul2fRC4UHN6HFN0lQDoz_AEInAcMSJiQnEow,44
1
+ stoobly_agent/__init__.py,sha256=pgRpNAxM2kYEnWKeHmmPTeaZZ9gCc4cXCyewkjyES70,44
2
2
  stoobly_agent/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  stoobly_agent/app/api/__init__.py,sha256=ctkB8KR-eXO0SFhj602huHiyvQ3PslFWd8fkcufgrAI,1000
4
4
  stoobly_agent/app/api/application_http_request_handler.py,sha256=Vvz53yB0bR7J-QqMAkLlhcZrA4P64ZEN7w8cMbgl6o0,5261
@@ -73,7 +73,7 @@ stoobly_agent/app/cli/scaffold/app_config.py,sha256=UGVJ7DVmXh-o_gYBlAAEjngNIUZP
73
73
  stoobly_agent/app/cli/scaffold/app_create_command.py,sha256=0ogYliGbq1PYP5rFs-ML33q_Z4t_rAgPWjhk7rhnGw0,1153
74
74
  stoobly_agent/app/cli/scaffold/command.py,sha256=aoTsdkkBzyu7TkVSMdNQQGk0Gj874jNgFcjR14y3TuM,254
75
75
  stoobly_agent/app/cli/scaffold/config.py,sha256=HZU5tkvr3dkPr4JMXZtrJlu2wxxO-134Em6jReFFcq0,688
76
- stoobly_agent/app/cli/scaffold/constants.py,sha256=dpCGvKzNtGQyaZfghfy0F6bJsZNp1KPACX3Z3rd13sw,2416
76
+ stoobly_agent/app/cli/scaffold/constants.py,sha256=e0aKyB80i1heJCubAvxt8DlzykAvYH37xeAcl9UTTgI,2496
77
77
  stoobly_agent/app/cli/scaffold/containerized_app.py,sha256=dAjn4RwcZV3aEL0POUmrbF_DC-r9h6s1zx7gT2t45v0,175
78
78
  stoobly_agent/app/cli/scaffold/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
79
  stoobly_agent/app/cli/scaffold/docker/app_builder.py,sha256=7z5pk5JKlRDHx2USxY-WurttLyyUkIVYfl34_u1x9dE,501
@@ -82,7 +82,7 @@ stoobly_agent/app/cli/scaffold/docker/constants.py,sha256=1khQdgTaQ89ykGRNdTQh_e
82
82
  stoobly_agent/app/cli/scaffold/docker/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
83
  stoobly_agent/app/cli/scaffold/docker/service/build_decorator.py,sha256=ZU7z4bkvdS3OK5O4fJhlA9_PNwnFtZW6t7vNF7V5obQ,1003
84
84
  stoobly_agent/app/cli/scaffold/docker/service/builder.py,sha256=4cIMSYvgrkGWVuuYymiwlrR829O91qQl9ML8FhaDMj4,5857
85
- stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py,sha256=jtx8lhvKHl0ubSHaQpE8m9lCYnOJ6Qju-SBJPBs0l7I,3921
85
+ stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py,sha256=8GQ2wUBwb45uSxhzkEMloezJT1hVu8v_3PudWLTU9ig,3910
86
86
  stoobly_agent/app/cli/scaffold/docker/service/types.py,sha256=qB-yYHlu-PZDc0HYgTUvE5bWNpHxaSThC3JUG8okR1k,88
87
87
  stoobly_agent/app/cli/scaffold/docker/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  stoobly_agent/app/cli/scaffold/docker/workflow/build_decorator.py,sha256=VKD9hXbJGRIWHS5IeYXeX0-FQ0F43zG8VmsegL6eYwA,703
@@ -94,17 +94,18 @@ stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py,sha256
94
94
  stoobly_agent/app/cli/scaffold/env.py,sha256=e-Ve4p3RUgzFx22B3SIYttvJ_yLuDtA27oDACZ8n-6E,1140
95
95
  stoobly_agent/app/cli/scaffold/hosts_file_manager.py,sha256=zNX5wh6zXQ4J2BA0YYdD7_CPqDz02b_ghXsY3oTjjB4,4999
96
96
  stoobly_agent/app/cli/scaffold/managed_services_docker_compose.py,sha256=-wLBXUi7DCWsfm5KzZzd_kdJKOTl1NT924XR7dyjbSY,574
97
- stoobly_agent/app/cli/scaffold/service.py,sha256=L9K6QE0k5KSEC8_fSwtdwwTSO_DsIpqSPW-AG7Bg76o,501
98
- stoobly_agent/app/cli/scaffold/service_command.py,sha256=9kIKiFC5Jo425VWYD4NDvUOdMP-pNyq2D5Ip1ZAPj3A,1054
97
+ stoobly_agent/app/cli/scaffold/service.py,sha256=74JwjTRRkk6lo-k9hre1iGztbKa9zDqjPVx3Qgpze-s,699
98
+ stoobly_agent/app/cli/scaffold/service_command.py,sha256=NxJakoq1Dy79LEIJ8QSsKEwsofIfN13GN0UGpp9i6qY,1230
99
99
  stoobly_agent/app/cli/scaffold/service_config.py,sha256=edL356wqpfJgFdeSrWof-CAUB1Tgi4nO1Jx9nkql9Qc,3903
100
100
  stoobly_agent/app/cli/scaffold/service_create_command.py,sha256=1B6TK3JDAjouikCV84WDrX7b0crdPMPIo1caMwhi-L8,2815
101
101
  stoobly_agent/app/cli/scaffold/service_delete_command.py,sha256=_nBDQjm8eL62MQpzSCxgUHlW04ZXKG8MDlN1BXxlqww,986
102
102
  stoobly_agent/app/cli/scaffold/service_docker_compose.py,sha256=OMUN1-ujQYIZXxDvS4XBf5C9wGalQULkwOiBBQPZbHY,820
103
+ stoobly_agent/app/cli/scaffold/service_update_command.py,sha256=oWusBKfvjt4RnK03_V3CJYWrfsCI4_LcR7W12eLXMR4,2579
103
104
  stoobly_agent/app/cli/scaffold/service_workflow.py,sha256=sQ_Edy_wGHKMXpD0DmhnOWkGEKz7gSgEGNI8f7aXOdg,444
104
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py,sha256=xONRUtfC3IBd-Kr4wdUKWgx9ppSsbu2H72pb2VinizQ,11412
105
+ stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py,sha256=veigidzR4EwGi8dc0v_l4Ik7cZikDBnLcvwcHNc1Wzg,11457
105
106
  stoobly_agent/app/cli/scaffold/templates/__init__.py,sha256=x8C_a0VoO_vUbosp4_6IC1U7Ge9NnUdVKDPpVMtMkeY,171
106
107
  stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context,sha256=Okk4Q0Fj7Wi5NU58gQfpjpFwAL3RUBJyRe56kteQfcA,158
107
- stoobly_agent/app/cli/scaffold/templates/app/.Makefile,sha256=4CTrKRHho9fl7NOGrQM0lJTfn-X09ddQKBq9Zsbjbww,9278
108
+ stoobly_agent/app/cli/scaffold/templates/app/.Makefile,sha256=ngPJu23xNtj7mxNotj-cgD6nijZx7I63-VlxhYnEVaw,8931
108
109
  stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.base.yml,sha256=6tFqXh3ine8vaD0FCL5TMoY5NjKx2wLUR8XpW3tJtew,245
109
110
  stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.networks.yml,sha256=I4PbJpQjFHb5IbAUWNvYM6okDEtmwtKFDQg-yog05WM,141
110
111
  stoobly_agent/app/cli/scaffold/templates/app/Makefile,sha256=TEmPG7Bf0KZOnmfsgdzza3UdwcVMmM5Lj1YdLc4cgjA,79
@@ -143,7 +144,7 @@ stoobly_agent/app/cli/scaffold/templates/app/gateway/record/.docker-compose.reco
143
144
  stoobly_agent/app/cli/scaffold/templates/app/gateway/test/.docker-compose.test.yml,sha256=oJO6i0lsuQaQeIH80yoPZo3Vs0LzUAH2WRl853yLq6g,136
144
145
  stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/.config.yml,sha256=XnLQZMzzMMIwVycjyPN5QXsmRztkTFAna1kIHYuDfJQ,19
145
146
  stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/.docker-compose.base.yml,sha256=bxrtZqf3YtaJCukzScslh5PgWC5q8xkGIP1wKJf33LA,111
146
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml,sha256=JN89sU5uRf6YqHvN_O63K8rwQIAPJHbhFDLFmuUjKNM,304
147
+ stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml,sha256=_lku3K0t2TRLMOcoSKcisCLQO_YCXZoevr_q6anjhL8,327
147
148
  stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/.docker-compose.mock.yml,sha256=2wg-YArlQVjat-bin_PLOnULQJW7mOmZjP7CFp6Knbs,242
148
149
  stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/.docker-compose.record.yml,sha256=yDw8OSX7rFsW6J51K5Qf33qM-isGL8V4xPAYayIfnvQ,245
149
150
  stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.configure,sha256=SKvht2K_3tW08K24rl8_j0jMYOhq1k-GsVwhoHwjxYA,337
@@ -158,19 +159,19 @@ stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.confi
158
159
  stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.init,sha256=AcM6SLUsZa6BOLDjxteDR_AXIco47GZNkWQCGPhPDAY,189
159
160
  stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.configure,sha256=xWJGhCKQejtVLFAOEZMWnaCeGAc9tuqEh_WsG3xfA_0,184
160
161
  stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.init,sha256=AcM6SLUsZa6BOLDjxteDR_AXIco47GZNkWQCGPhPDAY,189
161
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.create,sha256=EZe84bLAKB-mrB9PGMx-amyMjp6x-ESUZKC8wxrWdLE,245
162
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.delete,sha256=RspRDQ7WT5jpN2o-6qXOlH-A2VpN4981pD4ZJljk9Rw,260
163
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.disable,sha256=xVf4Pk1RLvJm7Ff0rbGoWhYHPv0ME5e93fxS2yFqLnE,45
164
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.down,sha256=WtEjm2hJ01-1GGxRmmcUqZq7VjEe5JfZZKvm8TNhNEs,219
165
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.enable,sha256=sfUSPG4uHdXX95BLgivXQYLbsLBP2DjJIiSTXRtvXuY,188
166
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.list,sha256=BdX3ARC-Piuwk0vFzBrcxEwtHjdFncpORzqP-hP4IwE,84
167
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.logs,sha256=4CJVEVLn9VTQN9LAjOJpijwd_DZ5IuIXL1aFCYkelxk,178
168
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.mkcert,sha256=vyHaXmvy-7oL2RD8rIxwT-fdJS5kXmB0yHK5fRMo_cM,46
169
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.overwrite,sha256=04VwyAXSGNLgbWRGacKAXhswfNlOk02ahprXK3LdSiA,297
170
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.reset,sha256=_pvbLk-ektsCHEh_egDtd6c0sVqCPunwUWggarfoli0,238
171
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.services,sha256=sAbaKzBxNDXimyUNinB_a2Kt47vUCa0Kd3Z1QAp2GrU,161
172
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.snapshot,sha256=Kav1QNhKG7f0DBzc4-9dmxZMmmVTxmPqakT_W4kVYKk,241
173
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/.up,sha256=S88O31UgsabaMvSwkQJjLF9C7mrFkyEk9x6JDE6qSXI,228
162
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/intercept/.disable,sha256=xVf4Pk1RLvJm7Ff0rbGoWhYHPv0ME5e93fxS2yFqLnE,45
163
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/intercept/.enable,sha256=sfUSPG4uHdXX95BLgivXQYLbsLBP2DjJIiSTXRtvXuY,188
164
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.down,sha256=WtEjm2hJ01-1GGxRmmcUqZq7VjEe5JfZZKvm8TNhNEs,219
165
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.logs,sha256=4CJVEVLn9VTQN9LAjOJpijwd_DZ5IuIXL1aFCYkelxk,178
166
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.mkcert,sha256=vyHaXmvy-7oL2RD8rIxwT-fdJS5kXmB0yHK5fRMo_cM,46
167
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.services,sha256=sAbaKzBxNDXimyUNinB_a2Kt47vUCa0Kd3Z1QAp2GrU,161
168
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.up,sha256=S88O31UgsabaMvSwkQJjLF9C7mrFkyEk9x6JDE6qSXI,228
169
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.create,sha256=EZe84bLAKB-mrB9PGMx-amyMjp6x-ESUZKC8wxrWdLE,245
170
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.delete,sha256=RspRDQ7WT5jpN2o-6qXOlH-A2VpN4981pD4ZJljk9Rw,260
171
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.list,sha256=BdX3ARC-Piuwk0vFzBrcxEwtHjdFncpORzqP-hP4IwE,84
172
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.overwrite,sha256=04VwyAXSGNLgbWRGacKAXhswfNlOk02ahprXK3LdSiA,297
173
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.reset,sha256=_pvbLk-ektsCHEh_egDtd6c0sVqCPunwUWggarfoli0,238
174
+ stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scenario/.snapshot,sha256=Kav1QNhKG7f0DBzc4-9dmxZMmmVTxmPqakT_W4kVYKk,241
174
175
  stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.configure,sha256=xWJGhCKQejtVLFAOEZMWnaCeGAc9tuqEh_WsG3xfA_0,184
175
176
  stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.init,sha256=el5LYLY-7P3-EuxZ8dAFgGNU_4zDhyA4D_iS6D4fvps,312
176
177
  stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.configure,sha256=xWJGhCKQejtVLFAOEZMWnaCeGAc9tuqEh_WsG3xfA_0,184
@@ -197,13 +198,13 @@ stoobly_agent/app/cli/scaffold/validate_exceptions.py,sha256=Jtjl4OkbbSRWm0hy7Kf
197
198
  stoobly_agent/app/cli/scaffold/workflow.py,sha256=KlbWT9CIo9EpZxKU1WVZtmodhxK7CpmLUHPNk4Mh6DA,1570
198
199
  stoobly_agent/app/cli/scaffold/workflow_command.py,sha256=eI9I5LLgO0U3b46QhHusy-4BV2zUDVai6jErcluYCRI,3344
199
200
  stoobly_agent/app/cli/scaffold/workflow_config.py,sha256=ghnbcnCyb6ECdylUJCAJ6A8ulzaFY9bu7RvRuYeiRkk,901
200
- stoobly_agent/app/cli/scaffold/workflow_copy_command.py,sha256=R9hh5dWVz7vGld7pENAA_a9gW56EkgG2K35nBQYXwyI,1462
201
- stoobly_agent/app/cli/scaffold/workflow_create_command.py,sha256=R3L1obUTidGngbIaRlVjt_Rjkw9qOPze_p5plHc8JHs,3532
201
+ stoobly_agent/app/cli/scaffold/workflow_copy_command.py,sha256=wi8qHH_M2e6jXIPuumx65Zd4Zt7hTBb6b3Z4vt4xYeQ,1320
202
+ stoobly_agent/app/cli/scaffold/workflow_create_command.py,sha256=-fwsr6_LvGT8BbBWdGY3Qd8cSQhBOSJiMr1r8s2R86w,3390
202
203
  stoobly_agent/app/cli/scaffold/workflow_env.py,sha256=x8V5pJmIiklD3f2q2-qq-CORf4YaXYq_r2JpR2MmSwk,416
203
204
  stoobly_agent/app/cli/scaffold/workflow_log_command.py,sha256=Bke4lMOMxuDUFuAx9nlXHbKgYMO4KAg9ASHvjz4aVWc,1372
204
- stoobly_agent/app/cli/scaffold/workflow_run_command.py,sha256=eF3aaK4OIZXYuSBEAeBnhAL7EZrS1G4mSYrJbEiXt2o,11082
205
+ stoobly_agent/app/cli/scaffold/workflow_run_command.py,sha256=AZhLd1N260RjXEiUSRppqfhQMwVyRnn0jpapRu4FwyM,11114
205
206
  stoobly_agent/app/cli/scaffold/workflow_validate_command.py,sha256=Uo_yo6rVR1ZR7xpvsQvlH48AyMBVLRupd4G-bRjzm_Q,5584
206
- stoobly_agent/app/cli/scaffold_cli.py,sha256=9NOSl3Qy7LN3PphuOqTFEM6t0PanVEHow8iyW-5eTW0,31958
207
+ stoobly_agent/app/cli/scaffold_cli.py,sha256=DTPrvfEC38e0RUILeiuevGJ7JiXs_YoXq8ITFtC3FIo,32523
207
208
  stoobly_agent/app/cli/scenario_cli.py,sha256=3J1EiJOvunkfWrEkOsanw-XrKkOk78ij_GjBlE9p7CE,8229
208
209
  stoobly_agent/app/cli/snapshot_cli.py,sha256=1Dw5JgDlmG6vctrawIRO7CdB73vAQk_wRBnPG2lVOrQ,11929
209
210
  stoobly_agent/app/cli/trace_cli.py,sha256=K7E-vx3JUcqEDSWOdIOi_AieKNQz7dBfmRrVvKDkzFI,4605
@@ -214,7 +215,7 @@ stoobly_agent/app/cli/types/request.py,sha256=QthojE5sfx7OvKu-vVNnSUfGk8n4pLzuBQ
214
215
  stoobly_agent/app/cli/types/scenario.py,sha256=28WxmOlbm2Bsek1uu7yc4hJGz-d5oHbYAro7LlFWRoc,81
215
216
  stoobly_agent/app/cli/types/snapshot_migration.py,sha256=4_Re46FKjsflcTOO3qhNsbWWmdEU67SFsF-XE_FKG3M,1859
216
217
  stoobly_agent/app/cli/types/test.py,sha256=1c458B7DFBWsEk5Q1CrZ2CUi84YzEzcs-W4qTcudwAk,714
217
- stoobly_agent/app/cli/validators/scaffold.py,sha256=mjLdb1lO8_SKOspwQSONSA8upXANg6HOvtttkHEqhrk,1187
218
+ stoobly_agent/app/cli/validators/scaffold.py,sha256=ERmdjcryf8YmTHNTHyptKjomATpZo-17bPAPb_ps8ao,1388
218
219
  stoobly_agent/app/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
220
  stoobly_agent/app/models/adapters/__init__.py,sha256=cEEE--Bvrvk6DAsHx_uPgFhLnZJETP4zSBtWjMqyIKc,233
220
221
  stoobly_agent/app/models/adapters/joined_request_adapter.py,sha256=fSq16n3AAlxi8KJdBESHp3JGio_M9uzMnHbnQU8VI3w,3598
@@ -750,8 +751,8 @@ stoobly_agent/test/mock_data/scaffold/docker-compose-local-service.yml,sha256=1W
750
751
  stoobly_agent/test/mock_data/scaffold/index.html,sha256=qJwuYajKZ4ihWZrJQ3BNObV5kf1VGnnm_vqlPJzdqLE,258
751
752
  stoobly_agent/test/mock_data/uspto.yaml,sha256=6U5se7C3o-86J4m9xpOk9Npias399f5CbfWzR87WKwE,7835
752
753
  stoobly_agent/test/test_helper.py,sha256=m_oAI7tmRYCNZdKfNqISWhMv3e44tjeYViQ3nTUfnos,1007
753
- stoobly_agent-1.9.6.dist-info/LICENSE,sha256=o93sj12cdoEOsTCjPaPFsw3Xq0SXs3pPcY-9reE2sEw,548
754
- stoobly_agent-1.9.6.dist-info/METADATA,sha256=uLLTaIvuC4eHvFOImTS-phj_G1HeK2F0qjhOYpPiyrM,3087
755
- stoobly_agent-1.9.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
756
- stoobly_agent-1.9.6.dist-info/entry_points.txt,sha256=aq5wix5oC8MDQtmyPGU0xaFrsjJg7WH28NmXh2sc3Z8,56
757
- stoobly_agent-1.9.6.dist-info/RECORD,,
754
+ stoobly_agent-1.9.8.dist-info/LICENSE,sha256=o93sj12cdoEOsTCjPaPFsw3Xq0SXs3pPcY-9reE2sEw,548
755
+ stoobly_agent-1.9.8.dist-info/METADATA,sha256=DCTUMgBj6zWTfB9H9U37CFC9sEcLasQtaXUIKjG9szo,3087
756
+ stoobly_agent-1.9.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
757
+ stoobly_agent-1.9.8.dist-info/entry_points.txt,sha256=aq5wix5oC8MDQtmyPGU0xaFrsjJg7WH28NmXh2sc3Z8,56
758
+ stoobly_agent-1.9.8.dist-info/RECORD,,