# Stephen Nimmo > Development, DevOps and Delivery ## Posts - [Compiling and installing a Linux kernel module in OpenShift - The AMD Solarflare™ Onload™ Edition](https://stephennimmo.com/2025/09/12/compiling-and-installing-a-linux-kernel-module-in-openshift-the-amd-solarflare-onload-edition/): tldr: Take me to the process What Is a Kernel Module? Have you ever wondered how your computer’s operating system manages to support a seemingly endless variety of devices, from your mouse and keyboard to your graphics card and Wi-Fi adapter? The secret lies in kernel modules, also known as Loadable Kernel Modules (LKMs). Think of a kernel module (kmod) as a plug-in for your computer’s brain, the kernel. It’s a piece of code that can be loaded into the operating system while it’s running, without requiring a full reboot. This dynamic nature is what makes modern operating systems so[...] - [Dynamic URL for Host using OpenShift routes](https://stephennimmo.com/2025/09/12/dynamic-url-for-host-using-openshift-routes/): Did you know that in OpenShift, you can use Route objects to simply define the prefix for the host url and that the route will automatically fill in the cluster context as the suffix. Let’s say you have an application called “app1” and it’s going to be in three different clusters – dev, test, prod – with three different cluster suffix. In the dev environment, you would want the URL to be “app1.dev.ocp.yourcompany.com” and of course change the values for the other environments. You can do that with the Route using the subdomain value in the spec. Here’s a full[...] - [Connecting OpenShift Virtualization to Underlay Networks with ClusterUserDefinedNetwork](https://stephennimmo.com/2025/08/25/connecting-openshift-virtualization-to-underlay-networks-with-clusteruserdefinednetwork/): OpenShift Virtualization lets you run VMs as first-class citizens in OpenShift. By default, VMs communicate over the cluster overlay (the OVN-Kubernetes pod network). That’s fine for east–west traffic inside the cluster, but often you want VMs to join an existing VLAN, talk to physical appliances, or get directly reachable IP addresses. Enter the ClusterUserDefinedNetwork (CUDN). Why CUDN? The ClusterUserDefinedNetwork (CUDN) is just an abstraction of the NetworkAttachmentDefinition (NAD), but has a features that differentiate it from the UserDefinedNetwork (UDN). The UDN is used for namespace-scopes network overlays, providing users the ability to create and manage additional L2 and L3 networks[...] - [Two Ways of creating a Red Hat Enterprise Linux virtual machine with a static ip address in OpenShift Virtualization](https://stephennimmo.com/2025/06/25/two-ways-of-creating-a-red-hat-enterprise-linux-virtual-machine-with-a-static-ip-address-in-openshift-virtualization/): OpenShift Virtualization is a feature of Red Hat OpenShift that enables you to run and manage virtual machines alongside containers on the same Kubernetes platform. It brings traditional VM workloads into the modern, cloud-native ecosystem by leveraging KubeVirt to integrate virtual machines directly into OpenShift. This allows organizations to consolidate infrastructure, simplify operations, and gradually modernize legacy applications without needing to migrate everything to containers all at once. With native support for VM lifecycle management, networking, and storage, OpenShift Virtualization offers a unified control plane for both VMs and containers, all managed through the same Kubernetes-native APIs and tools. NodeNetworkConfigurationPolicies[...] - [Bootstrapping an OpenShift Cluster with OpenShift GitOps](https://stephennimmo.com/2025/06/24/bootstrapping-an-openshift-cluster-with-openshift-gitops/): So you have a brand new shiny OpenShift cluster. Now what? It’s time for some GitOps. GitOps is a modern approach to managing infrastructure and application deployments using Git as the single source of truth. Instead of manually applying changes to a cluster or scripting deployments, GitOps treats your desired system state—like Kubernetes manifests, Helm charts, or Kustomize overlays—as version-controlled code. When a change is pushed to your Git repository, a GitOps controller running in the cluster automatically reconciles the live state to match the desired state in Git. This not only enables full auditability and rollback via Git history,[...] - [Install Hashicorp Vault on Red Hat Enterprise Linux](https://stephennimmo.com/2025/06/15/install-hashicorp-vault-on-red-hat-enterprise-linux/): I use Hashicorp Vault as my primary secrets management system. Mostly because most of my on-premise OpenShift customers use it as well. Here’s how to install it on a RHEL 9.6 box using ansible. One of the prerequisites is to get certbot installed on the host and configured to use DNS challenges. Why DNS challenges? Because I don’t like port 80 being open. I find the DNS challenge more palatable. Here’s the tasks for setting it up. Here’s the playbook for the vault install. - [New Router Setup - Mikrotik CRS305-1G-4S+IN](https://stephennimmo.com/2025/06/07/new-router-setup-mikrotik-crs305-1g-4sin/): I recently replaced my default gateway router with a Mikrotik CRS305-1G-4S+IN. Instead of clickopsing the setup, I decided to use the available cli to script it. Here’s the setup. If you need to reset the device manually, unplug the device, hold down the reset button while plugging it back in. Hold it until it blinks at you and then release it. To blow away the existing config and make sure the default config isn’t laid down, here’s the command. The default router config sets up on a 192.168.88.1/24 network. I connect to it directly using eth and manually set my[...] - [Running iperf3 tests in OpenShift](https://stephennimmo.com/2025/04/18/running-iperf3-tests-in-openshift/): In this blog post, I will document how to deploy and expose an iperf server for testing. Setup the Server In this example, we are starting an iperf3 server listening on port 5201. I am also manually positioning this pod on a particular node to ensure that the client pod won’t end up on the same node. Testing loopback doesn’t provide much quality data. Setup the Client Notice it’s running on a different node. Once these are setup, you can run the test. Exposing the Service The previous test would test connectivity between nodes. We also want to test from[...] - [Running an OpenShift Virtualization VM Connected to a VLAN](https://stephennimmo.com/2025/03/23/running-an-openshift-virtualization-vm-connected-to-a-vlan/): Prerequisites to be installed: Setting Up the VLAN Configuration In my homelab, I have a vlan created and tagged to the same port that is supplying the ethernet connection to the OCP cluster. I have bonds setup for my OpenShift cluster to not only emulate a more enterprisey setup but also to normalize the naming for the devices. If bond0 is always the connection and it hides what physical interfaces it fronts, then it gives me the ability to normalize all the configurations upstream and obfuscate differences in hardware. Check out the setup here: https://stephennimmo.com/2025/03/22/home-lab-openshift-using-agent-based-installer/ OpenShift Host Configurations with NodeNetworkConfigurationPolicy[...] - [Python to Bootstrap OpenShift Gitops](https://stephennimmo.com/2025/03/23/python-to-bootstrap-openshift-gitops/): Here’s a python script to bootstrap OpenShift gitops in a fresh cluster. I like this one a bit better because I think python is easier to code and debug. - [Home Lab OpenShift using Agent Based Installer](https://stephennimmo.com/2025/03/22/home-lab-openshift-using-agent-based-installer/): Install the tools. Here’s the setup for a Fedora/RHEL box. Install the Cluster One of the things about the OpenShift agent based installer is that when you provide it configs, it actually destroys them. The way I get around this, if I am iterating in my installs, is to do the following. Then once you boot the machines with the iso created, then run the following commands to complete the install. Config Files Here’s the configs for my homelab setup, which is a bare-metal 3 node cluster on some Intel NUCs. And the agent based install. Alternate Install – Bond[...] - [Running Jfrog Artifactory on Podman](https://stephennimmo.com/2025/03/14/running-jfrog-artifactory-on-podman/): This post is to document the process to run the OSS version of JFrog artifactory on Podman. Below is the podman compose. And then head to http://localhost:8081 and use the default admin/password Notes - [Setting Up Network Policies on a RHEL 9 VM running in OpenShift Virtualization](https://stephennimmo.com/2025/02/26/setting-up-network-policies-on-a-rhel-9-vm-running-in-openshift-virtualization/): OpenShift Virtualization is a powerful capability within Red Hat OpenShift that enables organizations to run and manage virtual machines (VMs) alongside containerized workloads on a unified Kubernetes-based platform. By leveraging KubeVirt, OpenShift Virtualization allows businesses to modernize their infrastructure by seamlessly integrating traditional VM-based applications with cloud-native technologies. This approach simplifies operations, enhances scalability, and provides a consistent development and deployment experience across VMs and containers, making it easier to transition to a cloud-first strategy without abandoning existing investments. OpenShift Virtualization bridges the gap between traditional virtualization and cloud-native development by blending virtual machine (VM) concepts with Kubernetes-native workflows. Unlike[...] - [REST API error modeling with Quarkus](https://stephennimmo.com/2025/01/31/rest-api-error-modeling-with-quarkus/): One of the main issues with code and API design across an enterprise is consistency. Due to the lack of specification in the OpenAPI specification regarding error messages, the resulting JSON schemas could vary significantly between APIs. These variances are rarely attributed to incorrect versus correct designs, but rather subjective viewpoints as it relates to the data structures. Most of the time, it actually varies simply based on naming of structure and attributes but can sometimes differ based on the degree of details included in the error responses. The first step is to create and agree to a single set[...] - [Bash to Bootstrap OpenShift Gitops](https://stephennimmo.com/2025/01/20/bash-to-bootstrap-openshift-gitops/): So you got a fresh OpenShift install? First thing to do is to install OpenShift Gitops. Here’s a script to do that. Make sure you are logged in as a cluster admin. - [Backing Up and Restoring a single VM using OpenShift Virtualization and OADP](https://stephennimmo.com/2024/10/09/backing-up-and-restoring-a-single-vm-using-openshift-virtualization-and-oadp/): Prerequisites: The OpenShift API for Data Protection (OADP) is a powerful extension of the OpenShift ecosystem designed to enhance data resilience and disaster recovery for Kubernetes workloads. OADP provides a standardized approach to backup, restore, and migration by integrating with popular data protection tools like Velero and incorporating cloud-native principles. This API abstracts complex backup operations, allowing users to safeguard both stateless and stateful applications running on OpenShift, including resources like KubeVirt virtual machines. With its flexible configuration and robust support for storage snapshots, OADP empowers administrators to implement comprehensive data protection strategies across hybrid and multi-cloud environments, ensuring critical[...] - [Building a Quarkus Application using OpenShift Pipelines](https://stephennimmo.com/2024/10/07/building-a-quarkus-application-using-openshift-pipelines/): In this blog post, we are going to explore building a Quarkus application using Tekton, which is the upstream project on which OpenShift Pipelines is based on. Understanding Tekton Tekton is a powerful and flexible open-source framework for creating continuous integration and continuous deployment (CI/CD) systems. Built to run on Kubernetes, Tekton abstracts the complexities of building and deploying pipelines by breaking them down into three core components: pipelines, tasks, and steps. At the highest level, a Pipeline in Tekton defines a series of Tasks that need to be executed to achieve a CI/CD workflow. This could range from compiling[...] - [Standalone Angular Project from Scratch](https://stephennimmo.com/2024/09/28/standalone-angular-project-from-scratch/): In this post, we will discuss the new standalone component concepts as well as the use of signals. To get started, let’s create a new project. We want routing. I like SCSS over the other styling mechanisms. And we don’t want any server side rendering. We are going to use Bootstrap as well so let’s add that in. Component Organization Now we are going to use standalone components which accomplish two major things. First, it reduces the amount of importing into all of the components. Second, it will help reduce refactoring. The project structure is greatly simplified as well. We[...] - [Deleting old pods using CronJob on OpenShift](https://stephennimmo.com/2024/09/18/deleting-old-pods-using-cronjob-on-openshift/): Whenever I do a cluster install and after running a cluster for a while, the “Completed” pod references start to mount up in the GUI. Here’s a quick and dirty way to clean up old pods. - [Running the Red Hat build of Keycloak on OpenShift](https://stephennimmo.com/2024/09/10/running-the-red-hat-build-of-keycloak-on-openshift/): In this blog post, we are going to bring a few different technologies together to support an instance of the Red Hat build of Keycloak running on Red Hat OpenShift. We are going to use the Red Hat build of Keycloak Operator, the cert-manager Operator for Red Hat OpenShift and Red Hat OpenShift Data Foundation for storage. Keycloak uses PostgreSQL as it’s underlying database, so to begin, we will need to get PostgreSQL running as a StatefulSet in our cluster. Create a new project using the command oc new-project keycloak. When you create a new project using the oc CLI,[...] - [Running Postgres as a StatefulSet on OpenShift](https://stephennimmo.com/2024/08/21/running-postgres-as-a-statefulset-on-openshift/): Here’s some example yaml for deploying Postgres on OpenShift. And some commands. - [Generating Let's Encrypt certificates with Red Hat OpenShift cert-manager operator using the Cloudflare DNS solver](https://stephennimmo.com/2024/05/15/generating-lets-encrypt-certificates-with-red-hat-openshift-cert-manager-operator-using-the-cloudflare-dns-solver/): Let’s Encrypt is a nonprofit certificate authority that provides free SSL/TLS certificates, which are essential for enabling secure HTTPS connections on websites. Launched in 2016 by the Internet Security Research Group (ISRG), its mission is to make encrypted connections ubiquitous on the web, enhancing privacy and security for all users. Let’s Encrypt simplifies the process of obtaining and renewing certificates through automation, making it accessible even for those without extensive technical knowledge. By offering a straightforward, cost-free way to secure websites, Let’s Encrypt plays a crucial role in promoting a safer and more privacy-respecting internet. Focus For the focus of[...] - [In-Depth Hashicorp Vault setup on OpenShift using OpenShift GitOps](https://stephennimmo.com/2024/05/05/hashicorp-vault-setup-on-openshift-using-argocd/): I’m running a couple of clusters in my lab environment. One of them is a “hub” cluster which is handling all of the core, centralized services which shouldn’t be considered workloads. As part of the hub cluster setup, I wanted to have a secure KMS and there is no better choice than Hashicorp Vault. Vault has a great Helm chart for setup. Combining this chart with an ArgoCD Application CR gives you mostly everything you need. The Complication Running Vault on Kubernetes has a complication. The application runs as a StatefulSet, which means it’s running multiple pods. One of the[...] - [Async Communication Best Practices](https://stephennimmo.com/2024/04/10/async-communication-best-practices/): Here’s a small list of some best practices when engaging in asynchronous communications with colleagues. General Email Slack Boss Comms Do you manage people? Then don’t do these in async. - [Build a REST API from the ground up with Quarkus 3](https://stephennimmo.com/2024/03/08/build-a-rest-api-from-the-ground-up-with-quarkus-3-0/): Last Updated: 8/28/2024 This blog post serves as an aggregation of how to build a REST API. Tools Used The API GET https://examplecompany.com/api/v1/customers GET https://examplecompany.com/api/v1/customers/{customerId} POST https://examplecompany.com/api/v1/customers PUT https://examplecompany.com/api/v1/customers/{customerId} DELETE https://examplecompany.com/api/v1/customers/{customerId} Security Roles CUSTOMER_READ CUSTOMER_WRITE Project Initialization We are going to start at the command line again, however we are going to be using the Quarkus CLI this time. Now we are ready to get started. Open the project in your favorite IDE and let’s get started. Repository Layer We are still using the Quarkus Panache extension to help us with our database persistence. Let’s get those extensions installed using[...] - [Linux File Permissions: Giving One User Read Access](https://stephennimmo.com/2024/02/16/linux-file-permissions-giving-one-user-read-access/): I recently did some work setting up multiple users on a RHEL box of mine and I wanted to document some understandings regarding giving fine-grained, user-based permissions to files. chmod is too broad Linux file permissions dictate how users and processes interact with files and directories, ensuring secure and controlled access to the system. The chmod command, short for “change mode,” is one tool for modifying these permissions. There are three primary permission categories: owner, group, and others. Each category has three permission types: read (r), write (w), and execute (x). The chmod command utilizes a numeric or symbolic representation[...] - [rpm-ostree kernel parameters](https://stephennimmo.com/2024/01/30/rpm-ostree-kernel-parameters/): I’ve been messing around with one of my boxes because of a faulty onboard ethernet adapter. I was trying to use a usb-c to ethernet adapter in it’s place for network connectivity, but have been running into weird stability issues. It works for hours at a time and then just disconnects. If I reboot or reseat the usb, it works again for a few hours and then drops. I thought it might have been something to do with the DHCP lease, but the lease expirations don’t line up. Anyway, the box is one of my OpenShift bare metal nodes, which[...] - [Building an API Hierarchy](https://stephennimmo.com/2024/01/25/building-an-api-hierarchy/): In the dynamic landscape of modern enterprises, Application Programming Interfaces (APIs) have emerged as indispensable catalysts for innovation, connectivity, and seamless digital experiences. APIs serve as the glue that binds diverse software systems, allowing them to communicate, share data, and collaborate efficiently. This blog post delves into the pivotal role of APIs within enterprises, exploring their significance in fostering agility, driving digital transformation, and unlocking new realms of possibilities. From enhancing operational efficiency to empowering businesses with scalable solutions, the power of APIs extends far beyond mere technical interfaces, shaping the very fabric of today’s interconnected business ecosystem. In the[...] - [Certificates from Let's Encrypt using certbot on RHEL](https://stephennimmo.com/2023/12/08/certificates-from-lets-encrypt-using-certbot-on-rhel/): Requirements: Certificates are a pain. But they are a very necessary and vital piece to your security. Here’s how to make things a bit simpler. Let’s Encrypt, certbot and ACME Protocol Let’s Encrypt is a free, automated, and open certificate authority. Their root certs are present in all versions of browsers and they have a nice, free service for generating certificates. When you want an authority to issue a certificate for you, you should be able to prove you own the domain. That’s where certbot comes in, which is a command line tool which integrates with Let’s Encrypt’s ACME service[...] - [Full Stack Development - Quarkus and Angular with Quinoa](https://stephennimmo.com/2023/12/01/full-stack-development-quarkus-and-angular-with-quinoa/): Prerequisites One Big App Sometimes, simpler is better. Not everything has to be overly optimized for the best performance possible. As for most lower traffic applications, building a complex multi-application microservice architecture to break out the frontend development with the backend development is overkill. Wouldn’t it be nice to create your REST API and package your browser-based single-page application (SPA) all in one container? That’s where Quinoa comes in handy. Quinoa is a Quarkus extension, available as part of the Quarkiverse, that allows you to quickly and easily engage in full stack development without the hassles of managing multiple project[...] - [Concise Keycloak Realm for Testing](https://stephennimmo.com/2023/11/18/concise-keycloak-realm-for-testing/): I’ve recently been working on some Quarkus and Angular projects requiring an OIDC provider and I have been using Keycloak. Keycloak is a great implementation for SSO/OAUTH/OIDC for your production applications but it can sometimes be unwieldy for those of us who do not fully grasp every feature or detail as it relates to setting up a Keycloak realm for testing. In Keycloak, a realm is a deployment or security domain where you manage, organize, and configure identity and access management components. Realms are a way to isolate different applications and their user bases from each other within the Keycloak[...] - [Modbus Integration at the Edge with Quarkus Native Image Compilation](https://stephennimmo.com/2023/10/05/modbus-integration-at-the-edge-with-quarkus-native-image-compilation/): When I came to Red Hat, I had mostly lived in the IT world. My servers were in data centers. The smallest box I had to deal with were usually my poorly equipped local desktop. We had build processes and deployment pipelines. Bandwidth was never a concern other than having a major hardware meltdown. We kept things up to date and if a change needed to be made, we were patching maybe dozens of machines. Rolling out new versions of the code eventually became a weekly or daily occurrence, as needed. I was then introduced to the OT. The operational[...] - [Build a REST API from the ground up with Python](https://stephennimmo.com/2023/09/07/build-a-rest-api-from-the-ground-up-with-python/): Python’s popularity continues to grow. While it’s best known as a scripting language, the language has evolved to handle many use cases with machine learning and data management being the best known use case. One of those use cases is building REST APIs. I am a Java developer and have written about building REST APIs in the past, mostly using Quarkus, which heavily utilizes the Microprofile specification. One of the more popular articles was an in-depth walkthrough of how to build a REST API “from the ground up”, where we build a simple REST API but explain all the architecture[...] - [Quit Telling your Developers they are Brilliant](https://stephennimmo.com/2023/07/27/quit-telling-your-developers-they-are-brilliant/): The growth mindset is a psychological concept that emphasizes the belief that one’s abilities and intelligence can be developed through dedication, hard work, and perseverance. Individuals with a growth mindset embrace challenges, view failures as opportunities for learning, and are open to feedback. They understand that effort and determination can lead to improvement and success, and they do not see their skills as fixed or limited. This mindset fosters a willingness to take on new challenges, seek continuous improvement, and ultimately, achieve higher levels of personal and professional development. Carol Dweck’s work on growth mindset with students has been influential[...] - [Intellij's Java toString Update to Match Records](https://stephennimmo.com/2023/07/15/intellijs-java-tostring-update-to-match-records/): Intellij has code generation feature built into the IDE to allow Java developers to quickly generate boilerplate code including getters, setters, hashCode, equals and toString. The default implementation for the toString has always used braces for the demarcation between the class name and the variables. However, the Java record uses brackets for it’s default toString implementation. With no adjustments, you will end up with both implementations resulting in incongruent logging statements. To achieve this, you can create a new template in Intellij that switches the brackets for the braces. Open up the generate dialog for the toString and click on[...] - [My conversation with ChatGPT on trade data structures](https://stephennimmo.com/2023/03/19/my-conversation-with-chatgpt-on-trade-data-structures/): I recently had a conversation with ChatGPT about helping me build some protobuf-based commodities trade structures. It was pretty amazing in terms of coupling both protobuf syntax and trade structure knowledge. It could even be corrected in certain cases without going off the rails. And on certain portions, even though it was wrong, it still rationalized why it did what it did in a pretty decent way. It got really interesting when it started to bring in some valid use cases where the data structures are needed – “calculate net positions and other risk metrics.” In some ways, it felt[...] - [Building a Comprehensive Functional Testing Strategy](https://stephennimmo.com/2023/01/13/building-a-comprehensive-functional-testing-strategy/): Software testing is important. Unit tests are important. However, there are so many different layers and scopes of testing software in an enterprise that many companies miss some great opportunities to not only make their testing efforts more comprehensive, but also how to better leverage the work done. Enterprises mostly struggle with inconsistencies between teams in what constitutes “done” in terms of testing which then requires additional layers of management to reconcile what constitutes readiness regarding deployments. Let’s Start Local We are going to be building and deploying a “simple” REST API. The API is going to do a couple[...] - [Microservices and the Foreign Key Dilemma](https://stephennimmo.com/2023/01/06/microservices-and-the-foreign-key-dilemma/): The journey to microservices is focused on breaking down monolithic applications into compose, domain driven services. There are many valuable aspects to creating smaller composable services. Smaller services are easier to deploy and scale. The overall system resilience using smaller composable services is stronger as failures can be isolated. It also supports more flexibility and reusability across the enterprise. However, the microservice architecture has drawbacks as well, making it more of a tradeoff scenario. One of those drawbacks is the splitting of data across multiple data stores. Many times the monoliths we are breaking up are backed by huge monolithic[...] - [Kafka Stream Transformation Patterns and Message Reprocessing](https://stephennimmo.com/2022/12/23/kafka-stream-transformation-patterns-and-message-reprocessing/): This blog post assumes you have at least a basic understanding of Kafka – topics, partitioning, offsets. If you have been in software for any decent amount of time, then you know the truth that the scope of any functionality is heavily weighted on handling all the error conditions rather than the happy path. Stream processing is no exception. In this post, we will dive deep into the transformation pattern of stream processing and discuss what makes it complicated as well as some core components required in building services to support such transformations. Let’s Transform Some Data When we start[...] - [Why Continuous Delivery?](https://stephennimmo.com/2022/12/19/why-continuous-delivery/): The need for continuous delivery is predicated on the fact that software is continuously deteriorating. From the second the code is checked into source control, entropy begins to set in. Some of this is related to the fundamental nature of the building blocks of software while others are related to a set of ever changing environmental needs from the organization. The sooner an organization fully accepts the truth that software is never done, the sooner they can begin to put systems into place to manage the chaos. What’s Changing? Software is made of components of other software. It’s a huge[...] - [Using Podman with Quarkus and Testcontainers on MacOS M1](https://stephennimmo.com/2022/10/19/using-podman-with-quarkus-and-testcontainers-on-macos/): Switching to use Podman instead of Docker for spinning up Testcontainers on MacOS just takes a bit of install and configuring. The main reason for the changes is the assumption that Testcontainers makes about the general availability of a Docker socket. Podman is daemonless. This assumes you are using homebrew to manage packages on MacOS. Edit ~/.testcontainers.properties and add the following line: Then run the following: Once you are sshed into the podman machine, run the following commands: NOTE: The systemctl reboot does restart the podman machine however, this restart doesn’t mount the $HOME directory. You must manually recycle the VM using[...] - [NFS PVC Dynamic Provisioning on OpenShift](https://stephennimmo.com/2022/05/12/nfs-pvc-dynamic-provisioning-on-openshift/): Setting Up the NFS Server I run a RHEL box which provides all the supporting services needed for my POCs and other demos. During the install of RHEL, I setup the disk partitioning to have a significant chunk of the disk mount apportioned to /nfs to support the NFS needs for my local OpenShift cluster. Start by installing the nfs-utils package, enable the service, and add the directories. Next, setup the exports and restart the service. Update the file at /etc/exports with the following NFS exports. Last, we need to update the firewall to allow for NFS. Installing the Helm[...] - [Using Lombok and MapStruct in a Maven Project](https://stephennimmo.com/2022/01/04/using-lombok-and-mapstruct-in-a-maven-project/): Lombok is a java library providing annotations for boilerplate generation. It will handle getters, setters, toStrings, hashCodes, equals, constructors, builders and even injecting Slf4j loggers into you classes. It’s a very powerful addition to Java. MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. When you add Lombok to the classpath, the annotation processing is picked up automatically with no problem. However, MapStruct does not automatically get picked up and requires an addition to the annotationProcessorPaths configuration of the maven-compiler-plugin. However, when the annotationProcessorPaths is explictly[...] - [Let's Encrypt Certificate Management on OpenShift using cert-manager Operator](https://stephennimmo.com/2021/11/22/lets-encrypt-certificate-management-on-openshift-using-cert-manager-operator/): I love me some Let’s Encrypt. This nonprofit certificate authority brought a no-nonsense set of tools and practices to managing certs, with a great price tag. The traditional route for managing certs was with certbot, which made the workflow for attestation of domain ownership very easy. However, the command line doesn’t scale and I was looking for a way to GitOps my certificate management. Installing the Operator The cert-manager project was originally created by Jetstack and was then donated to the CNCF Sandbox. The cert-manager operator installation is easy and they provide great docs on deploying using k8s manifests, helm, or the OLM.[...] - [The avro-maven-plugin configuration doesn't work in the execution definition](https://stephennimmo.com/2021/11/02/the-avro-maven-plugin-configuration-doesnt-work-in-the-execution-definition/): I wanted to write a quick blog because I’ve wasted a full hour figuring out why the imports on the avro-maven-plugin were not working. If you look at the documentation link above, you will see the following configuration example for the avro-maven-plugin. However, the configuration section in the execution definition was not actually respected. Here’s an example. Notice I changes the source and output directory names to blah and flarp. When I run the avro:schema target with debugging (mvn clean avro:schema -X), the output of the configuration in the logs do not reflect the changes. However, when I move the[...] - [Angular Project from Scratch](https://stephennimmo.com/2021/10/12/angular-project-from-scratch/): Last updated: 8/23/2024 This is a writeup for building a very rudimentary, yet clean, web UI using Angular and Bootstrap. As I add more relevant pieces and as the frameworks upgrade, I’ll do my best to keep it up to date. Project Initialization First, we need to create our angular application using the cli. Here’s the command I use. I want to add routing to the project so I add the --routing flag. I also want to use SCSS for all my stylesheets, so I set that using the --style scss flag. The naming is a bit subjective for me.[...] - [Angular Reactive Forms with ng-bootstrap](https://stephennimmo.com/2021/09/27/angular-reactive-forms-with-ng-bootstrap/): The Angular + Bootstrap is still my favorite front end development stack. I love Angular because of the clear separation of the view and controller. It’s probably because of my heavy career background in MVC frameworks such as Struts and Spring MVC, back when things weren’t all in the browser. Angular is also heavily focused on Typescript, which has much stronger typing than pure JS. Bootstrap is also just one of those tools that I find very easy to use, especially because of it’s focus on responsive design. I can easily put together useful UIs quickly which work across most[...] - [Running Testcontainers in OpenShift Pipelines with Docker-in-Docker](https://stephennimmo.com/2021/05/10/running-testcontainers-in-openshift-pipelines-with-docker-in-docker/): Container technologies have had a very strong influence in application development. In addition to the well documented value of containers related to deployment and management of applications, one of the biggest impacts has been the ability to create sets of full integration tests which can run anywhere. The traditional way to test applications was heavily rooted in mocking due to the inability for the developers to run external services in their local development environment. The reason for mocking is to be able to programmatically replicate expected results from an external service, such as a database or messaging broker. Developers would[...] - [Deploying the Red Hat Certified PostgreSQL Container on OpenShift using Kustomize and Sealed Secrets](https://stephennimmo.com/2021/04/13/deploying-the-red-hat-certified-postgresql-container-on-openshift-using-kustomize-and-sealed-secrets/): This blog covers deployment of the Red Hat Certified container for PostgreSQL on OpenShift, which is using RHEL 8.3 UBI from Red Hat. This container image provides a containerized packaging of the PostgreSQL postgres daemon. The postgres server daemon accepts connections from clients and provides access to content from PostgreSQL databases on behalf of the clients. What are the benefits of using a certified container? Certification brings peace of mind to our mutual customers. A solution stack that can be deployed with confidence, knowing that: All components come from a trusted source Platform packages have not been tampered with Container image[...] - [Fully Reactive Quarkus REST API](https://stephennimmo.com/2021/04/07/fully-reactive-quarkus-rest-api/): If you are not familiar with reactive, go check out the intro at: https://quarkus.io/guides/getting-started-reactive Reactive is a very powerful implementation pattern allowing your application to do more with less. The concept is simple: stop blocking. We want everything to be run on the I/O threads but because the I/O threads are used to handle multiple concurrent requests, we want the threads to not be consumed by a blocking call. In previous implementations, there was a hangup because the technology hadn’t made it’s way all the way down the stack, so you would end up with a blend of reactive and[...] - [Enterprise Integration Patterns - Trading](https://stephennimmo.com/2021/03/25/enterprise-integration-patterns-trading/): Energy trading (and trading in general) is heavily rooted in the consumption of external data feeds. In a traditional trading front office, most of the trading tools for executing trades are actually produced by the execution venues themselves. Traders can submit bids and offers on clients such as WebICE and CME Direct and while these clients do provide some information regarding the trades executed and market data, the actual data is ingested using the execution venues data feeds. These data feeds are typically broken into three separate feeds: trade capture, order routing and market data. The trade capture feed is[...] - [Quarkus Integration Testing with Testcontainers and LocalStack](https://stephennimmo.com/2021/03/16/quarkus-integration-testing-with-testcontainers-and-localstack/): With containers, the ability to perform integration testing in a local environment is now table stakes for programmers. We are no longer stuck writing mocks or settling for hacks such as in memory databases. We can use the real databases and middleware to test against, or at least we can use proper facsimiles of the real thing which will provide us the confidence we need to release code that works. Local Cloud Native Services I recently found Localstack. I am working on a project that intended to use S3 as an object store and luckily, the exact tutorial for utilizing[...] - [Quick Tip: OpenAPI UI Index Routing](https://stephennimmo.com/2021/03/02/quick-tip-openapi-ui-index-routing/): When building a REST API, it always easy to have the OpenAPI UI to be readily accessible at the index URL. Here’s how I do it. - [[REF] Quarkus pom.xml](https://stephennimmo.com/2021/02/28/ref-quarkus-pom-xml/): I tweak the Quarkus pom to optimize for my purposes. Here’s a reference. - [Adding Health Checks to Your Quarkus Application](https://stephennimmo.com/2021/02/26/adding-health-checks-to-your-quarkus-application/): As we continue our journey of creating a production ready REST API, we will need to start adding some additional non-functional capabilities to the application. We will be using our existing Customer API application as a base for our continued work. Check out the how we built the base application in the post “Building a Customer API using Quarkus From the Ground Up“. Health checks are an absolutely necessary piece of any application, especially when running in a Kubernetes environment like OpenShift. When the pods are being scheduled and started, it tells Kubernetes when they are ready to be added[...] - [Building a Customer API using Quarkus From the Ground Up](https://stephennimmo.com/2021/02/25/building-a-customer-api-using-quarkus-from-the-ground-up/): Motivation Building a production ready application has a ton of moving parts. Most of the time, developers create a new project using some sort of tool, like maven archetypes, and then go from tutorial to tutorial piecing together all the moving parts needed for their application. This blog post is an attempt to bring all the parts together and have a single full reference to all of the work that needs to be done. GitHub Repo: https://github.com/stephennimmo/quarkus-ground-up Scope and Getting Started Like any project, we need to start with some scope. We are going to build a Customer API. We[...] - [Driving Standards through Chapters: The Spotify Model](https://stephennimmo.com/2021/02/21/driving-standards-through-chapters-the-spotify-model/): Building valuable software is difficult. The technical complexities of implementing what the business needs should be the focus of the development teams. Too many times, the teams can get caught up in activities which detract from their desired focus but are necessary from a technical perspective. Many of these activities are not unique to the team and there are opportunities for groups of development teams to be able to come together and share the benefits of the work. One of the more famous models is the Spotify model, which does a great job in describing a way for teams to[...] - [The Power of Automated Acceptance Tests](https://stephennimmo.com/2021/02/18/the-power-of-automated-acceptance-tests/): The internet is filled with content related to software testing. There are also an overwhelming set of test types, related to the scope of testing. While developers are highly focused on scopes closer to the code itself, the real power comes from scopes closer to the users. For the purposes of this discussion, we will define and clarify what some of the terms mean. Additionally, we are going to exclude non-functional testing, such as performance and resiliency testing, from this discussion and stick to functional tests. Unit Tests – These are very small tests focused on a single method/function within[...] - [GitOpsing Operator Subscriptions in OpenShift](https://stephennimmo.com/2021/02/17/gitopsing-operator-subscriptions-in-openshift/): One of the better features of OpenShift is its fantastic support for finding, installing and managing operators from Red Hat’s Certified Operator catalog. Installing operators can be done easily within the OpenShift Operator management console. However, while this tooling is great for getting things quickly up and running, it’s not very repeatable and requires human clicking through buttons. There are much more automated and repeatable ways to install operators into your cluster using GitOps principles. OpenShift uses the Operator Lifecycle Manager to help users manage their operators running in the cluster. Operator Lifecycle Manager (OLM) helps users install, update, and manage[...] - [Open Source the Energy Industry](https://stephennimmo.com/2020/11/01/open-source-the-energy-industry/): I’v spent most of my career building custom software for large businesses. Living in Houston means most of these large businesses are Fortune 100 energy companies which means most of the custom software I have been involved in delivering revolves around the production, movement or marketing of energy including natural gas, crude oil, refined products as well as power. What most of these companies know, but which have yet to actually do something about, is that most of the baseline software they pay millions of dollars for doesn’t actually give them a strategic advantage – it’s table stakes. The deregulated[...] - [Securing OpenShift ingress with Let's Encrypt](https://stephennimmo.com/2020/10/28/securing-openshift-ingress-with-lets-encrypt/): I’m hosting an OpenShift cluster on a set of 4 Intel NUCs in the home office. I wanted to start integrating with external services, such as GitHub webhooks, but before I could do that I needed to get both DNS setup to resolve to my home network the correct way as well as secure the connections. For the purposes of this writeup, the domain will be an example: mydomain.com Let’s start with DNS. I work at home and although my IP address stays fairly stable, I went ahead and used a DDNS service to set everything up to auto update[...] - [[REF] docker-compose](https://stephennimmo.com/2020/10/26/ref-docker-compose/): I’ve been doing a ton of integration work lately. Here’s a current copy of my “start everything locally” docker compose file. - [Culture Change Requires People to Change](https://stephennimmo.com/2020/10/26/culture-change-people-change/): Most companies say they want “the DevOps” but they aren’t willing to do what’s necessary to get it. By now, you must have seen the reports, statistics and graphs showing all of the benefits of delivering software using DevOps-style methodologies. The data is clear. Companies that adopt DevOps have proven that changing a company IT culture can have a significant impact on business metrics including market position and profitability. It can be done. But does your company have the people to do it? Technical Skills The biggest change an IT organization endures in adopting a DevOps culture is automation. It’s[...] - [Best Extensions for Building a REST API with Quarkus](https://stephennimmo.com/2020/10/19/rest-api-with-quarkus-extensions/): After years in the Spring ecosystem, I’ve moved over to the Java EE side of the world. I started working with Red Hat in April and as an application services solution architect, I work with many different customers running mostly Java EE stack. That being said, prior to joining Red Hat, I had started to use their new runtime, Quarkus, to build some side projects. I’ve really enjoyed not only the ease of use of the runtime, but also getting back into the traditional Java EE CDI world and the Microprofile. Lately, I’ve been building quite a few REST APIs[...] - [Seven Standards Every OpenShift Customer Should Have on Day 1](https://stephennimmo.com/2020/10/17/seven-standards-every-openshift-customer-should-have-on-day-1/): This blog was originally featured on the Red Hat OpenShift Blog:https://www.openshift.com/blog/seven-standards-every-openshift-customer-should-have-on-day-1 The explosion of containers in the enterprise has been awesome. The benefits of containers have proven to be a game-changer for companies wishing to reduce costs, expand their technical capabilities, and move to a more agile, devops-driven organization. The container revolution is bringing new opportunities to companies that have not embarked on a technology refresh in for some time. Containers and Kubernetes are a brand new and completely novel way of managing your applications and infrastructure. This is not the same as the last revolutionary jump from bare metal[...] - [Local Integration Testing](https://stephennimmo.com/2020/09/10/local-integration-testing/): One of the ways containers have dramatically changed the way applications are developed is the ability to run production-like services on the developer machine. For years, developers have been stuck with a proverbial foot on either side of the testing world. They could write unit tests and run them quickly and easily on their local box, but integration testing would either require a choice. A developer could integrate by connecting to a running service in a shared development environment or be forced to wait until after their code is pushed to get the feedback from the CICD process before they[...] - [ERCOT Scraper](https://stephennimmo.com/2020/09/07/ercot-scraper/): The Electric Reliability Council of Texas (ERCOT) manages the flow of electric power to more than 26 million Texas customers — representing about 90 percent of the state’s electric load. As the independent system operator for the region, ERCOT schedules power on an electric grid that connects more than 46,500 miles of transmission lines and 650+ generation units. It also performs financial settlement for the competitive wholesale bulk-power market and administers retail switching for 8 million premises in competitive choice areas. One of the things ERCOT does really well is publish data out to the public. The data they publish ranges from[...] - [.NET Testing in Visual Studio Code](https://stephennimmo.com/2020/07/24/net-testing-in-visual-studio-code/): After some experimentation, I found a local testing pattern that made sense to me. For this case, the application is targeted to be run as a container using .net core 3.1 on linux. It’s a basic crud app and I needed a local database which I wanted to manage using a container as well. Additionally, I was wanting to use source control for managing the database versioning as well. Below is the launch.json for the solution. The two main changes to get things working the way I wanted them to was the preLaunchTask and the postDebugTask. These two attributes take[...] - [Running Embedded PostgreSQL Server for Integration Tests](https://stephennimmo.com/2019/07/12/running-embedded-postgres-sql-server-for-integration-tests/): Note: Don’t do this anymore. Use Testcontainers. I’ve been running H2 for years as an integration testing database. I’ve finally gotten fed up with the language support inconsistencies between it and PostgreSQL. I found an easy to use, easy to configure, full featured embedded SQL server to run in my integration testing. Add the library. Setup the DataSource config for the default profile. Now all your flyway scripts are fully testable and supported in local environments. https://github.com/opentable/otj-pg-embedded Thanks, OpenTable! - [Generating Swagger API documentation using SpringFox](https://stephennimmo.com/2019/07/10/generating-swagger-api-documentation-using-springfox/): Assuming you have a Spring Boot application, using the @RestController annotations, you can generate both the Swagger JSON and the Swagger UI by dropping in a couple of libraries and a single configuration file. Here’s SpringFox. Let’s start with the libraries. Maven example as follows. Once the libraries are added, then you just need to drop in the SpringFox configuration. If you notice, I added an IndexController that redirects requests to the root to the swagger UI. - [Hazelcast Backed MessageStore For QuickFix/J](https://stephennimmo.com/2019/07/09/hazelcast-backed-messagestore-for-quickfix-j/): I’ve been itching to mess around with fix engines again so I started to pry open Quickfix/J and see if I could implement using some updated tech. I quickly noticed the MessageStore implementation could possibly be backed by a distributed IMDG, so I broke out my favorite – Hazelcast. This was quickly implemented on the bus ride home and could stand some additional features to endure load. The next step would be to back the caches with a more persistent, write-behind data store. This would allow data to move to a more persistent place but still keep the latest messages[...] ## Pages - [Cheatsheet](https://stephennimmo.com/cheatsheet/): Project Init Quarkus Rest API Angular Inside of Quinoa Angular OpenShift Delete the CRDs for an Operator Graceful Node Reboot - [Favorites](https://stephennimmo.com/favorites/): Books Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations Sooner Safer Happier: Antipatterns and Patterns for Business Agility Modern Software Engineering: Doing What Works to Build Better Software Faster Clean Code: A Handbook of Agile Software Craftsmanship Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation The War of Art: Break Through the Blocks and Win Your Inner Creative Battles Podcasts Energy Insider’s Guide to Energy Digital Wildcatters Podcast Videos Trading at light speed: designing low latency systems in C++ – David Gross – Meeting C++ 2022 CppCon 2017: Carl Cook[...] - [About](https://stephennimmo.com/about/): Stephen is an experienced software engineer and solution architect with 20+ years of experience, including a decade of technical and management consulting. His primary domains of expertise is in commodities trading and financial services, spending much of his career around building trading and risk management applications for Fortune 100 companies. His current focus centers on Red Hat’s OpenShift Container Platform, the leading hybrid cloud Kubernetes application platform. As an application services specialist, he develops and delivers technically focused content, such as workshops and presentations, to customers in an effort to help their teams adopt the new technologies and delivery methodologies.[...] [comment]: # (Generated by Hostinger Tools Plugin)