Scenario C: Filing Jira Tickets for Reminders

Automatically file a Jira ticket whenever a maintenance reminder event occurs. In this scenario, whenever a reminder for upcoming database maintenance comes from Oracle Cloud Infrastructure, a Jira ticket is created for the on-call engineer.

This scenario involves writing a function to file Jira tickets (and creating a secret to store Jira credentials), adding that function and optional email as subscriptions  to a topic , and creating a rule that sends messages to that topic when maintenance reminder events occur (see Autonomous Container Database Event Types ). The message fans out to the topic's subscriptions, which includes a group email address in addition to the function. The function is invoked on receipt of the message.

Everything but the function can be set up in the Console. Alternatively, you can use the Oracle Cloud Infrastructure CLI or API, which lets you run the individual operations yourself.

Note

The Notifications service has no information about a function after it's invoked. For details, see the troubleshooting information in Function Not Invoked or Run.

This image shows Notifications in the context of a scenario that uses a function to file Jira tickets when reminder events occur.

For more information about this scenario, see Automated Jira Ticketing using OCI Events, Notifications, and Functions and the associated GitHub repository.

Required IAM Policy

To use Oracle Cloud Infrastructure, you must be granted security access in a policy  by an administrator. This access is required whether you're using the Console or the REST API with an SDK, CLI, or other tool. If you get a message that you don’t have permission or are unauthorized, verify with your administrator what type of access you have and which compartment  to work in.

If you're a member of the Administrators group, you already have the required access to execute this scenario. Otherwise, you need access to Events, Notifications, and Functions. You must have FN_INVOCATION permission against the function to be able to add the function as a subscription to a topic. To access your Jira credentials, the function must be authorized to read secrets. This scenario walks through steps to provide this authorization.

Task 1: Store Credentials in a Secret

For more information about creating secrets using the Vault service, see Creating a Secret in a Vault.

    1. Open the navigation menu, click Identity & Security, and then click Vault.
    2. Under List Scope, in the Compartment list, click the name of the compartment where you want to create a secret.
    3. From the list of vaults in the compartment, do one of the following:

      • Click the name of the vault where you want to create a secret.

      • Create a new vault for the secret by following the instructions in To create a new vault, and then click the name of the vault.

    4. Click Secrets, and then click Create Secret.
    5. In the Create Secret panel, choose a compartment from the Create in Compartment list. (Secrets can exist outside the compartment the vault is in.)
    6. Enter a Name to identify the secret. Avoid entering confidential information.

      Example name: jira_auth_plain_text

    7. Enter a brief Description of the secret to help identify it. Avoid entering confidential information.

      Example description: jira_auth_plain_text

    8. Choose the master encryption key that you want to use to encrypt the secret contents while they're imported to the vault. (The key must belong to the same vault.)
    9. For Secret Type Template, select Plain-Text.
    10. For Secret Contents, enter your Jira credentials in the following format, with a colon separating your login email from your auth token:

      <your-jira-cloud-login-email>:<your-jira-cloud-auth-token>

    11. Click Create Secret.
    12. Note the secret OCID  for use in your function code to securely fetch the secret.
  • Note

    You must specify a symmetric key to encrypt the secret during import to the vault. You cannot encrypt secrets with asymmetric keys. Furthermore, the key must exist in the vault that you specify.

    Use the oci vault secret create-base64 command and required parameters to create a secret storing your Jira credentials:

    oci vault secret create-base64 --compartment-id <target_compartment_id> --secret-name <secret_name> --vault-id <target_vault_id> --description <secret_description_text> --key-id <encryption_key_id> --secret-content-content <base64_encoded_secret_content> --secret-content-name <unique_content_name> --secret-content-stage <secret_version_rotation_state>

    For a complete list of parameters and values for CLI commands, see the CLI Command Reference.

  • Run the CreateSecret operation to create a secret.

    Example:

    POST /20180608/secrets
    Host: <managementEndpoint>
    <authorization and other headers>
    {
      "vaultId": "<vault_OCID>",
      "compartmentId": "<compartment_OCID>",
      "secretName": "jira_auth_plain_text",
      "description": "jira_auth_plain_text",
      "keyId": "<key_OCID>",
      "secretContent": 
        {
          "content": "<base64_encoded_secret_contents>",
          "contentType": "BASE64"
        }
    }
    Note

    Each region has a unique endpoint for create, update, and list operations for secrets. This endpoint is referred to as the control plane URL or secret management endpoint. Each region also has a unique endpoint for operations related to retrieving secret contents. This endpoint is known as the data plane URL or the secret retrieval endpoint. For regional endpoints, see the API Documentation.

    For information about using the API and signing requests, see REST API documentation and Security Credentials. For information about SDKs, see SDKs and the CLI.

