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

feat(#702): serviceaccount removal #724

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
5 changes: 4 additions & 1 deletion client/gefyra/api/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ def install(
from gefyra.configuration import ClientConfiguration

config = ClientConfiguration(
kube_config_file=kubeconfig, kube_context=kubecontext, ignore_docker=True
kube_config_file=kubeconfig,
kube_context=kubecontext,
ignore_docker=True,
registry_url=kwargs.get("registry_url", ""),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make a dedicated kw? I think that would be cleaner and nicer for code completion in IDEs

Copy link
Collaborator Author

@liquidiert liquidiert Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the construction of GefyraInstallOptions in lines 66-67. Making registry_url a dedicated keyword pops it from kwargs leading to the option not being respected anymore

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still I think it would be better to make it explicit, just for code completion and typing.
You could add it to the kwargs in case a preset is set.

)
if preset:
presetoptions = LB_PRESETS.get(preset) # type: ignore
Expand Down
2 changes: 1 addition & 1 deletion client/gefyra/api/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def update(
"containers": [
{
"name": "gefyra",
"image": f"quay.io/gefyra/operator:{version}",
"image": config.OPERATOR_IMAGE,
}
]
}
Expand Down
4 changes: 3 additions & 1 deletion client/gefyra/api/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ def status(connection_name: str = "") -> GefyraStatus:
client = _get_client_status(config)
except urllib3.exceptions.MaxRetryError as e:
raise ClientConfigurationError(
f"Cannot reach cluster on {e.pool.host}:{e.pool.port}"
f"Cannot reach cluster on {e.pool.host}:{e.pool.port}\n"
f"Used kubeconfig: {config.KUBE_CONFIG_FILE} from Gefyra connection {connection_name}\n"
f"Please delete the connection and create a new one. Use: gefyra connection remove {connection_name}"
)

if client.connection:
Expand Down
5 changes: 3 additions & 2 deletions client/gefyra/cli/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ def install(ctx, component, preset, apply, wait, **kwargs):
from alive_progress import alive_bar
from gefyra import api

if not all(kwargs.values()):
kwargs = {}
# filter out empty kwargs
kwargs = {k: v for k, v in kwargs.items() if v}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more transparent to show a warning when things are filtered out no? Otherwise users might wonder.


if wait and not apply:
raise click.BadOptionUsage(
option_name="wait", message="Cannot wait without '--apply'"
Expand Down
7 changes: 4 additions & 3 deletions client/gefyra/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
from gefyra.cli.utils import AliasedGroup


@click.group(
cls=AliasedGroup,
)
@click.group(cls=AliasedGroup)
@click.option(
"--kubeconfig",
help="Path to the kubeconfig file to use instead of loading the default",
Expand All @@ -32,6 +30,7 @@ def cli(ctx: click.Context, kubeconfig, context, debug):
import logging
from gefyra.cli.telemetry import CliTelemetry

# Set up logging based on the debug flag
if debug:
logger = logging.getLogger()
handler = logging.StreamHandler()
Expand All @@ -43,12 +42,14 @@ def cli(ctx: click.Context, kubeconfig, context, debug):
logging.getLogger("gefyra").setLevel(logging.DEBUG)
else:
logging.getLogger("gefyra").setLevel(logging.ERROR)

ctx.ensure_object(dict)

try:
ctx.obj["telemetry"] = CliTelemetry()
except Exception: # pragma: no cover
ctx.obj["telemetry"] = False
ctx.obj["debug"] = debug
ctx.obj["kubeconfig"] = kubeconfig
ctx.obj["context"] = context

Expand Down
21 changes: 19 additions & 2 deletions client/gefyra/cli/updown.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def _check_and_install(
connection_name: str = "",
preset: Optional[str] = None,
bar=None,
registry_url: Optional[str] = None,
) -> bool:
status = api.status(connection_name=connection_name)

Expand All @@ -32,12 +33,14 @@ def _check_and_install(
return False
else: # status.summary == StatusSummary.DOWN:
logger.debug(f"Preset {preset}")
logger.debug(f"Registry URL {registry_url}")
api.install(
kubeconfig=config.KUBE_CONFIG_FILE,
kubecontext=config.KUBE_CONTEXT,
apply=True,
wait=True,
preset=preset,
registry_url=registry_url,
)
return True

Expand All @@ -56,9 +59,19 @@ def _check_and_install(
help=f"Set configs from a preset (available: {','.join(api.LB_PRESETS.keys())})",
type=str,
)
@click.option(
"--registry-url",
help="Set the registry URL for the Gefyra operator",
type=str,
)
@pass_context
@standard_error_handler
def cluster_up(ctx, minikube: Optional[str] = None, preset: Optional[str] = None):
def cluster_up(
ctx,
minikube: Optional[str] = None,
preset: Optional[str] = None,
registry_url: Optional[str] = None,
):
from alive_progress import alive_bar
from gefyra.exceptions import GefyraClientAlreadyExists, ClientConfigurationError
from time import sleep
Expand Down Expand Up @@ -86,7 +99,11 @@ def cluster_up(ctx, minikube: Optional[str] = None, preset: Optional[str] = None
) as bar:
# run a default install
install_success = _check_and_install(
config=config, connection_name=connection_name, preset=preset, bar=bar
config=config,
connection_name=connection_name,
preset=preset,
bar=bar,
registry_url=registry_url,
)
if install_success:
bar()
Expand Down
2 changes: 1 addition & 1 deletion client/gefyra/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def parser_process(value, state):

def multi_options(options):
map_to_types = dict(
array=str,
array=list,
number=float,
string=str,
)
Expand Down
4 changes: 2 additions & 2 deletions client/gefyra/misc/comps/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def data(params: "GefyraInstallOptions") -> list[dict]:
"containers": [
{
"name": "gefyra",
"image": f"quay.io/gefyra/operator:{params.version}",
"image": f"{params.registry_url}/operator:{params.version}",
"imagePullPolicy": "IfNotPresent",
"ports": [{"containerPort": 9443}],
"env": [
Expand Down Expand Up @@ -88,7 +88,7 @@ def data(params: "GefyraInstallOptions") -> list[dict]:
"containers": [
{
"name": "gefyra",
"image": f"quay.io/gefyra/operator:{params.version}",
"image": f"{params.registry_url}/operator:{params.version}",
"imagePullPolicy": "IfNotPresent",
"ports": [{"containerPort": 9443}],
"env": [
Expand Down
9 changes: 8 additions & 1 deletion client/gefyra/misc/comps/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ def data(params: "GefyraInstallOptions") -> list[dict]:
)
if params.service_annotations:
try:
stowaway_annotations.update(params.service_annotations)
for annotation in params.service_annotations:
try:
# handle cli params as key=value
key, value = annotation[0].split("=")
stowaway_annotations[key] = value
except ValueError:
# handle preset values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably display a warning or something if this happens and the parameter is ignored no?

stowaway_annotations.update(params.service_annotations)
except IndexError:
raise ValueError(
f"Invalid service-annotations format. Please use the form key=value."
Expand Down
6 changes: 6 additions & 0 deletions client/gefyra/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ class GefyraInstallOptions:
type="array",
),
)
registry_url: str = field(
default_factory=lambda: "quay.io/gefyra",
metadata=dict(
help="The registry URL for the images (default: quay.io/gefyra)",
),
)


@dataclass
Expand Down
5 changes: 4 additions & 1 deletion operator/gefyra/clientstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from gefyra.resources.serviceaccounts import (
get_serviceaccount_data,
handle_create_gefyraclient_serviceaccount,
handle_delete_gefyraclient_serviceaccount,
)


Expand Down Expand Up @@ -149,7 +150,9 @@ def on_terminate(self):
f"Removing '{self.object_name}' from connection provider"
)
self.connection_provider.remove_peer(self.object_name)
# TODO delete SA, Rolebinding

sa_name = f"gefyra-client-{self.object_name}"
handle_delete_gefyraclient_serviceaccount(self.logger, sa_name, self.namespace)

def can_add_client(self):
if self.connection_provider.peer_exists(self.object_name):
Expand Down
29 changes: 29 additions & 0 deletions operator/gefyra/resources/serviceaccounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,35 @@ def handle_create_gefyraclient_serviceaccount(
raise e


def handle_delete_gefyraclient_serviceaccount(
logger,
name: str,
namespace: str,
) -> None:
"""
Deletes service account, role and role binding for a GefyraClient

Args:
logger (logging): The logger object
name (str): Name of the service account
namespace (str): Namespace of the service account

Raises:
e: Exception if the service account could not be deleted and the status code is not 404
"""
try:
sa = core_v1_api.read_namespaced_service_account(name=name, namespace=namespace)
rbac_v1_api.delete_cluster_role_binding(
name=f"gefyra-rolebinding-{sa.metadata.name}"
)
core_v1_api.delete_namespaced_service_account(name=name, namespace=namespace)
logger.info(f"Deleted serviceaccount and permissions for GefyraClient: {name}")
except k8s.client.exceptions.ApiException as e:
logger.warning(f"Could not delete serviceaccount {name}: {e}")
if e.status != 404:
raise e


def get_serviceaccount_data(name: str, namespace: str) -> dict[str, str]:
token_secret_name = f"{name}-token"
try:
Expand Down
Loading
Loading