• Unauthorized to use OML application error when trying to obtain an OML token from an Oracle Autonomous database with a private endpoint βŒ

    Probably the longest title I’ve ever had for a post!

    I have an Oracle Autonomous Database that I created a private endpoint for and published via a public load balancer in OCI……my reason for this complexity – I wanted to use a custom vanity URL to access the database and this is the supported way to do this. If want to know more about setting this up, be sure to check out this step by step guide πŸ“–.

    Once I’d got this setup, everything worked as expected apart from one small issue – when trying to get a token via REST so that I could call an Oracle Machine Learning model within the database I received the following error ❌.

    b'{“error_message”:”\’DEMO1USER\’ unauthorized to \’use OML application\’”,”errorCode”:0,”request_id”:”OMLIDMREST-955f999622584d33a70″}’

    I was calling the REST API via Python, but other methods such as Curl returned the same error (further details on calling the REST API to get a token and authenticate can be found here). The user had the relevant permissions so it was definitely something else πŸ€”.

    The trick to fixing this is to update the URL that is called to obtain the token, rather than using this:

    https://oml-cloud-service-location-url/omlusers/api/oauth2/v1/token

    The URL needs to be updated to include the OCID of the OCI tenancy and the name of the database to connect to, like this:

    https://oml-cloud-service-location-url/omlusers/tenants/TenancyOCID/databases/DatabaseName/api/oauth2/v1/token

    For example, I was originally using this URL:

    https://adb.brendg.co.uk/omlusers/api/oauth2/v1/token

    I had to update this to:

    https://adb.brendg.co.uk/omlusers/tenants/ocid1.tenancy.oc1..aaaaaabbjdjwnd3krfpjw23erghw4dxnvadd9w6j2hwcirea22qrtfam24mq/databases/DemoDB/api/oauth2/v1/token

    The reason for this, is that when using a custom (vanity) URL to access the REST endpoint, it doesn’t know which tenancy and database you are trying to obtain an authentication token for, therefore you need to specify this in the REST endpoint.

    Once I’d done this, it worked like magic πŸͺ„

  • OCI AI Vision – UK Oracle User Group Conference 2024 πŸ‡¬πŸ‡§

    I recently had the privilege of presenting a session on OCI AI Vision at the UK Oracle User Group conference in Birmingham πŸ™οΈ.

    img_2246-1

    The slides I presented can be downloaded from here and include a video of the second demo in my session (the important one).

    It was an absolutely fantastic event, with some brilliant sessions – I learnt a lot! 🧠

  • How to create a free SSL certificate with Let’s Encrypt…and as a bonus use this certificate with Oracle Analytics Cloud πŸ”

    I needed an SSL certificate recently as wanted to make an instance of Oracle Analytics Cloud available publicly with a nice vanity URL, rather than https://demo1analyticscloud-lrmvtbrwx-ld.analytics.ocp.oraclecloud.com, something a little more memorable, such as https://oac.oci-demo.co.uk.

    To do this I needed an SSL certificate and decided to use Let’s Encrypt as they provide free SSL certificates (with a validity period of 90 days).

    It was relatively straightforward to create a certificate using the Certbot client for macOS, to do this I did the following:

    Step 1 – Installed Certbot using the following command

    brew install certbot
    

    Step 2 – Created a directory to store the generated certificates

    mkdir certs
    cd certs
    

    Step 3 – Create the certificate request using Certbot

    This uses the DNS challenge type, which is ideal when you need to create a certificate for use on a system that doesn’t provide native integration with Certbot (such as Oracle Analytics Cloud). Replace “e-mail address” with a valid address to use for renewal reminders.

    cd certs
    certbot certonly --manual --preferred-challenges=dns --config-dir config --work-dir workdir --logs-dir logs --agree-tos -m e-mail address --key-type rsa
    

    When this command has been run, it will ask for the hostname to create the SSL certificate for. In my case I requested a certificate for demo1oac.oci-demo.co.uk.

    After hitting enter, it then provides a DNS record that needs to be created to validate domain ownership.

    I host my DNS within OCI, so this was as simple as creating a DNS TXT record using the OCI Console (the process will vary depending on your DNS provider).

    I then used the link within the instructions to validate the presence of the DNS TXT records that I had just created.

    Once I’d verified that the DNS record was available publicly, I hit enter and the SSL certificates were created for me!

    Step 4 – Configure OAC to use a custom hostname with SSL (example)

    I then navigated to Oracle Analytics Cloud within the OCI Console and within Vanity URL selected Create.

    I entered the hostname for the vanity URL – demo1oac.oci-demo.co.uk. I then uploaded the certificates that had just been generated.

    The mapping between certificate types and the .pem files created is as follows:

    • Certificate = cert1.pem
    • Private Key = privkey1.pem
    • Certificate Authority chain file = chain1.pem

    I then hit Create to apply the configuration. A final step was for me to create a DNS entry to point demo1oac.oci-demo.co.uk to the public IP address of the OAC instance.

    I then waited a few minutes for the DNS record to come to life and then browsed to https://demo1oac.oci-demo.co.uk and it worked!

  • Unable to connect to a Kubernetes cluster in OCI using kubectl πŸ”Œ

    The time finally came for me to get hands on with Kubernetes on OCI (or OKE as it’s affectionately know).

    Spinning up a Kubernetes cluster was an absolute breeze, however when I started to work through the Quick Start….or not so Quick Start for me – I stumbled up an error when attempting to deploy the sample app to my cluster.

    When I ran the command in Step 3 I received the following error:

    error: error validating “https://k8s.io/examples/application/deployment.yaml”: error validating data: failed to download openapi: the server has asked for the client to provide credentials; if you choose to ignore these errors, turn validation off with –validate=false

    Looked like some form of authentication issue, after much head scratching and experimentation I figured out what the problem was (it took me far too long ⏱️).

    I have multiple profiles specified within my OCI CLI configuration file, example below (with the juicy bits removed!):

    The OKE cluster I needed to connect to is within the tenancy I have named PubSec, if I take a look at the Kubernetes config file (located in “.kube” within my user profile), I could see that this uses the OCI CLI to connect to the cluster – however as it doesn’t specify a profile within the OCI CLI config this will use the DEFAULT profile, in my specific case I needed to override this to uses the PubSec profile.

    I resolved this by adding the highlighted lines (below) to the Kubernetes config file within “.kube”. This tells the OCI CLI to connect to the cluster using the PubSec profile rather than DEFAULT.

    Once I’d updated this, saved and re-sarted the terminal, I ran the command again and it worked like magic πŸͺ„

  • Creating a Generative AI Agent in less than 10 minutes.

    There’s been a lot of buzz about Generative AI Agents recently, so I thought that I’d take Oracle Gen AI Agents for a spin 🧠.

    In this short video (<10 minutes ⏱️), I walk through the full end-to-end process of creating a Gen AI agent within OCI that uses the power of a LLM and business data to provide contextually relevant answers to business questions, saving users time and reducing costs πŸ‘©β€πŸ’».

  • Creating sample data in Oracle Autonomous Database using AI πŸ§ 

    I’ve recently posted a short video on YouTube that walks through the process of creating and loading sample data into Oracle Autonomous Database using AI – this feature is fully baked into the product too!

    This will be a huge timesaver for me as I create a lot of demo’s πŸ‘¨β€πŸ’».

  • Upload a file to OCI Object Storage using a Pre-Authenticated Request (PAR) πŸ“

    OCI Object Storage has a notion of a Pre-Authenticated Request, this gives users access to a bucket or an object (file) without having provide their sign-on credentials πŸͺͺ – all is needed is a single URL (which can have an expiration time/date on).

    I’ve used PAR’s to provide read access to specific objects (files) within a storage bucket, this has been useful to quickly (and relatively securely) share content.

    I recently needed to provide a user the ability to upload content to a storage bucket using a PAR, to do this I configured PAR on a bucket as follows πŸͺ£:

    However, after creating the PAR on the bucket and getting the URL, I was at a loss as to how to upload files to the bucket. If I browsed to the URL in a browser, it simply listed the files within the bucket with no visual means to upload (I was expecting a nice upload button!).

    I couldn’t see any way to upload files using the OCI CLI either, after much head-scratching and experimentation it turned out that the easiest way upload a file is to use Curl

    Here is the command that I used:

    curl -v -X PUT --data-binary '@/Users/brendan/Downloads/MyFile.zip' PAR URL/MyFile.zip
    

    You need to include the path to the file to upload (after the @ sign). The PAR URL provided by OCI and finally the name to give the uploaded file within the storage bucket.

    Running this command successfully uploaded the file to the bucket that the PAR had been created for – result!

  • Create a Machine Learning Model in Less Than 10 Minutes using Oracle AutoML β±οΈ

    As this was quite a large topic for a blog post I decided to record a video instead. In this video I go through the process of…

    1. Loading a sample dataset that contains information on employee attrition into an Autonomous Database πŸ“Š
    2. Creating a machine learning model using this data with Oracle AutoML 🧠
    3. Calling the machine learning model using a Python script 🐍

  • Connecting to OCI Object Storage using S3 Browser πŸͺ£

    OCI Object Storage has an Amazon S3 compatible API, which got me thinking that I could likely connect to it using a GUI client, such as S3 Browser. After lots of trial and error I finally managed to configure S3 Browser to connect to OCI Object Storage.

    Below are the steps that I took to get this working:

    Step 1 – Obtain the Object Storage Namespace for the tenancy πŸͺ£

    The Object Storage Namespace is required to figure out the REST endpoint URL to connect to OCI Object Storage and can be obtained via the Cloud Console > Governance & Administration > Tenancy Details

    My namespace is below and begins with lrdkvq

    Step 2 – Create a secret key πŸ”‘

    I then needed to create a secret key, this is used to autheticate to OCI Object Storage, a secret key can be created using the Cloud Console via Profile (icon in the top right) > My Profile > Customer secrey keys > Generate secret key.

    Give the secret key a memorable name and remember to copy the key before closing the window as it will not be shown again.

    In the list of secret keys, hover over the Access Key section for the secret key that you have just created and copy this too.

    Step 3 – Configuring S3 Browser βš™οΈ

    Launch S3 Browser and add a new account, select S3 Compatible Storage from the Account type dropdown.

    This then unlocks some additional options:

    For the REST Endpoint take the namespace that you obtained in Step 1 and use this as the first part of the URL, follow this with compat.objectstorage.REGION CODE.oraclecloud.com, for example my URL looks like this:

    lrdkvqz1i7g9.compat.objectstorage.uk-london-1.oraclecloud.com

    To obtain the region code for your OCI tenancy, use this reference.

    Then enter the Access Key ID and Secret Access Key obtained in Step 2. Secret Access Key is the key that is only displated once and Access Key ID is the Access Key obtained from the list of customer secret keys.

    Step 4 – Connect πŸ”Œ

    I then saved this configuration and connected πŸ˜€.

    This is a nice (and a little more user-friendly) way to interact with Object Storage without having to use the OCI Console / APIs.

  • Unable to Create a Mount Target in OCI βŒ

    A customer contacted me a few days ago as they were unable to create a Mount Target within the File Storage service within OCI, they had two Mount Targets provisioned within their OCI tenancy and were attempting to create a third, when doing this they were receiving the error:

    “File System was created successfully but Mount Target creation failed because of error: “The following service limits were exceeded: mount-target-count. Request a service limit increase from the service limits page in the console. “. To enable access to the File System, associate it with an existing Mount Target by adding an Export to it.”

    Their PAYG OCI tenant had a limit of 2 x Mount Targets, however when I looked at the documentation the limit is 2 per tenant per Availability Domain, therefore in theory they could have up to 6 Mount Targets (as there are 3 x Availability Domain’s within the region they are using).

    It turned out that they were not given the opportunity to specify the Availability Domain when creating the Mount Points and the two previous Mount Points they had created resided within Availability Domain 1. The reason for this is that they had created the Mount Targets when creating a File System and when creating them this way, it doesn’t provide an option to specify the Availablity Domain to create the Mount Target within (see screenshot below).

    To work around this they created the 3rd Mount Target manually via Storage > File Storage > Mount Targets (within the OCI Console), specifying Availability Domain 2 (UK-LONDON-1-AD-2).

    This was created successfully…..they then created the File System but this time selected an existing Mount Target (MountTarget3), rather than having the OCI Console automagically create a new Mount Target for them.

    This allowed them to successfully create a third Mount Target and File System πŸ™Œ.