kubernetes-watch 0.1.5__py3-none-any.whl → 0.1.9__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.
@@ -1,188 +1,188 @@
1
- import hvac
2
- import os
3
- from prefect import get_run_logger
4
-
5
- from kube_watch.enums.providers import Providers
6
-
7
- logger = get_run_logger()
8
-
9
- def login(url, app_role_id, secret_id, path):
10
- """
11
- Login to Vault, using an existing token if available, or via AppRole otherwise.
12
-
13
- Parameters:
14
- url (str): Vault server URL.
15
- app_role_id (str): AppRole ID.
16
- secret_id (str): AppRole Secret ID.
17
- path (str): Path where the AppRole is enabled.
18
-
19
- Returns:
20
- dict: Dictionary containing the initialized vault_client.
21
- """
22
- vault_client = hvac.Client(url=url)
23
-
24
- # Attempt to use an existing token from environment variables
25
- vault_token = os.getenv('VAULT_TOKEN', None)
26
- if vault_token:
27
- vault_client.token = vault_token
28
- # Verify if the current token is still valid
29
- try:
30
- if vault_client.is_authenticated():
31
- logger.info("Authenticated with existing token.")
32
- return vault_client
33
- except hvac.exceptions.InvalidRequest as e:
34
- logger.warning(f"Failed to authenticate with the existing token: {str(e)}")
35
-
36
- # If token is not valid or not present, authenticate with AppRole
37
- try:
38
- vault_client.auth.approle.login(
39
- role_id=app_role_id,
40
- secret_id=secret_id,
41
- mount_point=f'approle/{path}'
42
- )
43
-
44
- # Store the new token in environment variables for subsequent use
45
- os.environ['VAULT_TOKEN'] = vault_client.token
46
- logger.info("Authenticated with new token and stored in environment variable.")
47
-
48
- return vault_client
49
- except hvac.exceptions.InvalidRequest as e:
50
- logger.error(f"Authentication failed with provided secret_id: {str(e)}")
51
- raise RuntimeError("Authentication failed: unable to log in with the provided credentials.") from e
52
-
53
-
54
-
55
- def get_secret(vault_client, secret_path, vault_mount_point):
56
- """
57
- Retrieve a secret from Vault
58
- """
59
- res = vault_client.secrets.kv.v2.read_secret_version(
60
- path=secret_path,
61
- mount_point=vault_mount_point,
62
- raise_on_deleted_version=True
63
- )
64
- return res.get('data', {}).get('data')
65
-
66
-
67
- def update_secret(vault_client, secret_path, secret_data, vault_mount_point):
68
- """
69
- Update or create a secret in Vault at the specified path.
70
-
71
- Args:
72
- vault_client: The authenticated Vault client instance.
73
- secret_path (str): The path where the secret will be stored or updated in Vault.
74
- secret_data (dict): The secret data to store as a dictionary.
75
- vault_mount_point (str): The mount point for the KV store.
76
-
77
- Returns:
78
- bool: True if the operation was successful, False otherwise.
79
- """
80
- try:
81
- # Writing the secret data to Vault at the specified path
82
- vault_client.secrets.kv.v2.create_or_update_secret(
83
- path=secret_path,
84
- secret=secret_data,
85
- mount_point=vault_mount_point
86
- )
87
- print("Secret updated successfully.")
88
- return True
89
- except Exception as e:
90
- print(f"Failed to update secret: {e}")
91
- return False
92
-
93
- def generate_provider_creds(vault_client, provider, backend_path, role_name):
94
- """
95
- Generate credentials for a specified provider
96
- """
97
- if provider == Providers.AWS:
98
- backend_path = backend_path
99
- role_name = role_name
100
- creds_path = f"{backend_path}/creds/{role_name}"
101
- return vault_client.read(creds_path)
102
-
103
- raise ValueError("Unknown provider")
104
-
105
-
106
-
107
- def generate_new_secret_id(vault_client, role_name, vault_path, env_var_name):
108
- """
109
- Generates new secret_id. Note an admin role is required for this.
110
- """
111
- try:
112
- # Write directly to the Vault endpoint to create the secret ID with num_uses
113
- # response = vault_client.write(
114
- # f"auth/approle/{vault_path}/role/{role_name}/secret-id",
115
- # )
116
- response = vault_client.auth.approle.generate_secret_id(
117
- role_name=role_name,
118
- mount_point=f'approle/{vault_path}'
119
- )
120
- # Check if the response contains the secret ID
121
- if response and 'data' in response:
122
- secret_id = response['data']['secret_id']
123
- secret_id_accessor = response['data']['secret_id_accessor']
124
- logger.info("Generated a new secret ID with usage buffer.")
125
- return {env_var_name: secret_id, f"{env_var_name}_ACCESSOR": secret_id_accessor}
126
- else:
127
- logger.error("No secret ID returned in the response.")
128
- raise RuntimeError("Failed to generate new secret ID: No content returned.")
129
- except hvac.exceptions.InvalidRequest as e:
130
- logger.error("Error generating new secret ID: %s", str(e))
131
- raise RuntimeError("Failed to generate new secret ID.") from e
132
- # new_secret_response = vault_client.auth.approle.generate_secret_id(
133
- # role_name=role_name,
134
- # mount_point=f'approle/{vault_path}'
135
- # )
136
-
137
- # return { env_var_name : new_secret_response['data']['secret_id'] }
138
-
139
-
140
-
141
- def delete_secret_id(vault_client, role_name, secret_id, vault_path):
142
- """
143
- Delete (revoke) a secret ID associated with a role in Vault.
144
-
145
- Parameters:
146
- vault_client (hvac.Client): An authenticated Vault client.
147
- role_name (str): The name of the role the secret ID is associated with.
148
- secret_id (str): The secret ID to be deleted.
149
- vault_path (str): The path where the AppRole is enabled.
150
- """
151
- try:
152
- vault_client.auth.approle.destroy_secret_id(
153
- mount_point=f"approle/{vault_path}",
154
- role_name=role_name,
155
- secret_id=secret_id
156
- )
157
-
158
- logger.info("Secret ID successfully revoked.")
159
- except hvac.exceptions.InvalidRequest as e:
160
- logger.error("Failed to revoke the secret ID: %s", str(e))
161
- raise RuntimeError("Failed to delete the secret ID.") from e
162
-
163
-
164
- def clean_secret_ids(vault_client, role_name, secret_id_env, vault_path, has_kube_secret_updated):
165
- """
166
- This function removes all idle secret-ids from `role_name`, except the
167
- inputted `secret_id_env`.
168
-
169
- Note: secret_id_env is a dictionary. The key, VAULT_SECRET_ID, has the secret_id value.
170
- """
171
- secret_id = secret_id_env.get("VAULT_SECRET_ID_ACCESSOR")
172
-
173
- if has_kube_secret_updated:
174
- secret_ids_path = f'auth/approle/{vault_path}/role/{role_name}/secret-id'
175
- try:
176
- response = vault_client.list(secret_ids_path)
177
- if 'data' in response:
178
- secret_ids = response['data']['keys']
179
- for idx in secret_ids:
180
- if idx != secret_id:
181
- delete_secret_id(vault_client, role_name, secret_id, vault_path)
182
- logger.info(f"Revoking idle secret id for role: {role_name}")
183
- else:
184
- logger.info("No secrets found at this path.")
185
- except hvac.exceptions.Forbidden:
186
- logger.error("Access denied. Ensure your token has the correct policies to read this path.")
187
- except Exception as e:
188
- logger.error(f"An error occurred: {e}")
1
+ import hvac
2
+ import os
3
+ from prefect import get_run_logger
4
+
5
+ from kube_watch.enums.providers import Providers
6
+
7
+ logger = get_run_logger()
8
+
9
+ def login(url, app_role_id, secret_id, path):
10
+ """
11
+ Login to Vault, using an existing token if available, or via AppRole otherwise.
12
+
13
+ Parameters:
14
+ url (str): Vault server URL.
15
+ app_role_id (str): AppRole ID.
16
+ secret_id (str): AppRole Secret ID.
17
+ path (str): Path where the AppRole is enabled.
18
+
19
+ Returns:
20
+ dict: Dictionary containing the initialized vault_client.
21
+ """
22
+ vault_client = hvac.Client(url=url)
23
+
24
+ # Attempt to use an existing token from environment variables
25
+ vault_token = os.getenv('VAULT_TOKEN', None)
26
+ if vault_token:
27
+ vault_client.token = vault_token
28
+ # Verify if the current token is still valid
29
+ try:
30
+ if vault_client.is_authenticated():
31
+ logger.info("Authenticated with existing token.")
32
+ return vault_client
33
+ except hvac.exceptions.InvalidRequest as e:
34
+ logger.warning(f"Failed to authenticate with the existing token: {str(e)}")
35
+
36
+ # If token is not valid or not present, authenticate with AppRole
37
+ try:
38
+ vault_client.auth.approle.login(
39
+ role_id=app_role_id,
40
+ secret_id=secret_id,
41
+ mount_point=f'approle/{path}'
42
+ )
43
+
44
+ # Store the new token in environment variables for subsequent use
45
+ os.environ['VAULT_TOKEN'] = vault_client.token
46
+ logger.info("Authenticated with new token and stored in environment variable.")
47
+
48
+ return vault_client
49
+ except hvac.exceptions.InvalidRequest as e:
50
+ logger.error(f"Authentication failed with provided secret_id: {str(e)}")
51
+ raise RuntimeError("Authentication failed: unable to log in with the provided credentials.") from e
52
+
53
+
54
+
55
+ def get_secret(vault_client, secret_path, vault_mount_point):
56
+ """
57
+ Retrieve a secret from Vault
58
+ """
59
+ res = vault_client.secrets.kv.v2.read_secret_version(
60
+ path=secret_path,
61
+ mount_point=vault_mount_point,
62
+ raise_on_deleted_version=True
63
+ )
64
+ return res.get('data', {}).get('data')
65
+
66
+
67
+ def update_secret(vault_client, secret_path, secret_data, vault_mount_point):
68
+ """
69
+ Update or create a secret in Vault at the specified path.
70
+
71
+ Args:
72
+ vault_client: The authenticated Vault client instance.
73
+ secret_path (str): The path where the secret will be stored or updated in Vault.
74
+ secret_data (dict): The secret data to store as a dictionary.
75
+ vault_mount_point (str): The mount point for the KV store.
76
+
77
+ Returns:
78
+ bool: True if the operation was successful, False otherwise.
79
+ """
80
+ try:
81
+ # Writing the secret data to Vault at the specified path
82
+ vault_client.secrets.kv.v2.create_or_update_secret(
83
+ path=secret_path,
84
+ secret=secret_data,
85
+ mount_point=vault_mount_point
86
+ )
87
+ print("Secret updated successfully.")
88
+ return True
89
+ except Exception as e:
90
+ print(f"Failed to update secret: {e}")
91
+ return False
92
+
93
+ def generate_provider_creds(vault_client, provider, backend_path, role_name):
94
+ """
95
+ Generate credentials for a specified provider
96
+ """
97
+ if provider == Providers.AWS:
98
+ backend_path = backend_path
99
+ role_name = role_name
100
+ creds_path = f"{backend_path}/creds/{role_name}"
101
+ return vault_client.read(creds_path)
102
+
103
+ raise ValueError("Unknown provider")
104
+
105
+
106
+
107
+ def generate_new_secret_id(vault_client, role_name, vault_path, env_var_name):
108
+ """
109
+ Generates new secret_id. Note an admin role is required for this.
110
+ """
111
+ try:
112
+ # Write directly to the Vault endpoint to create the secret ID with num_uses
113
+ # response = vault_client.write(
114
+ # f"auth/approle/{vault_path}/role/{role_name}/secret-id",
115
+ # )
116
+ response = vault_client.auth.approle.generate_secret_id(
117
+ role_name=role_name,
118
+ mount_point=f'approle/{vault_path}'
119
+ )
120
+ # Check if the response contains the secret ID
121
+ if response and 'data' in response:
122
+ secret_id = response['data']['secret_id']
123
+ secret_id_accessor = response['data']['secret_id_accessor']
124
+ logger.info("Generated a new secret ID with usage buffer.")
125
+ return {env_var_name: secret_id, f"{env_var_name}_ACCESSOR": secret_id_accessor}
126
+ else:
127
+ logger.error("No secret ID returned in the response.")
128
+ raise RuntimeError("Failed to generate new secret ID: No content returned.")
129
+ except hvac.exceptions.InvalidRequest as e:
130
+ logger.error("Error generating new secret ID: %s", str(e))
131
+ raise RuntimeError("Failed to generate new secret ID.") from e
132
+ # new_secret_response = vault_client.auth.approle.generate_secret_id(
133
+ # role_name=role_name,
134
+ # mount_point=f'approle/{vault_path}'
135
+ # )
136
+
137
+ # return { env_var_name : new_secret_response['data']['secret_id'] }
138
+
139
+
140
+
141
+ def delete_secret_id(vault_client, role_name, secret_id, vault_path):
142
+ """
143
+ Delete (revoke) a secret ID associated with a role in Vault.
144
+
145
+ Parameters:
146
+ vault_client (hvac.Client): An authenticated Vault client.
147
+ role_name (str): The name of the role the secret ID is associated with.
148
+ secret_id (str): The secret ID to be deleted.
149
+ vault_path (str): The path where the AppRole is enabled.
150
+ """
151
+ try:
152
+ vault_client.auth.approle.destroy_secret_id(
153
+ mount_point=f"approle/{vault_path}",
154
+ role_name=role_name,
155
+ secret_id=secret_id
156
+ )
157
+
158
+ logger.info("Secret ID successfully revoked.")
159
+ except hvac.exceptions.InvalidRequest as e:
160
+ logger.error("Failed to revoke the secret ID: %s", str(e))
161
+ raise RuntimeError("Failed to delete the secret ID.") from e
162
+
163
+
164
+ def clean_secret_ids(vault_client, role_name, secret_id_env, vault_path, has_kube_secret_updated):
165
+ """
166
+ This function removes all idle secret-ids from `role_name`, except the
167
+ inputted `secret_id_env`.
168
+
169
+ Note: secret_id_env is a dictionary. The key, VAULT_SECRET_ID, has the secret_id value.
170
+ """
171
+ secret_id = secret_id_env.get("VAULT_SECRET_ID_ACCESSOR")
172
+
173
+ if has_kube_secret_updated:
174
+ secret_ids_path = f'auth/approle/{vault_path}/role/{role_name}/secret-id'
175
+ try:
176
+ response = vault_client.list(secret_ids_path)
177
+ if 'data' in response:
178
+ secret_ids = response['data']['keys']
179
+ for idx in secret_ids:
180
+ if idx != secret_id:
181
+ delete_secret_id(vault_client, role_name, secret_id, vault_path)
182
+ logger.info(f"Revoking idle secret id for role: {role_name}")
183
+ else:
184
+ logger.info("No secrets found at this path.")
185
+ except hvac.exceptions.Forbidden:
186
+ logger.error("Access denied. Ensure your token has the correct policies to read this path.")
187
+ except Exception as e:
188
+ logger.error(f"An error occurred: {e}")
@@ -1,132 +1,132 @@
1
- import requests
2
- # from pathlib import Path
3
- import os
4
- import sys
5
-
6
- """
7
- A simple script to:
8
- 1. Retrieve all public records from a CKAN service
9
- 2. Insert CKAN records into a Geonetwork service
10
-
11
- This requires the 'iso19115' extension to be installed in CKAN and the following env. vars:
12
- 1. 'CKAN2GN_GN_USERNAME' geonetwork username for an account that can create records
13
- 2. 'CKAN2GN_GN_PASSWORD' geonetwork password for an account that can create records
14
- 3. 'CKAN2GN_GN_URL' geonetork service URL
15
- 4. 'CKAN2GN_CKAN_URL' CKAN service URL
16
- """
17
-
18
- # Geonetwork username and password:
19
- GN_USERNAME = os.environ.get('CKAN2GN_GN_USERNAME')
20
- GN_PASSWORD = os.environ.get('CKAN2GN_GN_PASSWORD')
21
-
22
- # Geonetwork and CKAN server URLs
23
- GN_URL = os.environ.get('CKAN2GN_GN_URL')
24
- CKAN_URL = os.environ.get('CKAN2GN_CKAN_URL')
25
-
26
- def get_gn_xsrf_token(session):
27
- """ Retrieves XSRF token from Geonetwork
28
-
29
- :param session: requests Session object
30
- :returns: XSRF as string or None upon error
31
- """
32
- authenticate_url = GN_URL + '/geonetwork/srv/eng/info?type=me'
33
- response = session.post(authenticate_url)
34
-
35
- # Extract XRSF token
36
- xsrf_token = response.cookies.get("XSRF-TOKEN")
37
- if xsrf_token:
38
- return xsrf_token
39
- return None
40
-
41
- def list_ckan_records():
42
- """ Contacts CKAN and retrieves a list of package ids for all public records
43
-
44
- :returns: list of package id strings or None upon error
45
- """
46
- session = requests.Session()
47
- url_path = 'api/3/action/package_list' # Path('api') / '3' / 'action' / 'package_list'
48
- url = f'{CKAN_URL}/{url_path}'
49
- r = session.get(url)
50
- resp = r.json()
51
- if resp['success'] is False:
52
- return None
53
- return resp['result']
54
-
55
- def get_ckan_record(package_id):
56
- """ Given a package id retrieves its record metadata
57
-
58
- :param package_id: CKAN package_id string
59
- :returns: package metadata as a dict or None upon error
60
- """
61
- session = requests.Session()
62
- # Set up CKAN URL
63
- url_path = 'api/3/action/iso19115_package_show' # Path('api') / '3' / 'action' / 'iso19115_package_show'
64
- url = f'{CKAN_URL}/{url_path}'
65
- r = session.get(url, params={'format':'xml', 'id':package_id})
66
- resp = r.json()
67
- if resp['success'] is False:
68
- return None
69
- return resp['result']
70
-
71
-
72
- def insert_gn_record(session, xsrf_token, xml_string):
73
- """ Inserts a record into Geonetwork
74
-
75
- :param session: requests Session object
76
- :param xsrf_token: Geonetwork's XSRF token as a string
77
- :param xml_string: XML to be inserted as a string
78
- :returns: True or False if insert succeeded
79
- """
80
- # Set header for connection
81
- headers = {'Accept': 'application/json',
82
- 'Content-Type': 'application/xml',
83
- 'X-XSRF-TOKEN': xsrf_token
84
- }
85
-
86
- # Set the parameters
87
- # Currently 'uuidProcessing' is set to 'NOTHING' so that records that
88
- # already exist are rejected by Geonetwork as duplicates
89
- params = {'metadataType': 'METADATA',
90
- 'publishToAll': 'true',
91
- 'uuidProcessing': 'NOTHING', # Available values : GENERATEUUID, NOTHING, OVERWRITE
92
- }
93
-
94
- # Send a put request to the endpoint to create record
95
- response = session.put(GN_URL + '/geonetwork/srv/api/0.1/records',
96
- data=xml_string,
97
- params=params,
98
- auth=(GN_USERNAME, GN_PASSWORD),
99
- headers=headers
100
- )
101
- resp = response.json()
102
-
103
- # Check if record was created in Geonetwork
104
- if response.status_code == requests.codes['created'] and resp['numberOfRecordsProcessed'] == 1 and \
105
- resp['numberOfRecordsWithErrors'] == 0:
106
- print("Inserted")
107
- return True
108
- print(f"Insert failed: status code: {response.status_code}\n{resp}")
109
- return False
110
-
111
-
112
- if __name__ == "__main__":
113
- # Check env. vars
114
- if GN_USERNAME is None or GN_PASSWORD is None or GN_URL is None or CKAN_URL is None:
115
- print("Please define the following env. vars:")
116
- print(" 'CKAN2GN_GN_USERNAME' 'CKAN2GN_GN_PASSWORD' 'CKAN2GN_GN_URL' 'CKAN2GN_CKAN_URL'")
117
- sys.exit(1)
118
- # Connect to server
119
- session = requests.Session()
120
- xsrf = get_gn_xsrf_token(session)
121
- if xsrf is not None:
122
- # Get records from CKAN
123
- for id in list_ckan_records():
124
- print(f"Inserting '{id}'")
125
- xml_string = get_ckan_record(id)
126
- if xml_string is not None:
127
- # Insert GN record
128
- insert_gn_record(session, xsrf, xml_string)
129
- else:
130
- print(f"Could not get record id {id} from CKAN")
131
-
132
-
1
+ import requests
2
+ # from pathlib import Path
3
+ import os
4
+ import sys
5
+
6
+ """
7
+ A simple script to:
8
+ 1. Retrieve all public records from a CKAN service
9
+ 2. Insert CKAN records into a Geonetwork service
10
+
11
+ This requires the 'iso19115' extension to be installed in CKAN and the following env. vars:
12
+ 1. 'CKAN2GN_GN_USERNAME' geonetwork username for an account that can create records
13
+ 2. 'CKAN2GN_GN_PASSWORD' geonetwork password for an account that can create records
14
+ 3. 'CKAN2GN_GN_URL' geonetork service URL
15
+ 4. 'CKAN2GN_CKAN_URL' CKAN service URL
16
+ """
17
+
18
+ # Geonetwork username and password:
19
+ GN_USERNAME = os.environ.get('CKAN2GN_GN_USERNAME')
20
+ GN_PASSWORD = os.environ.get('CKAN2GN_GN_PASSWORD')
21
+
22
+ # Geonetwork and CKAN server URLs
23
+ GN_URL = os.environ.get('CKAN2GN_GN_URL')
24
+ CKAN_URL = os.environ.get('CKAN2GN_CKAN_URL')
25
+
26
+ def get_gn_xsrf_token(session):
27
+ """ Retrieves XSRF token from Geonetwork
28
+
29
+ :param session: requests Session object
30
+ :returns: XSRF as string or None upon error
31
+ """
32
+ authenticate_url = GN_URL + '/geonetwork/srv/eng/info?type=me'
33
+ response = session.post(authenticate_url)
34
+
35
+ # Extract XRSF token
36
+ xsrf_token = response.cookies.get("XSRF-TOKEN")
37
+ if xsrf_token:
38
+ return xsrf_token
39
+ return None
40
+
41
+ def list_ckan_records():
42
+ """ Contacts CKAN and retrieves a list of package ids for all public records
43
+
44
+ :returns: list of package id strings or None upon error
45
+ """
46
+ session = requests.Session()
47
+ url_path = 'api/3/action/package_list' # Path('api') / '3' / 'action' / 'package_list'
48
+ url = f'{CKAN_URL}/{url_path}'
49
+ r = session.get(url)
50
+ resp = r.json()
51
+ if resp['success'] is False:
52
+ return None
53
+ return resp['result']
54
+
55
+ def get_ckan_record(package_id):
56
+ """ Given a package id retrieves its record metadata
57
+
58
+ :param package_id: CKAN package_id string
59
+ :returns: package metadata as a dict or None upon error
60
+ """
61
+ session = requests.Session()
62
+ # Set up CKAN URL
63
+ url_path = 'api/3/action/iso19115_package_show' # Path('api') / '3' / 'action' / 'iso19115_package_show'
64
+ url = f'{CKAN_URL}/{url_path}'
65
+ r = session.get(url, params={'format':'xml', 'id':package_id})
66
+ resp = r.json()
67
+ if resp['success'] is False:
68
+ return None
69
+ return resp['result']
70
+
71
+
72
+ def insert_gn_record(session, xsrf_token, xml_string):
73
+ """ Inserts a record into Geonetwork
74
+
75
+ :param session: requests Session object
76
+ :param xsrf_token: Geonetwork's XSRF token as a string
77
+ :param xml_string: XML to be inserted as a string
78
+ :returns: True or False if insert succeeded
79
+ """
80
+ # Set header for connection
81
+ headers = {'Accept': 'application/json',
82
+ 'Content-Type': 'application/xml',
83
+ 'X-XSRF-TOKEN': xsrf_token
84
+ }
85
+
86
+ # Set the parameters
87
+ # Currently 'uuidProcessing' is set to 'NOTHING' so that records that
88
+ # already exist are rejected by Geonetwork as duplicates
89
+ params = {'metadataType': 'METADATA',
90
+ 'publishToAll': 'true',
91
+ 'uuidProcessing': 'NOTHING', # Available values : GENERATEUUID, NOTHING, OVERWRITE
92
+ }
93
+
94
+ # Send a put request to the endpoint to create record
95
+ response = session.put(GN_URL + '/geonetwork/srv/api/0.1/records',
96
+ data=xml_string,
97
+ params=params,
98
+ auth=(GN_USERNAME, GN_PASSWORD),
99
+ headers=headers
100
+ )
101
+ resp = response.json()
102
+
103
+ # Check if record was created in Geonetwork
104
+ if response.status_code == requests.codes['created'] and resp['numberOfRecordsProcessed'] == 1 and \
105
+ resp['numberOfRecordsWithErrors'] == 0:
106
+ print("Inserted")
107
+ return True
108
+ print(f"Insert failed: status code: {response.status_code}\n{resp}")
109
+ return False
110
+
111
+
112
+ if __name__ == "__main__":
113
+ # Check env. vars
114
+ if GN_USERNAME is None or GN_PASSWORD is None or GN_URL is None or CKAN_URL is None:
115
+ print("Please define the following env. vars:")
116
+ print(" 'CKAN2GN_GN_USERNAME' 'CKAN2GN_GN_PASSWORD' 'CKAN2GN_GN_URL' 'CKAN2GN_CKAN_URL'")
117
+ sys.exit(1)
118
+ # Connect to server
119
+ session = requests.Session()
120
+ xsrf = get_gn_xsrf_token(session)
121
+ if xsrf is not None:
122
+ # Get records from CKAN
123
+ for id in list_ckan_records():
124
+ print(f"Inserting '{id}'")
125
+ xml_string = get_ckan_record(id)
126
+ if xml_string is not None:
127
+ # Insert GN record
128
+ insert_gn_record(session, xsrf, xml_string)
129
+ else:
130
+ print(f"Could not get record id {id} from CKAN")
131
+
132
+
@@ -1 +1 @@
1
- from .workflow import single_run_workflow, batch_run_workflow
1
+ from .workflow import single_run_workflow_async, batch_run_workflow, single_run_workflow