kctl-ak 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kctl_ak/SKILL.extra.md +20 -0
- kctl_ak/__init__.py +3 -0
- kctl_ak/__main__.py +5 -0
- kctl_ak/cli.py +156 -0
- kctl_ak/commands/__init__.py +0 -0
- kctl_ak/commands/apps.py +557 -0
- kctl_ak/commands/audit.py +609 -0
- kctl_ak/commands/blueprints.py +159 -0
- kctl_ak/commands/brands.py +200 -0
- kctl_ak/commands/certificates.py +190 -0
- kctl_ak/commands/config_cmd.py +528 -0
- kctl_ak/commands/dashboard.py +245 -0
- kctl_ak/commands/doctor_cmd.py +82 -0
- kctl_ak/commands/flows.py +319 -0
- kctl_ak/commands/groups.py +435 -0
- kctl_ak/commands/health.py +168 -0
- kctl_ak/commands/mail.py +287 -0
- kctl_ak/commands/maintenance.py +451 -0
- kctl_ak/commands/notifications.py +248 -0
- kctl_ak/commands/outposts.py +273 -0
- kctl_ak/commands/policies.py +251 -0
- kctl_ak/commands/property_mappings.py +205 -0
- kctl_ak/commands/providers.py +596 -0
- kctl_ak/commands/provision.py +645 -0
- kctl_ak/commands/sessions.py +211 -0
- kctl_ak/commands/setup.py +691 -0
- kctl_ak/commands/skill_cmd.py +76 -0
- kctl_ak/commands/stages.py +303 -0
- kctl_ak/commands/system.py +257 -0
- kctl_ak/commands/tokens.py +258 -0
- kctl_ak/commands/users.py +1251 -0
- kctl_ak/core/__init__.py +0 -0
- kctl_ak/core/callbacks.py +34 -0
- kctl_ak/core/client.py +108 -0
- kctl_ak/core/config.py +295 -0
- kctl_ak/core/exceptions.py +23 -0
- kctl_ak/core/mailer.py +204 -0
- kctl_ak/core/output.py +7 -0
- kctl_ak/core/resolve.py +69 -0
- kctl_ak/models/__init__.py +0 -0
- kctl_ak/models/application.py +42 -0
- kctl_ak/models/blueprint.py +17 -0
- kctl_ak/models/event.py +24 -0
- kctl_ak/models/flow.py +32 -0
- kctl_ak/models/group.py +39 -0
- kctl_ak/models/pagination.py +24 -0
- kctl_ak/models/provider.py +56 -0
- kctl_ak/models/provision.py +67 -0
- kctl_ak/models/role.py +12 -0
- kctl_ak/models/session.py +20 -0
- kctl_ak/models/system.py +50 -0
- kctl_ak/models/token.py +31 -0
- kctl_ak/models/user.py +48 -0
- kctl_ak/provision/__init__.py +0 -0
- kctl_ak/provision/chain.py +466 -0
- kctl_ak/provision/config.py +23 -0
- kctl_ak/provision/mailcow_client.py +96 -0
- kctl_ak/provision/odoo_client.py +133 -0
- kctl_ak/provision/webhook_setup.py +210 -0
- kctl_ak/reports/__init__.py +0 -0
- kctl_ak/reports/access_control.py +435 -0
- kctl_ak/roles/__init__.py +0 -0
- kctl_ak/roles/loader.py +57 -0
- kctl_ak/roles/provisioner.py +101 -0
- kctl_ak-0.2.0.dist-info/METADATA +20 -0
- kctl_ak-0.2.0.dist-info/RECORD +68 -0
- kctl_ak-0.2.0.dist-info/WHEEL +4 -0
- kctl_ak-0.2.0.dist-info/entry_points.txt +2 -0
kctl_ak/SKILL.extra.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## OAuth2 Provider Management for React SPAs
|
|
2
|
+
|
|
3
|
+
React PWAs (SPA clients) MUST use `client_type: public` — they cannot keep secrets.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Check current client type
|
|
7
|
+
kctl-ak providers oauth2 get <id>
|
|
8
|
+
|
|
9
|
+
# Fix to public if needed
|
|
10
|
+
kctl-ak providers oauth2 update <id> --client-type public
|
|
11
|
+
|
|
12
|
+
# Get credentials
|
|
13
|
+
kctl-ak providers oauth2 credentials <id>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Critical Rules
|
|
17
|
+
|
|
18
|
+
1. React/SPA apps = `public` client type (NEVER `confidential`)
|
|
19
|
+
2. Server-side apps (Odoo, FastAPI) = `confidential` client type
|
|
20
|
+
3. Redirect URIs must exactly match what the app sends
|
kctl_ak/__init__.py
ADDED
kctl_ak/__main__.py
ADDED
kctl_ak/cli.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Main CLI entry point for kctl-ak."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from kctl_lib import KctlError, handle_cli_error
|
|
9
|
+
|
|
10
|
+
from kctl_ak import __version__
|
|
11
|
+
from kctl_ak.commands.apps import app as apps_app
|
|
12
|
+
from kctl_ak.commands.audit import app as audit_app
|
|
13
|
+
from kctl_ak.commands.blueprints import app as blueprints_app
|
|
14
|
+
from kctl_ak.commands.brands import app as brands_app
|
|
15
|
+
from kctl_ak.commands.certificates import app as certificates_app
|
|
16
|
+
from kctl_ak.commands.config_cmd import app as config_app
|
|
17
|
+
from kctl_ak.commands.dashboard import app as dashboard_app
|
|
18
|
+
from kctl_ak.commands.flows import app as flows_app
|
|
19
|
+
from kctl_ak.commands.groups import app as groups_app
|
|
20
|
+
from kctl_ak.commands.health import app as health_app
|
|
21
|
+
from kctl_ak.commands.mail import app as mail_app
|
|
22
|
+
from kctl_ak.commands.maintenance import app as maintenance_app
|
|
23
|
+
from kctl_ak.commands.notifications import app as notifications_app
|
|
24
|
+
from kctl_ak.commands.outposts import app as outposts_app
|
|
25
|
+
from kctl_ak.commands.policies import app as policies_app
|
|
26
|
+
from kctl_ak.commands.property_mappings import app as property_mappings_app
|
|
27
|
+
from kctl_ak.commands.providers import app as providers_app
|
|
28
|
+
from kctl_ak.commands.sessions import app as sessions_app
|
|
29
|
+
from kctl_ak.commands.setup import app as setup_app
|
|
30
|
+
from kctl_ak.commands.stages import app as stages_app
|
|
31
|
+
from kctl_ak.commands.system import app as system_app
|
|
32
|
+
from kctl_ak.commands.tokens import app as tokens_app
|
|
33
|
+
from kctl_ak.commands.users import app as users_app
|
|
34
|
+
from kctl_ak.commands.provision import app as provision_app
|
|
35
|
+
from kctl_ak.core.callbacks import AppContext
|
|
36
|
+
from kctl_ak.commands.doctor_cmd import app as doctor_app
|
|
37
|
+
from kctl_ak.commands.skill_cmd import app as skill_app
|
|
38
|
+
from kctl_lib.self_update import notify_if_outdated
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def version_callback(value: bool) -> None:
|
|
42
|
+
if value:
|
|
43
|
+
typer.echo(f"kctl-ak {__version__}")
|
|
44
|
+
raise typer.Exit()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
app = typer.Typer(
|
|
48
|
+
name="kctl-ak",
|
|
49
|
+
help="Kodemeio Authentik CLI - manage your Authentik identity provider.",
|
|
50
|
+
no_args_is_help=True,
|
|
51
|
+
rich_markup_mode="rich",
|
|
52
|
+
pretty_exceptions_enable=False,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@app.callback()
|
|
57
|
+
def main(
|
|
58
|
+
ctx: typer.Context,
|
|
59
|
+
json_output: Annotated[bool, typer.Option("--json", help="Output as JSON")] = False,
|
|
60
|
+
quiet: Annotated[bool, typer.Option("--quiet", "-q", help="Suppress info messages")] = False,
|
|
61
|
+
profile: Annotated[str | None, typer.Option("--profile", "-p", help="Config profile name")] = None,
|
|
62
|
+
url: Annotated[str | None, typer.Option("--url", help="API URL override")] = None,
|
|
63
|
+
token: Annotated[str | None, typer.Option("--token", help="API token override")] = None,
|
|
64
|
+
version: Annotated[
|
|
65
|
+
bool, typer.Option("--version", "-V", callback=version_callback, is_eager=True, help="Show version")
|
|
66
|
+
] = False,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Kodemeio Authentik CLI."""
|
|
69
|
+
ctx.ensure_object(dict)
|
|
70
|
+
ctx.obj = AppContext(
|
|
71
|
+
json_mode=json_output,
|
|
72
|
+
quiet=quiet,
|
|
73
|
+
profile=profile,
|
|
74
|
+
url_override=url,
|
|
75
|
+
token_override=token,
|
|
76
|
+
)
|
|
77
|
+
notify_if_outdated(ctx.obj.output, "kctl-ak", __version__)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Register all command groups
|
|
81
|
+
app.add_typer(users_app, name="users")
|
|
82
|
+
app.add_typer(groups_app, name="groups")
|
|
83
|
+
app.add_typer(apps_app, name="apps")
|
|
84
|
+
app.add_typer(providers_app, name="providers")
|
|
85
|
+
app.add_typer(flows_app, name="flows")
|
|
86
|
+
app.add_typer(audit_app, name="audit")
|
|
87
|
+
app.add_typer(sessions_app, name="sessions")
|
|
88
|
+
app.add_typer(tokens_app, name="tokens")
|
|
89
|
+
app.add_typer(blueprints_app, name="blueprints")
|
|
90
|
+
app.add_typer(maintenance_app, name="maintenance")
|
|
91
|
+
app.add_typer(setup_app, name="setup")
|
|
92
|
+
app.add_typer(health_app, name="health")
|
|
93
|
+
app.add_typer(dashboard_app, name="dashboard")
|
|
94
|
+
app.add_typer(config_app, name="config")
|
|
95
|
+
app.add_typer(mail_app, name="mail")
|
|
96
|
+
app.add_typer(policies_app, name="policies")
|
|
97
|
+
app.add_typer(stages_app, name="stages")
|
|
98
|
+
app.add_typer(property_mappings_app, name="property-mappings")
|
|
99
|
+
app.add_typer(certificates_app, name="certificates")
|
|
100
|
+
app.add_typer(outposts_app, name="outposts")
|
|
101
|
+
app.add_typer(brands_app, name="brands")
|
|
102
|
+
app.add_typer(notifications_app, name="notifications")
|
|
103
|
+
app.add_typer(system_app, name="system")
|
|
104
|
+
app.add_typer(provision_app, name="provision")
|
|
105
|
+
app.add_typer(doctor_app, name="doctor")
|
|
106
|
+
app.add_typer(skill_app, name="skill", hidden=True)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@app.command("self-update")
|
|
110
|
+
def self_update_cmd(ctx: typer.Context) -> None:
|
|
111
|
+
"""Check for updates and upgrade kctl-ak."""
|
|
112
|
+
actx = ctx.obj
|
|
113
|
+
out = actx.output
|
|
114
|
+
|
|
115
|
+
from kctl_lib.self_update import check_update
|
|
116
|
+
from kctl_lib.self_update import update as do_update
|
|
117
|
+
|
|
118
|
+
latest = check_update("kctl-ak", __version__)
|
|
119
|
+
if latest:
|
|
120
|
+
out.info(f"Updating to {latest}...")
|
|
121
|
+
do_update("kctl-ak")
|
|
122
|
+
out.success(f"Updated to {latest}")
|
|
123
|
+
else:
|
|
124
|
+
out.success("Already up to date")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@app.command()
|
|
128
|
+
def completions(
|
|
129
|
+
shell: Annotated[str, typer.Argument(help="Shell type: zsh, bash, fish")] = "zsh",
|
|
130
|
+
install: Annotated[bool, typer.Option("--install", help="Install completions")] = False,
|
|
131
|
+
) -> None:
|
|
132
|
+
"""Generate or install shell completions."""
|
|
133
|
+
from kctl_lib.completions import get_completion_script, install_completions
|
|
134
|
+
|
|
135
|
+
if install:
|
|
136
|
+
path = install_completions("kctl-ak", shell)
|
|
137
|
+
if path:
|
|
138
|
+
typer.echo(f"Completions installed to {path}")
|
|
139
|
+
else:
|
|
140
|
+
typer.echo(f"Could not install completions for {shell}", err=True)
|
|
141
|
+
raise typer.Exit(code=1)
|
|
142
|
+
else:
|
|
143
|
+
script = get_completion_script("kctl-ak", shell)
|
|
144
|
+
typer.echo(script)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _run() -> None:
|
|
148
|
+
"""Entry point with error handling."""
|
|
149
|
+
try:
|
|
150
|
+
app()
|
|
151
|
+
except KctlError as e:
|
|
152
|
+
handle_cli_error(e)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
if __name__ == "__main__":
|
|
156
|
+
_run()
|
|
File without changes
|