Skip to content

Commit

Permalink
Merge pull request #25 from ocadotechnology/wip-24
Browse files Browse the repository at this point in the history
fix: set username and password on proxy properly
  • Loading branch information
stuart-warren authored Aug 23, 2018
2 parents 914c166 + b62d43f commit 609fd83
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 334 deletions.
145 changes: 53 additions & 92 deletions mirroroperator/registrymirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,106 +253,47 @@ def generate_headless_service(self, service_headless):
service_headless.spec.type = "ClusterIP"
return service_headless

def generate_new_auth_url(self, credentials_secret):
"""
Method which, given a credentials secret (secret named <self.credentials_secret_name>):
- decodes the username/password
- if they are valid, create a new authed upstream url
Args:
credentials_secret: V1Secret
Returns: base64-encoded str or None if the url was not valid
def handle_proxy_credentials(self, env):
credentials_secret = None
if self.credentials_secret_name:
credentials_secret = self.run_action_and_parse_error(self.core_api.read_namespaced_secret,
self.credentials_secret_name,
self.namespace)
if not credentials_secret:
LOGGER.error("No secret named %s was found in the %s namespace, will use unauth access",
self.credentials_secret_name, self.namespace)
return env

"""
encoded_user = credentials_secret.data.get("username")
encoded_pass = credentials_secret.data.get("password")
url = None
if not (encoded_pass and encoded_user):
# log an error, keep the url at none
LOGGER.error("Secret %s does not contain username/password, defaulting to %s",
self.credentials_secret_name, self.upstreamUrl)
else:
# decode the username, update the url
username = base64.b64decode(encoded_user).decode('utf-8')
password = base64.b64decode(encoded_pass).decode('utf-8')
decoded_url = "https://{}:{}@{}".format(username, password, self.upstreamUrl)
url = base64.b64encode(decoded_url.encode('utf-8')).decode('utf-8')

return url

def handle_secrets(self, keypair):
credentials_secret = self.run_action_and_parse_error(self.core_api.read_namespaced_secret,
self.credentials_secret_name,
self.namespace)
reg_secret = self.run_action_and_parse_error(self.core_api.read_namespaced_secret,
self.full_name, self.namespace)
valid_secret = None
url = None
if credentials_secret:
# create a new url
url = self.generate_new_auth_url(credentials_secret)

else:
LOGGER.error("No secret named %s was found, will use unauth access",
if not (encoded_user and encoded_pass):
LOGGER.error("Secret %s does not contain username/password",
self.credentials_secret_name)
return env
env.append(client.V1EnvVar(name="REGISTRY_PROXY_USERNAME",
value=None,
value_from=client.V1EnvVarSource(
secret_key_ref=client.V1SecretKeySelector(
key="username",
name=self.credentials_secret_name
)
))
)
env.append(client.V1EnvVar(name="REGISTRY_PROXY_PASSWORD",
value=None,
value_from=client.V1EnvVarSource(
secret_key_ref=client.V1SecretKeySelector(
key="password",
name=self.credentials_secret_name
)
))
)
LOGGER.info("Secret selected + env vars set successfully")
return env

if url:
if reg_secret:
reg_secret.metadata = self.metadata
reg_secret.data = {"url": url}
LOGGER.info("Updating the secret %s", self.full_name)
valid_secret = self.run_action_and_parse_error(
self.core_api.replace_namespaced_secret,
self.full_name, self.namespace, reg_secret
)
else:
# create a new one
reg_secret = client.V1Secret(
metadata=self.metadata,
data={"url": url}
)
LOGGER.info("Creating new secret %s", self.full_name)
valid_secret = self.run_action_and_parse_error(self.core_api.create_namespaced_secret,
self.namespace, reg_secret)

if valid_secret:
keypair.value = None
keypair.value_from = client.V1EnvVarSource(
secret_key_ref=client.V1SecretKeySelector(
key="url",
name=valid_secret.metadata.name
)
)
LOGGER.info("Secret selected + env var set successfully")
else:
LOGGER.error("Valid authenticated url secret could not be created or found, value will default to upstream url %s",
self.upstreamUrl)

return keypair

def generate_stateful_set(self, stateful_set):
keypair = client.V1EnvVar(
name="REGISTRY_PROXY_REMOTEURL",
value="https://" + self.upstreamUrl)
if self.credentials_secret_name:
keypair = self.handle_secrets(keypair)

env = [client.V1EnvVar(name="REGISTRY_HTTP_ADDR",
value=":5000"),
client.V1EnvVar(name="REGISTRY_HTTP_DEBUG_ADDR",
value="localhost:6000"),
client.V1EnvVar(name="REGISTRY_HTTP_TLS_CERTIFICATE",
value="/etc/registry-certs/tls.crt"),
client.V1EnvVar(name="REGISTRY_HTTP_TLS_KEY",
value="/etc/registry-certs/tls.key"),
keypair,
client.V1EnvVar(name="REGISTRY_LOG_FORMATTER",
value="logstash"),
client.V1EnvVar(name="REGISTRY_STORAGE_DELETE_ENABLED",
value="true"),
client.V1EnvVar(name="REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY",
value="/var/lib/registry")
]
stateful_set.metadata = self.metadata
stateful_set.spec.replicas = 2
pod_labels = {'component': 'registry'}
Expand Down Expand Up @@ -395,6 +336,26 @@ def generate_stateful_set(self, stateful_set):
read_only=True
)
)

