There are so many ways to install OpenShift: Assisted Installer, UPI, IPI, Red Hat Advanced Cluster Management and ZTP. However I have always longed for a single ISO image I could just boot my physical hardware and it would form a OpenShift cluster. Well that dream is on course to become a reality with the Agent Installer a tool that can generate an ephemeral OpenShift installation image. In the following blog I will demonstrate how to use this early incarnation of the tool.
$ git clone https://github.com/openshift/installer Cloning into 'installer'... remote: Enumerating objects: 204497, done. remote: Counting objects: 100% (210/210), done. remote: Compressing objects: 100% (130/130), done. remote: Total 204497 (delta 99), reused 153 (delta 70), pack-reused 204287 Receiving objects: 100% (204497/204497), 873.44 MiB | 10.53 MiB/s, done. Resolving deltas: 100% (132947/132947), done. Updating files: 100% (86883/86883), done. $ git checkout 88db7ef Updating files: 100% (23993/23993), done. Note: switching to '88db7ef'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at 88db7eff2 Fix unnecessary delays in start-cluster-installation $ git branch * (HEAD detached at 88db7eff2) master
$ hack/build.sh
+ minimum_go_version=1.17
++ go version
++ cut -d ' ' -f 3
+ current_go_version=go1.17.7
++ version 1.17.7
++ IFS=.
++ printf '%03d%03d%03d\n' 1 17 7
++ unset IFS
++ version 1.17
++ IFS=.
++ printf '%03d%03d%03d\n' 1 17
++ unset IFS
+ '[' 001017007 -lt 001017000 ']'
+ make -C terraform all
make: Entering directory '/home/bschmaus/installer/terraform'
cd providers/alicloud; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-alicloud "$path"; \
zip -1j ../../bin/terraform-provider-alicloud.zip ../../bin/terraform-provider-alicloud;
adding: terraform-provider-alicloud (deflated 81%)
cd providers/aws; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-aws "$path"; \
zip -1j ../../bin/terraform-provider-aws.zip ../../bin/terraform-provider-aws;
adding: terraform-provider-aws (deflated 75%)
cd providers/azureprivatedns; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-azureprivatedns "$path"; \
zip -1j ../../bin/terraform-provider-azureprivatedns.zip ../../bin/terraform-provider-azureprivatedns;
adding: terraform-provider-azureprivatedns (deflated 62%)
cd providers/azurerm; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-azurerm "$path"; \
zip -1j ../../bin/terraform-provider-azurerm.zip ../../bin/terraform-provider-azurerm;
adding: terraform-provider-azurerm (deflated 77%)
cd providers/azurestack; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-azurestack "$path"; \
zip -1j ../../bin/terraform-provider-azurestack.zip ../../bin/terraform-provider-azurestack;
adding: terraform-provider-azurestack (deflated 64%)
cd providers/google; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-google "$path"; \
zip -1j ../../bin/terraform-provider-google.zip ../../bin/terraform-provider-google;
adding: terraform-provider-google (deflated 68%)
cd providers/ibm; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-ibm "$path"; \
zip -1j ../../bin/terraform-provider-ibm.zip ../../bin/terraform-provider-ibm;
adding: terraform-provider-ibm (deflated 67%)
cd providers/ignition; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-ignition "$path"; \
zip -1j ../../bin/terraform-provider-ignition.zip ../../bin/terraform-provider-ignition;
adding: terraform-provider-ignition (deflated 61%)
cd providers/ironic; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-ironic "$path"; \
zip -1j ../../bin/terraform-provider-ironic.zip ../../bin/terraform-provider-ironic;
adding: terraform-provider-ironic (deflated 60%)
cd providers/libvirt; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-libvirt "$path"; \
zip -1j ../../bin/terraform-provider-libvirt.zip ../../bin/terraform-provider-libvirt;
adding: terraform-provider-libvirt (deflated 61%)
cd providers/local; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-local "$path"; \
zip -1j ../../bin/terraform-provider-local.zip ../../bin/terraform-provider-local;
adding: terraform-provider-local (deflated 59%)
cd providers/nutanix; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-nutanix "$path"; \
zip -1j ../../bin/terraform-provider-nutanix.zip ../../bin/terraform-provider-nutanix;
adding: terraform-provider-nutanix (deflated 60%)
cd providers/openstack; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-openstack "$path"; \
zip -1j ../../bin/terraform-provider-openstack.zip ../../bin/terraform-provider-openstack;
adding: terraform-provider-openstack (deflated 62%)
cd providers/ovirt; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-ovirt "$path"; \
zip -1j ../../bin/terraform-provider-ovirt.zip ../../bin/terraform-provider-ovirt;
adding: terraform-provider-ovirt (deflated 66%)
cd providers/random; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-random "$path"; \
zip -1j ../../bin/terraform-provider-random.zip ../../bin/terraform-provider-random;
adding: terraform-provider-random (deflated 59%)
cd providers/vsphere; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-vsphere "$path"; \
zip -1j ../../bin/terraform-provider-vsphere.zip ../../bin/terraform-provider-vsphere;
adding: terraform-provider-vsphere (deflated 68%)
cd providers/vsphereprivate; \
if [ -f main.go ]; then path="."; else path=./vendor/`grep _ tools.go|awk '{ print $2 }'|sed 's|"||g'`; fi; \
go build -ldflags "-s -w" -o ../../bin/terraform-provider-vsphereprivate "$path"; \
zip -1j ../../bin/terraform-provider-vsphereprivate.zip ../../bin/terraform-provider-vsphereprivate;
adding: terraform-provider-vsphereprivate (deflated 69%)
cd terraform; \
go build -ldflags "-s -w" -o ../bin/terraform ./vendor/github.com/hashicorp/terraform
make: Leaving directory '/home/bschmaus/installer/terraform'
+ copy_terraform_to_mirror
++ go env GOOS
++ go env GOARCH
+ TARGET_OS_ARCH=linux_amd64
+ rm -rf '/home/bschmaus/installer/pkg/terraform/providers/mirror/*/'
+ find /home/bschmaus/installer/terraform/bin/ -maxdepth 1 -name 'terraform-provider-*.zip' -exec bash -c '
providerName="$(basename "$1" | cut -d - -f 3 | cut -d . -f 1)"
targetOSArch="$2"
dstDir="${PWD}/pkg/terraform/providers/mirror/openshift/local/$providerName"
mkdir -p "$dstDir"
echo "Copying $providerName provider to mirror"
cp "$1" "$dstDir/terraform-provider-${providerName}_1.0.0_${targetOSArch}.zip"
' shell '{}' linux_amd64 ';'
Copying alicloud provider to mirror
Copying aws provider to mirror
Copying azureprivatedns provider to mirror
Copying azurerm provider to mirror
Copying azurestack provider to mirror
Copying google provider to mirror
Copying ibm provider to mirror
Copying ignition provider to mirror
Copying ironic provider to mirror
Copying libvirt provider to mirror
Copying local provider to mirror
Copying nutanix provider to mirror
Copying openstack provider to mirror
Copying ovirt provider to mirror
Copying random provider to mirror
Copying vsphere provider to mirror
Copying vsphereprivate provider to mirror
+ mkdir -p /home/bschmaus/installer/pkg/terraform/providers/mirror/terraform/
+ cp /home/bschmaus/installer/terraform/bin/terraform /home/bschmaus/installer/pkg/terraform/providers/mirror/terraform/
+ MODE=release
++ git rev-parse --verify 'HEAD^{commit}'
+ GIT_COMMIT=d74e210f30edf110764d87c8223a18b8a9952253
++ git describe --always --abbrev=40 --dirty
+ GIT_TAG=unreleased-master-6040-gd74e210f30edf110764d87c8223a18b8a9952253
+ DEFAULT_ARCH=amd64
+ GOFLAGS=-mod=vendor
+ LDFLAGS=' -X github.com/openshift/installer/pkg/version.Raw=unreleased-master-6040-gd74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.Commit=d74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.defaultArch=amd64'
+ TAGS=
+ OUTPUT=bin/openshift-install
+ export CGO_ENABLED=0
+ CGO_ENABLED=0
+ case "${MODE}" in
+ LDFLAGS=' -X github.com/openshift/installer/pkg/version.Raw=unreleased-master-6040-gd74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.Commit=d74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.defaultArch=amd64 -s -w'
+ TAGS=' release'
+ test '' '!=' y
+ go generate ./data
writing assets_vfsdata.go
+ echo ' release'
+ grep -q libvirt
+ go build -mod=vendor -ldflags ' -X github.com/openshift/installer/pkg/version.Raw=unreleased-master-6040-gd74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.Commit=d74e210f30edf110764d87c8223a18b8a9952253 -X github.com/openshift/installer/pkg/version.defaultArch=amd64 -s -w' -tags ' release' -o bin/openshift-install ./cmd/openshift-install
$ pwd /home/bschmaus/installer $ mkdir manifests
$ cat << EOF > ./manifests/agent-cluster-install.yaml
apiVersion: extensions.hive.openshift.io/v1beta1
kind: AgentClusterInstall
metadata:
name: kni22
namespace: kni22
spec:
apiVIP: 192.168.0.125
ingressVIP: 192.168.0.126
clusterDeploymentRef:
name: kni22
imageSetRef:
name: openshift-v4.10.0
networking:
clusterNetwork:
- cidr: 10.128.0.0/14
hostPrefix: 23
serviceNetwork:
- 172.30.0.0/16
provisionRequirements:
controlPlaneAgents: 3
workerAgents: 0
sshPublicKey: 'INSERT PUBLIC SSH KEY HERE'
EOF
$ cat << EOF > ./manifests/cluster-deployment.yaml
apiVersion: hive.openshift.io/v1
kind: ClusterDeployment
metadata:
name: kni22
namespace: kni22
spec:
baseDomain: schmaustech.com
clusterInstallRef:
group: extensions.hive.openshift.io
kind: AgentClusterInstall
name: kni22-agent-cluster-install
version: v1beta1
clusterName: kni22
controlPlaneConfig:
servingCertificates: {}
platform:
agentBareMetal:
agentSelector:
matchLabels:
bla: aaa
pullSecretRef:
name: pull-secret
EOF
$ cat << EOF > ./manifests/cluster-image-set.yaml apiVersion: hive.openshift.io/v1 kind: ClusterImageSet metadata: name: ocp-release-4.10.10-x86-64-for-4.10.0-0-to-4.11.0-0 spec: releaseImage: quay.io/openshift-release-dev/ocp-release:4.10.10-x86_64 EOF
$ cat << EOF > ./manifests/infraenv.yaml
apiVersion: agent-install.openshift.io/v1beta1
kind: InfraEnv
metadata:
name: kni22
namespace: kni22
spec:
clusterRef:
name: kni22
namespace: kni22
pullSecretRef:
name: pull-secret
sshAuthorizedKey: 'INSERT PUBLIC SSH KEY HERE'
nmStateConfigLabelSelector:
matchLabels:
kni22-nmstate-label-name: kni22-nmstate-label-value
EOF
$ cat << EOF > ./manifests/nmstateconfig.yaml
---
apiVersion: agent-install.openshift.io/v1beta1
kind: NMStateConfig
metadata:
name: mynmstateconfig01
namespace: openshift-machine-api
labels:
kni22-nmstate-label-name: kni22-nmstate-label-value
spec:
config:
interfaces:
- name: enp2s0
type: ethernet
state: up
mac-address: 52:54:00:e7:05:72
ipv4:
enabled: true
address:
- ip: 192.168.0.116
prefix-length: 24
dhcp: false
dns-resolver:
config:
server:
- 192.168.0.10
routes:
config:
- destination: 0.0.0.0/0
next-hop-address: 192.168.0.1
next-hop-interface: enp2s0
table-id: 254
interfaces:
- name: "enp2s0"
macAddress: 52:54:00:e7:05:72
---
apiVersion: agent-install.openshift.io/v1beta1
kind: NMStateConfig
metadata:
name: mynmstateconfig02
namespace: openshift-machine-api
labels:
kni22-nmstate-label-name: kni22-nmstate-label-value
spec:
config:
interfaces:
- name: enp2s0
type: ethernet
state: up
mac-address: 52:54:00:95:fd:f3
ipv4:
enabled: true
address:
- ip: 192.168.0.117
prefix-length: 24
dhcp: false
dns-resolver:
config:
server:
- 192.168.0.10
routes:
config:
- destination: 0.0.0.0/0
next-hop-address: 192.168.0.1
next-hop-interface: enp2s0
table-id: 254
interfaces:
- name: "enp2s0"
macAddress: 52:54:00:95:fd:f3
---
apiVersion: agent-install.openshift.io/v1beta1
kind: NMStateConfig
metadata:
name: mynmstateconfig03
namespace: openshift-machine-api
labels:
kni22-nmstate-label-name: kni22-nmstate-label-value
spec:
config:
interfaces:
- name: enp2s0
type: ethernet
state: up
mac-address: 52:54:00:e8:b9:18
ipv4:
enabled: true
address:
- ip: 192.168.0.118
prefix-length: 24
dhcp: false
dns-resolver:
config:
server:
- 192.168.0.10
routes:
config:
- destination: 0.0.0.0/0
next-hop-address: 192.168.0.1
next-hop-interface: enp2s0
table-id: 254
interfaces:
- name: "enp2s0"
macAddress: 52:54:00:e8:b9:18
EOF
$ cat << EOF > ./manifests/pull-secret.yaml apiVersion: v1 kind: Secret type: kubernetes.io/dockerconfigjson metadata: name: pull-secret namespace: kni22 stringData: .dockerconfigjson: 'INSERT JSON FORMATTED PULL-SECRET' EOF
$ ls -1 ./manifests/ agent-cluster-install.yaml cluster-deployment.yaml cluster-image-set.yaml infraenv.yaml nmstateconfig.yaml pull-secret.yaml
$ bin/openshift-install agent create image INFO adding MAC interface map to host static network config - Name: enp2s0 MacAddress: 52:54:00:e7:05:72 INFO adding MAC interface map to host static network config - Name: enp2s0 MacAddress: 52:54:00:95:fd:f3 INFO adding MAC interface map to host static network config - Name: enp2s0 MacAddress: 52:54:00:e8:b9:18 INFO[0000] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO[0000] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO[0001] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO[0001] Start configuring static network for 3 hosts pkg=manifests INFO[0001] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO[0001] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO[0001] Adding NMConnection file <enp2s0 .nmconnection=""> pkg=manifests INFO Obtaining RHCOS image file from 'https://rhcos-redirector.apps.art.xq1c.p1.openshiftapps.com/art/storage/releases/rhcos-4.11/411.85.202203181601-0/x86_64/rhcos-411.85.202203181601-0-live.x86_64.iso' INFO
$ ls -l ./output/ total 1073152 -rw-rw-r--. 1 bschmaus bschmaus 1098907648 May 20 08:55 agent.iso
$ scp ./output/agent.iso root@192.168.0.22:/var/lib/libvirt/images/ root@192.168.0.22's password: agent.iso
# virsh list --all Id Name State ---------------------------- - asus3-vm1 shut off - asus3-vm2 shut off - asus3-vm3 shut off - asus3-vm4 shut off - asus3-vm5 shut off - asus3-vm6 shut off # virsh domblklist asus3-vm1 Target Source --------------------------------------------------- sda /var/lib/libvirt/images/asus3-vm1.qcow2 sdb /var/lib/libvirt/images/agent.iso # virsh domblklist asus3-vm2 Target Source --------------------------------------------------- sda /var/lib/libvirt/images/asus3-vm2.qcow2 sdb /var/lib/libvirt/images/agent.iso # virsh domblklist asus3-vm3 Target Source --------------------------------------------------- sda /var/lib/libvirt/images/asus3-vm3.qcow2 sdb /var/lib/libvirt/images/agent.iso
# virsh start asus3-vm1 Domain asus3-vm1 started
$ export KUBECONFIG=/home/bschmaus/kubeconfig-kni22 $ oc get nodes NAME STATUS ROLES AGE VERSION asus3-vm1 Ready master,worker 2m v1.23.5+9ce5071 asus3-vm2 Ready master,worker 29m v1.23.5+9ce5071 asus3-vm3 Ready master,worker 29m v1.23.5+9ce5071
$ oc get co NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE authentication 4.10.10 False True True 18m WellKnownAvailable: The well-known endpoint is not yet available: need at least 3 kube-apiservers, got 2 baremetal 4.10.10 True False False 17m cloud-controller-manager 4.10.10 True False False 29m cloud-credential 4.10.10 True False False 34m cluster-autoscaler 4.10.10 True False False 16m config-operator 4.10.10 True False False 18m console 4.10.10 True False False 4m33s csi-snapshot-controller 4.10.10 True False False 18m dns 4.10.10 True False False 17m etcd 4.10.10 True True False 16m NodeInstallerProgressing: 1 nodes are at revision 0; 2 nodes are at revision 4; 0 nodes have achieved new revision 5 image-registry 4.10.10 True False False 9m44s ingress 4.10.10 True False False 11m insights 4.10.10 True False False 12m kube-apiserver 4.10.10 True True False 4m29s NodeInstallerProgressing: 1 nodes are at revision 0; 2 nodes are at revision 6 kube-controller-manager 4.10.10 True True False 14m NodeInstallerProgressing: 1 nodes are at revision 0; 2 nodes are at revision 7 kube-scheduler 4.10.10 True True False 14m NodeInstallerProgressing: 1 nodes are at revision 0; 2 nodes are at revision 6 kube-storage-version-migrator 4.10.10 True False False 18m machine-api 4.10.10 True False False 7m53s machine-approver 4.10.10 True False False 17m machine-config 4.10.10 True False False 17m marketplace 4.10.10 True False False 16m monitoring 4.10.10 True False False 5m52s network 4.10.10 True True False 19m DaemonSet "openshift-multus/network-metrics-daemon" is not available (awaiting 1 nodes)... node-tuning 4.10.10 True False False 15m openshift-apiserver 4.10.10 True False False 4m45s openshift-controller-manager 4.10.10 True False False 15m openshift-samples 4.10.10 True False False 7m37s operator-lifecycle-manager 4.10.10 True False False 17m operator-lifecycle-manager-catalog 4.10.10 True False False 17m operator-lifecycle-manager-packageserver 4.10.10 True False False 11m service-ca 4.10.10 True False False 19m storage 4.10.10 True False False 19m
$ oc get co NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE authentication 4.10.10 True False False 13m baremetal 4.10.10 True False False 31m cloud-controller-manager 4.10.10 True False False 43m cloud-credential 4.10.10 True False False 49m cluster-autoscaler 4.10.10 True False False 31m config-operator 4.10.10 True False False 33m console 4.10.10 True False False 19m csi-snapshot-controller 4.10.10 True False False 33m dns 4.10.10 True False False 32m etcd 4.10.10 True False False 31m image-registry 4.10.10 True False False 24m ingress 4.10.10 True False False 26m insights 4.10.10 True False False 27m kube-apiserver 4.10.10 True False False 19m kube-controller-manager 4.10.10 True False False 29m kube-scheduler 4.10.10 True False False 28m kube-storage-version-migrator 4.10.10 True False False 33m machine-api 4.10.10 True False False 22m machine-approver 4.10.10 True False False 32m machine-config 4.10.10 True False False 32m marketplace 4.10.10 True False False 31m monitoring 4.10.10 True False False 20m network 4.10.10 True False False 34m node-tuning 4.10.10 True False False 30m openshift-apiserver 4.10.10 True False False 19m openshift-controller-manager 4.10.10 True False False 29m openshift-samples 4.10.10 True False False 22m operator-lifecycle-manager 4.10.10 True False False 32m operator-lifecycle-manager-catalog 4.10.10 True False False 32m operator-lifecycle-manager-packageserver 4.10.10 True False False 26m service-ca 4.10.10 True False False 34m storage 4.10.10 True False False 34m
$ mkdir ~/kuberotate $cd ~/kuberotate $ cat << EOF > ./kubeadmin-rotate.go
package main import ( "fmt" "crypto/rand" "golang.org/x/crypto/bcrypt" b64 "encoding/base64" "math/big" ) // generateRandomPasswordHash generates a hash of a random ASCII password // 5char-5char-5char-5char func generateRandomPasswordHash(length int) (string, string, error) { const ( lowerLetters = "abcdefghijkmnopqrstuvwxyz" upperLetters = "ABCDEFGHIJKLMNPQRSTUVWXYZ" digits = "23456789" all = lowerLetters + upperLetters + digits ) var password string for i := 0; i < length; i++ { n, err := rand.Int(rand.Reader, big.NewInt(int64(len(all)))) if err != nil { return "", "", err } newchar := string(all[n.Int64()]) if password == "" { password = newchar } if i < length-1 { n, err = rand.Int(rand.Reader, big.NewInt(int64(len(password)+1))) if err != nil { return "", "",err } j := n.Int64() password = password[0:j] + newchar + password[j:] } } pw := []rune(password) for _, replace := range []int{5, 11, 17} { pw[replace] = '-' } bytes, err := bcrypt.GenerateFromPassword([]byte(string(pw)), bcrypt.DefaultCost) if err != nil { return "", "",err } return string(pw), string(bytes), nil } func main() { password, hash, err := generateRandomPasswordHash(23) if err != nil { fmt.Println(err.Error()) return } fmt.Printf("Actual Password: %s\n", password) fmt.Printf("Hashed Password: %s\n", hash) fmt.Printf("Data to Change in Secret: %s\n", b64.StdEncoding.EncodeToString([]byte(hash))) } EOF
$ go mod init kuberotate go: creating new go.mod: module kuberotate
$ go mod tidy go: finding module for package golang.org/x/crypto/bcrypt go: found golang.org/x/crypto/bcrypt in golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898
$ go run kubeadmin-rotate.go Actual Password: gWdYr-62GLh-QIynG-Boj7n Hashed Password: $2a$10$DN48Jp4YkuEEVMWZNyOR2.LkLn1ZZOJOtzR8c9detf1lVAQ2iVQGK Data to Change in Secret: JDJhJDEwJERONDhKcDRZa3VFRVZNV1pOeU9SMi5Ma0xuMVpaT0pPdHpSOGM5ZGV0ZjFsVkFRMmlWUUdL
$ oc patch secret -n kube-system kubeadmin --type json -p '[{"op": "replace", "path": "/data/kubeadmin", "value": "JDJhJDEwJERONDhKcDRZa3VFRVZNV1pOeU9SMi5Ma0xuMVpaT0pPdHpSOGM5ZGV0ZjFsVkFRMmlWUUdL"}]'
secret/kubeadmin patched









