Dependency Hell

It is not a secret even if we try to hide from it.

The dependencies in writing any application today is a nightmare and a lot of work to maintain straight.

Google has a tool to look at some open-source project and as much as it is not the first of such tool, I like the graph mode available.

https://deps.dev

I was trying to find something interesting to look at but most java projects I looked at had simple graphs. I found this one that makes the tool visual shine a bit:

https://deps.dev/maven/com.android.tools.build%3Agradle/2.3.0/dependencies/graph

Interesting tool.

Keycloak Identity Provider ID

That took a couple of hours to figure out so let’s share some notes.

I have code that creates the required Keycloak Realms and configures a few items in each of them.

One of those configuration is to create the Identity Provider so that we can link users to another realm. Internal SSO if you will.

I tested this with Keycloak 11.0.3.

I did not understand that the Identity Provider ID needed to be one of the specific values since it is only a string that you pass to it. Sometimes I wish they could use an enum to help users make sense of it quickly.

After getting errors that it was a required fields and trying a few values that did not make sense to Keycloak.

10:39:07.587 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "{"errorMessage":"Invalid identity provider id [password]"}"

10:41:50.814 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "{"errorMessage":"Invalid identity provider id [EmailAuthProviderID]"}"

I tried keycloak-oidc and it worked. So the value needs to be one of these:

  • saml
  • oidc
  • keycloak-oidc

You could also use one of the social identity provider.

I also understood to take the config from the endpoint:

http://192.168.1.50:8080/auth/realms/Customer/.well-known/openid-configuration

Sample code:

IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
identityProviderRepresentation.setDisplayName(IDP);
identityProviderRepresentation.setProviderId("keycloak-oidc");
identityProviderRepresentation.setAlias(IDP);
Map<String, String> config = new HashMap<>();
config.put("issuer", "http://192.168.1.50:8080/auth/realms/Customer");
config.put("authorization_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/auth");
config.put("token_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/token");
config.put("introspection_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/token/introspect");
config.put("userinfo_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/userinfo");
config.put("end_session_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/logout");
config.put("jwks_uri", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/certs");
config.put("check_session_iframe", "http://192.168.1.50:8080/auth/realms/Customer/protocol/openid-connect/login-status-iframe.html");
config.put("grant_types_supported", "[\"authorization_code\",\"implicit\",\"refresh_token\",\"password\",\"client_credentials\"]");
config.put("response_types_supported", "[\"code\",\"none\",\"id_token\",\"token\",\"id_token token\",\"code id_token\",\"code token\",\"code id_token token\"]");
config.put("subject_types_supported", "[\"public\",\"pairwise\"]");
config.put("id_token_signing_alg_values_supported", "[\"PS384\",\"ES384\",\"RS384\",\"HS256\",\"HS512\",\"ES256\",\"RS256\",\"HS384\",\"ES512\",\"PS256\",\"PS512\",\"RS512\"]");
config.put("id_token_encryption_alg_values_supported", "[\"RSA-OAEP\",\"RSA1_5\"]");
config.put("id_token_encryption_enc_values_supported", "[\"A256GCM\",\"A192GCM\",\"A128GCM\",\"A128CBC-HS256\",\"A192CBC-HS384\",\"A256CBC-HS512\"]");
config.put("userinfo_signing_alg_values_supported", "[\"PS384\",\"ES384\",\"RS384\",\"HS256\",\"HS512\",\"ES256\",\"RS256\",\"HS384\",\"ES512\",\"PS256\",\"PS512\",\"RS512\",\"none\"]");
config.put("request_object_signing_alg_values_supported", "[\"PS384\",\"ES384\",\"RS384\",\"HS256\",\"HS512\",\"ES256\",\"RS256\",\"HS384\",\"ES512\",\"PS256\",\"PS512\",\"RS512\",\"none\"]");
config.put("response_modes_supported", "[\"query\",\"fragment\",\"form_post\"]");
config.put("registration_endpoint", "http://192.168.1.50:8080/auth/realms/Customer/clients-registrations/openid-connect");
config.put("token_endpoint_auth_methods_supported", "[\"private_key_jwt\",\"client_secret_basic\",\"client_secret_post\",\"tls_client_auth\",\"client_secret_jwt\"]");
config.put("token_endpoint_auth_signing_alg_values_supported", "[\"PS384\",\"ES384\",\"RS384\",\"HS256\",\"HS512\",\"ES256\",\"RS256\",\"HS384\",\"ES512\",\"PS256\",\"PS512\",\"RS512\"]");
config.put("claims_supported", "[\"aud\",\"sub\",\"iss\",\"auth_time\",\"name\",\"given_name\",\"family_name\",\"preferred_username\",\"email\",\"acr\"]");
config.put("claim_types_supported", "[\"normal\"]");
config.put("claims_parameter_supported", "false");
config.put("scopes_supported", "[\"openid\",\"offline_access\", \"profile\",\"email\",\"address\",\"phone\",\"roles\",\"web-origins\",\"microprofile-jwt\"]");
config.put("request_parameter_supported", "true");
config.put("request_uri_parameter_supported", "true");
config.put("code_challenge_methods_supported", "[\"plain\",\"S256\"]");
config.put("tls_client_certificate_bound_access_tokens", "true");
identityProviderRepresentation.setConfig(config);

Finally, I have creation of the Identity Provider in my realm and I can link users to it.

No JDK 16 for Gradle 6

That was an annoying configuration where my project was using JDK 11 but I did not see that my Gradle settings were using JDK 16 and that kept giving me the error:

Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:

After I removed JDK 16 from my project, it pointed me to the fact that Gradle had no JDK configured. Hint.

Now that everything is using JDK 11, life is beautiful again in my IDE.

Development Software Management

I have used a simple tool for many years to manage the development software I need on my Linux workstation:

The installation is very simple has highlighted on their home page:

curl -s "https://get.sdkman.io" | bash

A bit scary to be running a script that you download straight into a shell but you can do as you see fit to examine the script first if you prefer.

I use it to install Java, Gradle, Kotlin, Spark, VisualVM and it allows you to try a few other framework. You can even decided which Java vendor you want to use.

A big advantage is that it installs all these software in your home directory and it does not affect the system. You can also quickly switch from a version to another and that has proven very useful more than once.

Quick Installation of K8S

The tutorials out there to install Kubernetes on your workstation are great but I simply need a quick series of steps. This is to install Micro-K8S on a Ubuntu workstation.

sudo snap install microk8s --classic

I also create a few aliases because typing the entire commands is a bit long

sudo microk8s kubectl get all -A

Aliases:

vi .bash_aliases

alias kgaa='sudo microk8s kubectl get all -A'
alias kga='sudo microk8s kubectl get all'
alias kg='sudo microk8s kubectl get'
alias kp='sudo microk8s kubectl get pods'
alias kn='sudo microk8s kubectl get ns'
alias kd='sudo microk8s kubectl describe'

source .bash_aliases

A Brave Browser

With all the tracking that exists today, I have been looking at minimizing what all these big corporations are collecting about me. There are many ways to do this but I decided to try the Brave browser.

It is easy to install on Ubuntu from these instructions: https://brave.com/linux/#linux

Only a few commands:

sudo apt install apt-transport-https curl gnupg

curl -s https://brave-browser-apt-release.s3.brave.com/brave-core.asc | sudo apt-key --keyring /etc/apt/trusted.gpg.d/brave-browser-release.gpg add -

echo "deb [arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main" | sudo tee /etc/apt/sources.list.d/brave-browser-release.list

sudo apt update

sudo apt install brave-browser

It is done in less than 2 minutes.

The first time I ran Brave I changed the default search engine to be https://duckduckgo.com/ so that I am closing another door on the tracking.

I have been using it for a few weeks and I am very happy.

It is always interesting to see the number of items that have been blocked. There is a lot of tracking going on (obviously).

Why run Kubernetes at home

In a discussion with co-worker the question was asked (as a rhetorical one) and it got me thinking about it.

Why would you run Kubernetes at home?

There is the obvious reason that I am testing for work a certain configuration or an operator or a new version of a container. These are more work reasons and they just happen to be executed at home since so many of us work from home.

For my home network and setup, why would I run Kubernetes?

A similar setup that we could compare with is having a raid device for your storage need. Many options exists for home to allow you to store all the photos and movies. If you have a raid device you can then replace a failed hard disk and not lose any of your data.

Could we apply the same rationale to the application you need to run on your home network?

Plex has a container available. Imagine that you are running it on a node and if it has some hardware issue, you can still watch your movies without having to repair anything first.

What I wonder is how many other software that I use at home would benefit from this.

Installing OpenJDK 11 on macOS (again)

I have started to use SDKMan to simplify my life with installing and updating many software that I use regurlarly. Java is one of them. It is the simplest thing to install java with sdk man:

sdk i java 11.0.8.hs-adpt

As simple as that.

I can just use Java 11 from that point on. You can also install Java 8 and switch between both. Convenient when you have to maintain older software.

If I want to update to a new release, I simply have to type:

sdk ug java

Can it really get any easier?

I use the SDKMan on my linux laptop as well and it easily works on both.

I also manage gradle, spring-boot and spark with SDKMan so most of my coding tools are kept up to date with the same tool.

Learning Kotlin by building

It took longer than I want to admit to have a simple Koltin application build this morning. The build.gradle.kts needed a bit of tweaking to get a simple 3 class application with a single test to properly build.

Here is the content of the build.gradle.kts:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.4.10"
}
dependencies {
implementation(kotlin("stdlib"))
implementation("org.jetbrains.kotlin:kotlin-test:1.4.10")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.2")
testImplementation("org.assertj:assertj-core:3.17.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.2")
}
repositories {
mavenCentral()
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions {
jvmTarget = "11"
}
val compileTestKotlin: KotlinCompile by tasks
compileTestKotlin.kotlinOptions {
jvmTarget = "11"
}

Lens

I just discovered this application for k8s and there is a lot to like. It allows me to look at a k8s cluster in a whole new way. It is so easy to see everything that is running and all the resources that have been created.

This is quite the upgrade from the command line to see things quickly. I am not abandoning the cli but I am certainly going to look here when I need to troubleshoot because I have a better view of everything that is on the cluster.

They want you to look at this software as the k8s IDE. I will have to explore a bit more to see how it can me another IDE for my use cases.