stoobly-agent 1.10.0__py3-none-any.whl → 1.10.2__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.
- stoobly_agent/__init__.py +1 -1
- stoobly_agent/__main__.py +10 -0
- stoobly_agent/app/api/application_http_request_handler.py +5 -2
- stoobly_agent/app/cli/ca_cert_cli.py +9 -5
- stoobly_agent/app/cli/helpers/replay_facade.py +2 -2
- stoobly_agent/app/cli/intercept_cli.py +5 -5
- stoobly_agent/app/cli/request_cli.py +2 -2
- stoobly_agent/app/cli/scaffold/app.py +14 -5
- stoobly_agent/app/cli/scaffold/app_command.py +0 -4
- stoobly_agent/app/cli/scaffold/app_config.py +49 -2
- stoobly_agent/app/cli/scaffold/app_create_command.py +145 -76
- stoobly_agent/app/cli/scaffold/constants.py +9 -4
- stoobly_agent/app/cli/scaffold/docker/constants.py +3 -1
- stoobly_agent/app/cli/scaffold/docker/service/build_decorator.py +4 -4
- stoobly_agent/app/cli/scaffold/docker/service/builder.py +31 -54
- stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py +3 -0
- stoobly_agent/app/cli/scaffold/docker/template_files.py +112 -0
- stoobly_agent/app/cli/scaffold/docker/workflow/build_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +30 -47
- stoobly_agent/app/cli/scaffold/docker/workflow/command_decorator.py +3 -2
- stoobly_agent/app/cli/scaffold/docker/workflow/detached_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/dns_decorator.py +2 -3
- stoobly_agent/app/cli/scaffold/docker/workflow/local_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/run_command.py +423 -0
- stoobly_agent/app/cli/scaffold/local/__init__.py +0 -0
- stoobly_agent/app/cli/scaffold/local/service/__init__.py +0 -0
- stoobly_agent/app/cli/scaffold/local/service/builder.py +72 -0
- stoobly_agent/app/cli/scaffold/local/workflow/__init__.py +0 -0
- stoobly_agent/app/cli/scaffold/local/workflow/builder.py +35 -0
- stoobly_agent/app/cli/scaffold/local/workflow/run_command.py +339 -0
- stoobly_agent/app/cli/scaffold/service_command.py +9 -1
- stoobly_agent/app/cli/scaffold/service_config.py +9 -25
- stoobly_agent/app/cli/scaffold/service_create_command.py +18 -6
- stoobly_agent/app/cli/scaffold/service_docker_compose.py +3 -3
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +10 -7
- stoobly_agent/app/cli/scaffold/templates/app/.Makefile +2 -2
- stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +4 -4
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/record/configure +28 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/test/configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +4 -4
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/run +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/run +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/run +3 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.run +19 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.run +19 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.run +19 -0
- stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.up +0 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.configure +25 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.configure +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.init +5 -1
- stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.run +14 -0
- stoobly_agent/app/cli/scaffold/templates/constants.py +35 -19
- stoobly_agent/app/cli/scaffold/templates/factory.py +34 -18
- stoobly_agent/app/cli/scaffold/templates/plugins/cypress/test/.run +21 -0
- stoobly_agent/app/cli/scaffold/templates/plugins/playwright/test/.run +21 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/configure +5 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/run +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/record/configure +21 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/record/run +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/test/configure +5 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/test/run +3 -0
- stoobly_agent/app/cli/scaffold/workflow_command.py +18 -4
- stoobly_agent/app/cli/scaffold/workflow_copy_command.py +5 -4
- stoobly_agent/app/cli/scaffold/workflow_create_command.py +31 -29
- stoobly_agent/app/cli/scaffold/workflow_run_command.py +18 -151
- stoobly_agent/app/cli/scaffold_cli.py +134 -182
- stoobly_agent/app/cli/scenario_cli.py +2 -2
- stoobly_agent/app/cli/types/test.py +2 -2
- stoobly_agent/app/cli/types/workflow_run_command.py +52 -3
- stoobly_agent/app/proxy/handle_mock_service.py +1 -1
- stoobly_agent/app/proxy/intercept_settings.py +6 -26
- stoobly_agent/app/proxy/mock/eval_fixtures_service.py +177 -27
- stoobly_agent/app/proxy/mock/types/__init__.py +22 -1
- stoobly_agent/app/proxy/record/upload_request_service.py +3 -6
- stoobly_agent/app/proxy/replay/body_parser_service.py +8 -5
- stoobly_agent/app/proxy/replay/multipart.py +15 -13
- stoobly_agent/app/proxy/replay/replay_request_service.py +2 -2
- stoobly_agent/app/proxy/run.py +3 -0
- stoobly_agent/app/proxy/test/context.py +0 -4
- stoobly_agent/app/proxy/test/context_abc.py +0 -5
- stoobly_agent/app/proxy/utils/publish_change_service.py +20 -23
- stoobly_agent/app/settings/__init__.py +10 -7
- stoobly_agent/cli.py +61 -16
- stoobly_agent/config/data_dir.py +1 -8
- stoobly_agent/public/12-es2015.618ecfd5f735b801b50f.js +1 -0
- stoobly_agent/public/12-es5.618ecfd5f735b801b50f.js +1 -0
- stoobly_agent/public/index.html +1 -1
- stoobly_agent/public/main-es2015.5a9aa16433404c3f423a.js +1 -0
- stoobly_agent/public/main-es5.5a9aa16433404c3f423a.js +1 -0
- stoobly_agent/public/runtime-es2015.77bcd31efed9e5d5d431.js +1 -0
- stoobly_agent/public/runtime-es5.77bcd31efed9e5d5d431.js +1 -0
- stoobly_agent/test/app/cli/intercept/intercept_configure_test.py +17 -6
- stoobly_agent/test/app/cli/scaffold/docker/cli_invoker.py +177 -0
- stoobly_agent/test/app/cli/scaffold/{cli_test.py → docker/cli_test.py} +4 -11
- stoobly_agent/test/app/cli/scaffold/{e2e_test.py → docker/e2e_test.py} +42 -27
- stoobly_agent/test/app/cli/scaffold/local/__init__.py +0 -0
- stoobly_agent/test/app/cli/scaffold/{cli_invoker.py → local/cli_invoker.py} +38 -32
- stoobly_agent/test/app/cli/scaffold/local/e2e_test.py +342 -0
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- stoobly_agent/test/app/proxy/mock/eval_fixtures_service_test.py +903 -2
- stoobly_agent/test/app/proxy/replay/body_parser_service_test.py +95 -3
- stoobly_agent/test/config/data_dir_test.py +2 -7
- stoobly_agent/test/test_helper.py +16 -5
- {stoobly_agent-1.10.0.dist-info → stoobly_agent-1.10.2.dist-info}/METADATA +4 -2
- {stoobly_agent-1.10.0.dist-info → stoobly_agent-1.10.2.dist-info}/RECORD +157 -129
- {stoobly_agent-1.10.0.dist-info → stoobly_agent-1.10.2.dist-info}/WHEEL +1 -1
- stoobly_agent/app/cli/helpers/shell.py +0 -26
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/bin/configure +0 -3
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/configure +0 -13
- stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/configure +0 -47
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/configure +0 -13
- stoobly_agent/public/12-es2015.be58ed0ef449008b932e.js +0 -1
- stoobly_agent/public/12-es5.be58ed0ef449008b932e.js +0 -1
- stoobly_agent/public/main-es2015.089b46f303768fbe864f.js +0 -1
- stoobly_agent/public/main-es5.089b46f303768fbe864f.js +0 -1
- stoobly_agent/public/runtime-es2015.f8c814b38b27708e91c1.js +0 -1
- stoobly_agent/public/runtime-es5.f8c814b38b27708e91c1.js +0 -1
- /stoobly_agent/app/cli/scaffold/templates/app/build/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/build/mock/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/build/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/build/record/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/build/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/build/test/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/gateway/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/gateway/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/gateway/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/{.docker-compose.exec.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/plugins/cypress/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/plugins/playwright/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/workflow/mock/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/workflow/record/{bin/init → init} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/workflow/test/{bin/init → init} +0 -0
- {stoobly_agent-1.10.0.dist-info → stoobly_agent-1.10.2.dist-info}/entry_points.txt +0 -0
- {stoobly_agent-1.10.0.dist-info → stoobly_agent-1.10.2.dist-info/licenses}/LICENSE +0 -0
@@ -1,44 +1,60 @@
|
|
1
1
|
import pdb
|
2
2
|
|
3
3
|
from ..constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE
|
4
|
-
from ..
|
4
|
+
from ..local.workflow.builder import WorkflowBuilder
|
5
|
+
from ..docker.workflow.builder import DockerWorkflowBuilder
|
5
6
|
from .constants import (
|
6
|
-
CUSTOM_CONFIGURE, CUSTOM_INIT, CUSTOM_PUBLIC_GITIGNORE, MAINTAINED_CONFIGURE,
|
7
|
+
CUSTOM_CONFIGURE, CUSTOM_INIT, CUSTOM_PUBLIC_GITIGNORE, MAINTAINED_CONFIGURE,
|
8
|
+
MOCK_WORKFLOW_CUSTOM_FILES, MOCK_WORKFLOW_CUSTOM_LOCAL_FILES, MOCK_WORKFLOW_MAINTAINED_FILES, MOCK_WORKFLOW_CUSTOM_DOCKER_FILES,
|
9
|
+
RECORD_WORKFLOW_CUSTOM_FILES, RECORD_WORKFLOW_CUSTOM_LOCAL_FILES, RECORD_WORKFLOW_MAINTAINED_FILES, RECORD_WORKFLOW_CUSTOM_DOCKER_FILES,
|
10
|
+
TEST_WORKFLOW_CUSTOM_FILES, TEST_WORKFLOW_CUSTOM_LOCAL_FILES, TEST_WORKFLOW_MAINTAINED_FILES, TEST_WORKFLOW_CUSTOM_DOCKER_FILES
|
7
11
|
)
|
8
12
|
|
9
|
-
def custom_files(workflow: str, workflow_builder: WorkflowBuilder):
|
13
|
+
def custom_files(workflow: str, workflow_builder: WorkflowBuilder = None):
|
10
14
|
files = []
|
11
15
|
if workflow == WORKFLOW_MOCK_TYPE:
|
12
|
-
files = MOCK_WORKFLOW_CUSTOM_FILES
|
16
|
+
files = MOCK_WORKFLOW_CUSTOM_FILES.copy()
|
13
17
|
elif workflow == WORKFLOW_RECORD_TYPE:
|
14
|
-
files = RECORD_WORKFLOW_CUSTOM_FILES
|
18
|
+
files = RECORD_WORKFLOW_CUSTOM_FILES.copy()
|
15
19
|
elif workflow == WORKFLOW_TEST_TYPE:
|
16
|
-
files = TEST_WORKFLOW_CUSTOM_FILES
|
20
|
+
files = TEST_WORKFLOW_CUSTOM_FILES.copy()
|
17
21
|
else:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
files.append(CUSTOM_CONFIGURE)
|
23
|
+
files.append(CUSTOM_INIT)
|
24
|
+
|
25
|
+
# Add Docker-specific files if workflow_builder is a DockerWorkflowBuilder
|
26
|
+
if isinstance(workflow_builder, DockerWorkflowBuilder):
|
27
|
+
if workflow == WORKFLOW_MOCK_TYPE:
|
28
|
+
files.extend(MOCK_WORKFLOW_CUSTOM_DOCKER_FILES)
|
29
|
+
elif workflow == WORKFLOW_RECORD_TYPE:
|
30
|
+
files.extend(RECORD_WORKFLOW_CUSTOM_DOCKER_FILES)
|
31
|
+
elif workflow == WORKFLOW_TEST_TYPE:
|
32
|
+
files.extend(TEST_WORKFLOW_CUSTOM_DOCKER_FILES)
|
33
|
+
else:
|
34
|
+
if workflow == WORKFLOW_MOCK_TYPE:
|
35
|
+
files.extend(MOCK_WORKFLOW_CUSTOM_LOCAL_FILES)
|
36
|
+
elif workflow == WORKFLOW_RECORD_TYPE:
|
37
|
+
files.extend(RECORD_WORKFLOW_CUSTOM_LOCAL_FILES)
|
38
|
+
elif workflow == WORKFLOW_TEST_TYPE:
|
39
|
+
files.extend(TEST_WORKFLOW_CUSTOM_LOCAL_FILES)
|
23
40
|
|
24
41
|
# Fixtures are only relevant if the workflow is mock/test and if the service has a hostname
|
25
|
-
if not workflow_builder.config.hostname:
|
42
|
+
if workflow_builder and not workflow_builder.config.hostname:
|
26
43
|
if CUSTOM_PUBLIC_GITIGNORE in files:
|
27
44
|
files.remove(CUSTOM_PUBLIC_GITIGNORE)
|
28
45
|
|
29
46
|
return files
|
30
47
|
|
31
|
-
def maintained_files(workflow: str, workflow_builder: WorkflowBuilder):
|
48
|
+
def maintained_files(workflow: str, workflow_builder: WorkflowBuilder = None):
|
32
49
|
files = []
|
33
50
|
|
34
51
|
if workflow == WORKFLOW_MOCK_TYPE:
|
35
|
-
files = MOCK_WORKFLOW_MAINTAINED_FILES
|
52
|
+
files = MOCK_WORKFLOW_MAINTAINED_FILES.copy()
|
36
53
|
elif workflow == WORKFLOW_RECORD_TYPE:
|
37
|
-
files = RECORD_WORKFLOW_MAINTAINED_FILES
|
54
|
+
files = RECORD_WORKFLOW_MAINTAINED_FILES.copy()
|
38
55
|
elif workflow == WORKFLOW_TEST_TYPE:
|
39
|
-
files = TEST_WORKFLOW_MAINTAINED_FILES
|
56
|
+
files = TEST_WORKFLOW_MAINTAINED_FILES.copy()
|
40
57
|
else:
|
41
|
-
|
42
|
-
files.append(MAINTAINED_CONFIGURE)
|
58
|
+
files.append(MAINTAINED_CONFIGURE)
|
43
59
|
|
44
60
|
return files
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# This file was automatically generated. DO NOT EDIT.
|
4
|
+
# Any changes made to this file will be overwritten.
|
5
|
+
|
6
|
+
if [ -f .env ]; then
|
7
|
+
set -a; . ./.env; set +a;
|
8
|
+
fi
|
9
|
+
|
10
|
+
export HTTP_PROXY=http://localhost:$APP_PROXY_PORT
|
11
|
+
export http_proxy=http://localhost:$APP_PROXY_PORT
|
12
|
+
export HTTPS_PROXY=http://localhost:$APP_PROXY_PORT
|
13
|
+
export https_proxy=http://localhost:$APP_PROXY_PORT
|
14
|
+
|
15
|
+
npx cypress run --project .
|
16
|
+
|
17
|
+
entrypoint=$1
|
18
|
+
|
19
|
+
if [ -e "$entrypoint" ]; then
|
20
|
+
./"$entrypoint"
|
21
|
+
fi
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# This file was automatically generated. DO NOT EDIT.
|
4
|
+
# Any changes made to this file will be overwritten.
|
5
|
+
|
6
|
+
if [ -f .env ]; then
|
7
|
+
set -a; . ./.env; set +a;
|
8
|
+
fi
|
9
|
+
|
10
|
+
export HTTP_PROXY=http://localhost:$APP_PROXY_PORT
|
11
|
+
export http_proxy=http://localhost:$APP_PROXY_PORT
|
12
|
+
export HTTPS_PROXY=http://localhost:$APP_PROXY_PORT
|
13
|
+
export https_proxy=http://localhost:$APP_PROXY_PORT
|
14
|
+
|
15
|
+
npx playwright test --reporter dot
|
16
|
+
|
17
|
+
entrypoint=$1
|
18
|
+
|
19
|
+
if [ -e "$entrypoint" ]; then
|
20
|
+
./"$entrypoint"
|
21
|
+
fi
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Add custom Stoobly configuration here, to learn more: https://docs.stoobly.com/core-concepts/agent/proxy-settings
|
4
|
+
|
5
|
+
origin=$1 # e.g. https://docs.stoobly.com
|
6
|
+
|
7
|
+
# Uncomment the following example to include or exclude requests
|
8
|
+
# stoobly-agent config firewall set \
|
9
|
+
# --action include \
|
10
|
+
# --method GET --method POST --method OPTIONS --method PUT --method DELETE \
|
11
|
+
# --mode record \
|
12
|
+
# --pattern "$origin/index.html"
|
13
|
+
|
14
|
+
# Uncomment the following example to modify parts of a request
|
15
|
+
# stoobly-agent config rewrite set \
|
16
|
+
# --method GET --method POST --method OPTIONS --method PUT --method DELETE \
|
17
|
+
# --mode record \
|
18
|
+
# --name etag \
|
19
|
+
# --pattern "$origin/.*" \
|
20
|
+
# --type Header \
|
21
|
+
# --value '' \
|
@@ -5,8 +5,8 @@ import yaml
|
|
5
5
|
from stoobly_agent.lib.logger import Logger
|
6
6
|
|
7
7
|
from .app import App
|
8
|
-
from .constants import BIN_FOLDER_NAME,
|
9
|
-
from .docker.constants import DOCKER_COMPOSE_CUSTOM
|
8
|
+
from .constants import BIN_FOLDER_NAME, CONFIG_FILE, DOTENV_FILE, FIXTURES_FILE_NAME, PUBLIC_FOLDER_NAME
|
9
|
+
from .docker.constants import DOCKER_COMPOSE_CUSTOM, DOCKER_COMPOSE_WORKFLOW
|
10
10
|
from .service_command import ServiceCommand
|
11
11
|
from .workflow_config import WorkflowConfig
|
12
12
|
|
@@ -18,7 +18,9 @@ class WorkflowCommand(ServiceCommand):
|
|
18
18
|
super().__init__(app, **kwargs)
|
19
19
|
|
20
20
|
self.__workflow_name = kwargs['workflow_name']
|
21
|
-
|
21
|
+
|
22
|
+
if kwargs.get('service_name'):
|
23
|
+
self.__config = WorkflowConfig(self.workflow_path, **kwargs)
|
22
24
|
|
23
25
|
@property
|
24
26
|
def bin_dir_path(self):
|
@@ -35,7 +37,7 @@ class WorkflowCommand(ServiceCommand):
|
|
35
37
|
def compose_relative_path(self):
|
36
38
|
return os.path.join(
|
37
39
|
self.workflow_relative_path,
|
38
|
-
|
40
|
+
DOCKER_COMPOSE_WORKFLOW
|
39
41
|
)
|
40
42
|
|
41
43
|
@property
|
@@ -92,6 +94,10 @@ class WorkflowCommand(ServiceCommand):
|
|
92
94
|
def public_dir_path(self):
|
93
95
|
return os.path.join(self.workflow_path, PUBLIC_FOLDER_NAME)
|
94
96
|
|
97
|
+
@property
|
98
|
+
def response_fixtures_path(self):
|
99
|
+
return os.path.join(self.workflow_path, FIXTURES_FILE_NAME)
|
100
|
+
|
95
101
|
@property
|
96
102
|
def workflow_config(self):
|
97
103
|
return self.__config
|
@@ -126,9 +132,17 @@ class WorkflowCommand(ServiceCommand):
|
|
126
132
|
self.workflow_name
|
127
133
|
)
|
128
134
|
|
135
|
+
@property
|
136
|
+
def workflow_template(self):
|
137
|
+
return self.workflow_config.template or self.workflow_name
|
138
|
+
|
129
139
|
@property
|
130
140
|
def workflow_templates_root_dir(self):
|
131
141
|
return os.path.join(self.templates_root_dir, 'workflow')
|
142
|
+
|
143
|
+
@property
|
144
|
+
def workflow_templates_build_dir(self):
|
145
|
+
return os.path.join(self.templates_root_dir, 'build', 'workflows', self.workflow_template)
|
132
146
|
|
133
147
|
def env(self, _c: dict):
|
134
148
|
_config = self.app_config.read()
|
@@ -2,8 +2,9 @@ import os
|
|
2
2
|
import pdb
|
3
3
|
import shutil
|
4
4
|
|
5
|
+
from stoobly_agent.app.cli.scaffold.docker.constants import DOCKER_COMPOSE_WORKFLOW
|
6
|
+
|
5
7
|
from .app import App
|
6
|
-
from .constants import COMPOSE_TEMPLATE
|
7
8
|
from .service_workflow import ServiceWorkflow
|
8
9
|
from .workflow_command import WorkflowCommand
|
9
10
|
|
@@ -32,11 +33,11 @@ class WorkflowCopyCommand(WorkflowCommand):
|
|
32
33
|
|
33
34
|
self.app.copy_folders_and_hidden_files(self.workflow_path, dest)
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
os.rename(compose_file_src, compose_file_dest)
|
36
|
+
# copy folder recursively
|
37
|
+
shutil.copytree(self.workflow_path, destination_workflow.path, dirs_exist_ok=True)
|
38
38
|
|
39
39
|
# Replace workflow name
|
40
|
+
compose_file_dest = os.path.join(dest, DOCKER_COMPOSE_WORKFLOW)
|
40
41
|
with open(compose_file_dest, 'r+') as fp:
|
41
42
|
contents = fp.read()
|
42
43
|
fp.seek(0)
|
@@ -4,21 +4,21 @@ import shutil
|
|
4
4
|
|
5
5
|
from typing import List, TypedDict, Union
|
6
6
|
|
7
|
+
from stoobly_agent.app.cli.scaffold.local.service.builder import ServiceBuilder
|
8
|
+
|
7
9
|
from .app import App
|
8
|
-
from .constants import WORKFLOW_TEMPLATE_OPTION
|
9
|
-
from .docker.service.builder import
|
10
|
-
|
11
|
-
from .docker.workflow.
|
12
|
-
from .docker.workflow.builder import WorkflowBuilder
|
10
|
+
from .constants import RUN_ON_DOCKER, WORKFLOW_TEMPLATE_OPTION
|
11
|
+
from .docker.service.builder import DockerServiceBuilder
|
12
|
+
|
13
|
+
from .docker.workflow.builder import DockerWorkflowBuilder
|
13
14
|
from .templates.factory import custom_files, maintained_files
|
15
|
+
from .local.workflow.builder import WorkflowBuilder
|
14
16
|
from .workflow_command import WorkflowCommand
|
15
17
|
|
16
|
-
|
17
18
|
class BuildOptions(TypedDict):
|
18
|
-
|
19
|
-
service_builder: ServiceBuilder
|
19
|
+
service_builder: DockerServiceBuilder
|
20
20
|
template: WORKFLOW_TEMPLATE_OPTION
|
21
|
-
workflow_decorators:
|
21
|
+
workflow_decorators: list
|
22
22
|
|
23
23
|
class WorkflowCreateCommand(WorkflowCommand):
|
24
24
|
|
@@ -40,6 +40,11 @@ class WorkflowCreateCommand(WorkflowCommand):
|
|
40
40
|
def force(self):
|
41
41
|
return self.__force
|
42
42
|
|
43
|
+
@property
|
44
|
+
def create_docker_files(self):
|
45
|
+
"""Determine if Docker files should be created based on app config run-on setting."""
|
46
|
+
return RUN_ON_DOCKER in self.app_config.run_on
|
47
|
+
|
43
48
|
def build(self, **kwargs: BuildOptions):
|
44
49
|
# Create workflow folder
|
45
50
|
dest = os.path.join(self.workflow_path)
|
@@ -49,8 +54,23 @@ class WorkflowCreateCommand(WorkflowCommand):
|
|
49
54
|
if not os.path.exists(dest):
|
50
55
|
os.makedirs(dest)
|
51
56
|
|
52
|
-
|
53
|
-
workflow_builder =
|
57
|
+
service_builder = kwargs.get('service_builder')
|
58
|
+
workflow_builder = None
|
59
|
+
|
60
|
+
# Create workflow maintained compose file only if Docker files are enabled
|
61
|
+
if self.create_docker_files:
|
62
|
+
if not service_builder:
|
63
|
+
service_builder = DockerServiceBuilder(self.service_config)
|
64
|
+
service_builder.load()
|
65
|
+
|
66
|
+
workflow_builder = DockerWorkflowBuilder(self.workflow_path, service_builder)
|
67
|
+
workflow_builder.build(kwargs.get('workflow_decorators'))
|
68
|
+
else:
|
69
|
+
if not service_builder:
|
70
|
+
service_builder = ServiceBuilder(self.service_config)
|
71
|
+
|
72
|
+
workflow_builder = WorkflowBuilder(self.workflow_path, service_builder)
|
73
|
+
|
54
74
|
self.__copy_templates(workflow_builder, kwargs.get('template'))
|
55
75
|
|
56
76
|
if not self.workflow_config.empty:
|
@@ -76,21 +96,3 @@ class WorkflowCreateCommand(WorkflowCommand):
|
|
76
96
|
custom_workflow_files = custom_files(template or self.workflow_name, workflow_builder)
|
77
97
|
self.copy_files_no_replace(templates_path, custom_workflow_files, self.workflow_path)
|
78
98
|
|
79
|
-
def __write_docker_compose_file(self, **kwargs: BuildOptions):
|
80
|
-
builder_class = kwargs.get('builder_class') or WorkflowBuilder
|
81
|
-
service_builder = kwargs.get('service_builder')
|
82
|
-
if not service_builder:
|
83
|
-
service_builder = ServiceBuilder(self.service_config)
|
84
|
-
service_builder.load()
|
85
|
-
workflow_decorators: List[Union[MockDecorator, ReverseProxyDecorator]] = kwargs.get('workflow_decorators')
|
86
|
-
|
87
|
-
workflow_builder = builder_class(self.workflow_path, service_builder)
|
88
|
-
workflow_builder.build_all()
|
89
|
-
|
90
|
-
if isinstance(workflow_decorators, list):
|
91
|
-
for workflow_decorator in workflow_decorators:
|
92
|
-
workflow_decorator(workflow_builder).decorate()
|
93
|
-
|
94
|
-
workflow_builder.write()
|
95
|
-
|
96
|
-
return workflow_builder
|
@@ -4,9 +4,7 @@ import pdb
|
|
4
4
|
import subprocess
|
5
5
|
import re
|
6
6
|
|
7
|
-
|
8
7
|
from stoobly_agent.config.data_dir import DataDir
|
9
|
-
from stoobly_agent.lib.logger import Logger
|
10
8
|
|
11
9
|
from .app import App
|
12
10
|
from .constants import (
|
@@ -14,11 +12,11 @@ from .constants import (
|
|
14
12
|
SERVICE_DNS_ENV, SERVICE_NAME_ENV, SERVICE_SCRIPTS_DIR, SERVICE_SCRIPTS_ENV, USER_ID_ENV,
|
15
13
|
WORKFLOW_NAME_ENV, WORKFLOW_NAMESPACE_ENV, WORKFLOW_SCRIPTS_DIR, WORKFLOW_SCRIPTS_ENV, WORKFLOW_TEMPLATE_ENV
|
16
14
|
)
|
17
|
-
|
15
|
+
|
18
16
|
from .workflow_command import WorkflowCommand
|
19
17
|
from .workflow_env import WorkflowEnv
|
20
18
|
from .workflow_namesapce import WorkflowNamespace
|
21
|
-
from ..types.workflow_run_command import
|
19
|
+
from ..types.workflow_run_command import ComposeOptions
|
22
20
|
|
23
21
|
LOG_ID = 'WorkflowRunCommand'
|
24
22
|
|
@@ -31,8 +29,12 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
31
29
|
self.__ca_certs_dir_path = kwargs.get('ca_certs_dir_path') or app.ca_certs_dir_path
|
32
30
|
self.__certs_dir_path = kwargs.get('certs_dir_path') or app.certs_dir_path
|
33
31
|
self.__context_dir_path = kwargs.get('context_dir_path') or app.context_dir_path
|
32
|
+
self.__dry_run = kwargs.get('dry_run', False)
|
34
33
|
self.__namespace = kwargs.get('namespace') or self.workflow_name
|
35
|
-
self.__network = f"{self.__namespace}.{
|
34
|
+
self.__network = f"{self.__namespace}.{app.network}"
|
35
|
+
self.__workflow_namespace = kwargs.get('workflow_namespace') or WorkflowNamespace(app, self.__namespace)
|
36
|
+
|
37
|
+
self.__workflow_namespace.copy_dotenv()
|
36
38
|
|
37
39
|
@property
|
38
40
|
def app_dir_path(self):
|
@@ -49,7 +51,7 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
49
51
|
@property
|
50
52
|
def context_dir_path(self):
|
51
53
|
if not self.__context_dir_path:
|
52
|
-
data_dir = DataDir.instance()
|
54
|
+
data_dir: DataDir = DataDir.instance()
|
53
55
|
return os.path.dirname(data_dir.path)
|
54
56
|
|
55
57
|
return self.__context_dir_path
|
@@ -64,7 +66,11 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
64
66
|
|
65
67
|
@property
|
66
68
|
def dotenv_path(self):
|
67
|
-
return
|
69
|
+
return self.__workflow_namespace.dotenv_path
|
70
|
+
|
71
|
+
@property
|
72
|
+
def dry_run(self):
|
73
|
+
return self.__dry_run
|
68
74
|
|
69
75
|
@property
|
70
76
|
def nameservers(self):
|
@@ -78,7 +84,7 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
78
84
|
|
79
85
|
@property
|
80
86
|
def nameservers_path(self):
|
81
|
-
return
|
87
|
+
return self.__workflow_namespace.nameservers_path
|
82
88
|
|
83
89
|
@property
|
84
90
|
def namespace(self):
|
@@ -88,149 +94,6 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
88
94
|
def network(self):
|
89
95
|
return self.__network
|
90
96
|
|
91
|
-
def create_image(self, **options: BuildOptions):
|
92
|
-
relative_namespace_path = os.path.relpath(self.scaffold_namespace_path, self.__current_working_dir)
|
93
|
-
dockerfile_path = os.path.join(relative_namespace_path, DOCKERFILE_CONTEXT)
|
94
|
-
user_id = options['user_id'] or os.getuid()
|
95
|
-
|
96
|
-
command = ['docker', 'build']
|
97
|
-
command.append(f"-f {dockerfile_path}")
|
98
|
-
command.append(f"-t stoobly.{user_id}")
|
99
|
-
command.append(f"--build-arg USER_ID={user_id}")
|
100
|
-
|
101
|
-
if not os.environ.get('STOOBLY_IMAGE_USE_LOCAL'):
|
102
|
-
command.append('--pull')
|
103
|
-
|
104
|
-
if not options.get('verbose'):
|
105
|
-
command.append('--quiet')
|
106
|
-
|
107
|
-
# To avoid large context transfer times, should be a folder with relatively low number of files
|
108
|
-
command.append(relative_namespace_path)
|
109
|
-
|
110
|
-
return ' '.join(command)
|
111
|
-
|
112
|
-
def remove_image(self, user_id: str = None):
|
113
|
-
user_id = user_id or os.getuid()
|
114
|
-
command = ['docker', 'rmi', f"stoobly.{user_id}", '&>', '/dev/null']
|
115
|
-
command.append('|| true')
|
116
|
-
return ' '.join(command)
|
117
|
-
|
118
|
-
def create_egress_network(self):
|
119
|
-
return f"docker network create {APP_EGRESS_NETWORK_TEMPLATE.format(network=self.network)} &> /dev/null"
|
120
|
-
|
121
|
-
def create_ingress_network(self):
|
122
|
-
return f"docker network create {APP_INGRESS_NETWORK_TEMPLATE.format(network=self.network)} &> /dev/null"
|
123
|
-
|
124
|
-
def remove_egress_network(self):
|
125
|
-
return f"docker network rm {APP_EGRESS_NETWORK_TEMPLATE.format(network=self.network)} &> /dev/null || true"
|
126
|
-
|
127
|
-
def remove_ingress_network(self):
|
128
|
-
return f"docker network rm {APP_INGRESS_NETWORK_TEMPLATE.format(network=self.network)} &> /dev/null || true"
|
129
|
-
|
130
|
-
def up(self, **options: UpOptions):
|
131
|
-
if not os.path.exists(self.compose_path):
|
132
|
-
return ''
|
133
|
-
|
134
|
-
command = ['COMPOSE_IGNORE_ORPHANS=true', 'docker', 'compose']
|
135
|
-
command_options = []
|
136
|
-
|
137
|
-
# Add docker compose file
|
138
|
-
command_options.append(f"-f {os.path.relpath(self.compose_path, self.__current_working_dir)}")
|
139
|
-
|
140
|
-
# Add docker compose networks file
|
141
|
-
command_options.append(f"-f {os.path.relpath(self.networks_compose_path, os.getcwd())}")
|
142
|
-
|
143
|
-
# Add custom docker compose file
|
144
|
-
custom_services = self.custom_services
|
145
|
-
if custom_services:
|
146
|
-
uses_profile = False
|
147
|
-
for service_name in custom_services:
|
148
|
-
service = custom_services[service_name]
|
149
|
-
profiles = service.get('profiles')
|
150
|
-
if isinstance(profiles, list):
|
151
|
-
if self.workflow_name in profiles:
|
152
|
-
uses_profile = True
|
153
|
-
break
|
154
|
-
if not uses_profile:
|
155
|
-
# TODO: looking into why warning does not print in docker
|
156
|
-
Logger.instance(LOG_ID).error(f"Missing {self.workflow_name} profile in custom compose file")
|
157
|
-
|
158
|
-
compose_file_path = os.path.relpath(self.custom_compose_path, self.__current_working_dir)
|
159
|
-
command_options.append(f"-f {compose_file_path}")
|
160
|
-
|
161
|
-
if options.get('extra_compose_path'):
|
162
|
-
compose_file_path = os.path.relpath(options['extra_compose_path'], self.__current_working_dir)
|
163
|
-
command_options.append(f"-f {compose_file_path}")
|
164
|
-
|
165
|
-
command_options.append(f"--profile {self.workflow_name}")
|
166
|
-
|
167
|
-
if not options.get('namespace'):
|
168
|
-
options['namespace'] = self.workflow_name
|
169
|
-
command_options.append(f"-p {options['namespace']}")
|
170
|
-
|
171
|
-
command += command_options
|
172
|
-
command.append('up')
|
173
|
-
|
174
|
-
if not options.get('no_build'):
|
175
|
-
command.append('--build')
|
176
|
-
|
177
|
-
if options.get('pull'):
|
178
|
-
command.append('--pull missing')
|
179
|
-
|
180
|
-
if not options.get('attached'):
|
181
|
-
command.append('-d')
|
182
|
-
else:
|
183
|
-
major_version = 2
|
184
|
-
minor_version = 27
|
185
|
-
patch_version = 0
|
186
|
-
min_version = major_version * 10000 + minor_version * 100 + patch_version
|
187
|
-
formula = "'{print $1*10000 + $2*100 + $3}'"
|
188
|
-
option = f"$(test $(echo $(docker compose version --short) | awk -F. {formula}) -ge {min_version} && echo '--abort-on-container-failure')"
|
189
|
-
|
190
|
-
# This option enables docker compose to return exit code 1
|
191
|
-
# when one of the services exits with a non-zero exit code
|
192
|
-
# Otherwise, even if a service exits with a non-zero exit code, exit code 0 is returned
|
193
|
-
command.append(option)
|
194
|
-
|
195
|
-
self.write_env(**options)
|
196
|
-
|
197
|
-
return ' '.join(command)
|
198
|
-
|
199
|
-
def down(self, **options: DownOptions):
|
200
|
-
if not os.path.exists(self.compose_path):
|
201
|
-
return ''
|
202
|
-
|
203
|
-
command = ['docker', 'compose']
|
204
|
-
|
205
|
-
# Add docker compose file
|
206
|
-
command.append(f"-f {os.path.relpath(self.compose_path, os.getcwd())}")
|
207
|
-
|
208
|
-
# Add docker compose networks file
|
209
|
-
command.append(f"-f {os.path.relpath(self.networks_compose_path, os.getcwd())}")
|
210
|
-
|
211
|
-
# Add custom docker compose file
|
212
|
-
if self.custom_services:
|
213
|
-
command.append(f"-f {os.path.relpath(self.custom_compose_path, self.__current_working_dir)}")
|
214
|
-
|
215
|
-
if options.get('extra_compose_path'):
|
216
|
-
command.append(f"-f {os.path.relpath(options['extra_compose_path'], self.__current_working_dir)}")
|
217
|
-
|
218
|
-
command.append(f"--profile {self.workflow_name}")
|
219
|
-
|
220
|
-
if not options.get('namespace'):
|
221
|
-
options['namespace'] = self.workflow_name
|
222
|
-
command.append(f"-p {options['namespace']}")
|
223
|
-
|
224
|
-
command.append('down')
|
225
|
-
command.append('--volumes')
|
226
|
-
|
227
|
-
if options.get('rmi'):
|
228
|
-
command.append('--rmi local')
|
229
|
-
|
230
|
-
self.write_env(**options)
|
231
|
-
|
232
|
-
return ' '.join(command)
|
233
|
-
|
234
97
|
def write_nameservers(self):
|
235
98
|
# If hostname is set then the service is external and we will need to configure the container's DNS.
|
236
99
|
# If we don't configure the container's DNS, then Docker's embedded DNS will potentially
|
@@ -252,6 +115,10 @@ class WorkflowRunCommand(WorkflowCommand):
|
|
252
115
|
if nameservers:
|
253
116
|
fp.write("\n".join(nameservers))
|
254
117
|
|
118
|
+
@property
|
119
|
+
def workflow_namespace(self):
|
120
|
+
return self.__workflow_namespace
|
121
|
+
|
255
122
|
def write_env(self, **options: ComposeOptions):
|
256
123
|
namespace = options.get('namespace')
|
257
124
|
user_id = options.get('user_id')
|