Commit 7091ec4c authored by Jorge Moratinos's avatar Jorge Moratinos
Browse files

Merge branch 'OCF173-create-ccfid-on-deployment-helper-component' into 'staging'

Resolve "Create ccfId on deployment (Helper component)"

Closes #173

See merge request !158
parents 8f14cd62 535cb602
Loading
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -191,3 +191,9 @@ def remove_config_category():
        return jsonify(message="Missing 'category_name' in request body"), 400

    return helper_operation.remove_config_category(category_name)


@helper_routes.route("/helper/getCcfId", methods=["GET"])
def get_ccf_id():
    """Returns the current CAPIF ccfId"""
    return helper_operation.get_ccf_id()
+46 −10
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ from utils.utils import (

class HelperOperations:

    PROTECTED_FIELDS = ["ccf_id"]

    def __init__(self):
        self.db = MongoDatabse()
        self.mimetype = 'application/json'
@@ -228,6 +230,10 @@ class HelperOperations:
        """
        current_app.logger.debug(f"Updating configuration parameter: {param_path} with value: {new_value}")

        # Protect immutable fields
        if any(param_path.startswith(field) for field in self.PROTECTED_FIELDS):
            return jsonify(message=f"The parameter '{param_path}' is immutable and cannot be modified"), 403

        config_col = self.db.get_col_by_name(self.db.capif_configuration)

        existing_config = config_col.find_one({}, {"_id": 0})
@@ -251,9 +257,6 @@ class HelperOperations:
    
    
    def replace_configuration(self, new_config):
        """
        Replace all current settings with a new one.
        """
        current_app.logger.debug("Replacing entire CAPIF configuration")

        error_response = validate_snake_case_keys(new_config)
@@ -263,16 +266,18 @@ class HelperOperations:
        config_col = self.db.get_col_by_name(self.db.capif_configuration)
        existing_config = config_col.find_one({}, {"_id": 0})

        if existing_config:
            new_config = convert_nested_values(new_config, existing_config)
        if not existing_config:
            return jsonify(message="No existing configuration found"), 404

        result = config_col.replace_one({}, new_config, upsert=True)
        # Preserve protected fields
        for field in self.PROTECTED_FIELDS:
            if field in existing_config:
                new_config[field] = existing_config[field]

        if result.matched_count == 0:
            return jsonify(message="No existing configuration found; a new one was created"), 201

        return jsonify(message="Configuration replaced successfully"), 200
        new_config = convert_nested_values(new_config, existing_config)
        result = config_col.replace_one({}, new_config, upsert=True)

        return jsonify(message="Configuration replaced successfully (protected fields preserved)"), 200


    def add_new_configuration(self, category_name, category_values):
@@ -281,6 +286,10 @@ class HelperOperations:
        """
        current_app.logger.debug(f"Adding new category: {category_name} with values: {category_values}")

        # Block protected field creation
        if category_name in self.PROTECTED_FIELDS:
            return jsonify(message=f"The category '{category_name}' is immutable and cannot be modified"), 403

        config_col = self.db.get_col_by_name(self.db.capif_configuration)

        category_name_snake = to_snake_case(category_name)
@@ -299,6 +308,11 @@ class HelperOperations:
    def add_new_config_setting(self, param_path, new_value):
        """Add a new parameter in 'settings'."""
        current_app.logger.debug(f"Adding new configuration setting: {param_path} with value: {new_value}")

        # Block protected field creation
        if any(param_path.startswith(field) for field in self.PROTECTED_FIELDS):
            return jsonify(message=f"The parameter '{param_path}' is immutable and cannot be added or modified"), 403
    
        config_col = self.db.get_col_by_name(self.db.capif_configuration)

        param_path_snake = ".".join(to_snake_case(part) for part in param_path.split("."))
@@ -316,6 +330,10 @@ class HelperOperations:
        """Removes a specific parameter inside 'settings'."""
        current_app.logger.debug(f"Removing configuration parameter: {param_path}")

        # Prevent deletion of protected fields
        if any(param_path.startswith(field) for field in self.PROTECTED_FIELDS):
            return jsonify(message=f"The parameter '{param_path}' is immutable and cannot be removed"), 403

        config_col = self.db.get_col_by_name(self.db.capif_configuration)

        param_path_snake = ".".join(to_snake_case(part) for part in param_path.split("."))
@@ -334,6 +352,10 @@ class HelperOperations:
        """Removes an entire category inside 'settings'."""
        current_app.logger.debug(f"Removing configuration category: {category_name}")

        # Prevent deletion of protected fields
        if category_name in self.PROTECTED_FIELDS:
            return jsonify(message=f"The category '{category_name}' is immutable and cannot be removed"), 403

        config_col = self.db.get_col_by_name(self.db.capif_configuration)

        category_name_snake = to_snake_case(category_name)
@@ -346,3 +368,17 @@ class HelperOperations:
            return jsonify(message=f"No configuration found or category '{category_name_snake}' not removed"), 404

        return jsonify(message=f"Category '{category_name_snake}' removed successfully"), 200
    
    def get_ccf_id(self):
        """
        Returns the current CAPIF unique identifier (ccf_id).
        """
        current_app.logger.debug("Retrieving ccf_id from capif_configuration")

        config_col = self.db.get_col_by_name(self.db.capif_configuration)
        config = config_col.find_one({}, {"_id": 0, "ccf_id": 1})

        if not config or "ccf_id" not in config:
            return jsonify(message="ccf_id not found"), 404

        return jsonify(ccf_id=config["ccf_id"]), 200
+16 −2
Original line number Diff line number Diff line
import time
import secrets

from bson.codec_options import CodecOptions
from config import Config
@@ -59,8 +60,21 @@ class MongoDatabse():
            # Read configuration from config.yaml
            default_config = self.config["capif_configuration"]

            # Generate unique ccf_id
            ccf_id = "CCF" + secrets.token_hex(15)
            default_config["ccf_id"] = ccf_id

            capif_col.insert_one(default_config)
            print("Default data inserted into the capif_configuration collection from config.yaml")
            print(f"Default data inserted into capif_configuration from config.yaml with ccf_id={ccf_id}")

        else:
            print("The capif_configuration collection already contains data. No default values were inserted.")
            # Ensure ccf_id exists even if config already there
            existing_config = capif_col.find_one({}, {"_id": 0})
            if "ccf_id" not in existing_config:
                ccf_id = "CCF" + secrets.token_hex(15)
                capif_col.update_one({}, {"$set": {"ccf_id": ccf_id}})
                print(f"Added missing ccf_id={ccf_id} to existing CAPIF configuration")
            else:
                print("Capif_configuration already contains data with a unique ccf_id. No default values inserted.")