Skip to content

Commit

Permalink
Added support for token authentication (eg. Harbor)
Browse files Browse the repository at this point in the history
  • Loading branch information
mortensteenrasmussen committed Dec 25, 2018
1 parent fb4c149 commit f8e68bc
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
9 changes: 8 additions & 1 deletion README.md
Expand Up @@ -21,7 +21,7 @@ This repo is meant as a workaround until we have the necessary tooling in Docker

## Usage
### Running against local storage
See the *examples* below if needed.
See the *examples* below if needed. Deletion needs to be enabled in your registry. See [the Docker documentation](https://docs.docker.com/registry/configuration/#delete)

After running this, you should do a garbage collect in the registry to free up the disk space.

Expand Down Expand Up @@ -83,6 +83,13 @@ With more options:
docker run -it -e REGISTRY_URL=http://192.168.77.88:5000 -e REGISTRY_STORAGE="S3" -e ACCESS_KEY="XXXXXXGZMXXXXQMAGXXX" -e SECRET_KEY="zfXXXXXEbq/JX++XXXAa/Z+ZCXXXXypfOXXXXC/X" -e BUCKET="registry-bucket-1" -e REGION="eu-central-1" -e SELF_SIGNED_CERT="true" -e REGISTRY_AUTH="myuser:sickpassword" mortensrasmussen/docker-registry-manifest-cleanup
```

### Running against Harbor and other baerer token-based authentication forms
The run should be the same, the only requirement is that the `user:pass` you provide should have full access to all repositories (and/or projects), since it needs to be able to delete manifests whereever its needed.

When running against Harbor, use a user that's in all projects as a project admin. When the run is finished, you can run the garbage collection through the Harbor UI.

This has been tested working in Harbor 1.7.0.

## License
This project is distributed under [Apache License, Version 2.0.](LICENSE)

Expand Down
25 changes: 23 additions & 2 deletions docker-registry-cleanup.py
Expand Up @@ -57,11 +57,25 @@ def exit_with_error(message):
else:
cert_verify = True

token_authentication = False
token_auth_details = {}
# Check connection to registry
try:
r = requests.get("%s/v2/" % (registry_url), auth=registry_auth, verify=cert_verify)
if r.status_code == 401:
exit_with_error("Got an authentication error connecting to the registry. Check credentials, or add REGISTRY_AUTH='username:password'")
if "Www-Authenticate" in r.headers and "Bearer" in r.headers["Www-Authenticate"]:
#We have token based auth, try it
auth_header = r.headers["Www-Authenticate"].split(" ")[1]
token_authentication = True
token_auth_details = dict(s.split("=", 1) for s in re.sub('"',"",auth_header).split(","))
r2 = requests.get("%s?service=%s&scope=" % (token_auth_details["realm"],token_auth_details["service"]), auth=registry_auth, verify=cert_verify)
if r2.status_code == 401:
exit_with_error("Got an authentication error connecting to the registry - even with token authentication. Check credentials, or add REGISTRY_AUTH='username:password'")
else:
auth_token = r2.json()["token"]
registry_headers = {"Authorization": "Bearer %s" % (auth_token)}
else:
exit_with_error("Got an authentication error connecting to the registry. Check credentials, or add REGISTRY_AUTH='username:password'")
except requests.exceptions.SSLError as e:
exit_with_error("Got an SSLError connecting to the registry. Might be a self signed cert, please set SELF_SIGNED_CERT=true")
except requests.exceptions.RequestException as e:
Expand Down Expand Up @@ -157,7 +171,14 @@ def exit_with_error(message):
if dry_run_mode:
print("DRY_RUN: Would have run an HTTP DELETE request to %s/v2/%s/manifests/sha256:%s" % (registry_url, repo, manifest))
else:
r = requests.delete("%s/v2/%s/manifests/sha256:%s" % (registry_url, repo, manifest), auth=registry_auth, verify=cert_verify)
if token_authentication:
r2 = requests.get("%s?service=%s&scope=repository:%s:*" % (token_auth_details["realm"],token_auth_details["service"],repo), auth=registry_auth, verify=cert_verify)
auth_token = r2.json()["token"]
registry_headers = {"Authorization": "Bearer %s" % (auth_token)}
r = requests.delete("%s/v2/%s/manifests/sha256:%s" % (registry_url, repo, manifest), verify=cert_verify, headers=registry_headers)
else:
r = requests.delete("%s/v2/%s/manifests/sha256:%s" % (registry_url, repo, manifest), auth=registry_auth, verify=cert_verify)

if r.status_code == 202:
cleaned_count += 1
else:
Expand Down

0 comments on commit f8e68bc

Please sign in to comment.