Task 2: Create the Function

This section provides the code sample for creating your function and covers steps to authorize the function to access your Jira credentials in the secret created using the Vault service.

Function code sample

The following code sample is for a function to file Jira tickets.

Add your secret OCID in the line that includes getSecretForOcid.

For instructions on creating and deploying functions, see Creating and Deploying Functions.

public String handleRequest(CloudEvent cloudEvent) {
 
    // Json body of Cloud event from Oracle Event Service in serialized into cloudEvent object by Fn SDK implicitly
    System.err.println("Inside Java jira function with input as " + cloudEvent.getEventType() + "  " + cloudEvent.getData().getResourceName());
 
    String response = jiraCreateTicket(cloudEvent);
 
    if (response != null) return response;
 
    return null;
}
 
private String jiraCreateTicket(CloudEvent cloudEvent) {
 
    try {
        //create jira ticket body as per CloudEvent
        String jsonBodyJira = getJiraApiBody(cloudEvent);
 
        String jiraCloudEndpoint = System.getenv().get("JIRA_CLOUD_URL");
        String ocidForSecretForJiraAuthToken = System.getenv().get("JIRA_CLOUD_SECRET_OCID");
        String jiraAuthToken= getSecretForOcid(ocidForSecretForJiraAuthToken); // base64 encoded form of <YourJiraUsername:YourJiraAuthToken>
 
        // actual REST call to JIRA cloud
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonBodyJira);
        Request request = new Request.Builder()
                .url(jiraCloudEndpoint)
                .method("POST", body)
                .addHeader("Accept", "application/json")
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Basic "+ jiraAuthToken)
                .build();
        Response response = client.newCall(request).execute();
        return response.body().string();
 
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
Authorize your function to access secrets

Use a dynamic group  to grant your function the ability to read secrets. Your function must have this authorization to access your Jira credentials, which are stored in the secret you created earlier.

To authorize your function to access secrets (Console)
  1. Find and note your function OCID  (format is ocid1.fnfunc.oc1.iad.exampleuniqueID).
  2. Include your function in a dynamic group: In the relevant dynamic group , specify the following rule:
    resource.id = '<function-ocid>'

    Alternatively, you can create a dynamic group that includes all functions:

    ALL{resource.type='fnfunc', resource.compartment.id='<compartment_OCID>'}
  3. Grant the dynamic group access to secrets: Add the following policy  :
    allow dynamic-group <dynamic-group-name> to read secret-family in tenancy

To authorize your function for access to other Oracle Cloud Infrastructure resources, such as compute instances, include the function in a dynamic group  and create a policy to grant the dynamic group access to those resources. For more information, see Accessing Other Oracle Cloud Infrastructure Resources from Running Functions.

For more information about dynamic groups, see Managing Dynamic Groups.

Task 3: Create the Topic

For help with troubleshooting, see Troubleshooting Notifications.

    1. Open the Create Topic panel.
      1. Open the navigation menu and click Developer Services. Under Application Integration, click Notifications.
      2. Select a Compartment that you have permissions to work with.
      3. Click Create Topic.
    2. For Name, type the following: Maintenance Topic
    3. Click Create.
  • Use the oci ons topic create command and required parameters to create a topic:

    oci ons topic create --name <name> --compartment-id <compartment_OCID>

    Example:

    oci ons topic create --name "Maintenance Topic" --compartment-id "<compartment-ocid>"

    For a complete list of parameters and values for CLI commands, see the Command Line Reference for Notifications.

  • Run the CreateTopic operation to create a topic.

    Example:

    POST /20181201/topics
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "name": "Maintenance Topic",
      "compartmentId": "<compartment_OCID>"
    }

Task 4: Create the Subscriptions

Your function must be deployed before creating the function subscription.

