diff --git a/README.md b/README.md index 5d9b2b669b73c481255bb57cc13603697defed29..42edb3686e0a924e310b9081eafe10ded5a6750d 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ Current version of OpenCAPIF SDK is compatible with following publicly available # Table of Contents 1. [NetApp developers](#netapp-developers) 2. [OpenCAPIF SDK summary](#opencapif-sdk-summary) - 3. [NetApp developer path](#netapp-developer-path) - 4. [OpenCAPIF SDK requirements](./doc/sdk-prerequirements.md) - 5. [OpenCAPIF SDK Installation](./doc/sdk-installation.md) - 6. [OpenCAPIF SDK Configuration](./doc/sdk-configuration.md) - 7. [OpenCAPIF SDK Usage](./doc/sdk-usage.md) - 8. [OpenCAPIF SDK known issues](./doc/sdk-issues.md) + 3. [OpenCAPIF SDK requirements](#opencapif-sdk-requirements) + 4. [NetApp developer path](#netapp-developer-path) + 5. [OpenCAPIF SDK Configuration](./doc/sdk-configuration.md) + 6. [OpenCAPIF SDK Usage](./doc/sdk-usage.md) + 7. [OpenCAPIF SDK known issues](./doc/sdk-issues.md) + 8. [OpenCAPIF SDK Developers](./doc/sdk-installation.md) # NetApp developers @@ -63,7 +63,12 @@ NOTE: Above mentioned CAPIF APIs are defined in these 3GPP references: - [CAPIF Publish API specification](https://github.com/jdegre/5GC_APIs/blob/Rel-18/TS29222_CAPIF_Publish_Service_API.yaml) - [CAPIF Security API specification](https://github.com/jdegre/5GC_APIs/blob/Rel-18/TS29222_CAPIF_Security_API.yaml) -### Invoker NetApp +## OpenCAPIF SDK requirements + +In order to leverage OpenCAPIF SDK it is required to have registered a user in the target CAPIF instance, so contact administrator to have required predefined credentials (username and password). + + +## Invoker NetApp A NetApp development running as an Invoker would usually follow this process step by step making use of SDK: @@ -105,15 +110,15 @@ Then all information for using the available APIs would be at Capif_api_security This file would be placed in the invoker_folder path, more specifically in the folder that corresponds of the capif_username used in the config_file. -Here is a sample of this [file](./samples/capif_api_security_context_details-sample.json) +Here is a sample of this Capif_api_security_context_details [file](./samples/capif_api_security_context_details-sample.json) -Here is a sample of the implementation of these [functionality](./netapp-samples/netapp-invoker-sample/netapp-invoker.py) +Here is a code sample of the implementation of this hole [functionality](./netapp-samples/netapp-invoker-sample/netapp-invoker.py) This image highlights Invoker path using SDK code:  -### Provider NetApp +## Provider NetApp A NetApp development running as a Provider would typically follow this process step by step, making use of the SDK: @@ -132,7 +137,7 @@ A NetApp development running as a Provider would typically follow this process s ``` 3. **Prepare API details:** \ - Locate the provider API details in the username folder. Choose the APF (Application Programming Function) and AEFs (Application Enabling Functions) identifiers, and fulfill the publish_req structure and the api_description_path: + Locate the provider API details in the provider_folder path, more specifically in the username folder. Choose the APF (Application Programming Function) and AEFs (Application Enabling Functions) identifiers, and fulfill the publish_req structure and the api_description_path: <p align="center"> <img src="./doc/images/capif-provider-details-example.png" alt="example" width="400"/> @@ -140,13 +145,14 @@ A NetApp development running as a Provider would typically follow this process s </p> 4. **Publish the services:** \ - Use the publish_services() method to register the APIs with the CAPIF framework: + Use the publish_services() method to register the APIs with the CAPIF framework(don't forget to update the CAPIFProviderConnector constructor in order to use the new APF and AEFs): ```python + provider = CAPIFProviderConnector(config_file=utilities.get_config_file()) provider.publish_services() ``` -Here is a sample of the implementation of these [functionality](./netapp-samples/netapp-provider-sample/netapp-provider.py) +Here is a sample of the implementation of this hole [functionality](./netapp-samples/netapp-provider-sample/netapp-provider.py) This image highlights Provider path using SDK code: diff --git a/doc/sdk-configuration.md b/doc/sdk-configuration.md index 346f24103368d08434e6e124032bbce64cf217a2..b9ff630cec3eadd382909b8f4f8c9838022cbb7c 100644 --- a/doc/sdk-configuration.md +++ b/doc/sdk-configuration.md @@ -2,8 +2,6 @@ Before configuration it's needed to have completed the [requirements](./sdk-prerequirements.md) section and the [installation](./sdk-installation.md) section. - - - [Configuration via Config.json](#1-configuration-via-configjson) - [Configuration via Register.json](#configuration-via-registerjson) diff --git a/doc/sdk-installation.md b/doc/sdk-installation.md index 08c9ee75d986005f6123ea72b2a083422338203e..56ddc05ee92e201bf85981f1dd9b60dc97f99bf6 100644 --- a/doc/sdk-installation.md +++ b/doc/sdk-installation.md @@ -1,15 +1,13 @@ -# OpenCAPIF SDK installation +# OpenCAPIF SDK development environment installation -Before installation it's needed to have completed the [requirements](sdk-prerequirements.md) section. +Before installation it's needed to have completed the [requirements](../README.md) section. -## OpenCAPIF SDK consumer installation - -SOON - -## OpenCAPIF SDK development environment installation Follow next steps to perform OpenCAPIF SDK installation: +- For developers installation is mandatory to have already installed: + - pyenv + 1. Create an enviroment with pyenv ```console diff --git a/doc/sdk-usage.md b/doc/sdk-usage.md index 2d745e0862926097617b8c72a4fe955b2e10f719..bd42b585346e9d362f4ee82f77ca6a23d1ade8c6 100644 --- a/doc/sdk-usage.md +++ b/doc/sdk-usage.md @@ -28,17 +28,17 @@ CAPIF is designed to use using two different roles: - [As an Invoker](#as-an-invoker) - [Onboard Invoker](#onboard_invoker--script-invoker_capif_connectorpy) - [Discover API](#discover--script-invoker_service_discoverpy) - - [Get Tokens](#get-tokens--script-invoker_service_get_tokenpy) - - [Update and Offboard Invoker](#update-and-offboard-invoker--scripts-invoker_capif_connector_updatepy-and-invoker_capif_connector_offboardingpy) + - [Get Tokens](#get_tokens--script-invoker_service_get_tokenpy) + - [Update and Offboard Invoker](#update_invoker-and-offboard_and_deregister_invoker--invoker_capif_connector_updatepy-and-invoker_capif_connector_offboardingpy) - [Important Information for Invoker](#important-information-for-invoker-consumer) -- [As a Provider](#as-a-provider) - - [Onboard Provider](#onboard-provider--script-provider_capif_connectorpy) - - [Publish Services](#publish-services--script-provider_publish_apipy) - - [Unpublish Services](#unpublish-services--script-provider_unpublish_apipy) - - [Update Services](#update-services--script-provider_update_apipy) - - [Get Published Services](#get-published-services--script-provider_get_published_apipy) - - [Get All Published Services](#get-all-published-services--script-provider_get_all_published_apipy) - - [Update and Offboard Provider](#update-and-offboard-provider--scripts-provider_capif_connector_updatepy-and-provider_capif_connector_offboardingpy) +- [As a Provider](#as-a-proxvider) + - [Onboard Provider](#onboard_provider--script-provider_capif_connectorpy) + - [Publish Services](#publish_services--script-provider_publish_apipy) + - [Unpublish Services](#unpublish_service--script-provider_unpublish_apipy) + - [Update Services](#update_provider-and-offboard_provider--provider_capif_connector_updatepy-and-provider_capif_connector_offboardingpy) + - [Get Published Services](#get_service--script-provider_get_published_apipy) + - [Get All Published Services](#get_all_services--script-provider_get_all_published_apipy) + - [Update and Offboard Provider](#update_provider-and-offboard_provider--provider_capif_connector_updatepy-and-provider_capif_connector_offboardingpy) - [Important Information for Provider](#important-information-for-provider-consumer) - [Other Features](#other-features) - [Register and Login](#script-register_and_loginpy) @@ -81,7 +81,7 @@ In the `invoker_folder`, it will be located several folders with each `capif_use 2. If you have already used the Service Discovery Functionality, you will find all the available APIs with their information. 3. If you have already used the Service Get Token functionality, you will find your access token for using the APIs you have already discovered. -# As an provider +# As a provider The common path to follow using CAPIF in order to publish an API is by following this steps: ### onboard_provider() // Script provider_capif_connector.py diff --git a/scripts/deregister_and_login.py b/scripts/deregister_and_login.py index efaa0902177653fbff38bc58f62660e9e731e238..1e63f9d5bc7fe4267c89b9aacb3650086512ba28 100644 --- a/scripts/deregister_and_login.py +++ b/scripts/deregister_and_login.py @@ -11,76 +11,76 @@ logging.basicConfig( level=logging.INFO, # Nivel mÃnimo de severidad a registrar format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # Formato del mensaje de log handlers=[ - logging.FileHandler("register_logs.log"), # Registra en un archivo + logging.FileHandler("logs/register_logs.log"), # Registra en un archivo logging.StreamHandler() # También muestra en la consola ] ) def main(): - - variables=__load_config_file(config_file=utilities.get_register_file()) + + variables = __load_config_file(config_file=utilities.get_register_file()) log_result = __log_to_capif(variables) admintoken = log_result["access_token"] - de_register_from_capif(admintoken,variables) + de_register_from_capif(admintoken, variables) logger.info("User eliminated succesfully") - + def __log_to_capif(variables): - logger.info("Logging in to CAPIF") - capif_register_url="https://" + variables["register_host"].strip()+ ":" + variables["capif_register_port"] + "/" - try: - url = capif_register_url + "login" - - response = requests.request( - "POST", - url, - headers={"Content-Type": "application/json"}, - auth=HTTPBasicAuth(variables["capif_register_username"], variables["capif_register_password"]), - verify=False, - ) - response.raise_for_status() - response_payload = json.loads(response.text) - logger.info("Logged in to CAPIF successfully") - return response_payload - except Exception as e: - logger.error(f"Error during login to CAPIF: {e}") - raise - -def de_register_from_capif(admin_token,variables): - logger.info("Deleting CAPIF user") - capif_register_url="https://" + variables["register_host"].strip()+ ":" + variables["capif_register_port"] + "/" - - - url = capif_register_url + "deleteUser/" + variables["uuid"] - - headers = { - "Authorization": "Bearer {}".format(admin_token), - "Content-Type": "application/json", - } + logger.info("Logging in to CAPIF") + capif_register_url = "https://" + variables["register_host"].strip() + ":" + variables["capif_register_port"] + "/" + try: + url = capif_register_url + "login" + response = requests.request( - "DELETE", + "POST", url, - headers=headers, - data=None, - verify=False + headers={"Content-Type": "application/json"}, + auth=HTTPBasicAuth(variables["capif_register_username"], variables["capif_register_password"]), + verify=False, ) response.raise_for_status() - logger.info("User deleted") + response_payload = json.loads(response.text) + logger.info("Logged in to CAPIF successfully") + return response_payload + except Exception as e: + logger.error(f"Error during login to CAPIF: {e}") + raise -def __load_config_file(config_file: str): - """Carga el archivo de configuración.""" - try: - with open(config_file, 'r') as file: - return json.load(file) - except FileNotFoundError: - logger.warning(f"Configuration file {config_file} not found. Using defaults or environment variables.") - return {} +def de_register_from_capif(admin_token, variables): + logger.info("Deleting CAPIF user") + capif_register_url = "https://" + variables["register_host"].strip() + ":" + variables["capif_register_port"] + "/" + + url = capif_register_url + "deleteUser/" + variables["uuid"] + + headers = { + "Authorization": "Bearer {}".format(admin_token), + "Content-Type": "application/json", + } + response = requests.request( + "DELETE", + url, + headers=headers, + data=None, + verify=False + ) + response.raise_for_status() + logger.info("User deleted") + + +def __load_config_file(config_file: str): + """Carga el archivo de configuración.""" + try: + with open(config_file, 'r') as file: + return json.load(file) + except FileNotFoundError: + logger.warning(f"Configuration file {config_file} not found. Using defaults or environment variables.") + return {} if __name__ == "__main__": logger = logging.getLogger("CAPIF Register") logger.info("Initializing CAPIF Register") - main() \ No newline at end of file + main() diff --git a/scripts/invoker_capif_connector_offboarding.py b/scripts/invoker_capif_connector_offboarding.py index 38b9a63d35ceb0360a31e6407c243cbcb40749b5..5dd7a8f914c5019f50e5311b825ef7c52cab180d 100755 --- a/scripts/invoker_capif_connector_offboarding.py +++ b/scripts/invoker_capif_connector_offboarding.py @@ -1,5 +1,6 @@ +from sdk import CAPIFInvokerConnector import sys import os import utilities @@ -9,8 +10,7 @@ script_dir = os.path.dirname(os.path.abspath(__file__)) # Directorio actual del sdk_path = os.path.join(script_dir, '..', 'sdk') # Subir un nivel y apuntar a 'sdk' sys.path.insert(0, sdk_path) -# Ahora importa la clase CAPIFProviderConnector desde el archivo sdk.py -from sdk import CAPIFInvokerConnector + def showcase_offboard_and_deregister_invoker(): @@ -21,5 +21,3 @@ def showcase_offboard_and_deregister_invoker(): if __name__ == "__main__": showcase_offboard_and_deregister_invoker() - - diff --git a/scripts/provider_get_all_published_api.py b/scripts/provider_get_all_published_api.py index 5e7b04655cd8aad05a5fa749b258da87bf681bf6..90937b65eec23458e2663fb3c976e32d2d4ae455 100644 --- a/scripts/provider_get_all_published_api.py +++ b/scripts/provider_get_all_published_api.py @@ -1,3 +1,4 @@ +from sdk import CAPIFProviderConnector import sys import os import utilities @@ -8,7 +9,8 @@ sdk_path = os.path.join(script_dir, '..', 'sdk') # Subir un nivel y apuntar a ' sys.path.insert(0, sdk_path) # Ahora importa las clases desde tu archivo sdk.py -from sdk import CAPIFProviderConnector + + def showcase_capif_nef_connector(): """ @@ -18,6 +20,7 @@ def showcase_capif_nef_connector(): capif_connector.get_all_services() print("COMPLETED") + if __name__ == "__main__": - #Let's register a NEF to CAPIF. This should happen exactly once + # Let's register a NEF to CAPIF. This should happen exactly once showcase_capif_nef_connector() diff --git a/scripts/register_and_login.py b/scripts/register_and_login.py index 7cb9e2ca463552146b4a6b26f3a34a8da83b2e3c..0659754e3298cdc895926ac5a7c99189588ee6c0 100644 --- a/scripts/register_and_login.py +++ b/scripts/register_and_login.py @@ -11,84 +11,86 @@ logging.basicConfig( level=logging.INFO, # Nivel mÃnimo de severidad a registrar format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # Formato del mensaje de log handlers=[ - logging.FileHandler("register_logs.log"), # Registra en un archivo + logging.FileHandler("logs/register_logs.log"), # Registra en un archivo logging.StreamHandler() # También muestra en la consola ] ) def main(): - - variables=__load_config_file(config_file=utilities.get_register_file()) + + variables = __load_config_file(config_file=utilities.get_register_file()) log_result = __log_to_capif(variables) admintoken = log_result["access_token"] - postcreation = __create_user(admintoken,variables) + postcreation = __create_user(admintoken, variables) uuid = postcreation["uuid"] logger.info(uuid) + def __log_to_capif(variables): - logger.info("Logging in to CAPIF") - capif_register_url="https://" + variables["register_host"].strip()+ ":" + variables["capif_register_port"] + "/" - try: - url = capif_register_url + "login" + logger.info("Logging in to CAPIF") + capif_register_url = "https://" + variables["register_host"].strip() + ":" + variables["capif_register_port"] + "/" + try: + url = capif_register_url + "login" + + response = requests.request( + "POST", + url, + headers={"Content-Type": "application/json"}, + auth=HTTPBasicAuth(variables["capif_register_username"], variables["capif_register_password"]), + verify=False, + ) + response.raise_for_status() + response_payload = json.loads(response.text) + logger.info("Logged in to CAPIF successfully") + return response_payload + except Exception as e: + logger.error(f"Error during login to CAPIF: {e}") + raise - response = requests.request( - "POST", - url, - headers={"Content-Type": "application/json"}, - auth=HTTPBasicAuth(variables["capif_register_username"], variables["capif_register_password"]), - verify=False, - ) - response.raise_for_status() - response_payload = json.loads(response.text) - logger.info("Logged in to CAPIF successfully") - return response_payload - except Exception as e: - logger.error(f"Error during login to CAPIF: {e}") - raise +def __create_user(admin_token, variables): + logger.info("Creating user in CAPIF") + capif_register_url = "https://" + variables["register_host"].strip() + ":" + variables["capif_register_port"] + "/" + try: + url = capif_register_url + "createUser" + payload = { + "username": variables["capif_username"], + "password": variables["capif_password"], + "description": "description", + "email": "csr_email_address@tid.es", + "enterprise": "csr_organization", + "country": "crs_locality", + "purpose": "SDK for SAFE 6G", + } + headers = { + "Authorization": "Bearer {}".format(admin_token), + "Content-Type": "application/json", + } -def __create_user(admin_token,variables): - logger.info("Creating user in CAPIF") - capif_register_url="https://" + variables["register_host"].strip()+ ":" + variables["capif_register_port"] + "/" - try: - url = capif_register_url + "createUser" - payload = { - "username": variables["capif_username"], - "password": variables["capif_password"], - "description": "description", - "email": "csr_email_address@tid.es", - "enterprise": "csr_organization", - "country": "crs_locality", - "purpose": "SDK for SAFE 6G", - } - headers = { - "Authorization": "Bearer {}".format(admin_token), - "Content-Type": "application/json", - } + response = requests.request( + "POST", url, headers=headers, data=json.dumps(payload), verify=False + ) + response.raise_for_status() + response_payload = json.loads(response.text) + logger.info("User created successfully") + return response_payload + except Exception as e: + logger.error(f"Error during user creation in CAPIF: {e}") + raise - response = requests.request( - "POST", url, headers=headers, data=json.dumps(payload), verify=False - ) - response.raise_for_status() - response_payload = json.loads(response.text) - logger.info("User created successfully") - return response_payload - except Exception as e: - logger.error(f"Error during user creation in CAPIF: {e}") - raise def __load_config_file(config_file: str): - """Carga el archivo de configuración.""" - try: - with open(config_file, 'r') as file: - return json.load(file) - except FileNotFoundError: - logger.warning(f"Configuration file {config_file} not found. Using defaults or environment variables.") - return {} + """Carga el archivo de configuración.""" + try: + with open(config_file, 'r') as file: + return json.load(file) + except FileNotFoundError: + logger.warning(f"Configuration file {config_file} not found. Using defaults or environment variables.") + return {} if __name__ == "__main__": logger = logging.getLogger("CAPIF Register") logger.info("Initializing CAPIF Register") - main() \ No newline at end of file + main()