diff --git a/examples/logan_sources/README.md b/examples/logan_sources/README.md new file mode 100644 index 0000000..0c3cb5b --- /dev/null +++ b/examples/logan_sources/README.md @@ -0,0 +1,24 @@ +## Import custom content after substituting property values + +This example is to import custom contents from the content path provided as input. It iterates over each content xml listed in the content path and substitute the property name with value from schema_names map and then imports the custom contents. + +Rename the provider.tf.example to provider.tf and provide the required values + +Also rename the terraform.tfvars.example to terraform.tfvars and provide products value as a comma separated product names string. And property name value map in schema_names as shown in the example. + +Make sure that the configuration file is placed at default location(~/.oci/) by populating the user and tenancy details as follows +```console +[DEFAULT] +user= +fingerprint= +key_file= +tenancy= +region= +``` + +Run the terraform commands to execute +```console +terraform init +terraform plan +terraform apply +``` diff --git a/examples/logan_sources/contents/sources/Oracle Adv1/src11.xml b/examples/logan_sources/contents/sources/Oracle Adv1/src11.xml new file mode 100644 index 0000000..a846025 --- /dev/null +++ b/examples/logan_sources/contents/sources/Oracle Adv1/src11.xml @@ -0,0 +1,110 @@ + + + + #Backend Status Code + Shows a response code received from the backend + 1 + 0 + 1 + INTEGER + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + os_file + + omc_host_linux + + mvTestSrc1 + 0 + 1 + + + /{SCHEMA2}/var/{SCHEMA1}/access_log11 + 1 + 1 + 0 + 1 + + + + + 1 + host_httpdaccesslog_logtype + + + + + udfi1 + 0 + 1 + + + accmask + 0 + 1 + + + + + + select + + + actnstart + + 0 + 1 + + + + + + method + + + continentclnt + countrycodeclnt + geolocclnt + continentcodeclnt + cityclnt + countryclnt + regioncodeclnt + regionclnt + + + + Geolocation + + + 0 + 1 + + + 0 + 0 + + + test2 + 1.0 + 1 + 0 + + + + + + udfi1 + #Backend Status Code + + + diff --git a/examples/logan_sources/contents/sources/Oracle Adv1/src12.xml b/examples/logan_sources/contents/sources/Oracle Adv1/src12.xml new file mode 100644 index 0000000..58b197c --- /dev/null +++ b/examples/logan_sources/contents/sources/Oracle Adv1/src12.xml @@ -0,0 +1,29 @@ + + + + os_file + + omc_host_linux + + mvTestSrc2 + 0 + 1 + + + /{SCHEMA1}/var/{SCHEMA2}/tmp/access_log22 + 1 + 1 + 0 + 1 + + + + + 1 + host_httpdaccesslog_logtype + + + 0 + 0 + + diff --git a/examples/logan_sources/contents/sources/Oracle Asts1/src21.xml b/examples/logan_sources/contents/sources/Oracle Asts1/src21.xml new file mode 100644 index 0000000..a846025 --- /dev/null +++ b/examples/logan_sources/contents/sources/Oracle Asts1/src21.xml @@ -0,0 +1,110 @@ + + + + #Backend Status Code + Shows a response code received from the backend + 1 + 0 + 1 + INTEGER + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + os_file + + omc_host_linux + + mvTestSrc1 + 0 + 1 + + + /{SCHEMA2}/var/{SCHEMA1}/access_log11 + 1 + 1 + 0 + 1 + + + + + 1 + host_httpdaccesslog_logtype + + + + + udfi1 + 0 + 1 + + + accmask + 0 + 1 + + + + + + select + + + actnstart + + 0 + 1 + + + + + + method + + + continentclnt + countrycodeclnt + geolocclnt + continentcodeclnt + cityclnt + countryclnt + regioncodeclnt + regionclnt + + + + Geolocation + + + 0 + 1 + + + 0 + 0 + + + test2 + 1.0 + 1 + 0 + + + + + + udfi1 + #Backend Status Code + + + diff --git a/examples/logan_sources/contents/sources/Oracle Asts1/src22.xml b/examples/logan_sources/contents/sources/Oracle Asts1/src22.xml new file mode 100644 index 0000000..58b197c --- /dev/null +++ b/examples/logan_sources/contents/sources/Oracle Asts1/src22.xml @@ -0,0 +1,29 @@ + + + + os_file + + omc_host_linux + + mvTestSrc2 + 0 + 1 + + + /{SCHEMA1}/var/{SCHEMA2}/tmp/access_log22 + 1 + 1 + 0 + 1 + + + + + 1 + host_httpdaccesslog_logtype + + + 0 + 0 + + diff --git a/examples/logan_sources/main.tf b/examples/logan_sources/main.tf new file mode 100644 index 0000000..d7c5342 --- /dev/null +++ b/examples/logan_sources/main.tf @@ -0,0 +1,9 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +module "logan_sources" { + source = "../../modules/logan_sources" + schema_names = var.schema_names + for_each = toset(split(",", var.products)) + path = format("%s/%s", "./contents/sources", each.value) +} diff --git a/examples/logan_sources/provider.tf.example b/examples/logan_sources/provider.tf.example new file mode 100644 index 0000000..f6cf7cf --- /dev/null +++ b/examples/logan_sources/provider.tf.example @@ -0,0 +1,22 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +provider "oci" { + region = "" + fingerprint = "" + private_key_path = "" + + tenancy_ocid = "" + user_ocid = "" + +} + +terraform { + required_providers { + oci = { + source = "oracle/oci" + version = ">= 4.67.3" + } + } + required_version = ">= 1.3.0" +} diff --git a/examples/logan_sources/terraform.tfvars.example b/examples/logan_sources/terraform.tfvars.example new file mode 100644 index 0000000..040110e --- /dev/null +++ b/examples/logan_sources/terraform.tfvars.example @@ -0,0 +1,8 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +products="Oracle Adv1,Oracle Asts1" +schema_names={ + "{SCHEMA1}" = "ABC" + "{SCHEMA2}" = "XYZ" + } diff --git a/examples/logan_sources/variables.tf b/examples/logan_sources/variables.tf new file mode 100644 index 0000000..2223f28 --- /dev/null +++ b/examples/logan_sources/variables.tf @@ -0,0 +1,21 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "config_file_profile" { + default = "DEFAULT" +} + +variable "auth_type" { + default = "user" +} + +variable "products" { + type = string +} + +variable "schema_names" { + type = map + default = { + "abc" = "xyz" + } +} diff --git a/modules/logan_sources/README.md b/modules/logan_sources/README.md new file mode 100644 index 0000000..f528594 --- /dev/null +++ b/modules/logan_sources/README.md @@ -0,0 +1,34 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [oci](#requirement\_oci) | >= 4.67.3 | + +## Providers + +| Name | Version | +|------|---------| +| [oci](#provider\_oci) | >= 4.67.3 | +| [oci.home](#provider\_oci.home) | >= 4.67.3 | + +## Modules + +No modules. + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [path](#input\_content\_path) | Custom Sources Content Path | `string` | n/a | yes | +| [schema_names](#input\_schema\_names) | Properties Name Value Map to be used for substitution | `map` | n/a | yes | + +## Outputs + +No outputs. + diff --git a/modules/logan_sources/main.tf b/modules/logan_sources/main.tf new file mode 100644 index 0000000..e02c1ef --- /dev/null +++ b/modules/logan_sources/main.tf @@ -0,0 +1,17 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Import custom content after property values are substituted +resource null_resource import_contents { + triggers = { + auth_type = "user" + profile_name = "test" + schema_names = format("%q", jsonencode(var.schema_names)) + path = format("%q", var.path) + current_time = timestamp() + } + + provisioner "local-exec" { + command = "python3 ../../scripts/import_contents.py -a ${self.triggers.auth_type} -p ${self.triggers.profile_name} -e ${self.triggers.schema_names} -f ${self.triggers.path}" + } +} diff --git a/modules/logan_sources/variables.tf b/modules/logan_sources/variables.tf new file mode 100644 index 0000000..0cbf4ce --- /dev/null +++ b/modules/logan_sources/variables.tf @@ -0,0 +1,9 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "path" { + type = string +} +variable "schema_names" { + type = map +} diff --git a/scripts/import_contents.py b/scripts/import_contents.py new file mode 100644 index 0000000..35a019f --- /dev/null +++ b/scripts/import_contents.py @@ -0,0 +1,111 @@ +#Copyright (c) 2023 Oracle Corporation and/or its affiliates. +#Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +import oci +import os,glob +import sys, getopt +import json +import time +import xml.etree.ElementTree as ET +from zipfile import ZipFile +import random + +def main(argv): + try: + options, args = getopt.getopt(argv, "h:a:p:e:f:", + ["authtype =", + "profile =", + "entityprops =", + "filepath ="]) + print('options: ', options) + print('args: ', args) + except: + print("Error Message ") + + entityprops = '' + filepath = '' + authType = 'user' + profile = '' + for name, value in options: + if name in ['-a', '--authtype']: + authType = value + elif name in ['-p', '--profile']: + profile = value + elif name in ['-e', '--entityprops']: + entityprops = value + elif name in ['-f', '--filepath']: + filepath = value + + try: + if (not filepath): + print ("Error: Source filepath is empty!") + return + if filepath.startswith('"') and filepath.endswith('"'): + filepath = filepath[1:-1] + + print("######################### Content Details ######################") + print("authtype :: ", authType) + print("profile :: ", profile) + print("entityprops :: ", entityprops) + print("filepath :: ", filepath) + + config = oci.config.from_file() + la_client = oci.log_analytics.LogAnalyticsClient(config=config) + object_storage_client = oci.object_storage.ObjectStorageClient(config=config) + + namespace = object_storage_client.get_namespace().data + print("Tenancy NameSpace :: ", namespace) + + substituteprops(filepath, entityprops) + + for zip_file in glob.glob(os.path.join(filepath, '*.zip')): + print('zip_file ::', zip_file) + + bytes_content = b'' + with open(zip_file, 'rb') as file_data: + bytes_content = file_data.read() + + response = la_client.import_custom_content( + namespace_name=namespace, + import_custom_content_file_body=bytes_content, + is_overwrite=True) + + print("import response:: ", response.headers) + + except Exception as e: + print("Error in importing sources: ",e) + raise + +def substituteprops(filepath, entityprops): + content_dir = filepath + print("content_dir :: ", content_dir) + + dict = json.loads(entityprops) + #for key, value in dict.items(): + # print(key+" "+ str(value)) + + tmpfile = 'content' + str(random.randint(0,999999)) + '.xml' + for content_file in glob.glob(os.path.join(content_dir, '*.xml')): + print('content_file ::', content_file) + + with open(content_file) as f: + tree = ET.parse(f) + root = tree.getroot() + + for elem in root.getiterator(): + try: + for key, value in dict.items(): + elem.text = elem.text.replace(key, value) + except AttributeError: + pass + + tree.write(tmpfile) + + with ZipFile(content_file + '.zip', 'w') as zip_object: + zip_object.write(tmpfile) + + tmpfilepath = os.path.join('.', tmpfile) + os.remove(tmpfilepath) + +if __name__ == "__main__": + main(sys.argv[1:])