mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 15:17:43 +01:00
Merge pull request #10369 from reasonerjt/registry-basic-auth
Populate basic auth information for registry
This commit is contained in:
commit
99e052aeb0
@ -26,6 +26,9 @@ https:
|
||||
# Remember Change the admin password from UI after launching Harbor.
|
||||
harbor_admin_password: Harbor12345
|
||||
|
||||
#TODO: remove this temporary flag before ships v1.11/v2, this should always be true
|
||||
registry_use_basic_auth: false
|
||||
|
||||
# Harbor DB configuration
|
||||
database:
|
||||
# The password for the root user of Harbor DB. Change this before any production use.
|
||||
|
@ -1,5 +1,6 @@
|
||||
FROM photon:2.0
|
||||
|
||||
RUN tdnf install -y python3 \
|
||||
&& tdnf install -y python3-pip
|
||||
RUN pip3 install pipenv==2018.11.26
|
||||
RUN tdnf install -y python3 python3-pip httpd
|
||||
RUN pip3 install pipenv==2018.11.26
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ def main(conf, with_notary, with_clair, with_chartmuseum):
|
||||
try:
|
||||
validate(config_dict, notary_mode=with_notary)
|
||||
except Exception as e:
|
||||
logging.info('Error happend in config validation...')
|
||||
logging.info('Error happened in config validation...')
|
||||
logging.error(e)
|
||||
sys.exit(-1)
|
||||
|
||||
|
@ -44,6 +44,8 @@ RELOAD_KEY={{reload_key}}
|
||||
CHART_REPOSITORY_URL={{chart_repository_url}}
|
||||
REGISTRY_CONTROLLER_URL={{registry_controller_url}}
|
||||
WITH_CHARTMUSEUM={{with_chartmuseum}}
|
||||
REGISTRY_CREDENTIAL_USERNAME={{registry_username}}
|
||||
REGISTRY_CREDENTIAL_PASSWORD={{registry_password}}
|
||||
|
||||
HTTP_PROXY={{core_http_proxy}}
|
||||
HTTPS_PROXY={{core_https_proxy}}
|
||||
|
@ -26,11 +26,17 @@ http:
|
||||
debug:
|
||||
addr: localhost:5001
|
||||
auth:
|
||||
{% if registry_use_basic_auth %}
|
||||
htpasswd:
|
||||
realm: harbor-registry-basic-realm
|
||||
path: /etc/registry/passwd
|
||||
{% else %}
|
||||
token:
|
||||
issuer: harbor-token-issuer
|
||||
realm: {{public_url}}/service/token
|
||||
rootcertbundle: /etc/registry/root.crt
|
||||
service: harbor-registry
|
||||
{% endif %}
|
||||
validation:
|
||||
disabled: true
|
||||
notifications:
|
||||
|
@ -1,14 +1,14 @@
|
||||
# Get or generate private key
|
||||
import os, sys, subprocess, shutil
|
||||
import os, subprocess, shutil
|
||||
from pathlib import Path
|
||||
from subprocess import DEVNULL
|
||||
from functools import wraps
|
||||
|
||||
from g import DEFAULT_GID, DEFAULT_UID
|
||||
from .misc import (
|
||||
mark_file,
|
||||
generate_random_string,
|
||||
check_permission)
|
||||
check_permission,
|
||||
stat_decorator)
|
||||
|
||||
SSL_CERT_PATH = os.path.join("/etc/cert", "server.crt")
|
||||
SSL_CERT_KEY_PATH = os.path.join("/etc/cert", "server.key")
|
||||
@ -44,19 +44,6 @@ def get_alias(path):
|
||||
alias = _get_secret(path, "defaultalias", length=8)
|
||||
return alias
|
||||
|
||||
## decorator actions
|
||||
def stat_decorator(func):
|
||||
@wraps(func)
|
||||
def check_wrapper(*args, **kw):
|
||||
stat = func(*args, **kw)
|
||||
if stat == 0:
|
||||
print("Generated certificate, key file: {key_path}, cert file: {cert_path}".format(**kw))
|
||||
else:
|
||||
print("Fail to generate key file: {key_path}, cert file: {cert_path}".format(**kw))
|
||||
sys.exit(1)
|
||||
return check_wrapper
|
||||
|
||||
|
||||
@stat_decorator
|
||||
def create_root_cert(subj, key_path="./k.key", cert_path="./cert.crt"):
|
||||
rc = subprocess.call(["/usr/bin/openssl", "genrsa", "-out", key_path, "4096"], stdout=DEVNULL, stderr=subprocess.STDOUT)
|
||||
|
@ -9,6 +9,8 @@ default_db_max_open_conns = 0 # NOTE: https://golang.org/pkg/database/sql/#DB.S
|
||||
default_https_cert_path = '/your/certificate/path'
|
||||
default_https_key_path = '/your/certificate/path'
|
||||
|
||||
REGISTRY_USER_NAME = 'harbor_registry_user'
|
||||
|
||||
|
||||
def validate(conf: dict, **kwargs):
|
||||
# hostname validate
|
||||
@ -83,6 +85,7 @@ def validate(conf: dict, **kwargs):
|
||||
# TODO:
|
||||
# If user enable trust cert dir, need check if the files in this dir is readable.
|
||||
|
||||
|
||||
def parse_versions():
|
||||
if not versions_file_path.is_file():
|
||||
return {}
|
||||
@ -90,6 +93,7 @@ def parse_versions():
|
||||
versions = yaml.load(f)
|
||||
return versions
|
||||
|
||||
|
||||
def parse_yaml_config(config_file_path, with_notary, with_clair, with_chartmuseum):
|
||||
'''
|
||||
:param configs: config_parser object
|
||||
@ -321,6 +325,12 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_chartmuseu
|
||||
# UAA configs
|
||||
config_dict['uaa'] = configs.get('uaa') or {}
|
||||
|
||||
config_dict['registry_username'] = REGISTRY_USER_NAME
|
||||
config_dict['registry_password'] = generate_random_string(32)
|
||||
|
||||
# TODO: remove the flag before release
|
||||
config_dict['registry_use_basic_auth'] = configs['registry_use_basic_auth']
|
||||
|
||||
return config_dict
|
||||
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import os
|
||||
import string
|
||||
import os, string, sys
|
||||
import secrets
|
||||
from pathlib import Path
|
||||
from functools import wraps
|
||||
|
||||
from g import DEFAULT_UID, DEFAULT_GID
|
||||
|
||||
|
||||
# To meet security requirement
|
||||
# By default it will change file mode to 0600, and make the owner of the file to 10000:10000
|
||||
def mark_file(path, mode=0o600, uid=DEFAULT_UID, gid=DEFAULT_GID):
|
||||
@ -154,3 +153,18 @@ def other_can_read(st_mode: int) -> bool:
|
||||
Check if other user have the read permission of this st_mode
|
||||
"""
|
||||
return True if st_mode & 0o004 else False
|
||||
|
||||
|
||||
# decorator actions
|
||||
def stat_decorator(func):
|
||||
@wraps(func)
|
||||
def check_wrapper(*args, **kw):
|
||||
stat = func(*args, **kw)
|
||||
if stat == 0:
|
||||
print("Successfully called func: %s" % func.__name__)
|
||||
else:
|
||||
print("Failed to call func: %s" % func.__name__)
|
||||
sys.exit(1)
|
||||
return check_wrapper
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import os, copy
|
||||
import os, copy, subprocess
|
||||
|
||||
from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID, data_dir
|
||||
from utils.misc import prepare_dir
|
||||
@ -8,6 +8,7 @@ from utils.jinja import render_jinja
|
||||
registry_config_dir = os.path.join(config_dir, "registry")
|
||||
registry_config_template_path = os.path.join(templates_dir, "registry", "config.yml.jinja")
|
||||
registry_conf = os.path.join(config_dir, "registry", "config.yml")
|
||||
registry_passwd_path = os.path.join(config_dir, "registry", "passwd")
|
||||
registry_data_dir = os.path.join(data_dir, 'registry')
|
||||
|
||||
levels_map = {
|
||||
@ -18,10 +19,13 @@ levels_map = {
|
||||
'fatal': 'fatal'
|
||||
}
|
||||
|
||||
|
||||
def prepare_registry(config_dict):
|
||||
prepare_dir(registry_data_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
|
||||
prepare_dir(registry_config_dir)
|
||||
|
||||
if config_dict['registry_use_basic_auth']:
|
||||
gen_passwd_file(config_dict)
|
||||
storage_provider_info = get_storage_provider_info(
|
||||
config_dict['storage_provider_name'],
|
||||
config_dict['storage_provider_config'])
|
||||
@ -55,3 +59,8 @@ def get_storage_provider_info(provider_name, provider_config):
|
||||
storage_provider_conf_list.append('{}: {}'.format(config[0], value))
|
||||
storage_provider_info = ('\n' + ' ' * 4).join(storage_provider_conf_list)
|
||||
return storage_provider_info
|
||||
|
||||
|
||||
def gen_passwd_file(config_dict):
|
||||
return subprocess.call(["/usr/bin/htpasswd", "-bcB", registry_passwd_path, config_dict['registry_username'],
|
||||
config_dict['registry_password']], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
||||
|
@ -299,6 +299,11 @@ func CoreSecret() string {
|
||||
return os.Getenv("CORE_SECRET")
|
||||
}
|
||||
|
||||
// RegistryCredential returns the username and password the core uses to access registry
|
||||
func RegistryCredential() (string, string) {
|
||||
return os.Getenv("REGISTRY_CREDENTIAL_USERNAME"), os.Getenv("REGISTRY_CREDENTIAL_PASSWORD")
|
||||
}
|
||||
|
||||
// JobserviceSecret returns a secret to mark Jobservice when communicate with
|
||||
// other component
|
||||
// TODO replace it with method of SecretStore
|
||||
|
Loading…
Reference in New Issue
Block a user