forked from p15670423/monkey
Merge pull request #2167 from guardicore/2109-refactor-ip-addresses-resource
Refactor IPAddresses resource
This commit is contained in:
commit
89b194d0ae
|
@ -35,13 +35,14 @@ class DIContainer:
|
||||||
if not inspect.isclass(concrete_type):
|
if not inspect.isclass(concrete_type):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Expected a class, but received an instance of type "
|
"Expected a class, but received an instance of type "
|
||||||
f'"{concrete_type.__class__.__name__}"; Pass a class, not an instance, to '
|
f'"{DIContainer._format_type_name(concrete_type.__class__)}"; Pass a class, not an '
|
||||||
"register(), or use register_instance() instead"
|
"instance, to register(), or use register_instance() instead"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not issubclass(concrete_type, interface):
|
if not issubclass(concrete_type, interface):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f'Class "{concrete_type.__name__}" is not a subclass of {interface.__name__}'
|
f'Class "{DIContainer._format_type_name(concrete_type)}" is not a subclass of '
|
||||||
|
f"{DIContainer._format_type_name(interface)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._type_registry[interface] = concrete_type
|
self._type_registry[interface] = concrete_type
|
||||||
|
@ -56,8 +57,9 @@ class DIContainer:
|
||||||
"""
|
"""
|
||||||
if not isinstance(instance, interface):
|
if not isinstance(instance, interface):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f'The provided instance of type "{instance.__class__.__name__}" '
|
"The provided instance of type "
|
||||||
f"is not an instance of {interface.__name__}"
|
f'"{DIContainer._format_type_name(instance.__class__)}" '
|
||||||
|
f"is not an instance of {DIContainer._format_type_name(interface)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._instance_registry[interface] = instance
|
self._instance_registry[interface] = instance
|
||||||
|
@ -151,7 +153,9 @@ class DIContainer:
|
||||||
elif type_ in self._instance_registry:
|
elif type_ in self._instance_registry:
|
||||||
return self._retrieve_registered_instance(type_)
|
return self._retrieve_registered_instance(type_)
|
||||||
|
|
||||||
raise UnregisteredTypeError(f'Failed to resolve unregistered type "{type_.__name__}"')
|
raise UnregisteredTypeError(
|
||||||
|
f'Failed to resolve unregistered type "{DIContainer._format_type_name(type)}"'
|
||||||
|
)
|
||||||
|
|
||||||
def _construct_new_instance(self, arg_type: Type[T]) -> T:
|
def _construct_new_instance(self, arg_type: Type[T]) -> T:
|
||||||
try:
|
try:
|
||||||
|
@ -182,3 +186,13 @@ class DIContainer:
|
||||||
"""
|
"""
|
||||||
convention_identifier = (type_, name)
|
convention_identifier = (type_, name)
|
||||||
del_key(self._convention_registry, convention_identifier)
|
del_key(self._convention_registry, convention_identifier)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _format_type_name(type_: Type) -> str:
|
||||||
|
try:
|
||||||
|
return type_.__name__
|
||||||
|
except AttributeError:
|
||||||
|
# Some Types, like typing.Sequence, don't have a __name__ attribute in python3.7. When
|
||||||
|
# we upgrade to a later version of Python, this exception handler may no longer be
|
||||||
|
# necessary.
|
||||||
|
return str(type_)
|
||||||
|
|
|
@ -13,6 +13,7 @@ from monkey_island.cc.database import database, mongo
|
||||||
from monkey_island.cc.resources import (
|
from monkey_island.cc.resources import (
|
||||||
AgentBinaries,
|
AgentBinaries,
|
||||||
ClearSimulationData,
|
ClearSimulationData,
|
||||||
|
IPAddresses,
|
||||||
IslandLog,
|
IslandLog,
|
||||||
PropagationCredentials,
|
PropagationCredentials,
|
||||||
RemoteRun,
|
RemoteRun,
|
||||||
|
@ -33,7 +34,6 @@ from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import (
|
||||||
from monkey_island.cc.resources.edge import Edge
|
from monkey_island.cc.resources.edge import Edge
|
||||||
from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation
|
from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation
|
||||||
from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation
|
from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation
|
||||||
from monkey_island.cc.resources.ip_addresses import IpAddresses
|
|
||||||
from monkey_island.cc.resources.island_mode import IslandMode
|
from monkey_island.cc.resources.island_mode import IslandMode
|
||||||
from monkey_island.cc.resources.local_run import LocalRun
|
from monkey_island.cc.resources.local_run import LocalRun
|
||||||
from monkey_island.cc.resources.log import Log
|
from monkey_island.cc.resources.log import Log
|
||||||
|
@ -179,7 +179,7 @@ def init_restful_endpoints(api: FlaskDIWrapper):
|
||||||
api.add_resource(TelemetryFeed)
|
api.add_resource(TelemetryFeed)
|
||||||
api.add_resource(Log)
|
api.add_resource(Log)
|
||||||
api.add_resource(IslandLog)
|
api.add_resource(IslandLog)
|
||||||
api.add_resource(IpAddresses)
|
api.add_resource(IPAddresses)
|
||||||
|
|
||||||
# API Spec: These two should be the same resource, GET for download and POST for upload
|
# API Spec: These two should be the same resource, GET for download and POST for upload
|
||||||
api.add_resource(PBAFileDownload)
|
api.add_resource(PBAFileDownload)
|
||||||
|
|
|
@ -19,7 +19,7 @@ from mongoengine import (
|
||||||
from monkey_island.cc.models.command_control_channel import CommandControlChannel
|
from monkey_island.cc.models.command_control_channel import CommandControlChannel
|
||||||
from monkey_island.cc.models.monkey_ttl import MonkeyTtl, create_monkey_ttl_document
|
from monkey_island.cc.models.monkey_ttl import MonkeyTtl, create_monkey_ttl_document
|
||||||
from monkey_island.cc.server_utils.consts import DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS
|
from monkey_island.cc.server_utils.consts import DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
from monkey_island.cc.services.utils.network_utils import get_ip_addresses
|
||||||
|
|
||||||
|
|
||||||
class ParentNotFoundError(Exception):
|
class ParentNotFoundError(Exception):
|
||||||
|
@ -123,7 +123,7 @@ class Monkey(Document):
|
||||||
def get_label_by_id(object_id):
|
def get_label_by_id(object_id):
|
||||||
current_monkey = Monkey.get_single_monkey_by_id(object_id)
|
current_monkey = Monkey.get_single_monkey_by_id(object_id)
|
||||||
label = Monkey.get_hostname_by_id(object_id) + " : " + current_monkey.ip_addresses[0]
|
label = Monkey.get_hostname_by_id(object_id) + " : " + current_monkey.ip_addresses[0]
|
||||||
if len(set(current_monkey.ip_addresses).intersection(local_ip_addresses())) > 0:
|
if len(set(current_monkey.ip_addresses).intersection(get_ip_addresses())) > 0:
|
||||||
label = "MonkeyIsland - " + label
|
label = "MonkeyIsland - " + label
|
||||||
return label
|
return label
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,4 @@ from .clear_simulation_data import ClearSimulationData
|
||||||
from .island_log import IslandLog
|
from .island_log import IslandLog
|
||||||
from .reset_agent_configuration import ResetAgentConfiguration
|
from .reset_agent_configuration import ResetAgentConfiguration
|
||||||
from .propagation_credentials import PropagationCredentials
|
from .propagation_credentials import PropagationCredentials
|
||||||
|
from .ip_addresses import IPAddresses
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
from typing import Mapping, Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.request_authentication import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
|
||||||
|
|
||||||
|
|
||||||
class IpAddresses(AbstractResource):
|
class IPAddresses(AbstractResource):
|
||||||
|
"""
|
||||||
|
Endpoint for the Monkey Island's IP addresses
|
||||||
|
"""
|
||||||
|
|
||||||
urls = ["/api/island/ip-addresses"]
|
urls = ["/api/island/ip-addresses"]
|
||||||
|
|
||||||
|
def __init__(self, ip_addresses: Sequence[str]):
|
||||||
|
self._ips = ip_addresses
|
||||||
|
|
||||||
@jwt_required
|
@jwt_required
|
||||||
def get(self) -> Mapping[str, Sequence[str]]:
|
def get(self) -> Sequence[str]:
|
||||||
"""
|
"""
|
||||||
Gets the IP addresses of the Island network interfaces
|
Sends the IP addresses of the Island
|
||||||
|
|
||||||
:return: a dictionary with "ip_addresses" key that points to a list of IP's
|
:return: IP addresses
|
||||||
"""
|
"""
|
||||||
local_ips = local_ip_addresses()
|
|
||||||
|
|
||||||
return {"ip_addresses": local_ips}
|
return self._ips
|
||||||
|
|
|
@ -6,7 +6,6 @@ from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.request_authentication import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.infection_lifecycle import get_completed_steps
|
from monkey_island.cc.services.infection_lifecycle import get_completed_steps
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ class Root(AbstractResource):
|
||||||
@jwt_required
|
@jwt_required
|
||||||
def get_server_info(self):
|
def get_server_info(self):
|
||||||
return jsonify(
|
return jsonify(
|
||||||
ip_addresses=local_ip_addresses(),
|
|
||||||
mongo=str(mongo.db),
|
mongo=str(mongo.db),
|
||||||
completed_steps=get_completed_steps(),
|
completed_steps=get_completed_steps(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,7 +27,7 @@ from monkey_island.cc.server_utils.consts import ( # noqa: E402
|
||||||
)
|
)
|
||||||
from monkey_island.cc.server_utils.island_logger import reset_logger, setup_logging # noqa: E402
|
from monkey_island.cc.server_utils.island_logger import reset_logger, setup_logging # noqa: E402
|
||||||
from monkey_island.cc.services.initialize import initialize_services # noqa: E402
|
from monkey_island.cc.services.initialize import initialize_services # noqa: E402
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses # noqa: E402
|
from monkey_island.cc.services.utils.network_utils import get_ip_addresses # noqa: E402
|
||||||
from monkey_island.cc.setup import PyWSGILoggingFilter # noqa: E402
|
from monkey_island.cc.setup import PyWSGILoggingFilter # noqa: E402
|
||||||
from monkey_island.cc.setup import island_config_options_validator # noqa: E402
|
from monkey_island.cc.setup import island_config_options_validator # noqa: E402
|
||||||
from monkey_island.cc.setup.data_dir import IncompatibleDataDirectory, setup_data_dir # noqa: E402
|
from monkey_island.cc.setup.data_dir import IncompatibleDataDirectory, setup_data_dir # noqa: E402
|
||||||
|
@ -168,7 +168,7 @@ def _log_init_info():
|
||||||
|
|
||||||
|
|
||||||
def _log_web_interface_access_urls():
|
def _log_web_interface_access_urls():
|
||||||
web_interface_urls = ", ".join([f"https://{ip}:{ISLAND_PORT}" for ip in local_ip_addresses()])
|
web_interface_urls = ", ".join([f"https://{ip}:{ISLAND_PORT}" for ip in get_ip_addresses()])
|
||||||
logger.info(
|
logger.info(
|
||||||
"To access the web interface, navigate to one of the the following URLs using your "
|
"To access the web interface, navigate to one of the the following URLs using your "
|
||||||
f"browser: {web_interface_urls}"
|
f"browser: {web_interface_urls}"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Sequence
|
||||||
|
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ from monkey_island.cc.services.telemetry.processing.credentials.credentials_pars
|
||||||
from monkey_island.cc.services.telemetry.processing.processing import (
|
from monkey_island.cc.services.telemetry.processing.processing import (
|
||||||
TELEMETRY_CATEGORY_TO_PROCESSING_FUNC,
|
TELEMETRY_CATEGORY_TO_PROCESSING_FUNC,
|
||||||
)
|
)
|
||||||
|
from monkey_island.cc.services.utils.network_utils import get_ip_addresses
|
||||||
from monkey_island.cc.setup.mongo.mongo_setup import MONGO_URL
|
from monkey_island.cc.setup.mongo.mongo_setup import MONGO_URL
|
||||||
|
|
||||||
from . import AuthenticationService
|
from . import AuthenticationService
|
||||||
|
@ -96,6 +98,7 @@ def _register_conventions(container: DIContainer, data_dir: Path):
|
||||||
)
|
)
|
||||||
container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir))
|
container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir))
|
||||||
container.register_convention(str, "version_number", get_version())
|
container.register_convention(str, "version_number", get_version())
|
||||||
|
container.register_convention(Sequence[str], "ip_addresses", get_ip_addresses())
|
||||||
|
|
||||||
|
|
||||||
def _register_repositories(container: DIContainer, data_dir: Path):
|
def _register_repositories(container: DIContainer, data_dir: Path):
|
||||||
|
|
|
@ -9,7 +9,7 @@ from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
||||||
from monkey_island.cc.services.edge.edge import EdgeService
|
from monkey_island.cc.services.edge.edge import EdgeService
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
from monkey_island.cc.services.utils.network_utils import get_ip_addresses
|
||||||
from monkey_island.cc.services.utils.node_states import NodeStates
|
from monkey_island.cc.services.utils.node_states import NodeStates
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class NodeService:
|
||||||
def get_monkey_label(monkey):
|
def get_monkey_label(monkey):
|
||||||
# todo
|
# todo
|
||||||
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]
|
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]
|
||||||
ip_addresses = local_ip_addresses()
|
ip_addresses = get_ip_addresses()
|
||||||
if len(set(monkey["ip_addresses"]).intersection(ip_addresses)) > 0:
|
if len(set(monkey["ip_addresses"]).intersection(ip_addresses)) > 0:
|
||||||
label = "MonkeyIsland - " + label
|
label = "MonkeyIsland - " + label
|
||||||
return label
|
return label
|
||||||
|
@ -118,7 +118,7 @@ class NodeService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_monkey_group(monkey):
|
def get_monkey_group(monkey):
|
||||||
keywords = []
|
keywords = []
|
||||||
if len(set(monkey["ip_addresses"]).intersection(local_ip_addresses())) != 0:
|
if len(set(monkey["ip_addresses"]).intersection(get_ip_addresses())) != 0:
|
||||||
keywords.extend(["island", "monkey"])
|
keywords.extend(["island", "monkey"])
|
||||||
else:
|
else:
|
||||||
monkey_type = "manual" if NodeService.get_monkey_manual_run(monkey) else "monkey"
|
monkey_type = "manual" if NodeService.get_monkey_manual_run(monkey) else "monkey"
|
||||||
|
@ -275,7 +275,7 @@ class NodeService:
|
||||||
# It's better to just initialize the island machine on reset I think
|
# It's better to just initialize the island machine on reset I think
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_monkey_island_monkey():
|
def get_monkey_island_monkey():
|
||||||
ip_addresses = local_ip_addresses()
|
ip_addresses = get_ip_addresses()
|
||||||
for ip_address in ip_addresses:
|
for ip_address in ip_addresses:
|
||||||
monkey = NodeService.get_monkey_by_ip(ip_address)
|
monkey = NodeService.get_monkey_by_ip(ip_address)
|
||||||
if monkey is not None:
|
if monkey is not None:
|
||||||
|
@ -297,7 +297,7 @@ class NodeService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_monkey_island_node():
|
def get_monkey_island_node():
|
||||||
island_node = NodeService.get_monkey_island_pseudo_net_node()
|
island_node = NodeService.get_monkey_island_pseudo_net_node()
|
||||||
island_node["ip_addresses"] = local_ip_addresses()
|
island_node["ip_addresses"] = get_ip_addresses()
|
||||||
island_node["domain_name"] = socket.gethostname()
|
island_node["domain_name"] = socket.gethostname()
|
||||||
return island_node
|
return island_node
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from monkey_island.cc.services.reporting.pth_report import PTHReportService
|
||||||
from monkey_island.cc.services.reporting.report_generation_synchronisation import (
|
from monkey_island.cc.services.reporting.report_generation_synchronisation import (
|
||||||
safe_generate_regular_report,
|
safe_generate_regular_report,
|
||||||
)
|
)
|
||||||
from monkey_island.cc.services.utils.network_utils import get_subnets, local_ip_addresses
|
from monkey_island.cc.services.utils.network_utils import get_ip_addresses, get_subnets
|
||||||
|
|
||||||
from .. import AWSService
|
from .. import AWSService
|
||||||
from . import aws_exporter
|
from . import aws_exporter
|
||||||
|
@ -175,7 +175,7 @@ class ReportService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_island_cross_segment_issues():
|
def get_island_cross_segment_issues():
|
||||||
issues = []
|
issues = []
|
||||||
island_ips = local_ip_addresses()
|
island_ips = get_ip_addresses()
|
||||||
for monkey in mongo.db.monkey.find(
|
for monkey in mongo.db.monkey.find(
|
||||||
{"tunnel": {"$exists": False}}, {"tunnel": 1, "guid": 1, "hostname": 1}
|
{"tunnel": {"$exists": False}}, {"tunnel": 1, "guid": 1, "hostname": 1}
|
||||||
):
|
):
|
||||||
|
|
|
@ -4,10 +4,10 @@ import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import copyfileobj
|
from shutil import copyfileobj
|
||||||
|
from typing import Sequence
|
||||||
|
|
||||||
from monkey_island.cc.repository import IAgentBinaryRepository, RetrievalError
|
from monkey_island.cc.repository import IAgentBinaryRepository, RetrievalError
|
||||||
from monkey_island.cc.server_utils.consts import ISLAND_PORT
|
from monkey_island.cc.server_utils.consts import ISLAND_PORT
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -15,9 +15,15 @@ AGENT_NAMES = {"linux": "monkey-linux-64", "windows": "monkey-windows-64.exe"}
|
||||||
|
|
||||||
|
|
||||||
class LocalMonkeyRunService:
|
class LocalMonkeyRunService:
|
||||||
def __init__(self, data_dir: Path, agent_binary_repository: IAgentBinaryRepository):
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_dir: Path,
|
||||||
|
agent_binary_repository: IAgentBinaryRepository,
|
||||||
|
ip_addresses: Sequence[str],
|
||||||
|
):
|
||||||
self._data_dir = data_dir
|
self._data_dir = data_dir
|
||||||
self._agent_binary_repository = agent_binary_repository
|
self._agent_binary_repository = agent_binary_repository
|
||||||
|
self._ips = ip_addresses
|
||||||
|
|
||||||
def run_local_monkey(self):
|
def run_local_monkey(self):
|
||||||
# get the monkey executable suitable to run on the server
|
# get the monkey executable suitable to run on the server
|
||||||
|
@ -59,7 +65,7 @@ class LocalMonkeyRunService:
|
||||||
|
|
||||||
# run the monkey
|
# run the monkey
|
||||||
try:
|
try:
|
||||||
ip = local_ip_addresses()[0]
|
ip = self._ips[0]
|
||||||
port = ISLAND_PORT
|
port = ISLAND_PORT
|
||||||
|
|
||||||
args = [str(dest_path), "m0nk3y", "-s", f"{ip}:{port}"]
|
args = [str(dest_path), "m0nk3y", "-s", f"{ip}:{port}"]
|
||||||
|
|
|
@ -58,7 +58,7 @@ else:
|
||||||
# lot of times during the report generation. This means that if the interfaces of the Island machine
|
# lot of times during the report generation. This means that if the interfaces of the Island machine
|
||||||
# change, the Island process needs to be restarted.
|
# change, the Island process needs to be restarted.
|
||||||
@lru(maxsize=1)
|
@lru(maxsize=1)
|
||||||
def local_ip_addresses() -> Sequence[str]:
|
def get_ip_addresses() -> Sequence[str]:
|
||||||
ip_list = []
|
ip_list = []
|
||||||
for interface in interfaces():
|
for interface in interfaces():
|
||||||
addresses = ifaddresses(interface).get(AF_INET, [])
|
addresses = ifaddresses(interface).get(AF_INET, [])
|
||||||
|
|
|
@ -32,11 +32,11 @@ const getContents = (props) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function getIps() {
|
function getIps() {
|
||||||
authComponent.authFetch('/api')
|
authComponent.authFetch('/api/island/ip-addresses')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(res => {
|
.then(ip_addresses => {
|
||||||
setAllIPs(res['ip_addresses']);
|
setAllIPs(ip_addresses);
|
||||||
setSelectedIp(res['ip_addresses'][0]);
|
setSelectedIp(ip_addresses[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,7 @@ function RunOptions(props) {
|
||||||
if (initialized === false) {
|
if (initialized === false) {
|
||||||
authComponent.authFetch(IP_ADDRESSES_URL)
|
authComponent.authFetch(IP_ADDRESSES_URL)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(res => {
|
.then(ipAddresses => {
|
||||||
let ipAddresses = res.ip_addresses;
|
|
||||||
setIps(ipAddresses);
|
setIps(ipAddresses);
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue