okdata-cli 3.2.0__tar.gz → 4.1.0__tar.gz
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.
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/PKG-INFO +2 -2
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/README.md +1 -1
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/__main__.py +6 -5
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/command.py +2 -2
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/datasets/datasets.py +4 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/datasets/questions.py +5 -56
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/datasets/wizards.py +0 -7
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/permissions.py +15 -14
- okdata-cli-4.1.0/okdata/cli/commands/pubs/__init__.py +3 -0
- {okdata-cli-3.2.0/okdata/cli/commands/pubreg → okdata-cli-4.1.0/okdata/cli/commands/pubs}/client.py +29 -4
- okdata-cli-3.2.0/okdata/cli/commands/pubreg/pubreg.py → okdata-cli-4.1.0/okdata/cli/commands/pubs/pubs.py +83 -57
- {okdata-cli-3.2.0/okdata/cli/commands/pubreg → okdata-cli-4.1.0/okdata/cli/commands/pubs}/questions.py +80 -21
- {okdata-cli-3.2.0/okdata/cli/commands/pubreg → okdata-cli-4.1.0/okdata/cli/commands/pubs}/wizards.py +29 -16
- {okdata-cli-3.2.0/okdata/cli/commands/datasets → okdata-cli-4.1.0/okdata/cli/commands}/validators.py +32 -45
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/wizard.py +8 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_dataset_config.json +0 -1
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/output.py +3 -4
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/PKG-INFO +2 -2
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/SOURCES.txt +10 -10
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/requires.txt +1 -1
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/pyproject.toml +4 -1
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/setup.py +2 -2
- okdata-cli-3.2.0/okdata/cli/commands/pubreg/__init__.py +0 -3
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/LICENSE +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/__init__.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/__init__.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/__init__.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/datasets/__init__.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/status.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/teams/questions.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/teams/teams.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/teams/util.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/commands/teams/wizards.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_copy_file_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_copy_file_config_2.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_dataset_version_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_dataset_version_edition_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_dataset_version_edition_distributions_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/datasets_dataset_versions_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/my_permissions_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/permissions_config.json +0 -0
- /okdata-cli-3.2.0/okdata/cli/data/output-format/pubreg_audit_log_config.json → /okdata-cli-4.1.0/okdata/cli/data/output-format/pubs_audit_log_config.json +0 -0
- /okdata-cli-3.2.0/okdata/cli/data/output-format/pubreg_clients_config.json → /okdata-cli-4.1.0/okdata/cli/data/output-format/pubs_clients_config.json +0 -0
- /okdata-cli-3.2.0/okdata/cli/data/output-format/pubreg_multiple_client_keys_config.json → /okdata-cli-4.1.0/okdata/cli/data/output-format/pubs_multiple_client_keys_config.json +0 -0
- /okdata-cli-3.2.0/okdata/cli/data/output-format/pubreg_single_client_keys_config.json → /okdata-cli-4.1.0/okdata/cli/data/output-format/pubs_single_client_keys_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/status_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/status_history_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/team_members_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/data/output-format/teams_config.json +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata/cli/io.py +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/dependency_links.txt +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/entry_points.txt +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/namespace_packages.txt +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/okdata_cli.egg-info/top_level.txt +0 -0
- {okdata-cli-3.2.0 → okdata-cli-4.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: okdata-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.1.0
|
|
4
4
|
Summary: CLI for services provided by Oslo Origo
|
|
5
5
|
Home-page: https://github.com/oslokommune/okdata-cli/
|
|
6
6
|
Author: Oslo Origo
|
|
@@ -24,7 +24,7 @@ Okdata CLI provides a unified interface to data services for Oslo Origo teams.
|
|
|
24
24
|
|
|
25
25
|
* [Install](doc/install.md)
|
|
26
26
|
* [Configuration](doc/configuration.md)
|
|
27
|
-
* [Public
|
|
27
|
+
* [Public services](doc/pubs.md)
|
|
28
28
|
* [Teams](doc/teams.md)
|
|
29
29
|
* [Datasets](doc/datasets.md)
|
|
30
30
|
* [Permissions](doc/permissions.md)
|
|
@@ -4,7 +4,7 @@ Okdata CLI provides a unified interface to data services for Oslo Origo teams.
|
|
|
4
4
|
|
|
5
5
|
* [Install](doc/install.md)
|
|
6
6
|
* [Configuration](doc/configuration.md)
|
|
7
|
-
* [Public
|
|
7
|
+
* [Public services](doc/pubs.md)
|
|
8
8
|
* [Teams](doc/teams.md)
|
|
9
9
|
* [Datasets](doc/datasets.md)
|
|
10
10
|
* [Permissions](doc/permissions.md)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
-
from keycloak.exceptions import KeycloakGetError
|
|
4
|
+
from keycloak.exceptions import KeycloakGetError, KeycloakPostError
|
|
5
5
|
from okdata.sdk.exceptions import ApiAuthenticateError
|
|
6
6
|
from requests.exceptions import RequestException
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ from okdata.cli import MAINTAINER
|
|
|
9
9
|
from okdata.cli.command import BaseCommand
|
|
10
10
|
from okdata.cli.commands.datasets import DatasetsCommand
|
|
11
11
|
from okdata.cli.commands.permissions import PermissionsCommand
|
|
12
|
-
from okdata.cli.commands.
|
|
12
|
+
from okdata.cli.commands.pubs import PubsCommand
|
|
13
13
|
from okdata.cli.commands.status import StatusCommand
|
|
14
14
|
from okdata.cli.commands.teams.teams import TeamsCommand
|
|
15
15
|
|
|
@@ -40,11 +40,12 @@ def main():
|
|
|
40
40
|
"An error occurred (ApiAuthenticateError): Invalid credentials",
|
|
41
41
|
{"error": 1, "message": "Invalid credentials"},
|
|
42
42
|
)
|
|
43
|
-
except KeycloakGetError as e:
|
|
43
|
+
except (KeycloakGetError, KeycloakPostError) as e:
|
|
44
44
|
error = json.loads(e.error_message)
|
|
45
|
+
error_type = e.__class__.__name__
|
|
45
46
|
instance.log.info(f"Keycloak reported: {e}")
|
|
46
47
|
instance.print(
|
|
47
|
-
f"An error occurred (
|
|
48
|
+
f"An error occurred ({error_type}): {error['error_description']}"
|
|
48
49
|
)
|
|
49
50
|
except (EOFError, KeyboardInterrupt):
|
|
50
51
|
instance.print("\nAbort.")
|
|
@@ -69,7 +70,7 @@ def get_command_class(argv):
|
|
|
69
70
|
commands = {
|
|
70
71
|
"datasets": DatasetsCommand,
|
|
71
72
|
"permissions": PermissionsCommand,
|
|
72
|
-
"
|
|
73
|
+
"pubs": PubsCommand,
|
|
73
74
|
"status": StatusCommand,
|
|
74
75
|
"teams": TeamsCommand,
|
|
75
76
|
}
|
|
@@ -21,7 +21,7 @@ class BaseCommand:
|
|
|
21
21
|
usage:
|
|
22
22
|
okdata datasets [options]
|
|
23
23
|
okdata permissions [options]
|
|
24
|
-
okdata
|
|
24
|
+
okdata pubs [options]
|
|
25
25
|
okdata status [options]
|
|
26
26
|
okdata teams [options]
|
|
27
27
|
okdata -h | --help
|
|
@@ -29,7 +29,7 @@ usage:
|
|
|
29
29
|
Commands available:
|
|
30
30
|
datasets
|
|
31
31
|
permissions
|
|
32
|
-
|
|
32
|
+
pubs
|
|
33
33
|
status
|
|
34
34
|
teams
|
|
35
35
|
|
|
@@ -292,6 +292,10 @@ Options:{BASE_COMMAND_OPTIONS}
|
|
|
292
292
|
parts = dataset_uri.split("/")
|
|
293
293
|
dataset_id, version, edition = parts + [None] * (3 - len(parts))
|
|
294
294
|
|
|
295
|
+
# First verify that the dataset exists; `get_dataset` raises an error
|
|
296
|
+
# if not.
|
|
297
|
+
self.sdk.get_dataset(dataset_id)
|
|
298
|
+
|
|
295
299
|
if auto_resolve:
|
|
296
300
|
if not version:
|
|
297
301
|
version = self._get_latest_version(dataset_id)["version"]
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
|
|
3
1
|
from questionary import Choice
|
|
4
2
|
|
|
5
|
-
from okdata.cli.commands.
|
|
3
|
+
from okdata.cli.commands.validators import (
|
|
6
4
|
KeywordValidator,
|
|
7
|
-
PhoneValidator,
|
|
8
5
|
SimpleEmailValidator,
|
|
9
|
-
SpatialResolutionValidator,
|
|
10
|
-
SpatialValidator,
|
|
11
|
-
StandardsValidator,
|
|
12
6
|
TitleValidator,
|
|
13
7
|
)
|
|
14
|
-
from okdata.cli.commands.wizard import required_style
|
|
8
|
+
from okdata.cli.commands.wizard import filter_comma_separated, required_style
|
|
15
9
|
|
|
16
10
|
pipeline_choices = {
|
|
17
11
|
"file": [
|
|
18
12
|
Choice("Lagre dataen slik den er", "data-copy"),
|
|
13
|
+
Choice("Konverter fra CSV til Delta", "csv-to-delta"),
|
|
14
|
+
Choice("Konverter fra JSON til Delta", "json-to-delta"),
|
|
19
15
|
Choice("Konverter fra CSV til Parquet", "csv-to-parquet"),
|
|
20
16
|
Choice("Konverter fra Excel til CSV", "pipeline-excel-to-csv"),
|
|
21
17
|
Choice("Ingen prosessering (krever manuell konfigurasjon av pipeline)", False),
|
|
@@ -30,14 +26,7 @@ available_pipelines = [
|
|
|
30
26
|
]
|
|
31
27
|
|
|
32
28
|
|
|
33
|
-
def
|
|
34
|
-
values = next(
|
|
35
|
-
csv.reader([value], delimiter=",", escapechar="\\", skipinitialspace=True)
|
|
36
|
-
)
|
|
37
|
-
return [x.strip() for x in values if x]
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def qs_create(include_extra_metadata=True):
|
|
29
|
+
def qs_create():
|
|
41
30
|
return [
|
|
42
31
|
{
|
|
43
32
|
**required_style,
|
|
@@ -67,38 +56,6 @@ def qs_create(include_extra_metadata=True):
|
|
|
67
56
|
"validate": KeywordValidator,
|
|
68
57
|
"filter": filter_comma_separated,
|
|
69
58
|
},
|
|
70
|
-
{
|
|
71
|
-
**required_style,
|
|
72
|
-
"type": "confirm",
|
|
73
|
-
"name": "contains_geodata",
|
|
74
|
-
"message": "Inneholder datasettet geodata?",
|
|
75
|
-
"default": False,
|
|
76
|
-
"when": lambda x: include_extra_metadata,
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"type": "text",
|
|
80
|
-
"name": "spatial",
|
|
81
|
-
"message": "Romlig avgrensning (komma-separert)",
|
|
82
|
-
"validate": SpatialValidator,
|
|
83
|
-
"filter": filter_comma_separated,
|
|
84
|
-
"when": lambda x: include_extra_metadata and x["contains_geodata"],
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"type": "text",
|
|
88
|
-
"name": "spatialResolutionInMeters",
|
|
89
|
-
"message": "Romlig oppløsning (i meter)",
|
|
90
|
-
"validate": SpatialResolutionValidator,
|
|
91
|
-
"filter": lambda v: float(v.replace(",", ".")) if v else None,
|
|
92
|
-
"when": lambda x: include_extra_metadata and x["contains_geodata"],
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"type": "text",
|
|
96
|
-
"name": "conformsTo",
|
|
97
|
-
"message": "I samsvar med standarder (komma-separert)",
|
|
98
|
-
"validate": StandardsValidator,
|
|
99
|
-
"filter": filter_comma_separated,
|
|
100
|
-
"when": lambda x: include_extra_metadata,
|
|
101
|
-
},
|
|
102
59
|
{
|
|
103
60
|
**required_style,
|
|
104
61
|
"type": "select",
|
|
@@ -138,7 +95,6 @@ def qs_create(include_extra_metadata=True):
|
|
|
138
95
|
"http://creativecommons.org/publicdomain/zero/1.0/",
|
|
139
96
|
),
|
|
140
97
|
],
|
|
141
|
-
"when": lambda x: include_extra_metadata,
|
|
142
98
|
},
|
|
143
99
|
{"type": "text", "name": "name", "message": "Kontaktperson – navn"},
|
|
144
100
|
{
|
|
@@ -148,13 +104,6 @@ def qs_create(include_extra_metadata=True):
|
|
|
148
104
|
"message": "Kontaktperson – epost",
|
|
149
105
|
"validate": SimpleEmailValidator,
|
|
150
106
|
},
|
|
151
|
-
{
|
|
152
|
-
**required_style,
|
|
153
|
-
"type": "text",
|
|
154
|
-
"name": "phone",
|
|
155
|
-
"message": "Kontaktperson – telefon",
|
|
156
|
-
"validate": PhoneValidator,
|
|
157
|
-
},
|
|
158
107
|
{"type": "text", "name": "publisher", "message": "Utgiver"},
|
|
159
108
|
{
|
|
160
109
|
**required_style,
|
|
@@ -29,17 +29,10 @@ class DatasetCreateWizard:
|
|
|
29
29
|
"contactPoint": {
|
|
30
30
|
"name": choices["name"],
|
|
31
31
|
"email": choices["email"],
|
|
32
|
-
"phone": choices["phone"],
|
|
33
32
|
},
|
|
34
33
|
"publisher": choices["publisher"],
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
if choices.get("spatial"):
|
|
38
|
-
config["spatial"] = choices["spatial"]
|
|
39
|
-
if choices.get("spatialResolutionInMeters"):
|
|
40
|
-
config["spatialResolutionInMeters"] = choices["spatialResolutionInMeters"]
|
|
41
|
-
if choices.get("conformsTo"):
|
|
42
|
-
config["conformsTo"] = choices["conformsTo"]
|
|
43
36
|
if choices.get("license"):
|
|
44
37
|
config["license"] = choices["license"]
|
|
45
38
|
|
|
@@ -12,12 +12,13 @@ class PermissionsCommand(BaseCommand):
|
|
|
12
12
|
|
|
13
13
|
Usage:
|
|
14
14
|
okdata permissions ls [<resource_name>] [options]
|
|
15
|
-
okdata permissions add <resource_name> <user> <scope> [--team | --client] [options]
|
|
15
|
+
okdata permissions add <resource_name> <user> [<scope>] [--team | --client] [options]
|
|
16
16
|
okdata permissions rm <resource_name> <user> [<scope>] [--team | --client] [options]
|
|
17
17
|
|
|
18
18
|
Examples:
|
|
19
19
|
okdata permissions ls
|
|
20
20
|
okdata permissions ls okdata:dataset:my-dataset
|
|
21
|
+
okdata permissions add okdata:dataset:my-dataset janedoe
|
|
21
22
|
okdata permissions add okdata:dataset:my-dataset janedoe okdata:dataset:read
|
|
22
23
|
okdata permissions rm okdata:dataset:my-dataset janedoe
|
|
23
24
|
okdata permissions rm okdata:dataset:my-dataset janedoe okdata:dataset:write
|
|
@@ -57,10 +58,10 @@ Options:{BASE_COMMAND_OPTIONS}
|
|
|
57
58
|
]
|
|
58
59
|
if self.cmd("add"):
|
|
59
60
|
self.add_user(resource_name, user_class(user), scope)
|
|
60
|
-
self.print("Granted {} on '{}'
|
|
61
|
+
self.print("Granted {} on '{}' to {} '{}'".format(*fmt_args))
|
|
61
62
|
else:
|
|
62
63
|
self.remove_user(resource_name, user_class(user), scope)
|
|
63
|
-
self.print("Revoked {} on '{}'
|
|
64
|
+
self.print("Revoked {} on '{}' from {} '{}'".format(*fmt_args))
|
|
64
65
|
|
|
65
66
|
def list_my_permissions(self):
|
|
66
67
|
"""Print all permissions for the current user."""
|
|
@@ -99,9 +100,14 @@ Options:{BASE_COMMAND_OPTIONS}
|
|
|
99
100
|
out.add_rows(sorted(results, key=itemgetter("user_type", "user_name")))
|
|
100
101
|
self.print(f"Permissions for '{resource_name}'", out)
|
|
101
102
|
|
|
102
|
-
def add_user(self, resource_name, user, scope):
|
|
103
|
-
"""Grant `scope` on `resource_name` to `user`.
|
|
104
|
-
|
|
103
|
+
def add_user(self, resource_name, user, scope=None):
|
|
104
|
+
"""Grant `scope` on `resource_name` to `user`.
|
|
105
|
+
|
|
106
|
+
When `scope` is unspecified, grant every permission on `resource_name`.
|
|
107
|
+
"""
|
|
108
|
+
return self.client.update_permission(
|
|
109
|
+
resource_name, scope or "__all__", add_users=[user]
|
|
110
|
+
)
|
|
105
111
|
|
|
106
112
|
def remove_user(self, resource_name, user, scope=None):
|
|
107
113
|
"""Revoke `scope` on `resource_name` for `user`.
|
|
@@ -109,11 +115,6 @@ Options:{BASE_COMMAND_OPTIONS}
|
|
|
109
115
|
When `scope` is unspecified, revoke every permission on `resource_name`
|
|
110
116
|
for `user`.
|
|
111
117
|
"""
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for permission in self.client.get_permissions(resource_name):
|
|
116
|
-
if user.user_id in permission[f"{user.user_type}s"]:
|
|
117
|
-
self.client.update_permission(
|
|
118
|
-
resource_name, permission["scope"], remove_users=[user]
|
|
119
|
-
)
|
|
118
|
+
return self.client.update_permission(
|
|
119
|
+
resource_name, scope or "__all__", remove_users=[user]
|
|
120
|
+
)
|
{okdata-cli-3.2.0/okdata/cli/commands/pubreg → okdata-cli-4.1.0/okdata/cli/commands/pubs}/client.py
RENAMED
|
@@ -5,23 +5,48 @@ from okdata.sdk import SDK
|
|
|
5
5
|
log = logging.getLogger()
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class PubsClient(SDK):
|
|
9
9
|
def __init__(self, config=None, auth=None, env=None):
|
|
10
|
-
self.__name__ = "
|
|
10
|
+
self.__name__ = "pubs"
|
|
11
11
|
super().__init__(config, auth, env)
|
|
12
12
|
self.api_url = "https://api.data{}.oslo.systems/maskinporten".format(
|
|
13
13
|
"-dev" if self.config.config["env"] == "dev" else ""
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def create_maskinporten_client(self, team_id, provider, integration, scopes, env):
|
|
17
17
|
data = {
|
|
18
|
+
"client_type": "maskinporten",
|
|
18
19
|
"team_id": team_id,
|
|
19
20
|
"provider": provider,
|
|
20
21
|
"integration": integration,
|
|
21
22
|
"scopes": scopes,
|
|
22
23
|
"env": env,
|
|
23
24
|
}
|
|
24
|
-
log.info(f"Creating client with payload: {data}")
|
|
25
|
+
log.info(f"Creating Maskinporten client with payload: {data}")
|
|
26
|
+
return self.post(f"{self.api_url}/clients", data=data).json()
|
|
27
|
+
|
|
28
|
+
def create_idporten_client(
|
|
29
|
+
self,
|
|
30
|
+
team_id,
|
|
31
|
+
integration,
|
|
32
|
+
client_uri,
|
|
33
|
+
frontchannel_logout_uri,
|
|
34
|
+
redirect_uris,
|
|
35
|
+
post_logout_redirect_uris,
|
|
36
|
+
env,
|
|
37
|
+
):
|
|
38
|
+
data = {
|
|
39
|
+
"client_type": "idporten",
|
|
40
|
+
"team_id": team_id,
|
|
41
|
+
"provider": "idporten",
|
|
42
|
+
"integration": integration,
|
|
43
|
+
"client_uri": client_uri,
|
|
44
|
+
"frontchannel_logout_uri": frontchannel_logout_uri,
|
|
45
|
+
"redirect_uris": redirect_uris,
|
|
46
|
+
"post_logout_redirect_uris": post_logout_redirect_uris,
|
|
47
|
+
"env": env,
|
|
48
|
+
}
|
|
49
|
+
log.info(f"Creating ID-porten client with payload: {data}")
|
|
25
50
|
return self.post(f"{self.api_url}/clients", data=data).json()
|
|
26
51
|
|
|
27
52
|
def get_clients(self, env):
|
|
@@ -6,9 +6,14 @@ from okdata.sdk.team.client import TeamClient
|
|
|
6
6
|
|
|
7
7
|
from okdata.cli import MAINTAINER
|
|
8
8
|
from okdata.cli.command import BASE_COMMAND_OPTIONS, BaseCommand
|
|
9
|
-
from okdata.cli.commands.
|
|
10
|
-
from okdata.cli.commands.
|
|
11
|
-
|
|
9
|
+
from okdata.cli.commands.pubs.client import PubsClient
|
|
10
|
+
from okdata.cli.commands.pubs.questions import (
|
|
11
|
+
NoClientsError,
|
|
12
|
+
NoKeysError,
|
|
13
|
+
client_types,
|
|
14
|
+
providers,
|
|
15
|
+
)
|
|
16
|
+
from okdata.cli.commands.pubs.wizards import (
|
|
12
17
|
audit_log_wizard,
|
|
13
18
|
create_client_wizard,
|
|
14
19
|
create_key_wizard,
|
|
@@ -21,33 +26,33 @@ from okdata.cli.commands.teams.questions import NoTeamError
|
|
|
21
26
|
from okdata.cli.output import create_output
|
|
22
27
|
|
|
23
28
|
|
|
24
|
-
class
|
|
25
|
-
__doc__ = f"""Oslo :: Public
|
|
29
|
+
class PubsCommand(BaseCommand):
|
|
30
|
+
__doc__ = f"""Oslo :: Public services
|
|
26
31
|
|
|
27
32
|
Usage:
|
|
28
|
-
okdata
|
|
29
|
-
okdata
|
|
30
|
-
okdata
|
|
31
|
-
okdata
|
|
32
|
-
okdata
|
|
33
|
-
okdata
|
|
34
|
-
okdata
|
|
33
|
+
okdata pubs create-client [options]
|
|
34
|
+
okdata pubs list-clients [options]
|
|
35
|
+
okdata pubs delete-client [options]
|
|
36
|
+
okdata pubs create-key [options]
|
|
37
|
+
okdata pubs list-keys [options]
|
|
38
|
+
okdata pubs delete-key [options]
|
|
39
|
+
okdata pubs audit-log [options]
|
|
35
40
|
|
|
36
41
|
Examples:
|
|
37
|
-
okdata
|
|
38
|
-
okdata
|
|
39
|
-
okdata
|
|
40
|
-
okdata
|
|
41
|
-
okdata
|
|
42
|
-
okdata
|
|
43
|
-
okdata
|
|
42
|
+
okdata pubs create-client
|
|
43
|
+
okdata pubs list-clients
|
|
44
|
+
okdata pubs delete-client
|
|
45
|
+
okdata pubs create-key
|
|
46
|
+
okdata pubs list-keys
|
|
47
|
+
okdata pubs delete-key
|
|
48
|
+
okdata pubs audit-log
|
|
44
49
|
|
|
45
50
|
Options:{BASE_COMMAND_OPTIONS}
|
|
46
51
|
"""
|
|
47
52
|
|
|
48
53
|
def __init__(self):
|
|
49
54
|
super().__init__()
|
|
50
|
-
self.
|
|
55
|
+
self.pubs_client = PubsClient(env=self.opt("env"))
|
|
51
56
|
self.team_client = TeamClient(env=self.opt("env"))
|
|
52
57
|
|
|
53
58
|
def handler(self):
|
|
@@ -77,40 +82,55 @@ Options:{BASE_COMMAND_OPTIONS}
|
|
|
77
82
|
return
|
|
78
83
|
|
|
79
84
|
team_id = config["team_id"]
|
|
85
|
+
client_type_id = config["client_type_id"]
|
|
80
86
|
provider_id = config["provider_id"]
|
|
81
|
-
provider_name = config["provider_name"]
|
|
82
87
|
integration = config["integration"]
|
|
83
88
|
scopes = config["scopes"]
|
|
84
89
|
env = config["env"]
|
|
85
90
|
|
|
86
91
|
self.confirm_to_continue(
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
"Will create a new {} client{} in {}{}.".format(
|
|
93
|
+
client_types[client_type_id],
|
|
94
|
+
f" for {providers[provider_id]}" if provider_id else "",
|
|
95
|
+
env,
|
|
96
|
+
f" with scopes {scopes}" if scopes else "",
|
|
97
|
+
)
|
|
89
98
|
)
|
|
90
99
|
|
|
91
100
|
self.print("Creating client...")
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
if client_type_id == "maskinporten":
|
|
102
|
+
response = self.pubs_client.create_maskinporten_client(
|
|
103
|
+
team_id, provider_id, integration, scopes, env
|
|
104
|
+
)
|
|
105
|
+
else:
|
|
106
|
+
response = self.pubs_client.create_idporten_client(
|
|
107
|
+
team_id,
|
|
108
|
+
integration,
|
|
109
|
+
config["client_uri"],
|
|
110
|
+
config["frontchannel_logout_uri"],
|
|
111
|
+
config["redirect_uris"],
|
|
112
|
+
config["post_logout_redirect_uris"],
|
|
113
|
+
env,
|
|
114
|
+
)
|
|
95
115
|
client_name = response["client_name"]
|
|
96
116
|
self.print(
|
|
97
117
|
f"""
|
|
98
118
|
Done! Created a new client '{client_name}'.
|
|
99
119
|
You may now go ahead and create a key for it by running:
|
|
100
120
|
|
|
101
|
-
okdata
|
|
121
|
+
okdata pubs create-key"""
|
|
102
122
|
)
|
|
103
123
|
|
|
104
124
|
def list_clients(self):
|
|
105
125
|
config = list_clients_wizard()
|
|
106
126
|
env = config["env"]
|
|
107
|
-
clients = self.
|
|
108
|
-
out = create_output(self.opt("format"), "
|
|
127
|
+
clients = self.pubs_client.get_clients(env)
|
|
128
|
+
out = create_output(self.opt("format"), "pubs_clients_config.json")
|
|
109
129
|
out.add_rows(sorted(clients, key=itemgetter("client_name")))
|
|
110
130
|
self.print(f"Clients in {env}:", out)
|
|
111
131
|
|
|
112
132
|
def delete_client(self):
|
|
113
|
-
choices = delete_client_wizard(self.
|
|
133
|
+
choices = delete_client_wizard(self.pubs_client)
|
|
114
134
|
env = choices["env"]
|
|
115
135
|
client_id = choices["client_id"]
|
|
116
136
|
client_name = choices["client_name"]
|
|
@@ -123,16 +143,18 @@ You may now go ahead and create a key for it by running:
|
|
|
123
143
|
client_name,
|
|
124
144
|
env,
|
|
125
145
|
(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
146
|
+
(
|
|
147
|
+
f" along with the key stored in AWS account {aws_account} "
|
|
148
|
+
f"({aws_region})"
|
|
149
|
+
)
|
|
150
|
+
if delete_from_aws
|
|
151
|
+
else ""
|
|
152
|
+
),
|
|
131
153
|
),
|
|
132
154
|
)
|
|
133
155
|
|
|
134
156
|
self.print(f"Deleting client '{client_name}' [{env}]...")
|
|
135
|
-
res = self.
|
|
157
|
+
res = self.pubs_client.delete_client(env, client_id, aws_account, aws_region)
|
|
136
158
|
deleted_ssm_params = res["deleted_ssm_params"]
|
|
137
159
|
|
|
138
160
|
self.print("\nDone! The client is deleted and will no longer work.")
|
|
@@ -203,11 +225,11 @@ You may now go ahead and create a key for it by running:
|
|
|
203
225
|
|
|
204
226
|
def create_client_key(self):
|
|
205
227
|
try:
|
|
206
|
-
config = create_key_wizard(self.
|
|
228
|
+
config = create_key_wizard(self.pubs_client)
|
|
207
229
|
except NoClientsError:
|
|
208
230
|
self.print(
|
|
209
231
|
"No clients in the given environment yet!\n\n"
|
|
210
|
-
" Create one with `okdata
|
|
232
|
+
" Create one with `okdata pubs create-client`.\n"
|
|
211
233
|
)
|
|
212
234
|
return
|
|
213
235
|
|
|
@@ -226,22 +248,26 @@ You may now go ahead and create a key for it by running:
|
|
|
226
248
|
client_name,
|
|
227
249
|
env,
|
|
228
250
|
(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
251
|
+
(
|
|
252
|
+
f"send it to AWS account {aws_account} ({aws_region}), "
|
|
253
|
+
"REPLACING any existing key for this client"
|
|
254
|
+
)
|
|
255
|
+
if key_destination == "aws"
|
|
256
|
+
else "save it locally"
|
|
257
|
+
),
|
|
258
|
+
),
|
|
259
|
+
(
|
|
260
|
+
"The key will be rotated automatically every night on weekdays.\n"
|
|
261
|
+
if enable_auto_rotate
|
|
262
|
+
else "The key will NOT be rotated automatically.\n"
|
|
234
263
|
),
|
|
235
|
-
"The key will be rotated automatically every night on weekdays.\n"
|
|
236
|
-
if enable_auto_rotate
|
|
237
|
-
else "The key will NOT be rotated automatically.\n",
|
|
238
264
|
]
|
|
239
265
|
)
|
|
240
266
|
)
|
|
241
267
|
|
|
242
268
|
self.print("Creating key for '{}' [{}]...".format(client_name, env))
|
|
243
269
|
|
|
244
|
-
key = self.
|
|
270
|
+
key = self.pubs_client.create_key(
|
|
245
271
|
env, client_id, aws_account, aws_region, enable_auto_rotate
|
|
246
272
|
)
|
|
247
273
|
|
|
@@ -256,10 +282,10 @@ You may now go ahead and create a key for it by running:
|
|
|
256
282
|
)
|
|
257
283
|
|
|
258
284
|
def _list_client_keys_single(self, client_id, client_name, env):
|
|
259
|
-
keys = self.
|
|
285
|
+
keys = self.pubs_client.get_keys(env, client_id)
|
|
260
286
|
out = create_output(
|
|
261
287
|
self.opt("format"),
|
|
262
|
-
"
|
|
288
|
+
"pubs_single_client_keys_config.json",
|
|
263
289
|
)
|
|
264
290
|
out.add_rows(sorted(keys, key=itemgetter("expires")))
|
|
265
291
|
self.print(f"Keys for client {client_name} [{env}]:", out)
|
|
@@ -269,17 +295,17 @@ You may now go ahead and create a key for it by running:
|
|
|
269
295
|
keys = [
|
|
270
296
|
{**key, "client_name": client["name"]}
|
|
271
297
|
for client in clients
|
|
272
|
-
for key in self.
|
|
298
|
+
for key in self.pubs_client.get_keys(env, client["id"])
|
|
273
299
|
]
|
|
274
300
|
out = create_output(
|
|
275
301
|
self.opt("format"),
|
|
276
|
-
"
|
|
302
|
+
"pubs_multiple_client_keys_config.json",
|
|
277
303
|
)
|
|
278
304
|
out.add_rows(sorted(keys, key=itemgetter("expires")))
|
|
279
305
|
self.print(f"All client keys [{env}]:", out)
|
|
280
306
|
|
|
281
307
|
def list_client_keys(self):
|
|
282
|
-
choices = list_keys_wizard(self.
|
|
308
|
+
choices = list_keys_wizard(self.pubs_client)
|
|
283
309
|
env = choices["env"]
|
|
284
310
|
|
|
285
311
|
if "clients" in choices:
|
|
@@ -291,7 +317,7 @@ You may now go ahead and create a key for it by running:
|
|
|
291
317
|
|
|
292
318
|
def delete_client_key(self):
|
|
293
319
|
try:
|
|
294
|
-
choices = delete_key_wizard(self.
|
|
320
|
+
choices = delete_key_wizard(self.pubs_client)
|
|
295
321
|
except NoKeysError:
|
|
296
322
|
self.print("The selected client doesn't have any keys.")
|
|
297
323
|
return
|
|
@@ -306,17 +332,17 @@ You may now go ahead and create a key for it by running:
|
|
|
306
332
|
)
|
|
307
333
|
|
|
308
334
|
self.print(f"Deleting key '{key_id}' from '{client_name}' [{env}]...")
|
|
309
|
-
self.
|
|
335
|
+
self.pubs_client.delete_key(env, client_id, key_id)
|
|
310
336
|
self.print("Done! The key is deleted and will no longer work.")
|
|
311
337
|
|
|
312
338
|
def audit_log(self):
|
|
313
|
-
choices = audit_log_wizard(self.
|
|
339
|
+
choices = audit_log_wizard(self.pubs_client)
|
|
314
340
|
env = choices["env"]
|
|
315
341
|
client_id = choices["client_id"]
|
|
316
342
|
client_name = choices["client_name"]
|
|
317
343
|
|
|
318
|
-
audit_log = self.
|
|
344
|
+
audit_log = self.pubs_client.get_audit_log(env, client_id)
|
|
319
345
|
|
|
320
|
-
out = create_output(self.opt("format"), "
|
|
346
|
+
out = create_output(self.opt("format"), "pubs_audit_log_config.json")
|
|
321
347
|
out.add_rows(sorted(audit_log, key=itemgetter("timestamp")))
|
|
322
348
|
self.print(f"Audit log for client {client_name} [{env}]:", out)
|