Skip to content

Commit 0549958

Browse files
ablakley-r7croberts-r7igorski-r7sj-curtin
authored
Surface Command Plugin (#3365) (#3413)
* Surface Command Plugin * Surface Command Connector * Update Vendor * Update plugins/rapid7_surface_command/build/lib/icon_rapid7_surface_command/connection/connection.py * Fixes from review * Add timeout to Requests * Add test connection * Fix Linting * More fixes from linting * linting * Add tests * remove json import * unittest fixes * testing * Add more tests * Remove pyenv file * Add more tests * Final linting fixes * {SC Plugin} update region enums - add more docs * {SC Plugin} fix test * {SC Plugin} update checksum --------- Co-authored-by: croberts-r7 <[email protected]> Co-authored-by: igorski-r7 <[email protected]> Co-authored-by: Shane Curtin <[email protected]>
1 parent aac087c commit 0549958

26 files changed

+822
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"spec": "5febf21fbe44e862139ab3766d09c1ea",
3+
"manifest": "1705ea353660f8471dfb517a2f53f9ca",
4+
"setup": "0ef6fdfaf9b7c048050f77a57dc08d5b",
5+
"schemas": [
6+
{
7+
"identifier": "run_query/schema.py",
8+
"hash": "c5424ab1593ab341da6fe2513002eca3"
9+
},
10+
{
11+
"identifier": "connection/schema.py",
12+
"hash": "b9f6e2e9f113d4f91ebf027d03978ca4"
13+
}
14+
]
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
unit_test/**/*
2+
unit_test
3+
examples/**/*
4+
examples
5+
tests
6+
tests/**/*
7+
**/*.json
8+
**/*.tar
9+
**/*.gz
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-slim-plugin:latest AS builder
2+
3+
WORKDIR /python/src
4+
5+
ADD ./plugin.spec.yaml /plugin.spec.yaml
6+
ADD ./requirements.txt /python/src/requirements.txt
7+
ADD . /python/src
8+
9+
10+
11+
RUN pip install .
12+
RUN pip uninstall -y setuptools
13+
14+
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-slim-plugin:latest
15+
16+
LABEL organization=rapid7
17+
LABEL sdk=python
18+
19+
WORKDIR /python/src
20+
21+
COPY --from=builder /python/src /python/src
22+
COPY --from=builder /plugin.spec.yaml /plugin.spec.yaml
23+
24+
25+
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
26+
27+
ENV PYTHONPATH="/python/src:${PYTHONPATH}"
28+
29+
RUN rm -rf /root/.cache;
30+
31+
# User to run plugin code. The two supported users are: root, nobody
32+
USER nobody
33+
34+
ENTRYPOINT ["python", "/python/src/bin/icon_rapid7_surface_command"]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Include other Makefiles for improved functionality
2+
INCLUDE_DIR = ../../tools/Makefiles
3+
MAKEFILES := $(wildcard $(INCLUDE_DIR)/*.mk)
4+
# We can't guarantee customers will have the include files
5+
# - prefix to ignore Makefiles when not present
6+
# https://www.gnu.org/software/make/manual/html_node/Include.html
7+
-include $(MAKEFILES)
8+
9+
ifneq ($(MAKEFILES),)
10+
$(info [$(YELLOW)*$(NORMAL)] Use ``make menu`` for available targets)
11+
$(info [$(YELLOW)*$(NORMAL)] Including available Makefiles: $(MAKEFILES))
12+
$(info --)
13+
else
14+
$(warning Makefile includes directory not present: $(INCLUDE_DIR))
15+
endif
16+
17+
VERSION?=$(shell grep '^version: ' plugin.spec.yaml | sed 's/version: //')
18+
NAME?=$(shell grep '^name: ' plugin.spec.yaml | sed 's/name: //')
19+
VENDOR?=$(shell grep '^vendor: ' plugin.spec.yaml | sed 's/vendor: //')
20+
CWD?=$(shell basename $(PWD))
21+
_NAME?=$(shell echo $(NAME) | awk '{ print toupper(substr($$0,1,1)) tolower(substr($$0,2)) }')
22+
PKG=$(VENDOR)-$(NAME)-$(VERSION).tar.gz
23+
24+
# Set default target explicitly. Make's default behavior is the first target in the Makefile.
25+
# We don't want that behavior due to includes which are read first
26+
.DEFAULT_GOAL := default # Make >= v3.80 (make -version)
27+
28+
29+
default: image tarball
30+
31+
tarball:
32+
$(info [$(YELLOW)*$(NORMAL)] Creating plugin tarball)
33+
rm -rf build
34+
rm -rf $(PKG)
35+
tar -cvzf $(PKG) --exclude=$(PKG) --exclude=tests --exclude=run.sh *
36+
37+
image:
38+
$(info [$(YELLOW)*$(NORMAL)] Building plugin image)
39+
docker build --pull -t $(VENDOR)/$(NAME):$(VERSION) .
40+
docker tag $(VENDOR)/$(NAME):$(VERSION) $(VENDOR)/$(NAME):latest
41+
42+
regenerate:
43+
$(info [$(YELLOW)*$(NORMAL)] Refreshing schema from plugin.spec.yaml)
44+
insight-plugin refresh
45+
46+
export: image
47+
$(info [$(YELLOW)*$(NORMAL)] Exporting docker image)
48+
@printf "\n ---> Exporting Docker image to ./$(VENDOR)_$(NAME)_$(VERSION).tar\n"
49+
@docker save $(VENDOR)/$(NAME):$(VERSION) | gzip > $(VENDOR)_$(NAME)_$(VERSION).tar
50+
51+
# Make will not run a target if a file of the same name exists unless setting phony targets
52+
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
53+
.PHONY: default tarball image regenerate
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env python
2+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
3+
import os
4+
import json
5+
from sys import argv
6+
7+
Name = "Rapid7 Surface Command"
8+
Vendor = "rapid7"
9+
Version = "1.0.0"
10+
Description = "Surface Command gives you full visibility over your assets and identities across multiple technology platforms"
11+
12+
13+
def main():
14+
if 'http' in argv:
15+
if os.environ.get("GUNICORN_CONFIG_FILE"):
16+
with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf:
17+
gunicorn_cfg = json.load(gf)
18+
if gunicorn_cfg.get("worker_class", "sync") == "gevent":
19+
from gevent import monkey
20+
monkey.patch_all()
21+
elif 'gevent' in argv:
22+
from gevent import monkey
23+
monkey.patch_all()
24+
25+
import insightconnect_plugin_runtime
26+
from icon_rapid7_surface_command import connection, actions, triggers, tasks
27+
28+
class ICONRapid7SurfaceCommand(insightconnect_plugin_runtime.Plugin):
29+
def __init__(self):
30+
super(self.__class__, self).__init__(
31+
name=Name,
32+
vendor=Vendor,
33+
version=Version,
34+
description=Description,
35+
connection=connection.Connection()
36+
)
37+
self.add_action(actions.RunQuery())
38+
39+
40+
"""Run plugin"""
41+
cli = insightconnect_plugin_runtime.CLI(ICONRapid7SurfaceCommand())
42+
cli.run()
43+
44+
45+
if __name__ == "__main__":
46+
main()
6.02 KB
Loading
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Description
2+
3+
Surface Command gives you full visibility over your assets and identities across multiple technology platforms
4+
5+
# Key Features
6+
7+
* Query Surface Command Data
8+
9+
# Requirements
10+
11+
* User or Organization Key from the Insight Platform. To create one follow [Generate User API Key guide](https://docs.rapid7.com/insight/managing-platform-api-keys/#generating-a-user-key)
12+
* The Region where your Rapid7 Surface Command instance is hosted. To identify your region, see [Identify Data Region](https://docs.rapid7.com/insight/navigate-the-insight-platform/#check-your-data-region)
13+
* A valid Query ID (UUID) from Rapid7 Surface Command. To obtain a Query ID, edit a Saved Query in the Surface Command UI and retrieve its ID from the URL
14+
15+
# Supported Product Versions
16+
17+
* v1
18+
19+
# Documentation
20+
21+
## Setup
22+
23+
The connection configuration accepts the following parameters:
24+
25+
|Name|Type|Default|Required|Description|Enum|Example|Placeholder|Tooltip|
26+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
27+
|api_key|credential_secret_key|None|True|User or Organization Key from the Insight Platform|None|a5zy0a6g-504e-46bz-84xx-1b3f5ci36l99|None|None|
28+
|region|string|us|True|Region|["us", "us2", "us3", "eu", "ca", "au", "ap"]|us|None|None|
29+
30+
Example input:
31+
32+
```
33+
{
34+
"api_key": "a5zy0a6g-504e-46bz-84xx-1b3f5ci36l99",
35+
"region": "us"
36+
}
37+
```
38+
39+
## Technical Details
40+
41+
### Actions
42+
43+
44+
#### Run Surface Command Query
45+
46+
This action is used to run and execute Surface Command Query
47+
48+
##### Input
49+
50+
|Name|Type|Default|Required|Description|Enum|Example|Placeholder|Tooltip|
51+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
52+
|query_id|string|None|True|Query ID (UUID) to Run from Surface Command|None|12345678-1234-1234-1234-123456789012|None|None|
53+
54+
Example input:
55+
56+
```
57+
{
58+
"query_id": "12345678-1234-1234-1234-123456789012"
59+
}
60+
```
61+
62+
##### Output
63+
64+
|Name|Type|Required|Description|Example|
65+
| :--- | :--- | :--- | :--- | :--- |
66+
|items|[]object|False|Array of Items|[]|
67+
68+
Example output:
69+
70+
```
71+
{
72+
"items": []
73+
}
74+
```
75+
### Triggers
76+
77+
*This plugin does not contain any triggers.*
78+
### Tasks
79+
80+
*This plugin does not contain any tasks.*
81+
82+
### Custom Types
83+
84+
*This plugin does not contain any custom output types.*
85+
86+
## Troubleshooting
87+
88+
89+
# Version History
90+
91+
* 1.0.0 - Initial plugin
92+
93+
# Links
94+
95+
* [Rapid7 Surface Command](https://www.rapid7.com/products/command/attack-surface-management-asm/)
96+
97+
## References
98+
99+
* [Identify Data Region](https://docs.rapid7.com/insight/navigate-the-insight-platform/#check-your-data-region)
100+
* [Generate User API Key](https://docs.rapid7.com/insight/managing-platform-api-keys/#generating-a-user-key)
1.57 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
2+
3+
from .run_query.action import RunQuery
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
2+
from .action import RunQuery
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import insightconnect_plugin_runtime
2+
from .schema import RunQueryInput, RunQueryOutput, Input, Output, Component
3+
4+
# Custom imports below
5+
6+
7+
class RunQuery(insightconnect_plugin_runtime.Action):
8+
9+
def __init__(self):
10+
super(self.__class__, self).__init__(
11+
name="run_query",
12+
description=Component.DESCRIPTION,
13+
input=RunQueryInput(),
14+
output=RunQueryOutput(),
15+
)
16+
17+
def run(self, params={}):
18+
# START INPUT BINDING - DO NOT REMOVE - ANY INPUTS BELOW WILL UPDATE WITH YOUR PLUGIN SPEC AFTER REGENERATION
19+
query_id = params.get(Input.QUERY_ID)
20+
# END INPUT BINDING - DO NOT REMOVE
21+
22+
return self.connection.api.run_query(query_id=query_id)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
2+
import insightconnect_plugin_runtime
3+
import json
4+
5+
6+
class Component:
7+
DESCRIPTION = "Run and execute Surface Command Query"
8+
9+
10+
class Input:
11+
QUERY_ID = "query_id"
12+
13+
14+
class Output:
15+
ITEMS = "items"
16+
17+
18+
class RunQueryInput(insightconnect_plugin_runtime.Input):
19+
schema = json.loads(
20+
r"""
21+
{
22+
"type": "object",
23+
"title": "Variables",
24+
"properties": {
25+
"query_id": {
26+
"type": "string",
27+
"title": "ID of Query to Run",
28+
"description": "Query ID (UUID) to Run from Surface Command",
29+
"order": 1
30+
}
31+
},
32+
"required": [
33+
"query_id"
34+
],
35+
"definitions": {}
36+
}
37+
"""
38+
)
39+
40+
def __init__(self):
41+
super(self.__class__, self).__init__(self.schema)
42+
43+
44+
class RunQueryOutput(insightconnect_plugin_runtime.Output):
45+
schema = json.loads(
46+
r"""
47+
{
48+
"type": "object",
49+
"title": "Variables",
50+
"properties": {
51+
"items": {
52+
"type": "array",
53+
"title": "Items",
54+
"description": "Array of Items",
55+
"items": {
56+
"type": "object"
57+
},
58+
"order": 1
59+
}
60+
},
61+
"definitions": {}
62+
}
63+
"""
64+
)
65+
66+
def __init__(self):
67+
super(self.__class__, self).__init__(self.schema)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT
2+
from .connection import Connection

0 commit comments

Comments
 (0)