Script File to Create Policies for Autoscaling Functions Post Provisioning
Use the script file to create policies for autoscaling functions after creating the Oracle WebLogic Server for OCI domain.
If the OCI Policies check box is not selected during
domain creation (create_policies
set to false
), you
can use the script file to create function's dynamic group and policies after creating
the domain. The script verifies if the stack has create_policies
set to
false
, in which case it returns an error that policies would be
automatically created via stack. However, you can use the --force
option to override and create dynamic group and policies when create_policies ==
true
.
create_autoscaling_policies.py
Note:
For instructions on how to use the script to create function's dynamic group and policies, see Dynamic Group Policies for Autoscaling.After you run the script, you must enable alarms from the Oracle Cloud Infrastructure console. See To enable an alarm in Oracle Cloud Infrastructure documentation.
"""
#
# Copyright (c) 2022, 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 argparse
import logging
import oci
import os
import sys
import textwrap
from oci.identity import models as identity_models
logger = logging.getLogger()
logging.basicConfig()
REGION = ''
def get_config():
if REGION != '':
return {"region": REGION}
return {}
def get_variable(variables, name, default=None):
"""
First read from stack variables
If not found and default provided, return default
:param variables:
:param name:
:param default:
:return:
"""
ret = None
found = True
if name in variables:
ret = variables.get(name)
else:
if default is not None:
return default
else:
logger.info("ERROR: value for the variable [%s] could not be found!" % (name))
found = False
if found:
logger.debug("Value of variable [%s] is [%s]" % (name, ret))
return ret
def inspect_stack(signer, stack_ocid):
client = oci.resource_manager.ResourceManagerClient(config=get_config(), signer=signer)
try:
stack = client.get_stack(stack_id=stack_ocid)
except(Exception, ValueError) as ex:
logger.exception("ERROR: accessing resource manager stack failed")
raise
resp = stack.data
return resp
def create_functions_dynamic_group(signer, stack_compartment_id, tenancy_id, service_name):
"""
Creates functions dynamic group in root compartment.
:param signer:
:param stack_compartment_id:
:param tenancy_id:
:param service_name:
:return:
"""
client = oci.identity.IdentityClient(config={}, signer=signer)
client_composite_ops = oci.identity.IdentityClientCompositeOperations(client)
dg_name = "{0}-functions-dynamic-group-manual".format(service_name)
try:
create_dynamicgrp_resp = client_composite_ops.create_dynamic_group_and_wait_for_state(
create_dynamic_group_details=identity_models.CreateDynamicGroupDetails(
compartment_id=tenancy_id,
description="Autoscaling Functions Dynamic Group of stack: {0}".format(service_name),
matching_rule="All {resource.type = 'fnfunc', "
"resource.compartment.id='%s'}" % (stack_compartment_id),
name=dg_name
),
wait_for_states=[identity_models.DynamicGroup.LIFECYCLE_STATE_ACTIVE]
)
except(Exception, ValueError) as ex:
logger.exception("Failed to create functions dynamic group {0}".format(dg_name))
raise
return create_dynamicgrp_resp.data
def create_policies_for_functions_dynamic_group(signer, stack_compartment_id, tenancy_id, service_name,
network_compartment_id,
apm_domain_compartment_id=None,
atp_db_compartment_id=None,
ocidb_compartment_id=None,
app_atp_db_compartment_id=None,
app_ocidb_compartment_id=None,
fss_compartment_id=None):
"""
Creates policies for functions dynamic group.
:param signer:
:param stack_compartment_id:
:param tenancy_id:
:param service_name:
:param network_compartment_id:
:param apm_domain_compartment_id:
:param atp_db_compartment_id:
:param ocidb_compartment_id:
:param app_atp_db_compartment_id:
:param app_ocidb_compartment_id:
:param fss_compartment_id:
:return:
"""
client = oci.identity.IdentityClient(config={}, signer=signer)
client_composite_ops = oci.identity.IdentityClientCompositeOperations(client)
dg_name = "{0}-functions-dynamic-group-manual".format(service_name)
try:
policies = [
"Allow dynamic-group {0} to inspect tenancies in tenancy".format(dg_name),
"Allow dynamic-group {0} to inspect limits in tenancy".format(dg_name),
"Allow dynamic-group {0} to manage volume-family in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to manage instance-family in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to use app-catalog-listing in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to manage virtual-network-family in compartment id {1}".format(dg_name,
network_compartment_id),
"Allow dynamic-group {0} to manage load-balancers in compartment id {1}".format(dg_name,
network_compartment_id),
"Allow dynamic-group {0} to manage orm-family in compartment id {1}".format(dg_name, stack_compartment_id),
"Allow dynamic-group {0} to read metrics in compartment id {1}".format(dg_name, stack_compartment_id),
"Allow dynamic-group {0} to manage repos in tenancy".format(dg_name),
"Allow dynamic-group {0} to manage functions-family in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to manage ons-topics in compartment id {1}".format(dg_name, stack_compartment_id),
"Allow dynamic-group {0} to manage instance-agent-command-family in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to manage alarms in compartment id {1}".format(dg_name, stack_compartment_id),
"Allow dynamic-group {0} to manage log-groups in compartment id {1}".format(dg_name, stack_compartment_id),
"Allow dynamic-group {0} to manage unified-configuration in compartment id {1}".format(dg_name,
stack_compartment_id),
"Allow dynamic-group {0} to inspect dynamic-groups in tenancy".format(dg_name),
"Allow dynamic-group {0} to manage policies in tenancy".format(dg_name),
"Allow dynamic-group {0} to use tag-namespaces in tenancy".format(dg_name)
]
if apm_domain_compartment_id is not None:
policies.append("Allow dynamic-group {0} to use apm-domains in compartment id {1}".format(dg_name,
apm_domain_compartment_id))
if atp_db_compartment_id is not None:
policies.append(
"Allow dynamic-group {0} to inspect autonomous-transaction-processing-family in compartment id {1}".format(
dg_name,
atp_db_compartment_id))
if ocidb_compartment_id is not None:
policies.append("Allow dynamic-group {0} to inspect database-family in compartment id {1}".format(dg_name,
ocidb_compartment_id))
if app_ocidb_compartment_id is not None:
policies.append("Allow dynamic-group {0} to inspect database-family in compartment id {1}".format(dg_name,
app_ocidb_compartment_id))
if app_atp_db_compartment_id is not None:
policies.append(
"Allow dynamic-group {0} to use autonomous-transaction-processing-family in compartment id {1}".format(
dg_name,
app_atp_db_compartment_id))
if fss_compartment_id is not None:
policies.append("Allow dynamic-group {0} to manage mount-targets in compartment id {1}".format(dg_name,
fss_compartment_id))
policies.append("Allow dynamic-group {0} to manage file-systems in compartment id {1}".format(dg_name,
fss_compartment_id))
policies.append("Allow dynamic-group {0} to manage export-sets in compartment id {1}".format(dg_name,
fss_compartment_id))
create_policy_resp = client_composite_ops.create_policy_and_wait_for_state(
create_policy_details=identity_models.CreatePolicyDetails(
compartment_id=tenancy_id,
description="Policy for Autoscaling Functions Dynamic Group of stack: {0}".format(service_name),
statements=policies,
name="{0}-wlsc-policy-manual".format(service_name)
),
wait_for_states=[identity_models.Policy.LIFECYCLE_STATE_ACTIVE]
)
except(Exception, ValueError) as ex:
logger.exception("Failed to create policies for functions dynamic group {0}".format(dg_name))
raise
return create_policy_resp.data
def get_apm_compartment_id(signer, apm_domain_id):
client = oci.apm_control_plane.ApmDomainClient(config=get_config(), signer=signer)
try:
resp = client.get_apm_domain(apm_domain_id)
except(Exception, ValueError) as ex:
logger.exception("Failed to get compartment for APM domain ID [{0}]".format(apm_domain_id))
raise
apm_domain = resp.data
return apm_domain.compartment_id
def main():
signer = None
# delegate token should be present at /etc/oci/delegation_token in cloud shell
if os.path.exists('/etc/oci/delegation_token'):
with open('/etc/oci/delegation_token', 'r') as file:
delegation_token = file.read()
signer = oci.auth.signers.InstancePrincipalsDelegationTokenSigner(delegation_token=delegation_token)
else:
logger.error("In the Cloud shell the delegation token does not exist at location /etc/oci/delegation_token. "
"Run the script from the Cloud shell, where you need to delete the resources.")
sys.exit(1)
if signer is None:
logger.error('Instance principal signer is not initialized')
sys.exit(1)
parser = argparse.ArgumentParser(description=textwrap.dedent('''
This script creates Functions Dynamic Group and Policies for Autoscaling.
'''), formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('stack_ocid', help='Stack OCID')
parser.add_argument('-r', '--region', default='', help='Region other than home region must be specified.')
parser.add_argument('-d', '--debug', action='store_const', const=True, help='Enable Debug')
parser.add_argument('-f', '--force', action='store_const', const=True, help='Force creation of dynamic group and '
'policies')
args = parser.parse_args()
stack_ocid = args.stack_ocid
global REGION
REGION = args.region
debug = args.debug
if debug:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
force = args.force
# Get stack variables
resp = inspect_stack(signer, stack_ocid)
logger.debug(resp)
variables = resp.variables
create_policies = get_variable(variables, 'create_policies', "true")
if create_policies == 'true':
if not force:
logger.error('Stack has create_policies enabled so manual creation of autoscaling functions dynamic group '
'and policies is not required. Bailing out!')
return
else:
logger.warning('Stack has create_policies enabled so manual creation of autoscaling functions dynamic '
'group and policies is not required.')
stack_compartment_id = get_variable(variables, 'compartment_ocid')
tenancy_id = get_variable(variables, 'tenancy_ocid')
service_name = get_variable(variables, 'service_name')
# create functions dynamic group
create_functions_dynamic_group(signer, stack_compartment_id, tenancy_id, service_name)
# create policies for the functions dynamic group
apm_domain_id = get_variable(variables, 'apm_domain_id', "")
atp_db_id = get_variable(variables, "atp_db_id", "")
ocidb_dbsystem_id = get_variable(variables, "ocidb_dbsystem_id", "")
app_atp_db_id = get_variable(variables, "app_atp_db_id", "")
appdb_dbsystem_id = get_variable(variables, "appdb_dbsystem_id", "")
add_fss = get_variable(variables, "add_fss", "false")
network_compartment_id = get_variable(variables, 'network_compartment_id', stack_compartment_id)
apm_domain_compartment_id = get_apm_compartment_id(signer, apm_domain_id) if apm_domain_id != '' else None
atp_db_compartment_id = get_variable(variables, 'atp_db_compartment_id',
stack_compartment_id) if atp_db_id != '' else None
ocidb_compartment_id = get_variable(variables, 'ocidb_compartment_id',
stack_compartment_id) if ocidb_dbsystem_id != '' else None
app_atp_db_compartment_id = get_variable(variables, 'app_atp_db_compartment_id',
stack_compartment_id) if app_atp_db_id != '' else None
app_ocidb_compartment_id = get_variable(variables, 'app_ocidb_compartment_id',
stack_compartment_id) if appdb_dbsystem_id != '' else None
fss_compartment_id = get_variable(variables, 'fss_compartment_id',
stack_compartment_id) if add_fss == 'true' else None
create_policies_for_functions_dynamic_group(signer, stack_compartment_id, tenancy_id, service_name,
network_compartment_id, apm_domain_compartment_id,
atp_db_compartment_id,
ocidb_compartment_id,
app_atp_db_compartment_id,
app_ocidb_compartment_id,
fss_compartment_id)
if __name__ == '__main__':
main()