CheckDockerImageAvailable
Check if a docker image is available for performing docker pull. Script simulates the docker pull flow but doesn't actually pull the image. Returns an entry with 'ok' if all is good otherwise will return an error.
python · Base
Source
import re import demistomock as demisto import requests import urllib3 from CommonServerPython import * urllib3.disable_warnings() ACCEPT_HEADER = { "Accept": "application/json, " "application/vnd.docker.distribution.manifest.v2+json, " "application/vnd.docker.distribution.manifest.list.v2+json" } # use 10 seconds timeout for requests TIMEOUT = 10 DEFAULT_REGISTRY = "registry-1.docker.io" def parse_www_auth(www_auth): """Parse realm and service from www-authenticate string of the form: Bearer realm="https://auth.docker.io/token",service="registry.docker.io" :param www_auth: www-authenticate header value :type www_auth: string """ match = re.match(r'.*realm="(.+)",service="(.+)".*', www_auth, re.IGNORECASE) if not match: return None return match.group(1), match.group(2) def docker_auth(image_name, verify_ssl=True, registry=DEFAULT_REGISTRY): # pragma: no cover """ Authenticate to the docker service. Return an authentication token if authentication is required. """ res = requests.get(f"https://{registry}/v2/", headers=ACCEPT_HEADER, timeout=TIMEOUT, verify=verify_ssl) if res.status_code == 401: # need to authenticate # defaults in case we fail for some reason realm = "https://auth.docker.io/token" service = "registry.docker.io" # Shold contain header: Www-Authenticate www_auth = res.headers.get("www-authenticate") if www_auth: parse_auth = parse_www_auth(www_auth) if parse_auth: realm, service = parse_auth else: demisto.info(f"Failed parsing www-authenticate header: {www_auth}") else: demisto.info(f"Failed extracting www-authenticate header from registry: {registry}, final url: {res.url}") auth = None if registry.lower().startswith("xsoar-registry"): demisto.debug(f"Authenticating using license id to registry: {registry}") licenseID = demisto.getLicenseID() auth = ("preview", licenseID) res = requests.get( f"{realm}?scope=repository:{image_name}:pull&service={service}", headers=ACCEPT_HEADER, timeout=TIMEOUT, verify=verify_ssl, auth=auth, ) res.raise_for_status() res_json = res.json() return res_json.get("token") else: res.raise_for_status() return None def docker_min_layer(layers): def layer_size(layer): return layer["size"] return min(layers, key=layer_size) def main(): # pragma: no cover args = demisto.args() if args.get("use_system_proxy") == "no": for key in ("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"): del os.environ[key] verify_ssl = args.get("trust_any_certificate") != "yes" docker_full_name = args["input"] registry = DEFAULT_REGISTRY image_name_tag = docker_full_name if docker_full_name.count("/") > 1: registry, image_name_tag = docker_full_name.split("/", 1) try: split = image_name_tag.split(":") image_name = split[0] tag = "latest" if len(split) > 1: tag = split[1] if tag is None: tag = "latest" auth_token = docker_auth(image_name, verify_ssl, registry) headers = ACCEPT_HEADER.copy() if auth_token: headers["Authorization"] = f"Bearer {auth_token}" res = requests.get( f"https://{registry}/v2/{image_name}/manifests/{tag}", headers=headers, timeout=TIMEOUT, verify=verify_ssl ) res.raise_for_status() layers = res.json().get("layers") if not layers: raise ValueError(f'No "layers" found in json response: {res.content}') # type: ignore[str-bytes-safe] layer_min = docker_min_layer(layers) headers["Range"] = "bytes=0-99" res = requests.get( f"https://{registry}/v2/{image_name}/blobs/{layer_min['digest']}", headers=headers, timeout=TIMEOUT, verify=verify_ssl ) res.raise_for_status() expected_len = min([100, layer_min["size"]]) cont_len = len(res.content) demisto.info(f"Docker image check [{docker_full_name}] downloaded layer content of len: {cont_len}") if cont_len < expected_len: raise ValueError( f"Content returned is shorter than expected length:" # type: ignore[str-bytes-safe] f" {expected_len}. Content: {res.content}" # type: ignore[str-bytes-safe] ) demisto.results("ok") except Exception as ex: return_error(f"Failed verifying: {docker_full_name}. Err: {ex!s}") # python2 uses __builtin__ python3 uses builtins if __name__ in ("__builtin__", "builtins", "__main__"): main()
README
Check if a docker image is available for performing docker pull. Script simulates the docker pull flow but doesn’t actually pull the image. Returns an entry with ‘ok’ if all is good otherwise will return an error.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Cortex XSOAR Version | 5.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| input | Docker image full name with version: For example: demisto/python:2.7.15.155 |
| use_system_proxy | Use system proxy settings |
| trust_any_certificate | Trust any certificate (not secure) |
Outputs
There are no outputs for this script.