Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add issuer override #202

Merged
merged 9 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/operator_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ Used to configure how the ingress will be annotated for issuing a TLS certificat
* `tls-certificate-issuer` sets the _value_ of the annotation, for example to decide between production and staging versions of an issuer in different namespaces
* `tls-certificate-issuer-type-default` sets the default for the _key_ of the annotation, for example to use either `certmanager.k8s.io/cluster-issuer` (the default) or `certmanager.k8s.io/issuer`
* `tls-certificate-issuer-type-overrides` allows specifying a mapping between the suffix of a domain and the issuer-type, to override the default. For example, assuming the 'cluster-issuer' type as the default, then specifying `--tls-certificate-issuer-type-overrides foo.example.com=certmanager.k8s.io/issuer` would mean that foo.example.com and any of its subdomains will use the 'issuer' type instead. In the case of multiple matching suffixes, the more specific (i.e. longest) will be used.
* `tls-certificate-issuer-overrides` allows specifying a mapping between the suffix of a domain and the issuer-name, to override the default. For example, assuming the 'letsencrypt' issuer name as the default, then specifying `--tls-certificate-issuer-type-overrides foo.example.com=issuer-2` would mean that foo.example.com and any of its subdomains will use the 'issuer-2' as issuer name instead. In the case of multiple matching suffixes, the more specific (i.e. longest) will be used.

### use-in-memory-emptydirs