env = [client.V1EnvVar(name="REGISTRY_PROXY_REMOTEURL",
value="https://" + self.upstreamUrl),
client.V1EnvVar(name="REGISTRY_HTTP_ADDR",
value=":5000"),
client.V1EnvVar(name="REGISTRY_HTTP_DEBUG_ADDR",
value="localhost:6000"),
client.V1EnvVar(name="REGISTRY_HTTP_TLS_CERTIFICATE",
value="/etc/registry-certs/tls.crt"),
client.V1EnvVar(name="REGISTRY_HTTP_TLS_KEY",
value="/etc/registry-certs/tls.key"),
client.V1EnvVar(name="REGISTRY_LOG_FORMATTER",
value="logstash"),
client.V1EnvVar(name="REGISTRY_STORAGE_DELETE_ENABLED",
value="true"),
client.V1EnvVar(name="REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY",
value="/var/lib/registry")
]
env = self.handle_proxy_credentials(env)

stateful_set.spec.template = client.V1PodTemplateSpec(
metadata=client.V1ObjectMeta(
labels=pod_labels
Expand Down
20 changes: 1 addition & 19 deletions tests/kubernetes_mock_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,25 +202,7 @@
},
"type": "Opaque"
}
url = "https://{}:{}@{}".format(username, password, "hubtest")
url = base64.b64encode(url.encode('utf-8')).decode('utf-8')
valid_reg_secret = {
"apiVersion": "v1",
"data": {
"url": url
},
"kind": "Secret",
"metadata": {
"creationTimestamp": "2017-09-13T10:20:26Z",
"name": "registry-mirror-hub",
"namespace": "default",
"resourceVersion": "7889",
"selfLink": "/api/v1/namespaces/default/secrets/internal-mirror",
"uid": "294e16e7-986d-11e7-9c1f-0800275e72fe"
},
"type": "Opaque"
}
VALID_REG_SECRET = json.dumps(valid_reg_secret)

VALID_SECRET = json.dumps(valid_secret)

INVALID_SECRET = """
Expand Down
2 changes: 1 addition & 1 deletion tests/test_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_will_read_crds_blanks_already_exist(self):

@responses.activate
def test_will_read_crds_blanks_dont_exist(self):
'''Should listen to CRDs being streamed + call apis appropriately. In this case the objects don't alreadu exist'''
'''Should listen to CRDs being streamed + call apis appropriately. In this case the objects don't already exist'''
stream_generator = stream_mock()
responses.add('GET', '/api/v1/namespaces/default/services/registry-mirror-hub', status=404, body='{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"services \\"registry-mirror-internal\\" not found","reason":"NotFound","details":{"name":"registry-mirror-internal","kind":"services"},"code":404}')
responses.add('GET', '/api/v1/namespaces/default/services/registry-mirror-hub-headless', status=404)
Expand Down
Loading

0 comments on commit 609fd83

Please sign in to comment.