spaceforge 1.3.0__tar.gz → 1.4.0__tar.gz
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.
- spaceforge-1.4.0/CODEOWNERS +1 -0
- {spaceforge-1.3.0/spaceforge.egg-info → spaceforge-1.4.0}/PKG-INFO +1 -1
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/sops/plugin.py +10 -1
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/sops/plugin.yaml +17 -2
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/wiz/plugin.py +131 -43
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/wiz/plugin.yaml +196 -48
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/_version_scm.py +3 -3
- {spaceforge-1.3.0 → spaceforge-1.4.0/spaceforge.egg-info}/PKG-INFO +1 -1
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge.egg-info/SOURCES.txt +1 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/.github/workflows/ci.yml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/.github/workflows/release.yml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/.gitignore +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/CONTRIBUTING.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/LICENSE +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/MANIFEST.in +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/go.mod +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/linting/__init__.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/linting/spaceforge_checker.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/aws_sam/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/aws_sam/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/aws_sam/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/aws_sam/requirements.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/checkov/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/checkov/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/checkov/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/checkov/requirements.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/enviroment_manager/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/enviroment_manager/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/enviroment_manager/requirements.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/envsubst/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/envsubst/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/infracost/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/infracost/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/opentofu-tracing/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/opentofu-tracing/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/sops/requirements.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/ssm_parameter_store/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/ssm_parameter_store/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/ssm_parameter_store/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/ssm_parameter_store/requirements.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/terrascan/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/terrascan/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/terrascan/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trivy/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trivy/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trivy/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trufflehog/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trufflehog/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/plugins/trufflehog/plugin.yaml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/pyproject.toml +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/regenerate_plugins.sh +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/setup.cfg +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/README.md +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/__init__.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/__main__.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/_version.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/cls.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/conftest.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/generator.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/runner.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/schema.json +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/templates/binary_install.sh.j2 +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/templates/ensure_spaceforge_and_run.sh.j2 +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_cls.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_generator.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_generator_binaries.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_generator_core.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_generator_hooks.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_generator_parameters.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_plugin.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_plugin_file_operations.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_plugin_hooks.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_plugin_inheritance.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_runner.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_runner_cli.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_runner_core.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge/test_runner_execution.py +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge.egg-info/dependency_links.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge.egg-info/entry_points.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge.egg-info/requires.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/spaceforge.egg-info/top_level.txt +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/templates.go +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/test.sh +0 -0
- {spaceforge-1.3.0 → spaceforge-1.4.0}/validate_plugins.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @spacelift-io/ecosystem
|
|
@@ -43,12 +43,18 @@ class SopsPlugin(SpaceforgePlugin):
|
|
|
43
43
|
file is at the repository root.
|
|
44
44
|
|
|
45
45
|
Example: `${TF_VAR_spacelift_workspace_root}/source/.sops.yaml`
|
|
46
|
+
|
|
47
|
+
Environment variables are supported in the `secrets` list using `$VAR` or `${VAR}` syntax:
|
|
48
|
+
```yaml
|
|
49
|
+
secrets:
|
|
50
|
+
- services/${TF_VAR_service_name}/secrets/${TF_VAR_environment}.enc.yaml
|
|
51
|
+
```
|
|
46
52
|
"""
|
|
47
53
|
|
|
48
54
|
# Plugin metadata
|
|
49
55
|
__plugin_name__ = "Sops"
|
|
50
56
|
__labels__ = ["secrets management", "encryption"]
|
|
51
|
-
__version__ = "1.
|
|
57
|
+
__version__ = "1.2.0"
|
|
52
58
|
__author__ = "Spacelift Team"
|
|
53
59
|
|
|
54
60
|
__binaries__ = [
|
|
@@ -107,6 +113,9 @@ class SopsPlugin(SpaceforgePlugin):
|
|
|
107
113
|
secrets = secrets["secrets"]
|
|
108
114
|
|
|
109
115
|
for secret in secrets:
|
|
116
|
+
# Expand environment variables in secret paths (supports $VAR and ${VAR} syntax)
|
|
117
|
+
secret = os.path.expandvars(secret)
|
|
118
|
+
|
|
110
119
|
if not Path(secret).exists():
|
|
111
120
|
self.logger.error(f"Secret file {secret} does not exist.")
|
|
112
121
|
continue
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: Sops
|
|
2
|
-
version: 1.
|
|
2
|
+
version: 1.2.0
|
|
3
3
|
description: |-
|
|
4
4
|
This adds the `SOPS` plugin to your Spacelift account.
|
|
5
5
|
It will decrypt an arbitrary number of files based on config you set.
|
|
@@ -35,6 +35,12 @@ description: |-
|
|
|
35
35
|
file is at the repository root.
|
|
36
36
|
|
|
37
37
|
Example: `${TF_VAR_spacelift_workspace_root}/source/.sops.yaml`
|
|
38
|
+
|
|
39
|
+
Environment variables are supported in the `secrets` list using `$VAR` or `${VAR}` syntax:
|
|
40
|
+
```yaml
|
|
41
|
+
secrets:
|
|
42
|
+
- services/${TF_VAR_service_name}/secrets/${TF_VAR_environment}.enc.yaml
|
|
43
|
+
```
|
|
38
44
|
author: Spacelift Team
|
|
39
45
|
labels:
|
|
40
46
|
- secrets management
|
|
@@ -107,12 +113,18 @@ contexts:
|
|
|
107
113
|
file is at the repository root.
|
|
108
114
|
|
|
109
115
|
Example: `${TF_VAR_spacelift_workspace_root}/source/.sops.yaml`
|
|
116
|
+
|
|
117
|
+
Environment variables are supported in the `secrets` list using `$VAR` or `${VAR}` syntax:
|
|
118
|
+
```yaml
|
|
119
|
+
secrets:
|
|
120
|
+
- services/${TF_VAR_service_name}/secrets/${TF_VAR_environment}.enc.yaml
|
|
121
|
+
```
|
|
110
122
|
"""
|
|
111
123
|
|
|
112
124
|
# Plugin metadata
|
|
113
125
|
__plugin_name__ = "Sops"
|
|
114
126
|
__labels__ = ["secrets management", "encryption"]
|
|
115
|
-
__version__ = "1.
|
|
127
|
+
__version__ = "1.2.0"
|
|
116
128
|
__author__ = "Spacelift Team"
|
|
117
129
|
|
|
118
130
|
__binaries__ = [
|
|
@@ -171,6 +183,9 @@ contexts:
|
|
|
171
183
|
secrets = secrets["secrets"]
|
|
172
184
|
|
|
173
185
|
for secret in secrets:
|
|
186
|
+
# Expand environment variables in secret paths (supports $VAR and ${VAR} syntax)
|
|
187
|
+
secret = os.path.expandvars(secret)
|
|
188
|
+
|
|
174
189
|
if not Path(secret).exists():
|
|
175
190
|
self.logger.error(f"Secret file {secret} does not exist.")
|
|
176
191
|
continue
|
|
@@ -23,28 +23,46 @@ class WizPlugin(SpaceforgePlugin):
|
|
|
23
23
|
# Plugin metadata
|
|
24
24
|
__plugin_name__ = "Wiz"
|
|
25
25
|
__labels__ = ["security", "code scanning", "vulnerability"]
|
|
26
|
-
__version__ = "
|
|
26
|
+
__version__ = "2.0.0"
|
|
27
27
|
__author__ = "Spacelift Team"
|
|
28
28
|
|
|
29
29
|
__binaries__ = [
|
|
30
30
|
Binary(
|
|
31
31
|
name="wizcli",
|
|
32
32
|
download_urls={
|
|
33
|
-
"amd64": "https://downloads.wiz.io/wizcli/latest/wizcli-linux-amd64",
|
|
34
|
-
"arm64": "https://downloads.wiz.io/wizcli/latest/wizcli-linux-arm64",
|
|
33
|
+
"amd64": "https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-amd64",
|
|
34
|
+
"arm64": "https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-arm64",
|
|
35
35
|
},
|
|
36
36
|
)
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
# Plugin parameters
|
|
40
40
|
__parameters__ = [
|
|
41
|
+
Parameter(
|
|
42
|
+
name="Default Scan Name",
|
|
43
|
+
id="default_scan_name",
|
|
44
|
+
description="The default name of the scan that shows up in wiz. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_SCAN_NAME) there",
|
|
45
|
+
default="",
|
|
46
|
+
type="string",
|
|
47
|
+
required=False,
|
|
48
|
+
sensitive=False,
|
|
49
|
+
),
|
|
50
|
+
Parameter(
|
|
51
|
+
name="Default Policies",
|
|
52
|
+
id="default_policies",
|
|
53
|
+
description="Comma separated list of policies to include in all scans. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_POLICIES) there.",
|
|
54
|
+
default="",
|
|
55
|
+
type="string",
|
|
56
|
+
required=False,
|
|
57
|
+
sensitive=False,
|
|
58
|
+
),
|
|
41
59
|
Parameter(
|
|
42
60
|
name="Wiz Client ID",
|
|
43
61
|
id="wiz_client_id",
|
|
44
62
|
description="The client ID for Wiz API authentication",
|
|
45
63
|
type="string",
|
|
46
64
|
required=True,
|
|
47
|
-
sensitive=
|
|
65
|
+
sensitive=False,
|
|
48
66
|
),
|
|
49
67
|
Parameter(
|
|
50
68
|
name="Wiz Client Secret",
|
|
@@ -54,6 +72,41 @@ class WizPlugin(SpaceforgePlugin):
|
|
|
54
72
|
required=True,
|
|
55
73
|
sensitive=True,
|
|
56
74
|
),
|
|
75
|
+
Parameter(
|
|
76
|
+
name="Additional Arguments",
|
|
77
|
+
id="wiz_additional_args",
|
|
78
|
+
description="Additional command-line arguments to pass to Wiz",
|
|
79
|
+
default="",
|
|
80
|
+
type="string",
|
|
81
|
+
required=False,
|
|
82
|
+
),
|
|
83
|
+
Parameter(
|
|
84
|
+
name="Wiz CLI Autofail",
|
|
85
|
+
id="wizcli_autofail",
|
|
86
|
+
description="Allow wizcli to fail the run (instead of policies)",
|
|
87
|
+
default=False,
|
|
88
|
+
type="boolean",
|
|
89
|
+
required=False,
|
|
90
|
+
sensitive=False,
|
|
91
|
+
),
|
|
92
|
+
Parameter(
|
|
93
|
+
name="Is GovCloud",
|
|
94
|
+
id="is_govcloud",
|
|
95
|
+
description="Enable if you access wiz via gov.wiz.io",
|
|
96
|
+
default=False,
|
|
97
|
+
type="boolean",
|
|
98
|
+
required=False,
|
|
99
|
+
sensitive=False,
|
|
100
|
+
),
|
|
101
|
+
Parameter(
|
|
102
|
+
name="Is Fedramp",
|
|
103
|
+
id="is_fedramp",
|
|
104
|
+
description="Enable if you access wiz via app.wiz.us",
|
|
105
|
+
default=False,
|
|
106
|
+
type="boolean",
|
|
107
|
+
required=False,
|
|
108
|
+
sensitive=False,
|
|
109
|
+
),
|
|
57
110
|
]
|
|
58
111
|
|
|
59
112
|
# Plugin contexts
|
|
@@ -62,16 +115,46 @@ class WizPlugin(SpaceforgePlugin):
|
|
|
62
115
|
name_prefix="WIZ",
|
|
63
116
|
description="Wiz Plugin",
|
|
64
117
|
env=[
|
|
118
|
+
Variable(
|
|
119
|
+
key="DEFAULT_SCAN_NAME",
|
|
120
|
+
value_from_parameter="default_scan_name",
|
|
121
|
+
sensitive=False,
|
|
122
|
+
),
|
|
123
|
+
Variable(
|
|
124
|
+
key="DEFAULT_POLICIES",
|
|
125
|
+
value_from_parameter="default_policies",
|
|
126
|
+
sensitive=False,
|
|
127
|
+
),
|
|
65
128
|
Variable(
|
|
66
129
|
key="WIZ_CLIENT_ID",
|
|
67
|
-
value_from_parameter="
|
|
68
|
-
sensitive=
|
|
130
|
+
value_from_parameter="wiz_client_id",
|
|
131
|
+
sensitive=False,
|
|
69
132
|
),
|
|
70
133
|
Variable(
|
|
71
134
|
key="WIZ_CLIENT_SECRET",
|
|
72
|
-
value_from_parameter="
|
|
135
|
+
value_from_parameter="wiz_client_secret",
|
|
73
136
|
sensitive=True,
|
|
74
137
|
),
|
|
138
|
+
Variable(
|
|
139
|
+
key="WIZ_ADDITIONAL_ARGS",
|
|
140
|
+
value_from_parameter="wiz_additional_args",
|
|
141
|
+
sensitive=False,
|
|
142
|
+
),
|
|
143
|
+
Variable(
|
|
144
|
+
key="WIZCLI_AUTOFAIL",
|
|
145
|
+
value_from_parameter="wizcli_autofail",
|
|
146
|
+
sensitive=False,
|
|
147
|
+
),
|
|
148
|
+
Variable(
|
|
149
|
+
key="IS_GOVCLOUD",
|
|
150
|
+
value_from_parameter="is_govcloud",
|
|
151
|
+
sensitive=False,
|
|
152
|
+
),
|
|
153
|
+
Variable(
|
|
154
|
+
key="IS_FEDRAMP",
|
|
155
|
+
value_from_parameter="is_fedramp",
|
|
156
|
+
sensitive=False,
|
|
157
|
+
),
|
|
75
158
|
],
|
|
76
159
|
)
|
|
77
160
|
]
|
|
@@ -119,63 +202,68 @@ deny[sprintf("Too many low vulnerabilities (%d)", [num])] {
|
|
|
119
202
|
def before_plan(self):
|
|
120
203
|
self.logger.info("Checking IAC Code")
|
|
121
204
|
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
os.environ
|
|
127
|
-
"--secret",
|
|
128
|
-
os.environ.get("WIZ_CLIENT_SECRET"),
|
|
129
|
-
)
|
|
130
|
-
if return_code != 0:
|
|
131
|
-
exit(1)
|
|
205
|
+
if os.environ.get("IS_GOVCLOUD", "false").lower() == "true":
|
|
206
|
+
os.environ["WIZ_ENV"] = "gov"
|
|
207
|
+
|
|
208
|
+
if os.environ.get("IS_FEDRAMP", "false").lower() == "true":
|
|
209
|
+
os.environ["WIZ_ENV"] = "fedramp"
|
|
132
210
|
|
|
133
|
-
|
|
211
|
+
args = [
|
|
134
212
|
"wizcli",
|
|
135
|
-
"iac",
|
|
136
213
|
"scan",
|
|
137
|
-
"
|
|
138
|
-
"json",
|
|
139
|
-
"--path",
|
|
214
|
+
"dir",
|
|
140
215
|
"./",
|
|
216
|
+
"--json-output-file",
|
|
217
|
+
"./wiz_scan.json",
|
|
141
218
|
"--no-style",
|
|
142
219
|
"--no-color",
|
|
143
220
|
"--no-telemetry",
|
|
144
|
-
"--
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if
|
|
221
|
+
"--no-browser",
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
if os.environ.get("DEFAULT_SCAN_NAME", "") != "":
|
|
225
|
+
args.extend(["--name", os.environ.get("DEFAULT_SCAN_NAME")])
|
|
226
|
+
|
|
227
|
+
if os.environ.get("DEFAULT_POLICIES", "") != "":
|
|
228
|
+
args.extend(["--policies", os.environ.get("DEFAULT_POLICIES")])
|
|
229
|
+
|
|
230
|
+
additional_args = os.environ.get("WIZ_ADDITIONAL_ARGS", "").strip()
|
|
231
|
+
if additional_args:
|
|
232
|
+
args.extend(additional_args.split())
|
|
233
|
+
|
|
234
|
+
return_code, stdout, stderr = self.run_cli(*args, print_output=False)
|
|
235
|
+
if (
|
|
236
|
+
os.environ.get("WIZCLI_AUTOFAIL", "false").lower() == "true"
|
|
237
|
+
and return_code != 0
|
|
238
|
+
):
|
|
148
239
|
# Print the output because we set print_output=False because wizcli outputs errors to stdout.
|
|
149
240
|
for line in stdout:
|
|
150
241
|
self.logger.error(line)
|
|
151
242
|
exit(1)
|
|
152
243
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
break
|
|
158
|
-
except json.decoder.JSONDecodeError:
|
|
159
|
-
stdout_json = None
|
|
244
|
+
with open("wiz_scan.json", "r") as f:
|
|
245
|
+
results = json.load(f)
|
|
246
|
+
|
|
247
|
+
self.logger.debug(results)
|
|
160
248
|
|
|
161
|
-
if
|
|
249
|
+
if results is None:
|
|
162
250
|
self.logger.error("Failed to parse Wiz CLI output as JSON")
|
|
163
|
-
self.logger.debug(stdout)
|
|
251
|
+
self.logger.debug(stdout, results)
|
|
164
252
|
exit(1)
|
|
165
253
|
|
|
166
|
-
if "result" not in
|
|
254
|
+
if "result" not in results or "ruleMatches" not in results["result"]:
|
|
167
255
|
self.logger.error("Unexpected Wiz CLI output format")
|
|
168
|
-
self.logger.debug(
|
|
256
|
+
self.logger.debug(results)
|
|
169
257
|
exit(1)
|
|
170
258
|
|
|
171
|
-
self.add_to_policy_input("wiz",
|
|
259
|
+
self.add_to_policy_input("wiz", results)
|
|
172
260
|
|
|
173
|
-
if
|
|
261
|
+
if results["result"]["ruleMatches"] is None:
|
|
174
262
|
self.logger.info("No findings found in the IAC scan.")
|
|
175
263
|
else:
|
|
176
264
|
findings = {}
|
|
177
265
|
# Sort the findings by the severity and their rule id
|
|
178
|
-
for match in
|
|
266
|
+
for match in results["result"]["ruleMatches"]:
|
|
179
267
|
if match["severity"] not in findings:
|
|
180
268
|
findings[match["severity"]] = {}
|
|
181
269
|
if match["rule"]["id"] not in findings[match["severity"]]:
|
|
@@ -188,7 +276,7 @@ deny[sprintf("Too many low vulnerabilities (%d)", [num])] {
|
|
|
188
276
|
)
|
|
189
277
|
|
|
190
278
|
markdown = "# Wiz IAC Scan Findings\n\n"
|
|
191
|
-
markdown += f"**Status:** {
|
|
279
|
+
markdown += f"**Status:** {results['status']['state']} **Verdict:** {results['status']['verdict']}\n"
|
|
192
280
|
for severity, matches in findings.items():
|
|
193
281
|
severity = severity.upper()
|
|
194
282
|
|
|
@@ -214,8 +302,8 @@ deny[sprintf("Too many low vulnerabilities (%d)", [num])] {
|
|
|
214
302
|
for match in cycled_rule["matches"]:
|
|
215
303
|
markdown += f"- File: {match['fileName']}, Line: {match['lineNumber']}\n"
|
|
216
304
|
markdown += "\n"
|
|
217
|
-
if "reportUrl" in
|
|
218
|
-
markdown += f"[View Report]({
|
|
305
|
+
if "reportUrl" in results:
|
|
306
|
+
markdown += f"[View Report]({results['reportUrl']})\n"
|
|
219
307
|
result = self.send_markdown(markdown)
|
|
220
308
|
if not result:
|
|
221
309
|
self.logger.error("Failed to send Wiz CLI output to spacelift")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: Wiz
|
|
2
|
-
version:
|
|
2
|
+
version: 2.0.0
|
|
3
3
|
description: |-
|
|
4
4
|
This adds the `wiz` plugin to your Spacelift account.
|
|
5
5
|
It will scan your infrastructure as code (IaC) for vulnerabilities using Wiz CLI, generating a report of findings and
|
|
@@ -19,10 +19,24 @@ labels:
|
|
|
19
19
|
- code scanning
|
|
20
20
|
- vulnerability
|
|
21
21
|
parameters:
|
|
22
|
+
- name: Default Scan Name
|
|
23
|
+
description: The default name of the scan that shows up in wiz. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_SCAN_NAME) there
|
|
24
|
+
type: string
|
|
25
|
+
sensitive: false
|
|
26
|
+
required: false
|
|
27
|
+
default: ''
|
|
28
|
+
id: default_scan_name
|
|
29
|
+
- name: Default Policies
|
|
30
|
+
description: Comma separated list of policies to include in all scans. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_POLICIES) there.
|
|
31
|
+
type: string
|
|
32
|
+
sensitive: false
|
|
33
|
+
required: false
|
|
34
|
+
default: ''
|
|
35
|
+
id: default_policies
|
|
22
36
|
- name: Wiz Client ID
|
|
23
37
|
description: The client ID for Wiz API authentication
|
|
24
38
|
type: string
|
|
25
|
-
sensitive:
|
|
39
|
+
sensitive: false
|
|
26
40
|
required: true
|
|
27
41
|
id: wiz_client_id
|
|
28
42
|
- name: Wiz Client Secret
|
|
@@ -31,16 +45,62 @@ parameters:
|
|
|
31
45
|
sensitive: true
|
|
32
46
|
required: true
|
|
33
47
|
id: wiz_client_secret
|
|
48
|
+
- name: Additional Arguments
|
|
49
|
+
description: Additional command-line arguments to pass to Wiz
|
|
50
|
+
type: string
|
|
51
|
+
sensitive: false
|
|
52
|
+
required: false
|
|
53
|
+
default: ''
|
|
54
|
+
id: wiz_additional_args
|
|
55
|
+
- name: Wiz CLI Autofail
|
|
56
|
+
description: Allow wizcli to fail the run (instead of policies)
|
|
57
|
+
type: boolean
|
|
58
|
+
sensitive: false
|
|
59
|
+
required: false
|
|
60
|
+
default: false
|
|
61
|
+
id: wizcli_autofail
|
|
62
|
+
- name: Is GovCloud
|
|
63
|
+
description: Enable if you access wiz via gov.wiz.io
|
|
64
|
+
type: boolean
|
|
65
|
+
sensitive: false
|
|
66
|
+
required: false
|
|
67
|
+
default: false
|
|
68
|
+
id: is_govcloud
|
|
69
|
+
- name: Is Fedramp
|
|
70
|
+
description: Enable if you access wiz via app.wiz.us
|
|
71
|
+
type: boolean
|
|
72
|
+
sensitive: false
|
|
73
|
+
required: false
|
|
74
|
+
default: false
|
|
75
|
+
id: is_fedramp
|
|
34
76
|
contexts:
|
|
35
77
|
- name_prefix: WIZ
|
|
36
78
|
description: Wiz Plugin
|
|
37
79
|
env:
|
|
80
|
+
- key: DEFAULT_SCAN_NAME
|
|
81
|
+
value_from_parameter: default_scan_name
|
|
82
|
+
sensitive: false
|
|
83
|
+
- key: DEFAULT_POLICIES
|
|
84
|
+
value_from_parameter: default_policies
|
|
85
|
+
sensitive: false
|
|
38
86
|
- key: WIZ_CLIENT_ID
|
|
39
87
|
value_from_parameter: wiz_client_id
|
|
40
|
-
sensitive:
|
|
88
|
+
sensitive: false
|
|
41
89
|
- key: WIZ_CLIENT_SECRET
|
|
42
90
|
value_from_parameter: wiz_client_secret
|
|
43
91
|
sensitive: true
|
|
92
|
+
- key: WIZ_ADDITIONAL_ARGS
|
|
93
|
+
value_from_parameter: wiz_additional_args
|
|
94
|
+
sensitive: false
|
|
95
|
+
- key: WIZCLI_AUTOFAIL
|
|
96
|
+
value_from_parameter: wizcli_autofail
|
|
97
|
+
sensitive: false
|
|
98
|
+
- key: IS_GOVCLOUD
|
|
99
|
+
value_from_parameter: is_govcloud
|
|
100
|
+
sensitive: false
|
|
101
|
+
- key: IS_FEDRAMP
|
|
102
|
+
value_from_parameter: is_fedramp
|
|
103
|
+
sensitive: false
|
|
44
104
|
mounted_files:
|
|
45
105
|
- path: /mnt/workspace/plugins/wiz/plugin.py
|
|
46
106
|
content: |-
|
|
@@ -69,28 +129,46 @@ contexts:
|
|
|
69
129
|
# Plugin metadata
|
|
70
130
|
__plugin_name__ = "Wiz"
|
|
71
131
|
__labels__ = ["security", "code scanning", "vulnerability"]
|
|
72
|
-
__version__ = "
|
|
132
|
+
__version__ = "2.0.0"
|
|
73
133
|
__author__ = "Spacelift Team"
|
|
74
134
|
|
|
75
135
|
__binaries__ = [
|
|
76
136
|
Binary(
|
|
77
137
|
name="wizcli",
|
|
78
138
|
download_urls={
|
|
79
|
-
"amd64": "https://downloads.wiz.io/wizcli/latest/wizcli-linux-amd64",
|
|
80
|
-
"arm64": "https://downloads.wiz.io/wizcli/latest/wizcli-linux-arm64",
|
|
139
|
+
"amd64": "https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-amd64",
|
|
140
|
+
"arm64": "https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-arm64",
|
|
81
141
|
},
|
|
82
142
|
)
|
|
83
143
|
]
|
|
84
144
|
|
|
85
145
|
# Plugin parameters
|
|
86
146
|
__parameters__ = [
|
|
147
|
+
Parameter(
|
|
148
|
+
name="Default Scan Name",
|
|
149
|
+
id="default_scan_name",
|
|
150
|
+
description="The default name of the scan that shows up in wiz. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_SCAN_NAME) there",
|
|
151
|
+
default="",
|
|
152
|
+
type="string",
|
|
153
|
+
required=False,
|
|
154
|
+
sensitive=False,
|
|
155
|
+
),
|
|
156
|
+
Parameter(
|
|
157
|
+
name="Default Policies",
|
|
158
|
+
id="default_policies",
|
|
159
|
+
description="Comma separated list of policies to include in all scans. This setting can be overridden on individual stacks by manually setting the environment variable (DEFAULT_POLICIES) there.",
|
|
160
|
+
default="",
|
|
161
|
+
type="string",
|
|
162
|
+
required=False,
|
|
163
|
+
sensitive=False,
|
|
164
|
+
),
|
|
87
165
|
Parameter(
|
|
88
166
|
name="Wiz Client ID",
|
|
89
167
|
id="wiz_client_id",
|
|
90
168
|
description="The client ID for Wiz API authentication",
|
|
91
169
|
type="string",
|
|
92
170
|
required=True,
|
|
93
|
-
sensitive=
|
|
171
|
+
sensitive=False,
|
|
94
172
|
),
|
|
95
173
|
Parameter(
|
|
96
174
|
name="Wiz Client Secret",
|
|
@@ -100,6 +178,41 @@ contexts:
|
|
|
100
178
|
required=True,
|
|
101
179
|
sensitive=True,
|
|
102
180
|
),
|
|
181
|
+
Parameter(
|
|
182
|
+
name="Additional Arguments",
|
|
183
|
+
id="wiz_additional_args",
|
|
184
|
+
description="Additional command-line arguments to pass to Wiz",
|
|
185
|
+
default="",
|
|
186
|
+
type="string",
|
|
187
|
+
required=False,
|
|
188
|
+
),
|
|
189
|
+
Parameter(
|
|
190
|
+
name="Wiz CLI Autofail",
|
|
191
|
+
id="wizcli_autofail",
|
|
192
|
+
description="Allow wizcli to fail the run (instead of policies)",
|
|
193
|
+
default=False,
|
|
194
|
+
type="boolean",
|
|
195
|
+
required=False,
|
|
196
|
+
sensitive=False,
|
|
197
|
+
),
|
|
198
|
+
Parameter(
|
|
199
|
+
name="Is GovCloud",
|
|
200
|
+
id="is_govcloud",
|
|
201
|
+
description="Enable if you access wiz via gov.wiz.io",
|
|
202
|
+
default=False,
|
|
203
|
+
type="boolean",
|
|
204
|
+
required=False,
|
|
205
|
+
sensitive=False,
|
|
206
|
+
),
|
|
207
|
+
Parameter(
|
|
208
|
+
name="Is Fedramp",
|
|
209
|
+
id="is_fedramp",
|
|
210
|
+
description="Enable if you access wiz via app.wiz.us",
|
|
211
|
+
default=False,
|
|
212
|
+
type="boolean",
|
|
213
|
+
required=False,
|
|
214
|
+
sensitive=False,
|
|
215
|
+
),
|
|
103
216
|
]
|
|
104
217
|
|
|
105
218
|
# Plugin contexts
|
|
@@ -108,16 +221,46 @@ contexts:
|
|
|
108
221
|
name_prefix="WIZ",
|
|
109
222
|
description="Wiz Plugin",
|
|
110
223
|
env=[
|
|
224
|
+
Variable(
|
|
225
|
+
key="DEFAULT_SCAN_NAME",
|
|
226
|
+
value_from_parameter="default_scan_name",
|
|
227
|
+
sensitive=False,
|
|
228
|
+
),
|
|
229
|
+
Variable(
|
|
230
|
+
key="DEFAULT_POLICIES",
|
|
231
|
+
value_from_parameter="default_policies",
|
|
232
|
+
sensitive=False,
|
|
233
|
+
),
|
|
111
234
|
Variable(
|
|
112
235
|
key="WIZ_CLIENT_ID",
|
|
113
|
-
value_from_parameter="
|
|
114
|
-
sensitive=
|
|
236
|
+
value_from_parameter="wiz_client_id",
|
|
237
|
+
sensitive=False,
|
|
115
238
|
),
|
|
116
239
|
Variable(
|
|
117
240
|
key="WIZ_CLIENT_SECRET",
|
|
118
|
-
value_from_parameter="
|
|
241
|
+
value_from_parameter="wiz_client_secret",
|
|
119
242
|
sensitive=True,
|
|
120
243
|
),
|
|
244
|
+
Variable(
|
|
245
|
+
key="WIZ_ADDITIONAL_ARGS",
|
|
246
|
+
value_from_parameter="wiz_additional_args",
|
|
247
|
+
sensitive=False,
|
|
248
|
+
),
|
|
249
|
+
Variable(
|
|
250
|
+
key="WIZCLI_AUTOFAIL",
|
|
251
|
+
value_from_parameter="wizcli_autofail",
|
|
252
|
+
sensitive=False,
|
|
253
|
+
),
|
|
254
|
+
Variable(
|
|
255
|
+
key="IS_GOVCLOUD",
|
|
256
|
+
value_from_parameter="is_govcloud",
|
|
257
|
+
sensitive=False,
|
|
258
|
+
),
|
|
259
|
+
Variable(
|
|
260
|
+
key="IS_FEDRAMP",
|
|
261
|
+
value_from_parameter="is_fedramp",
|
|
262
|
+
sensitive=False,
|
|
263
|
+
),
|
|
121
264
|
],
|
|
122
265
|
)
|
|
123
266
|
]
|
|
@@ -165,63 +308,68 @@ contexts:
|
|
|
165
308
|
def before_plan(self):
|
|
166
309
|
self.logger.info("Checking IAC Code")
|
|
167
310
|
|
|
168
|
-
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
os.environ
|
|
173
|
-
"--secret",
|
|
174
|
-
os.environ.get("WIZ_CLIENT_SECRET"),
|
|
175
|
-
)
|
|
176
|
-
if return_code != 0:
|
|
177
|
-
exit(1)
|
|
311
|
+
if os.environ.get("IS_GOVCLOUD", "false").lower() == "true":
|
|
312
|
+
os.environ["WIZ_ENV"] = "gov"
|
|
313
|
+
|
|
314
|
+
if os.environ.get("IS_FEDRAMP", "false").lower() == "true":
|
|
315
|
+
os.environ["WIZ_ENV"] = "fedramp"
|
|
178
316
|
|
|
179
|
-
|
|
317
|
+
args = [
|
|
180
318
|
"wizcli",
|
|
181
|
-
"iac",
|
|
182
319
|
"scan",
|
|
183
|
-
"
|
|
184
|
-
"json",
|
|
185
|
-
"--path",
|
|
320
|
+
"dir",
|
|
186
321
|
"./",
|
|
322
|
+
"--json-output-file",
|
|
323
|
+
"./wiz_scan.json",
|
|
187
324
|
"--no-style",
|
|
188
325
|
"--no-color",
|
|
189
326
|
"--no-telemetry",
|
|
190
|
-
"--
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if
|
|
327
|
+
"--no-browser",
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
if os.environ.get("DEFAULT_SCAN_NAME", "") != "":
|
|
331
|
+
args.extend(["--name", os.environ.get("DEFAULT_SCAN_NAME")])
|
|
332
|
+
|
|
333
|
+
if os.environ.get("DEFAULT_POLICIES", "") != "":
|
|
334
|
+
args.extend(["--policies", os.environ.get("DEFAULT_POLICIES")])
|
|
335
|
+
|
|
336
|
+
additional_args = os.environ.get("WIZ_ADDITIONAL_ARGS", "").strip()
|
|
337
|
+
if additional_args:
|
|
338
|
+
args.extend(additional_args.split())
|
|
339
|
+
|
|
340
|
+
return_code, stdout, stderr = self.run_cli(*args, print_output=False)
|
|
341
|
+
if (
|
|
342
|
+
os.environ.get("WIZCLI_AUTOFAIL", "false").lower() == "true"
|
|
343
|
+
and return_code != 0
|
|
344
|
+
):
|
|
194
345
|
# Print the output because we set print_output=False because wizcli outputs errors to stdout.
|
|
195
346
|
for line in stdout:
|
|
196
347
|
self.logger.error(line)
|
|
197
348
|
exit(1)
|
|
198
349
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
break
|
|
204
|
-
except json.decoder.JSONDecodeError:
|
|
205
|
-
stdout_json = None
|
|
350
|
+
with open("wiz_scan.json", "r") as f:
|
|
351
|
+
results = json.load(f)
|
|
352
|
+
|
|
353
|
+
self.logger.debug(results)
|
|
206
354
|
|
|
207
|
-
if
|
|
355
|
+
if results is None:
|
|
208
356
|
self.logger.error("Failed to parse Wiz CLI output as JSON")
|
|
209
|
-
self.logger.debug(stdout)
|
|
357
|
+
self.logger.debug(stdout, results)
|
|
210
358
|
exit(1)
|
|
211
359
|
|
|
212
|
-
if "result" not in
|
|
360
|
+
if "result" not in results or "ruleMatches" not in results["result"]:
|
|
213
361
|
self.logger.error("Unexpected Wiz CLI output format")
|
|
214
|
-
self.logger.debug(
|
|
362
|
+
self.logger.debug(results)
|
|
215
363
|
exit(1)
|
|
216
364
|
|
|
217
|
-
self.add_to_policy_input("wiz",
|
|
365
|
+
self.add_to_policy_input("wiz", results)
|
|
218
366
|
|
|
219
|
-
if
|
|
367
|
+
if results["result"]["ruleMatches"] is None:
|
|
220
368
|
self.logger.info("No findings found in the IAC scan.")
|
|
221
369
|
else:
|
|
222
370
|
findings = {}
|
|
223
371
|
# Sort the findings by the severity and their rule id
|
|
224
|
-
for match in
|
|
372
|
+
for match in results["result"]["ruleMatches"]:
|
|
225
373
|
if match["severity"] not in findings:
|
|
226
374
|
findings[match["severity"]] = {}
|
|
227
375
|
if match["rule"]["id"] not in findings[match["severity"]]:
|
|
@@ -234,7 +382,7 @@ contexts:
|
|
|
234
382
|
)
|
|
235
383
|
|
|
236
384
|
markdown = "# Wiz IAC Scan Findings\n\n"
|
|
237
|
-
markdown += f"**Status:** {
|
|
385
|
+
markdown += f"**Status:** {results['status']['state']} **Verdict:** {results['status']['verdict']}\n"
|
|
238
386
|
for severity, matches in findings.items():
|
|
239
387
|
severity = severity.upper()
|
|
240
388
|
|
|
@@ -260,8 +408,8 @@ contexts:
|
|
|
260
408
|
for match in cycled_rule["matches"]:
|
|
261
409
|
markdown += f"- File: {match['fileName']}, Line: {match['lineNumber']}\n"
|
|
262
410
|
markdown += "\n"
|
|
263
|
-
if "reportUrl" in
|
|
264
|
-
markdown += f"[View Report]({
|
|
411
|
+
if "reportUrl" in results:
|
|
412
|
+
markdown += f"[View Report]({results['reportUrl']})\n"
|
|
265
413
|
result = self.send_markdown(markdown)
|
|
266
414
|
if not result:
|
|
267
415
|
self.logger.error("Failed to send Wiz CLI output to spacelift")
|
|
@@ -283,9 +431,9 @@ contexts:
|
|
|
283
431
|
|
|
284
432
|
ARCH="$(arch)"
|
|
285
433
|
if [ "$ARCH" = "x86_64" ]; then
|
|
286
|
-
URL="https://downloads.wiz.io/wizcli/latest/wizcli-linux-amd64"
|
|
434
|
+
URL="https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-amd64"
|
|
287
435
|
elif [ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ]; then
|
|
288
|
-
URL="https://downloads.wiz.io/wizcli/latest/wizcli-linux-arm64"
|
|
436
|
+
URL="https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-arm64"
|
|
289
437
|
else
|
|
290
438
|
echo "Error: Unsupported architecture '$ARCH'"
|
|
291
439
|
exit 1
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.4.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g6b2d2141a'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|