For help with troubleshooting, see Troubleshooting Notifications.

    1. Select the topic that you created earlier.
      1. Open the navigation menu and click Developer Services. Under Application Integration, click Notifications.
      2. Select a Compartment that you have permissions to work with.
      3. Click the name of the topic that you created earlier (example name was Maintenance Topic).
    2. Create the function subscription.
      1. Open the Create Subscription panel: In the detail page for the topic, click Create Subscription.
        The Create Subscription panel opens.
      2. For Protocol, select Function.
      3. Fill in the remaining fields.
        Field Description
        Function Compartment Select the compartment containing the function.
        Function Application Select the application containing the function.
        Function Select the function.
      4. Click Create.
        No confirmation is needed for new function subscriptions.
    3. Create the email subscription.
      1. Open the Create Subscription panel: In the detail page for the topic, click Create Subscription.
        The Create Subscription panel opens.
      2. For Protocol, select Email.
      3. Fill in the remaining fields.
        Field Description
        Email Type an email address.
      4. Click Create.
      5. Confirm the new email subscription: Open the email and navigate to the confirmation URL.
  • Note

    After creating the email subscription, confirm it.

    Use the oci ons subscription create command and required parameters to create each subscription:

    oci ons subscription create --protocol <subscription_type> --subscription-endpoint <endpoint> --compartment-id <compartment_OCID> --topic-id <topic_OCID>

    Function subscription example:

    oci ons subscription create --protocol "ORACLE_FUNCTIONS" --subscription-endpoint "<function-ocid>" --compartment-id "<compartment_OCID>" --topic-id "<topic_OCID>"

    Email subscription example:

    oci ons subscription create --protocol "EMAIL" --subscription-endpoint "maintenance.team@example.com" --compartment-id "<compartment_OCID>" --topic-id "<topic_OCID>"

    For a complete list of parameters and values for CLI commands, see the Command Line Reference for Notifications.

  • Note

    After creating the email subscription, confirm it.

    Run the CreateSubscription operation to create each subscription.

    Function subscription example:

    POST /20181201/subscriptions
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "topicId": "<topic_OCID>",
      "compartmentId": "<compartment_OCID>",
      "protocol": "ORACLE_FUNCTIONS",
      "endpoint": "<function_OCID>"
    }

    Email subscription example:

    POST /20181201/subscriptions
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "topicId": "<topic_OCID>",
      "compartmentId": "<compartment_OCID>",
      "protocol": "EMAIL",
      "endpoint": "maintenance.team@example.com"
    }

Task 5: Create the Event Rule

  • This section walks through creating the rule that sends a message to the topic whenever the Database service emits an event for a database maintenance reminder.

    1. Open the navigation menu and click Observability & Management. Under Events Service, click Rules.
    2. Choose a Compartment you have permission to work in, and then click Create Rule.

      Events compares the rules you create in this compartment to event messages emitted from resources in this compartment and any child compartments.

    3. Enter the following.
      • Display Name: Specify a friendly name for the rule. You can change this name later. Avoid entering confidential information.

        Example: Maintenance Reminder

      • Description: Specify a description of what the rule does. You can change this description later. Avoid entering confidential information.

        Example: Sends messages to Maintenance Topic

    4. In Rule Conditions, create a filter for database reminder events: 
      • For Service Name, select Database.
      • In Event type, select Autonomous Container Database – Maintenance Reminder.
    5. In Actions, select the topic you previously created:
      1. Select Notifications.
      2. Select the Notifications Compartment.
      3. Select the Topic that you previously created.
    6. Click Create Rule.
  • Create a rule that's triggered by maintenance reminders and references this topic as the destination.

    1. Create a file, action.json, that contains the following, referencing your topic created previously.

      Example:

      {
        "actions": [
            {
              "actionType": "ONS",
              "description": "string",
              "isEnabled": true,
              "topicId": "<topic_OCID>"
            }
        ]
      }
    2. Open a command prompt and run the oci events rule create command.

      Example:

      oci events rule create --display-name <friendly_name> --is-enabled true --condition "{\"eventType\":[\"com.oraclecloud.databaseservice.autonomous.container.database.maintenance.reminder\"]}" --compartment-id <compartment_OCID> --actions file://action.json

      For a complete list of parameters and values for CLI commands, see the CLI Command Reference.

      For more information about creating rules using the CLI, see Creating an Events Rule.

  • Run the CreateRule operation to create an event rule.

    Example:

    POST /20181201/rules
    Host: events.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    
    {
      "displayName": "Maintenance Reminder",
      "condition": "{
        \"eventType\": \"com.oraclecloud.databaseservice.autonomous.container.database.maintenance.reminder\"
        }",
      "compartmentId": "<compartment_OCID>",
      "isEnabled": true,
      "actions": {
        "actions": [
          {
            "actionType": "ONS",
            "topicId": "<topic_OCID>",
            "isEnabled": true
          }
        ]
      }
    }