Expand Down
11 changes: 11 additions & 0 deletions fiaas_deploy_daemon/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ def _parse_args(self, args):
help="Certificate issuer to use with cert-manager to provision certificates",
default=None,
)
tls_parser.add_argument(
"--tls-certificate-issuer-overrides",
help="Issuers name to use for specified domain suffixes",
default=[],
action="append",
type=KeyValue,
dest="tls_certificate_issuer_overrides",
)
tls_parser.add_argument(
"--tls-certificate-issuer-type-default",
help="The annotation to set for cert-manager to provision certificates",
Expand All @@ -394,6 +402,9 @@ def _parse_args(self, args):
self.tls_certificate_issuer_type_overrides = {
issuer_type.key: issuer_type.value for issuer_type in self.tls_certificate_issuer_type_overrides
}
self.tls_certificate_issuer_overrides = {
issuer_name.key: issuer_name.value for issuer_name in self.tls_certificate_issuer_overrides
}

def _resolve_env(self):
image = os.getenv("IMAGE")
Expand Down
58 changes: 44 additions & 14 deletions fiaas_deploy_daemon/deployer/kubernetes/ingress.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ def __init__(self, config, default_app_spec, ingress_adapter):
self._ingress_suffixes = config.ingress_suffixes
self._host_rewrite_rules = config.host_rewrite_rules
self._ingress_adapter = ingress_adapter
self._tls_issuer_type_default = config.tls_certificate_issuer_type_default
self._tls_issuer_overrides = sorted(
iter(config.tls_certificate_issuer_overrides.items()), key=lambda k_v: len(k_v[0]), reverse=True
)
self._tls_issuer_type_overrides = sorted(
iter(config.tls_certificate_issuer_type_overrides.items()), key=lambda k_v: len(k_v[0]), reverse=True
)
self._tls_issuer_type_default = self._get_issuer_type_default_ingress(config)
self._tls_issuer_name_default = config.tls_certificate_issuer

def deploy(self, app_spec, labels):
if self._should_have_ingress(app_spec):
Expand Down Expand Up @@ -96,13 +100,39 @@ def _resolve_default_path(self):
default_ingress_item = next(ingress_item for ingress_item in self._default_app_spec().ingresses)
return next(pathmapping.path for pathmapping in default_ingress_item.pathmappings)

def _get_issuer_type_default_ingress(self, config):
for ingress_suffix in self._ingress_suffixes:
for (suffix, issuer_type) in self._tls_issuer_type_overrides:
if ingress_suffix and (ingress_suffix == suffix or ingress_suffix.endswith("." + suffix)):
return issuer_type

return config.tls_certificate_issuer_type_default

def _get_issuer_name_default_ingress(self, app_spec):
for ingress_suffix in self._ingress_suffixes:
if ingress_suffix:
for (suffix, issuer_name) in self._tls_issuer_overrides:
if ingress_suffix == suffix or ingress_suffix.endswith("." + suffix):
return issuer_name

return app_spec.ingress_tls.certificate_issuer if app_spec.ingress_tls.certificate_issuer else self._tls_issuer_name_default

def _get_issuer_type(self, host):
for (suffix, issuer_type) in self._tls_issuer_type_overrides:
if host and (host == suffix or host.endswith("." + suffix)):
return issuer_type
if host:
for (suffix, issuer_type) in self._tls_issuer_type_overrides:
if (host == suffix or host.endswith("." + suffix)):
return issuer_type

return self._tls_issuer_type_default

def _get_issuer_name(self, host, app_spec):
if host:
for (suffix, issuer_name) in self._tls_issuer_overrides:
if (host == suffix or host.endswith("." + suffix)):
return issuer_name

return app_spec.ingress_tls.certificate_issuer if app_spec.ingress_tls.certificate_issuer else self._tls_issuer_name_default

def _group_ingresses(self, app_spec):
"""Group the ingresses so that those with annotations are individual, and so that those using non-default TLS-issuers
are separated
Expand All @@ -114,20 +144,23 @@ def _group_ingresses(self, app_spec):
ingress_items += self._expand_default_hosts(app_spec)

AnnotatedIngress = namedtuple(
"AnnotatedIngress", ["name", "ingress_items", "annotations", "explicit_host", "issuer_type", "default"]
"AnnotatedIngress", ["name", "ingress_items", "annotations", "explicit_host", "issuer_type", "issuer_name", "default"]
)
tls_issuer_name_default = self._get_issuer_name_default_ingress(app_spec)
default_ingress = AnnotatedIngress(
name=app_spec.name,
ingress_items=[],
annotations={},
explicit_host=explicit_host,
issuer_type=self._tls_issuer_type_default,
issuer_name=tls_issuer_name_default,
default=True,
)
ingresses = [default_ingress]
override_issuer_ingresses = {}
for ingress_item in ingress_items:
issuer_type = self._get_issuer_type(ingress_item.host)
issuer_name = self._get_issuer_name(ingress_item.host, app_spec)
next_name = "{}-{}".format(app_spec.name, len(ingresses) + len(override_issuer_ingresses))
if ingress_item.annotations:
annotated_ingresses = AnnotatedIngress(
Expand All @@ -136,18 +169,20 @@ def _group_ingresses(self, app_spec):
annotations=ingress_item.annotations,
explicit_host=True,
issuer_type=issuer_type,
issuer_name=issuer_name,
default=False,
)
ingresses.append(annotated_ingresses)
elif issuer_type != self._tls_issuer_type_default:
elif issuer_type != self._tls_issuer_type_default or issuer_name != tls_issuer_name_default:
annotated_ingress = override_issuer_ingresses.setdefault(
issuer_type,
"{}:{}".format(issuer_type, issuer_name),
AnnotatedIngress(
name=next_name,
ingress_items=[],
annotations={},
explicit_host=explicit_host,
issuer_type=issuer_type,
issuer_name=issuer_name,
default=False,
),
)
Expand Down Expand Up @@ -211,16 +246,11 @@ def __init__(self, config, ingress_tls):
self.enable_deprecated_tls_entry_per_host = config.enable_deprecated_tls_entry_per_host
self.ingress_tls = ingress_tls

def apply(self, ingress, app_spec, hosts, issuer_type, use_suffixes=True):
def apply(self, ingress, app_spec, hosts, issuer_type, issuer_name, use_suffixes=True):
if self._should_have_ingress_tls(app_spec):
tls_annotations = {}
if self._cert_issuer or app_spec.ingress_tls.certificate_issuer:
issuer = (
app_spec.ingress_tls.certificate_issuer
if app_spec.ingress_tls.certificate_issuer
else self._cert_issuer
)
tls_annotations[issuer_type] = issuer
tls_annotations[issuer_type] = issuer_name
else:
tls_annotations["kubernetes.io/tls-acme"] = "true"
ingress.metadata.annotations = merge_dicts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def create_ingress(self, app_spec, annotated_ingress, labels):

hosts_for_tls = [rule.host for rule in per_host_ingress_rules]
self._ingress_tls_deployer.apply(
ingress, app_spec, hosts_for_tls, annotated_ingress.issuer_type, use_suffixes=use_suffixes
ingress, app_spec, hosts_for_tls, annotated_ingress.issuer_type, annotated_ingress.issuer_name, use_suffixes=use_suffixes
)
self._owner_references.apply(ingress, app_spec)
self._extension_hook.apply(ingress, app_spec)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def create_ingress(self, app_spec, annotated_ingress, labels):

hosts_for_tls = [rule.host for rule in per_host_ingress_rules]
self._ingress_tls_deployer.apply(
ingress, app_spec, hosts_for_tls, annotated_ingress.issuer_type, use_suffixes=use_suffixes
ingress, app_spec, hosts_for_tls, annotated_ingress.issuer_type, annotated_ingress.issuer_name, use_suffixes=use_suffixes
)
self._owner_references.apply(ingress, app_spec)
self._extension_hook.apply(ingress, app_spec)
Expand Down
2 changes: 1 addition & 1 deletion fiaas_deploy_daemon/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def log_request_response(resp, *args, **kwargs):
return # k8s library already does its own dumping, we don't need to do it here
log = logging.getLogger(__name__)
data = dump_all(resp, "<<<", ">>>")
log.debug("Request/Response\n" + data)
log.debug("Request/Response\n" + data.decode('utf-8'))


class IterableQueue(Queue, Iterator):
Expand Down
6 changes: 3 additions & 3 deletions fiaas_deploy_daemon/usage_reporting/dev_hose_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
class DevHoseAuth(AuthBase):
def __init__(self, key, tenant):
self._key = base64.b64decode(key.strip())
self._auth_context = base64.b64encode(json.dumps({"type": tenant}).encode("utf-8")).decode("utf-8")
oyvindio marked this conversation as resolved.
Show resolved Hide resolved
self._auth_context = base64.b64encode(json.dumps({"type": tenant}).encode("utf-8"))

def __call__(self, r):
timestamp = time.time()
nonce = str(uuid.uuid4())
r.headers["Content-Signature"] = self._calculate_signature(r, timestamp, nonce)
r.headers["DevHose-AuthContext"] = self._auth_context
r.headers["DevHose-AuthContext"] = self._auth_context.decode("utf-8")
r.headers["DevHose-Nonce"] = nonce
r.headers["Date"] = email.utils.formatdate(timestamp)
return r
Expand All @@ -53,7 +53,7 @@ def _create_string_to_sign(self, r, timestamp, nonce):
quote_plus(nonce.encode("utf-8")),
str(int(timestamp) * 1000),
quote_plus(self._auth_context),
quote_plus(r.body.encode("utf-8")),
quote_plus(r.body),
"",
)
)
Loading