stoobly-agent 1.2.3__py3-none-any.whl → 1.3.0__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/app/cli/helpers/certificate_authority.py +1 -5
- stoobly_agent/app/cli/scaffold/app.py +14 -32
- stoobly_agent/app/cli/scaffold/app_command.py +4 -7
- stoobly_agent/app/cli/scaffold/app_config.py +15 -2
- stoobly_agent/app/cli/scaffold/app_create_command.py +18 -2
- stoobly_agent/app/cli/scaffold/command.py +1 -1
- stoobly_agent/app/cli/scaffold/constants.py +9 -3
- stoobly_agent/app/cli/scaffold/docker/app_builder.py +3 -7
- stoobly_agent/app/cli/scaffold/docker/constants.py +0 -1
- stoobly_agent/app/cli/scaffold/docker/service/builder.py +12 -11
- stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +14 -31
- stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +6 -2
- stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +6 -2
- stoobly_agent/app/cli/scaffold/service.py +1 -1
- stoobly_agent/app/cli/scaffold/service_command.py +1 -1
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +6 -8
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +2 -4
- stoobly_agent/app/cli/scaffold/templates/app/.Makefile +37 -21
- stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.base.yml +8 -13
- stoobly_agent/app/cli/scaffold/templates/app/Makefile +1 -1
- stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +8 -4
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/.docker-compose.mock.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/record/.docker-compose.record.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/test/.docker-compose.test.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +2 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/.docker-compose.mock.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/.docker-compose.record.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/.docker-compose.test.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml +2 -3
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.logs +1 -0
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/.docker-compose.mock.yml +1 -2
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/.docker-compose.record.yml +1 -2
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/validate_command.py +2 -2
- stoobly_agent/app/cli/scaffold/workflow.py +5 -4
- stoobly_agent/app/cli/scaffold/workflow_command.py +3 -3
- stoobly_agent/app/cli/scaffold/workflow_run_command.py +72 -36
- stoobly_agent/app/cli/scaffold_cli.py +51 -45
- stoobly_agent/app/cli/snapshot_cli.py +6 -2
- stoobly_agent/app/models/adapters/joined_request_adapter.py +6 -0
- stoobly_agent/app/models/factories/resource/local_db/helpers/scenario_snapshot.py +3 -1
- stoobly_agent/app/models/helpers/apply.py +34 -17
- stoobly_agent/app/models/helpers/create_request_params_service.py +4 -0
- stoobly_agent/app/proxy/replay/body_parser_service.py +11 -3
- stoobly_agent/config/data_dir.py +2 -1
- stoobly_agent/config/schema.yml +2 -2
- stoobly_agent/test/app/cli/scaffold/cli_invoker.py +1 -2
- stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py +162 -1
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- stoobly_agent/test/mock_data/scaffold/docker-compose-assets-service.yml +1 -3
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.3.0.dist-info}/METADATA +1 -1
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.3.0.dist-info}/RECORD +67 -68
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.proxy +0 -34
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.3.0.dist-info}/LICENSE +0 -0
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.3.0.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.3.0.dist-info}/entry_points.txt +0 -0
stoobly_agent/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
COMMAND = 'stoobly-agent'
|
2
|
-
VERSION = '1.
|
2
|
+
VERSION = '1.3.0'
|
@@ -23,10 +23,6 @@ class CertificateAuthority():
|
|
23
23
|
|
24
24
|
def __init__(self, certs_dir = DataDir.instance().mitmproxy_conf_dir_path, cn = MITMPROXY_CN):
|
25
25
|
self.certs_dir = certs_dir
|
26
|
-
|
27
|
-
if not os.path.exists(certs_dir):
|
28
|
-
self.generate_certs()
|
29
|
-
|
30
26
|
self.cn = cn
|
31
27
|
self.key_size = 2048
|
32
28
|
|
@@ -201,5 +197,5 @@ class CertificateAuthority():
|
|
201
197
|
return org_name, alt_names
|
202
198
|
|
203
199
|
except Exception as e:
|
204
|
-
Logger.instance(LOG_ID).
|
200
|
+
Logger.instance(LOG_ID).debug(f"Could not retrieve certificate for {domain}: {e}")
|
205
201
|
return None, alt_names
|
@@ -5,20 +5,18 @@ from stoobly_agent.config.data_dir import DataDir, DATA_DIR_NAME
|
|
5
5
|
|
6
6
|
class App():
|
7
7
|
|
8
|
-
def __init__(self, path: str,
|
8
|
+
def __init__(self, path: str, scaffold_namespace: str, **kwargs):
|
9
9
|
path = os.path.abspath(path) or os.getcwd()
|
10
10
|
data_dir: DataDir = DataDir.instance(path)
|
11
11
|
|
12
|
-
self.
|
12
|
+
self.__data_dir_path = data_dir.path
|
13
13
|
self.__ca_certs_dir_path = kwargs.get('ca_certs_dir_path') or data_dir.mitmproxy_conf_dir_path
|
14
|
-
self.__certs_dir_path = data_dir.certs_dir_path
|
15
|
-
self.__context_dir_path = data_dir.context_dir_path
|
14
|
+
self.__certs_dir_path = kwargs.get('certs_dir_path') or data_dir.certs_dir_path
|
15
|
+
self.__context_dir_path = kwargs.get('context_dir_path') or data_dir.context_dir_path
|
16
16
|
self.__data_dir = data_dir
|
17
17
|
self.__dir_path = path
|
18
|
-
self.
|
19
|
-
self.
|
20
|
-
self.__namespace = namespace
|
21
|
-
self.__skip_validate_path = not not kwargs.get('skip_validate_path')
|
18
|
+
self.__scaffold_namespace = scaffold_namespace
|
19
|
+
self.__skip_validate_path = not not kwargs.get('dry_run')
|
22
20
|
|
23
21
|
@property
|
24
22
|
def ca_certs_dir_path(self):
|
@@ -60,40 +58,24 @@ class App():
|
|
60
58
|
return os.path.exists(self.dir_path)
|
61
59
|
|
62
60
|
@property
|
63
|
-
def
|
64
|
-
return self.
|
65
|
-
|
66
|
-
@name.setter
|
67
|
-
def name(self, v: str):
|
68
|
-
self.__name = v
|
69
|
-
|
70
|
-
@property
|
71
|
-
def network(self):
|
72
|
-
return self.__network
|
73
|
-
|
74
|
-
@network.setter
|
75
|
-
def network(self, v: str):
|
76
|
-
self.__network = v
|
61
|
+
def scaffold_namespace(self):
|
62
|
+
return self.__scaffold_namespace
|
77
63
|
|
78
64
|
@property
|
79
|
-
def
|
80
|
-
return self.
|
81
|
-
|
82
|
-
@property
|
83
|
-
def namespace_path(self):
|
84
|
-
return os.path.join(self.data_dir_path, self.namespace)
|
65
|
+
def scaffold_namespace_path(self):
|
66
|
+
return os.path.join(self.data_dir_path, self.scaffold_namespace)
|
85
67
|
|
86
68
|
@property
|
87
69
|
def dir_path(self):
|
88
70
|
return self.__dir_path
|
89
71
|
|
90
72
|
@property
|
91
|
-
def
|
92
|
-
return self.
|
73
|
+
def data_dir_path(self):
|
74
|
+
return self.__data_dir_path
|
93
75
|
|
94
76
|
@property
|
95
77
|
def scaffold_namespace_path(self):
|
96
|
-
return os.path.join(self.
|
78
|
+
return os.path.join(self.data_dir_path, self.scaffold_namespace)
|
97
79
|
|
98
80
|
@property
|
99
81
|
def services(self):
|
@@ -101,7 +83,7 @@ class App():
|
|
101
83
|
|
102
84
|
@property
|
103
85
|
def service_paths(self):
|
104
|
-
services_dir = os.path.join(self.
|
86
|
+
services_dir = os.path.join(self.data_dir_path, self.scaffold_namespace)
|
105
87
|
|
106
88
|
services = []
|
107
89
|
for filename in os.listdir(services_dir):
|
@@ -13,9 +13,6 @@ class AppCommand(Command):
|
|
13
13
|
|
14
14
|
self.__config = AppConfig(self.scaffold_namespace_path)
|
15
15
|
|
16
|
-
if not self.__config.network:
|
17
|
-
self.__config.network = app.network
|
18
|
-
|
19
16
|
@property
|
20
17
|
def app_dir_path(self):
|
21
18
|
return self.app.dir_path
|
@@ -33,16 +30,16 @@ class AppCommand(Command):
|
|
33
30
|
return self.__config.path
|
34
31
|
|
35
32
|
@property
|
36
|
-
def
|
37
|
-
return self.app.
|
33
|
+
def scaffold_namespace_path(self):
|
34
|
+
return self.app.scaffold_namespace_path
|
38
35
|
|
39
36
|
@property
|
40
37
|
def app_templates_root_dir(self):
|
41
38
|
return os.path.join(self.templates_root_dir, 'app')
|
42
39
|
|
43
40
|
@property
|
44
|
-
def
|
45
|
-
return self.app.
|
41
|
+
def data_dir_path(self):
|
42
|
+
return self.app.data_dir_path
|
46
43
|
|
47
44
|
@property
|
48
45
|
def scaffold_namespace_path(self):
|
@@ -1,15 +1,24 @@
|
|
1
1
|
from .config import Config
|
2
|
-
from .constants import APP_NETWORK_ENV
|
2
|
+
from .constants import APP_NAME_ENV, APP_NETWORK_ENV
|
3
3
|
|
4
4
|
class AppConfig(Config):
|
5
5
|
|
6
6
|
def __init__(self, dir: str):
|
7
7
|
super().__init__(dir)
|
8
8
|
|
9
|
+
self.__name = None
|
9
10
|
self.__network = None
|
10
11
|
|
11
12
|
self.load()
|
12
13
|
|
14
|
+
@property
|
15
|
+
def name(self):
|
16
|
+
return self.__name
|
17
|
+
|
18
|
+
@name.setter
|
19
|
+
def name(self, v):
|
20
|
+
self.__name = v
|
21
|
+
|
13
22
|
@property
|
14
23
|
def network(self):
|
15
24
|
return self.__network
|
@@ -21,11 +30,15 @@ class AppConfig(Config):
|
|
21
30
|
def load(self, config = None):
|
22
31
|
config = config or self.read()
|
23
32
|
|
24
|
-
self.
|
33
|
+
self.name = config.get(APP_NAME_ENV)
|
34
|
+
self.network = config.get(APP_NETWORK_ENV)
|
25
35
|
|
26
36
|
def write(self):
|
27
37
|
config = {}
|
28
38
|
|
39
|
+
if self.name:
|
40
|
+
config[APP_NAME_ENV] = self.name
|
41
|
+
|
29
42
|
if self.network:
|
30
43
|
config[APP_NETWORK_ENV] = self.network
|
31
44
|
|
@@ -1,17 +1,33 @@
|
|
1
1
|
import os
|
2
2
|
import pdb
|
3
3
|
|
4
|
+
from typing import TypedDict
|
5
|
+
|
4
6
|
from .app import App
|
5
7
|
from .app_command import AppCommand
|
6
8
|
|
9
|
+
class AppCreateOptions(TypedDict):
|
10
|
+
name: str
|
11
|
+
network: str
|
12
|
+
|
7
13
|
class AppCreateCommand(AppCommand):
|
8
14
|
|
9
|
-
def __init__(self, app: App, **kwargs):
|
15
|
+
def __init__(self, app: App, **kwargs: AppCreateOptions):
|
10
16
|
super().__init__(app)
|
11
17
|
|
18
|
+
if kwargs.get('app_name'):
|
19
|
+
self.app_config.name = kwargs['app_name']
|
20
|
+
|
21
|
+
if kwargs.get('network'):
|
22
|
+
self.app_config.network = kwargs['network']
|
23
|
+
|
12
24
|
@property
|
13
25
|
def app_name(self):
|
14
|
-
return self.
|
26
|
+
return self.app_config.name
|
27
|
+
|
28
|
+
@property
|
29
|
+
def app_network(self):
|
30
|
+
return self.app_config.network
|
15
31
|
|
16
32
|
def build(self):
|
17
33
|
dest = self.scaffold_namespace_path
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
import os
|
2
2
|
|
3
|
-
from
|
3
|
+
from typing import Literal
|
4
4
|
|
5
|
+
from stoobly_agent.config.data_dir import CERTS_DIR_NAME, DATA_DIR_NAME
|
5
6
|
|
6
7
|
APP_NETWORK_ENV = 'APP_NETWORK'
|
8
|
+
APP_NAME_ENV = 'APP_NAME'
|
7
9
|
BIN_FOLDER_NAME = 'bin'
|
8
10
|
CA_CERTS_DIR_ENV = 'CA_CERTS_DIR'
|
9
11
|
CERTS_DIR_ENV = 'CERTS_DIR'
|
@@ -22,6 +24,7 @@ SERVICE_HOSTNAME = '${SERVICE_HOSTNAME}'
|
|
22
24
|
SERVICE_HOSTNAME_ENV = 'SERVICE_HOSTNAME'
|
23
25
|
SERVICE_DNS = '${SERVICE_DNS}'
|
24
26
|
SERVICE_DNS_ENV = 'SERVICE_DNS'
|
27
|
+
SERVICE_NAME = '${SERVICE_NAME}'
|
25
28
|
SERVICE_NAME_ENV = 'SERVICE_NAME'
|
26
29
|
SERVICE_PROXY_MODE = '${SERVICE_PROXY_MODE}'
|
27
30
|
SERVICE_PROXY_MODE_ENV = 'SERVICE_PROXY_MODE'
|
@@ -31,7 +34,8 @@ SERVICE_PORT = '${SERVICE_PORT}'
|
|
31
34
|
SERVICE_PORT_ENV = 'SERVICE_PORT'
|
32
35
|
SERVICE_PRIORITY_ENV = 'SERVICE_PRIORITY'
|
33
36
|
STOOBLY_HOME_DIR = '/home/stoobly'
|
34
|
-
STOOBLY_DATA_DIR =
|
37
|
+
STOOBLY_DATA_DIR = os.path.join(STOOBLY_HOME_DIR, DATA_DIR_NAME)
|
38
|
+
STOOBLY_CERTS_DIR = os.path.join(STOOBLY_DATA_DIR, CERTS_DIR_NAME)
|
35
39
|
USER_ID_ENV = 'USER_ID'
|
36
40
|
VIRTUAL_HOST_ENV = 'VIRTUAL_HOST'
|
37
41
|
VIRTUAL_PORT_ENV = 'VIRTUAL_PORT'
|
@@ -44,7 +48,9 @@ WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_C
|
|
44
48
|
WORKFLOW_CONTAINER_INIT_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_INIT
|
45
49
|
WORKFLOW_CONTAINER_PROXY_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_PROXY
|
46
50
|
WORKFLOW_MOCK_TYPE = 'mock'
|
51
|
+
WORKFLOW_NAME = '${WORKFLOW_NAME}'
|
47
52
|
WORKFLOW_NAME_ENV = 'WORKFLOW_NAME'
|
53
|
+
WORKFLOW_NAMESPACE_ENV = 'WORKFLOW_NAMESPACE'
|
48
54
|
WORKFLOW_RECORD_TYPE = 'record'
|
49
55
|
WORKFLOW_TEST_TYPE = 'test'
|
50
56
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import os
|
2
2
|
|
3
3
|
from .builder import Builder
|
4
|
-
from .constants import DOCKER_COMPOSE_BASE, DOCKERFILE_CONTEXT
|
4
|
+
from .constants import DOCKER_COMPOSE_BASE, DOCKERFILE_CONTEXT
|
5
5
|
from ..app_config import AppConfig
|
6
6
|
|
7
7
|
class AppBuilder(Builder):
|
@@ -18,9 +18,5 @@ class AppBuilder(Builder):
|
|
18
18
|
return os.path.join(self.dir_path, DOCKERFILE_CONTEXT)
|
19
19
|
|
20
20
|
@property
|
21
|
-
def
|
22
|
-
return '
|
23
|
-
|
24
|
-
@property
|
25
|
-
def proxy_docker_file_path(self):
|
26
|
-
return os.path.join(self.dir_path, DOCKERFILE_PROXY)
|
21
|
+
def stoobly_base(self):
|
22
|
+
return 'stoobly_base'
|
@@ -3,7 +3,6 @@ DOCKER_COMPOSE_BASE = '.docker-compose.base.yml'
|
|
3
3
|
DOCKER_COMPOSE_BASE_TEMPLATE = '.docker-compose.base.template.yml'
|
4
4
|
DOCKER_COMPOSE_CUSTOM = 'docker-compose.yml'
|
5
5
|
DOCKERFILE_CONTEXT = '.Dockerfile.context'
|
6
|
-
DOCKERFILE_PROXY = '.Dockerfile.proxy'
|
7
6
|
DOCKERFILE_SERVICE = 'Dockerfile.source'
|
8
7
|
GATEWAY_NETWORK = 'gateway'
|
9
8
|
|
@@ -2,7 +2,7 @@ import os
|
|
2
2
|
import pdb
|
3
3
|
|
4
4
|
from ...app_config import AppConfig
|
5
|
-
from ...constants import SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, STOOBLY_HOME_DIR
|
5
|
+
from ...constants import SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME, STOOBLY_HOME_DIR, WORKFLOW_NAME
|
6
6
|
from ...service_config import ServiceConfig
|
7
7
|
from ..app_builder import AppBuilder
|
8
8
|
from ..builder import Builder
|
@@ -44,6 +44,13 @@ class ServiceBuilder(Builder):
|
|
44
44
|
def configure_base_service(self):
|
45
45
|
return self.services.get(self.configure_base)
|
46
46
|
|
47
|
+
@property
|
48
|
+
def extends_service(self):
|
49
|
+
if self.config.detached:
|
50
|
+
return self.app_builder.stoobly_base
|
51
|
+
else:
|
52
|
+
return self.app_builder.context_base
|
53
|
+
|
47
54
|
@property
|
48
55
|
def proxy_base(self):
|
49
56
|
return f"{self.service_name}.proxy_base"
|
@@ -52,10 +59,6 @@ class ServiceBuilder(Builder):
|
|
52
59
|
def proxy_base_service(self):
|
53
60
|
return self.services.get(self.proxy_base)
|
54
61
|
|
55
|
-
@property
|
56
|
-
def service_mount(self):
|
57
|
-
return f".:{STOOBLY_HOME_DIR}"
|
58
|
-
|
59
62
|
@property
|
60
63
|
def service_name(self):
|
61
64
|
return self.__service_name
|
@@ -80,9 +83,8 @@ class ServiceBuilder(Builder):
|
|
80
83
|
},
|
81
84
|
'extends': {
|
82
85
|
'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
|
83
|
-
'service': self.
|
86
|
+
'service': self.extends_service
|
84
87
|
},
|
85
|
-
'volumes': [self.service_mount]
|
86
88
|
})
|
87
89
|
|
88
90
|
args[SERVICE_HOSTNAME_ENV] = f"{SERVICE_HOSTNAME}"
|
@@ -90,13 +92,12 @@ class ServiceBuilder(Builder):
|
|
90
92
|
def build_init_base(self):
|
91
93
|
environment = {}
|
92
94
|
self.with_service(self.init_base, {
|
93
|
-
'command': ['bin/.init'
|
95
|
+
'command': ['bin/.init'],
|
94
96
|
'environment': environment,
|
95
97
|
'extends': {
|
96
98
|
'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
|
97
|
-
'service': self.
|
99
|
+
'service': self.extends_service
|
98
100
|
},
|
99
|
-
'volumes': [self.service_mount]
|
100
101
|
})
|
101
102
|
|
102
103
|
def build_configure_base(self):
|
@@ -106,7 +107,7 @@ class ServiceBuilder(Builder):
|
|
106
107
|
'environment': environment,
|
107
108
|
'extends': {
|
108
109
|
'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
|
109
|
-
'service': self.
|
110
|
+
'service': self.extends_service
|
110
111
|
}
|
111
112
|
})
|
112
113
|
|
@@ -3,12 +3,13 @@ import pdb
|
|
3
3
|
|
4
4
|
from typing import List
|
5
5
|
|
6
|
+
from stoobly_agent.config.data_dir import DATA_DIR_NAME
|
7
|
+
|
6
8
|
from ...constants import (
|
7
|
-
COMPOSE_TEMPLATE, STOOBLY_HOME_DIR, SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME_ENV,
|
9
|
+
COMPOSE_TEMPLATE, DOCKER_NAMESPACE, STOOBLY_HOME_DIR, SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME_ENV,
|
8
10
|
SERVICE_PORT, SERVICE_PORT_ENV, SERVICE_SCHEME, SERVICE_SCHEME_ENV,
|
9
11
|
WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE, WORKFLOW_CONTAINER_INIT_TEMPLATE, WORKFLOW_CONTAINER_PROXY_TEMPLATE, WORKFLOW_NAME_ENV
|
10
12
|
)
|
11
|
-
from ...templates.constants import SERVICE_HOSTNAME_BUILD_ARG
|
12
13
|
from ..builder import Builder
|
13
14
|
from ..service.builder import ServiceBuilder
|
14
15
|
|
@@ -21,13 +22,15 @@ class WorkflowBuilder(Builder):
|
|
21
22
|
|
22
23
|
self.__context = '../'
|
23
24
|
self.__profiles = [self.__workflow_name]
|
24
|
-
self.__workdir = os.path.join(STOOBLY_HOME_DIR, self.workflow_name)
|
25
25
|
|
26
26
|
if not service_builder:
|
27
27
|
service_path = os.path.dirname(workflow_path)
|
28
28
|
service_builder = ServiceBuilder(service_path)
|
29
29
|
|
30
30
|
self.__service_builder = service_builder
|
31
|
+
self.__working_dir = os.path.join(
|
32
|
+
STOOBLY_HOME_DIR, DATA_DIR_NAME, DOCKER_NAMESPACE, self.service_builder.service_name, self.workflow_name
|
33
|
+
)
|
31
34
|
|
32
35
|
if self.config.hostname:
|
33
36
|
self.with_public_network()
|
@@ -58,13 +61,6 @@ class WorkflowBuilder(Builder):
|
|
58
61
|
def context(self):
|
59
62
|
return self.__context
|
60
63
|
|
61
|
-
@property
|
62
|
-
def context_build(self):
|
63
|
-
return {
|
64
|
-
'context': self.context,
|
65
|
-
'dockerfile': self.context_docker_file_path,
|
66
|
-
}
|
67
|
-
|
68
64
|
@property
|
69
65
|
def context_docker_file_path(self):
|
70
66
|
return os.path.relpath(self.service_builder.app_builder.context_docker_file_path, self.service_path)
|
@@ -81,21 +77,6 @@ class WorkflowBuilder(Builder):
|
|
81
77
|
def proxy(self):
|
82
78
|
return WORKFLOW_CONTAINER_PROXY_TEMPLATE.format(service_name=self.namespace)
|
83
79
|
|
84
|
-
@property
|
85
|
-
def proxy_build(self):
|
86
|
-
args = {}
|
87
|
-
args[SERVICE_HOSTNAME_BUILD_ARG] = SERVICE_HOSTNAME
|
88
|
-
|
89
|
-
return {
|
90
|
-
'args': args,
|
91
|
-
'context': self.context,
|
92
|
-
'dockerfile': self.proxy_docker_file_path,
|
93
|
-
}
|
94
|
-
|
95
|
-
@property
|
96
|
-
def proxy_docker_file_path(self):
|
97
|
-
return os.path.relpath(self.service_builder.app_builder.proxy_docker_file_path, self.service_path)
|
98
|
-
|
99
80
|
@property
|
100
81
|
def service_builder(self):
|
101
82
|
return self.__service_builder
|
@@ -128,19 +109,21 @@ class WorkflowBuilder(Builder):
|
|
128
109
|
volumes = []
|
129
110
|
|
130
111
|
service = {
|
131
|
-
'build': self.context_build,
|
132
112
|
'environment': environment,
|
133
113
|
'extends': self.service_builder.build_extends_init_base(self.dir_path),
|
134
114
|
'profiles': self.profiles,
|
135
115
|
'volumes': volumes,
|
136
|
-
'working_dir': self.
|
116
|
+
'working_dir': self.__working_dir,
|
137
117
|
}
|
138
118
|
|
139
119
|
if self.config.hostname:
|
140
120
|
self.__with_url_environment(environment)
|
141
121
|
|
142
122
|
if self.config.detached:
|
123
|
+
# Mount named volume
|
143
124
|
volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
|
125
|
+
# Mount docker folder
|
126
|
+
volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
|
144
127
|
|
145
128
|
self.with_service(self.init, service)
|
146
129
|
|
@@ -154,13 +137,12 @@ class WorkflowBuilder(Builder):
|
|
154
137
|
volumes = []
|
155
138
|
|
156
139
|
service = {
|
157
|
-
'build': self.context_build,
|
158
140
|
'depends_on': depends_on,
|
159
141
|
'environment': environment,
|
160
142
|
'extends': self.service_builder.build_extends_configure_base(self.dir_path),
|
161
143
|
'profiles': self.profiles,
|
162
144
|
'volumes': volumes,
|
163
|
-
'working_dir': self.
|
145
|
+
'working_dir': self.__working_dir,
|
164
146
|
}
|
165
147
|
|
166
148
|
if self.config.hostname:
|
@@ -173,6 +155,7 @@ class WorkflowBuilder(Builder):
|
|
173
155
|
|
174
156
|
if self.config.detached:
|
175
157
|
volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
|
158
|
+
volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
|
176
159
|
|
177
160
|
self.with_service(self.configure, service)
|
178
161
|
|
@@ -187,14 +170,13 @@ class WorkflowBuilder(Builder):
|
|
187
170
|
volumes = []
|
188
171
|
|
189
172
|
service = {
|
190
|
-
'build': self.proxy_build,
|
191
173
|
'depends_on': depends_on,
|
192
174
|
'environment': environment,
|
193
175
|
'extends': self.service_builder.build_extends_proxy_base(self.dir_path),
|
194
176
|
'networks': networks,
|
195
177
|
'profiles': self.profiles,
|
196
178
|
'volumes': volumes,
|
197
|
-
'working_dir': self.
|
179
|
+
'working_dir': self.__working_dir,
|
198
180
|
}
|
199
181
|
|
200
182
|
if self.configure in self.services:
|
@@ -217,6 +199,7 @@ class WorkflowBuilder(Builder):
|
|
217
199
|
|
218
200
|
if self.config.detached:
|
219
201
|
volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
|
202
|
+
volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
|
220
203
|
|
221
204
|
self.with_service(self.proxy, service)
|
222
205
|
|
@@ -1,6 +1,7 @@
|
|
1
|
+
import os
|
1
2
|
import pdb
|
2
3
|
|
3
|
-
from ...constants import SERVICE_HOSTNAME, SERVICE_PORT
|
4
|
+
from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
|
4
5
|
from .builder import WorkflowBuilder
|
5
6
|
|
6
7
|
class MockDecorator():
|
@@ -20,7 +21,6 @@ class MockDecorator():
|
|
20
21
|
config = self.service_builder.config
|
21
22
|
|
22
23
|
command = [
|
23
|
-
'--certs', f"/etc/ssl/certs/{SERVICE_HOSTNAME}-joined.pem",
|
24
24
|
'--headless',
|
25
25
|
'--intercept',
|
26
26
|
'--lifecycle-hooks-path', 'lifecycle_hooks.py',
|
@@ -30,6 +30,10 @@ class MockDecorator():
|
|
30
30
|
'--ssl-insecure'
|
31
31
|
]
|
32
32
|
|
33
|
+
if config.scheme == 'https':
|
34
|
+
command.append('--certs')
|
35
|
+
command.append(os.path.join(STOOBLY_CERTS_DIR, f"{SERVICE_HOSTNAME}-joined.pem"))
|
36
|
+
|
33
37
|
services = self.__workflow_builder.services
|
34
38
|
proxy_name = self.__workflow_builder.proxy
|
35
39
|
proxy_service = services.get(proxy_name) or {}
|
@@ -1,8 +1,9 @@
|
|
1
|
+
import os
|
1
2
|
import pdb
|
2
3
|
|
3
4
|
from urllib.parse import urlparse
|
4
5
|
|
5
|
-
from ...constants import SERVICE_HOSTNAME, SERVICE_PORT
|
6
|
+
from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
|
6
7
|
from .builder import WorkflowBuilder
|
7
8
|
|
8
9
|
class ReverseProxyDecorator():
|
@@ -22,7 +23,6 @@ class ReverseProxyDecorator():
|
|
22
23
|
config = self.service_builder.config
|
23
24
|
|
24
25
|
command = [
|
25
|
-
'--certs', f"/etc/ssl/certs/{SERVICE_HOSTNAME}-joined.pem",
|
26
26
|
'--headless',
|
27
27
|
'--lifecycle-hooks-path', 'lifecycle_hooks.py',
|
28
28
|
'--proxy-mode', config.proxy_mode,
|
@@ -30,6 +30,10 @@ class ReverseProxyDecorator():
|
|
30
30
|
'--ssl-insecure'
|
31
31
|
]
|
32
32
|
|
33
|
+
if config.scheme == 'https':
|
34
|
+
command.append('--certs')
|
35
|
+
command.append(os.path.join(STOOBLY_CERTS_DIR, f"{SERVICE_HOSTNAME}-joined.pem"))
|
36
|
+
|
33
37
|
services = self.workflow_builder.services
|
34
38
|
proxy_name = self.workflow_builder.proxy
|
35
39
|
proxy_service = services.get(proxy_name) or {}
|
@@ -1,21 +1,17 @@
|
|
1
1
|
import os
|
2
2
|
import pdb
|
3
3
|
import socket
|
4
|
-
import ssl
|
5
4
|
import time
|
5
|
+
|
6
6
|
from collections import Counter
|
7
7
|
from pathlib import Path
|
8
8
|
|
9
|
-
import requests
|
10
9
|
import yaml
|
11
10
|
from docker.models.containers import Container
|
12
|
-
from requests.adapters import HTTPAdapter
|
13
|
-
from urllib3 import Retry
|
14
11
|
|
15
12
|
from stoobly_agent.app.cli.scaffold.constants import (
|
16
13
|
FIXTURES_FOLDER_NAME,
|
17
14
|
STOOBLY_DATA_DIR,
|
18
|
-
STOOBLY_HOME_DIR,
|
19
15
|
VIRTUAL_HOST_ENV,
|
20
16
|
VIRTUAL_PORT_ENV,
|
21
17
|
VIRTUAL_PROTO_ENV,
|
@@ -39,7 +35,9 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
|
|
39
35
|
|
40
36
|
self.workflow_name = kwargs['workflow_name']
|
41
37
|
self.hostname = self.service_config.hostname
|
42
|
-
self.service_docker_compose = ServiceDockerCompose(
|
38
|
+
self.service_docker_compose = ServiceDockerCompose(
|
39
|
+
app_dir_path=app.dir_path, target_workflow_name=self.workflow_name, service_name=self.service_name, hostname=self.hostname
|
40
|
+
)
|
43
41
|
|
44
42
|
@property
|
45
43
|
def fixtures_dir_path(self):
|
@@ -48,7 +46,7 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
|
|
48
46
|
@property
|
49
47
|
def workflow_path(self):
|
50
48
|
return os.path.join(
|
51
|
-
self.
|
49
|
+
self.data_dir_path,
|
52
50
|
self.workflow_relative_path
|
53
51
|
)
|
54
52
|
@property
|
@@ -151,7 +149,7 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
|
|
151
149
|
return
|
152
150
|
|
153
151
|
# Check contents of fixtures folder to confirm it's shared
|
154
|
-
fixtures_folder_path = f"{
|
152
|
+
fixtures_folder_path = f"{FIXTURES_FOLDER_NAME}"
|
155
153
|
exec_result = container.exec_run(f"ls -A {fixtures_folder_path}")
|
156
154
|
output = exec_result.output
|
157
155
|
|
@@ -1,8 +1,6 @@
|
|
1
|
-
FROM stoobly/agent:1.
|
1
|
+
FROM stoobly/agent:1.3
|
2
2
|
|
3
3
|
ARG USER_ID
|
4
4
|
|
5
5
|
# Change user id of stoobly user to that of host's user id
|
6
|
-
RUN if [ -n "$USER_ID" ]; then usermod -u $USER_ID stoobly; fi
|
7
|
-
|
8
|
-
COPY --chown=stoobly:stoobly . .
|
6
|
+
RUN if [ -n "$USER_ID" ]; then usermod -u $USER_ID stoobly; fi
|