assemblyline-core 4.5.1.dev70__tar.gz → 4.5.1.dev72__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.
Potentially problematic release.
This version of assemblyline-core might be problematic. Click here for more details.
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/PKG-INFO +1 -1
- assemblyline-core-4.5.1.dev72/assemblyline_core/VERSION +1 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/archiver/run_archiver.py +20 -3
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/controllers/docker_ctl.py +8 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/controllers/kubernetes_ctl.py +2 -13
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/updater/helper.py +86 -126
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/updater/run_updater.py +3 -3
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core.egg-info/PKG-INFO +1 -1
- assemblyline-core-4.5.1.dev70/assemblyline_core/VERSION +0 -1
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/LICENCE.md +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/README.md +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/alerter/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/alerter/processing.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/alerter/run_alerter.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/archiver/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/badlist_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/__main__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/dispatcher.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/schedules.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/dispatching/timeout.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/expiry/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/expiry/run_expiry.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/ingester/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/ingester/__main__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/ingester/constants.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/ingester/ingester.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/es_metrics.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/heartbeat_formatter.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/helper.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/metrics_server.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/run_heartbeat_manager.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/run_metrics_aggregator.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/run_statistics_aggregator.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/plumber/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/plumber/run_plumber.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/creator/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/creator/run.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/creator/run_worker.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/loader/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/loader/run.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/loader/run_worker.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/replay.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/safelist_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/collection.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/controllers/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/controllers/interface.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/run_scaler.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/scaler_server.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/server_base.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/signature_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/submission_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/tasking_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/updater/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/crawler.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/department_map.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/safelist.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/stream_map.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/worker.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/workflow/__init__.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/workflow/run_workflow.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core.egg-info/SOURCES.txt +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core.egg-info/dependency_links.txt +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core.egg-info/requires.txt +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core.egg-info/top_level.txt +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/setup.cfg +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/setup.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_alerter.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_badlist_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_dispatcher.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_expiry.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_plumber.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_replay.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_safelist_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_scaler.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_scheduler.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_signature_client.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_simulation.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_vacuum.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_worker_ingest.py +0 -0
- {assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_worker_submit.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.5.1.dev72
|
|
@@ -7,8 +7,8 @@ from assemblyline.common import forge
|
|
|
7
7
|
from assemblyline.common.archiving import ARCHIVE_QUEUE_NAME
|
|
8
8
|
from assemblyline.common.metrics import MetricsFactory
|
|
9
9
|
from assemblyline.datastore.collection import ESCollection, Index
|
|
10
|
+
from assemblyline.datastore.exceptions import VersionConflictException
|
|
10
11
|
from assemblyline.odm.messages.archive_heartbeat import Metrics
|
|
11
|
-
from assemblyline.odm.models.submission import Submission
|
|
12
12
|
from assemblyline.remote.datatypes import get_client
|
|
13
13
|
from assemblyline.remote.datatypes.queues.named import NamedQueue
|
|
14
14
|
|
|
@@ -62,7 +62,12 @@ class Archiver(ServerBase):
|
|
|
62
62
|
return
|
|
63
63
|
else:
|
|
64
64
|
try:
|
|
65
|
-
|
|
65
|
+
if len(message) == 3:
|
|
66
|
+
archive_type, type_id, delete_after = message
|
|
67
|
+
metadata = None
|
|
68
|
+
else:
|
|
69
|
+
archive_type, type_id, delete_after, metadata = message
|
|
70
|
+
|
|
66
71
|
self.counter.increment('received')
|
|
67
72
|
except Exception:
|
|
68
73
|
self.log.error(f"Invalid message received: {message}")
|
|
@@ -76,7 +81,19 @@ class Archiver(ServerBase):
|
|
|
76
81
|
if archive_type == "submission":
|
|
77
82
|
self.counter.increment('submission')
|
|
78
83
|
# Load submission
|
|
79
|
-
|
|
84
|
+
while True:
|
|
85
|
+
try:
|
|
86
|
+
submission, version = self.datastore.submission.get_if_exists(type_id, version=True)
|
|
87
|
+
|
|
88
|
+
# If we have metadata passed in the message, we need to apply it before archiving the submission
|
|
89
|
+
if metadata and self.config.core.archiver.use_metadata:
|
|
90
|
+
submission.metadata.update({f"archive.{k}": v for k, v in metadata.items()})
|
|
91
|
+
self.datastore.submission.save(type_id, submission, version=version)
|
|
92
|
+
|
|
93
|
+
break
|
|
94
|
+
except VersionConflictException as vce:
|
|
95
|
+
self.log.info(f"Retrying saving metadata due to version conflict: {str(vce)}")
|
|
96
|
+
|
|
80
97
|
if not submission:
|
|
81
98
|
raise SubmissionNotFound(type_id)
|
|
82
99
|
|
|
@@ -158,6 +158,14 @@ class DockerController(ControllerInterface):
|
|
|
158
158
|
if 'already exists' in str(e):
|
|
159
159
|
return
|
|
160
160
|
raise e
|
|
161
|
+
except docker.errors.NotFound as e:
|
|
162
|
+
if aliases == ['service-server']:
|
|
163
|
+
# We've lost our service-server container, time to find another
|
|
164
|
+
self.service_server = self.find_service_server()
|
|
165
|
+
network.connect(self.service_server, aliases=aliases)
|
|
166
|
+
return
|
|
167
|
+
raise e
|
|
168
|
+
|
|
161
169
|
|
|
162
170
|
def _start(self, service_name):
|
|
163
171
|
"""Launch a docker container in a manner suitable for Assemblyline."""
|
|
@@ -21,7 +21,7 @@ from assemblyline.odm.models.config import Selector
|
|
|
21
21
|
|
|
22
22
|
from kubernetes import client, config, watch
|
|
23
23
|
from kubernetes.client import V1Deployment, V1DeploymentSpec, V1PodTemplateSpec, V1DeploymentStrategy, \
|
|
24
|
-
V1PodSpec,
|
|
24
|
+
V1PodSpec, V1ObjectMeta, V1Volume, V1Container, V1VolumeMount, V1EnvVar, V1ConfigMapVolumeSource, \
|
|
25
25
|
V1PersistentVolumeClaimVolumeSource, V1LabelSelector, V1ResourceRequirements, V1PersistentVolumeClaim, \
|
|
26
26
|
V1PersistentVolumeClaimSpec, V1NetworkPolicy, V1NetworkPolicySpec, V1NetworkPolicyEgressRule, V1NetworkPolicyPeer, \
|
|
27
27
|
V1NetworkPolicyIngressRule, V1Secret, V1SecretVolumeSource, V1LocalObjectReference, V1Service, \
|
|
@@ -839,25 +839,14 @@ class KubernetesController(ControllerInterface):
|
|
|
839
839
|
volume_mounts=chown_mounts
|
|
840
840
|
))
|
|
841
841
|
|
|
842
|
-
pod_os = None
|
|
843
|
-
security_context = V1PodSecurityContext(fs_group=1000)
|
|
844
|
-
if docker_config.operating_system:
|
|
845
|
-
# Allow Kubernetes to schedule the pod to a compatible node
|
|
846
|
-
pod_os = V1PodOS(name=docker_config.operating_system)
|
|
847
|
-
|
|
848
|
-
if docker_config.operating_system == 'windows':
|
|
849
|
-
security_context = None
|
|
850
|
-
|
|
851
|
-
|
|
852
842
|
pod = V1PodSpec(
|
|
853
843
|
init_containers=init_containers,
|
|
854
844
|
volumes=all_volumes,
|
|
855
845
|
containers=self._create_containers(service_name, deployment_name, docker_config,
|
|
856
846
|
all_mounts, core_container=core_mounts),
|
|
857
|
-
os=pod_os,
|
|
858
847
|
priority_class_name=self.dependency_priority if high_priority else self.priority,
|
|
859
848
|
termination_grace_period_seconds=shutdown_seconds,
|
|
860
|
-
security_context=
|
|
849
|
+
security_context=V1PodSecurityContext(fs_group=1000),
|
|
861
850
|
service_account_name=service_account,
|
|
862
851
|
affinity=selector_to_node_affinity(self.linux_node_selector),
|
|
863
852
|
)
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/updater/helper.py
RENAMED
|
@@ -12,147 +12,95 @@ from base64 import b64encode
|
|
|
12
12
|
from collections import defaultdict
|
|
13
13
|
from logging import Logger
|
|
14
14
|
from packaging.version import parse, Version
|
|
15
|
-
from typing import Any, Dict, List, Tuple
|
|
16
15
|
|
|
17
16
|
DEFAULT_DOCKER_REGISTRY = "registry.hub.docker.com"
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
class ContainerRegistry():
|
|
21
|
-
def __init__(self, server, headers: Dict[str, str] = None, verify: bool = True,
|
|
22
|
-
proxies: Dict[str, str] = None, *args, **kwargs):
|
|
23
|
-
self.server = server
|
|
24
|
-
self.session = requests.Session()
|
|
25
|
-
self.session.headers = headers
|
|
26
|
-
self.session.verify = verify
|
|
27
|
-
self.session.proxies = proxies
|
|
28
|
-
|
|
29
|
-
def _make_request(self, path: str) -> Dict[str, Any]:
|
|
30
|
-
request_path = f"{self.server}{path}"
|
|
31
|
-
resp = None
|
|
32
|
-
try:
|
|
33
|
-
resp = self.session.get(f"https://{request_path}")
|
|
34
|
-
except requests.exceptions.SSLError:
|
|
35
|
-
# Connect to insecure registry over HTTP (development only)
|
|
36
|
-
if not self.session.verify:
|
|
37
|
-
resp = self.session.get(f"http://{request_path}")
|
|
38
|
-
# Test for valid response
|
|
39
|
-
if resp and resp.ok:
|
|
40
|
-
return resp.json()
|
|
41
|
-
return None
|
|
42
|
-
|
|
43
20
|
# Provide a means of obtaining a list of tags from a container registry
|
|
44
|
-
def
|
|
21
|
+
def _get_proprietary_registry_tags(self, server, image_name, auth, verify, proxies=None, token_server=None):
|
|
45
22
|
raise NotImplementedError()
|
|
46
23
|
|
|
47
|
-
# Provide a means of obtaining the compatible operating system for the container image
|
|
48
|
-
def get_image_os(self, image_name, image_tag) -> str:
|
|
49
|
-
raise NotImplementedError()
|
|
50
|
-
|
|
51
|
-
def get_token(self, image_name) -> None: ...
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class DockerHub(ContainerRegistry):
|
|
55
|
-
def __init__(self, update_channel, proxies: Dict[str, str] = None, *args, **kwargs):
|
|
56
|
-
super().__init__(DEFAULT_DOCKER_REGISTRY, None, True, proxies)
|
|
57
|
-
self.update_channel = update_channel
|
|
58
|
-
|
|
59
|
-
def get_image_tags(self, image_name) -> List[str]:
|
|
60
|
-
resp = self._make_request(f"/v2/repositories/{image_name}/tags?page_size=5&page=1&name={self.update_channel}")
|
|
61
|
-
if resp:
|
|
62
|
-
return [x['name'] for x in resp['results']]
|
|
63
|
-
return []
|
|
64
|
-
|
|
65
|
-
def get_image_os(self, image_name, image_tag) -> str:
|
|
66
|
-
resp = self._make_request(f"/v2/repositories/{image_name}/tags/{image_tag}")
|
|
67
|
-
if resp:
|
|
68
|
-
return resp['images'][0]['os']
|
|
69
|
-
return None
|
|
70
|
-
|
|
71
24
|
|
|
72
|
-
# Ref: https://docs.docker.com/registry/spec/api/#detail
|
|
73
25
|
class DockerRegistry(ContainerRegistry):
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.token_server = token_server
|
|
26
|
+
def _get_proprietary_registry_tags(self, server, image_name, auth, verify, proxies=None, token_server=None):
|
|
27
|
+
# Find latest tag for each types
|
|
28
|
+
url = f"https://{server}/v2/{image_name}/tags/list"
|
|
78
29
|
|
|
79
|
-
|
|
80
|
-
|
|
30
|
+
# Get tag list
|
|
31
|
+
headers = {}
|
|
32
|
+
if auth:
|
|
33
|
+
headers["Authorization"] = auth
|
|
34
|
+
else:
|
|
81
35
|
# Retrieve token for authentication: https://distribution.github.io/distribution/spec/auth/token/
|
|
82
36
|
|
|
83
37
|
# Assume the token server is the same as the container image registry host if not explicitly set
|
|
84
|
-
token_server =
|
|
38
|
+
token_server = token_server if token_server else server
|
|
85
39
|
token_url = f"https://{token_server}/token?scope=repository:{image_name}:pull"
|
|
86
|
-
|
|
87
|
-
|
|
40
|
+
resp = requests.get(token_url)
|
|
41
|
+
if resp.ok:
|
|
42
|
+
# Request to obtain token was successful, set Authorization header for registry API
|
|
43
|
+
token = resp.json().get('token')
|
|
44
|
+
headers["Authorization"] = f"Bearer {token}"
|
|
88
45
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
46
|
+
resp = None
|
|
47
|
+
try:
|
|
48
|
+
resp = requests.get(url, headers=headers, verify=verify, proxies=proxies)
|
|
49
|
+
except requests.exceptions.SSLError:
|
|
50
|
+
# Connect to insecure registry over HTTP (development only)
|
|
51
|
+
if not verify:
|
|
52
|
+
url = f"http://{server}/v2/{image_name}/tags/list"
|
|
53
|
+
resp = requests.get(url, headers=headers, verify=verify, proxies=proxies)
|
|
54
|
+
# Test for valid response
|
|
55
|
+
if resp and resp.ok:
|
|
56
|
+
# Test for positive list of tags
|
|
57
|
+
resp_data = resp.json()
|
|
58
|
+
return resp_data['tags'] or []
|
|
94
59
|
return []
|
|
95
60
|
|
|
96
|
-
def get_image_os(self, image_name, image_tag) -> str:
|
|
97
|
-
resp = self._make_request(f"/v2/{image_name}/manifests/{image_tag}")
|
|
98
|
-
if resp:
|
|
99
|
-
# Retrieve OS compatibilty from historical record
|
|
100
|
-
if resp['schemaVersion'] == 1:
|
|
101
|
-
return json.loads(resp['history'][0]['v1Compatibility'])['os']
|
|
102
|
-
|
|
103
|
-
# Unable to determine the OS compatibility
|
|
104
|
-
return None
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# Ref: https://github.com/goharbor/harbor/blob/main/api/v2.0/swagger.yaml
|
|
108
61
|
class HarborRegistry(ContainerRegistry):
|
|
109
|
-
def
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
62
|
+
def _get_proprietary_registry_tags(self, server, image_name, auth, verify, proxies=None, token_server=None):
|
|
63
|
+
# Determine project/repo IDs from image name
|
|
64
|
+
project_id, repo_id = image_name.split('/', 1)
|
|
65
|
+
repo_id = repo_id.replace('/', "%2F")
|
|
66
|
+
url = f"https://{server}/api/v2.0/projects/{project_id}/repositories/{repo_id}/artifacts?page_size=0"
|
|
113
67
|
|
|
114
|
-
|
|
115
|
-
if
|
|
68
|
+
headers = {}
|
|
69
|
+
if auth:
|
|
70
|
+
headers["Authorization"] = auth
|
|
71
|
+
else:
|
|
116
72
|
# Retrieve token for authentication: https://github.com/goharbor/harbor/wiki/Harbor-FAQs#api
|
|
117
73
|
|
|
118
74
|
# Assume the token server is the same as the container image registry host if not explicitly set
|
|
119
|
-
token_server =
|
|
75
|
+
token_server = token_server if token_server else server
|
|
120
76
|
token_url = f"https://{server}/service/token?scope=repository:{image_name}:pull"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
77
|
+
resp = requests.get(token_url)
|
|
78
|
+
if resp.ok:
|
|
79
|
+
# Request to obtain token was successful, set Authorization header for registry API
|
|
80
|
+
token = resp.json().get('token')
|
|
81
|
+
headers["Authorization"] = f"Bearer {token}"
|
|
82
|
+
resp = None
|
|
83
|
+
try:
|
|
84
|
+
resp = requests.get(url, headers=headers, verify=verify, proxies=proxies)
|
|
85
|
+
except requests.exceptions.SSLError:
|
|
86
|
+
# Connect to insecure registry over HTTP (development only)
|
|
87
|
+
if not verify:
|
|
88
|
+
url = f"http://{server}/api/v2.0/projects/{project_id}/repositories/{repo_id}/artifacts"
|
|
89
|
+
resp = requests.get(url, headers=headers, verify=verify, proxies=proxies)
|
|
129
90
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
resp = self._make_request(f"/api/v2.0/projects/{project_id}/repositories/{repo_id}/artifacts?page_size=0")
|
|
133
|
-
if resp:
|
|
134
|
-
return [tag['name'] for image in resp if image['tags'] for tag in image['tags']]
|
|
91
|
+
if resp and resp.ok:
|
|
92
|
+
return [tag['name'] for image in resp.json() if image['tags'] for tag in image['tags']]
|
|
135
93
|
return []
|
|
136
94
|
|
|
137
|
-
def get_image_os(self, image_name, image_tag) -> str:
|
|
138
|
-
project_id, repo_id = self._get_project_repo_ids(image_name)
|
|
139
|
-
resp = self._make_request(f"/api/v2.0/projects/{project_id}/repositories/{repo_id}/artifacts/{image_tag}")
|
|
140
|
-
if resp:
|
|
141
|
-
# Retrieve OS compatibilty from reference
|
|
142
|
-
return resp['references'][0]['platform']['os']
|
|
143
|
-
|
|
144
|
-
# Unable to determine the OS compatibility
|
|
145
|
-
return None
|
|
146
|
-
|
|
147
95
|
|
|
148
96
|
REGISTRY_TYPE_MAPPING = {
|
|
149
|
-
'
|
|
150
|
-
'
|
|
151
|
-
'harbor': HarborRegistry
|
|
97
|
+
'docker': DockerRegistry(),
|
|
98
|
+
'harbor': HarborRegistry()
|
|
152
99
|
}
|
|
153
100
|
|
|
154
101
|
|
|
155
|
-
def get_latest_tag_for_service(
|
|
102
|
+
def get_latest_tag_for_service(
|
|
103
|
+
service_config: ServiceConfig, system_config: SystemConfig, logger: Logger, prefix: str = ""):
|
|
156
104
|
def process_image(image):
|
|
157
105
|
# Find which server to search in
|
|
158
106
|
server = image.split("/")[0]
|
|
@@ -213,6 +161,7 @@ def get_latest_tag_for_service(service_config: ServiceConfig, system_config: Sys
|
|
|
213
161
|
# We're assuming that if only a password is given, then this is a token
|
|
214
162
|
auth = f"Bearer {service_config.docker_config.registry_password}"
|
|
215
163
|
|
|
164
|
+
registry = REGISTRY_TYPE_MAPPING[service_config.docker_config.registry_type]
|
|
216
165
|
token_server = None
|
|
217
166
|
proxies = None
|
|
218
167
|
for reg_conf in system_config.core.updater.registry_configs:
|
|
@@ -221,21 +170,14 @@ def get_latest_tag_for_service(service_config: ServiceConfig, system_config: Sys
|
|
|
221
170
|
token_server = reg_conf.token_server or None
|
|
222
171
|
break
|
|
223
172
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
'update_channel': update_channel,
|
|
231
|
-
'token_server': token_server
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
registry: ContainerRegistry = REGISTRY_TYPE_MAPPING[registry_type](**registry_args)
|
|
235
|
-
registry.get_token(image_name)
|
|
236
|
-
tags = registry.get_image_tags(image_name)
|
|
237
|
-
|
|
173
|
+
if server == DEFAULT_DOCKER_REGISTRY:
|
|
174
|
+
tags = _get_dockerhub_tags(image_name, update_channel, proxies)
|
|
175
|
+
else:
|
|
176
|
+
tags = registry._get_proprietary_registry_tags(server, image_name, auth,
|
|
177
|
+
not system_config.services.allow_insecure_registry,
|
|
178
|
+
proxies, token_server)
|
|
238
179
|
tag_name = None
|
|
180
|
+
|
|
239
181
|
# Pre-filter tags to only consider 'compatible' tags relative to the running system
|
|
240
182
|
tags = [t for t in tags
|
|
241
183
|
if re.match(f"({FRAMEWORK_VERSION})[.]({SYSTEM_VERSION})[.]\\d+[.]({update_channel})\\d+", t)]
|
|
@@ -259,10 +201,28 @@ def get_latest_tag_for_service(service_config: ServiceConfig, system_config: Sys
|
|
|
259
201
|
image_variables = defaultdict(str)
|
|
260
202
|
image_variables.update(system_config.services.image_variables)
|
|
261
203
|
image = string.Template(image).safe_substitute(image_variables)
|
|
262
|
-
|
|
204
|
+
server, image_name = process_image(image)
|
|
263
205
|
|
|
264
206
|
# Append server to image if not the default server
|
|
265
|
-
if server !=
|
|
207
|
+
if server != "registry.hub.docker.com":
|
|
266
208
|
image_name = "/".join([server, image_name])
|
|
267
209
|
|
|
268
|
-
return image_name, tag_name, auth_config
|
|
210
|
+
return image_name, tag_name, auth_config
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# Default for obtaining tags from DockerHub
|
|
214
|
+
def _get_dockerhub_tags(image_name, update_channel, proxies=None):
|
|
215
|
+
# Find latest tag for each types
|
|
216
|
+
url = f"https://{DEFAULT_DOCKER_REGISTRY}/v2/repositories/{image_name}/tags" \
|
|
217
|
+
f"?page_size=5&page=1&name={update_channel}"
|
|
218
|
+
|
|
219
|
+
# Get tag list
|
|
220
|
+
resp = requests.get(url, proxies=proxies)
|
|
221
|
+
|
|
222
|
+
# Test for valid response
|
|
223
|
+
if resp.ok:
|
|
224
|
+
# Test for positive list of tags
|
|
225
|
+
resp_data = resp.json()
|
|
226
|
+
return [x['name'] for x in resp_data['results']]
|
|
227
|
+
|
|
228
|
+
return []
|
|
@@ -476,10 +476,10 @@ class ServiceUpdater(ThreadedCoreBase):
|
|
|
476
476
|
'version': tag,
|
|
477
477
|
'docker_config': {'image': install_data.get('image')}})
|
|
478
478
|
|
|
479
|
-
image_name, tag_name, auth
|
|
479
|
+
image_name, tag_name, auth = get_latest_tag_for_service(
|
|
480
480
|
service, self.config, self.log, prefix="[CI] ")
|
|
481
481
|
|
|
482
|
-
docker_config = dict(image=f"{image_name}:{tag_name}"
|
|
482
|
+
docker_config = dict(image=f"{image_name}:{tag_name}")
|
|
483
483
|
if auth:
|
|
484
484
|
docker_config.update(dict(registry_username=auth['username'],
|
|
485
485
|
registry_password=auth['password']))
|
|
@@ -675,7 +675,7 @@ class ServiceUpdater(ThreadedCoreBase):
|
|
|
675
675
|
|
|
676
676
|
for service in self.datastore.list_all_services(full=True):
|
|
677
677
|
discovered_services.append(service.name)
|
|
678
|
-
image_name, tag_name, auth
|
|
678
|
+
image_name, tag_name, auth = get_latest_tag_for_service(service, self.config, self.log, prefix="[CV] ")
|
|
679
679
|
self.latest_service_tags.set(service.name,
|
|
680
680
|
{'auth': auth, 'image': image_name, service.update_channel: tag_name})
|
|
681
681
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4.5.1.dev70
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/badlist_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/expiry/__init__.py
RENAMED
|
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
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/metrics/helper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/__init__.py
RENAMED
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/replay/replay.py
RENAMED
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/safelist_client.py
RENAMED
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/scaler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/server_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/tasking_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/__init__.py
RENAMED
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/crawler.py
RENAMED
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/safelist.py
RENAMED
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/assemblyline_core/vacuum/worker.py
RENAMED
|
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
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_safelist_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{assemblyline-core-4.5.1.dev70 → assemblyline-core-4.5.1.dev72}/test/test_signature_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|