Skip to content

Commit

Permalink
Add hypershift-agent-automation cli application
Browse files Browse the repository at this point in the history
  • Loading branch information
dharaneeshvrd committed Sep 27, 2023
1 parent 00a92c1 commit 959323e
Show file tree
Hide file tree
Showing 18 changed files with 2,133 additions and 2 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
# Go workspace file
go.work


# editor and IDE paraphernalia
.idea
*.swp
Expand All @@ -33,3 +32,10 @@ go.work
/kubeconfig
.dockerignore
.docker

*.yaml
*.iso

bin/

env.sh
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GO_GCFLAGS ?= -gcflags=all='-N -l'
GO=GO111MODULE=on go
GO_BUILD_RECIPE=CGO_ENABLED=0 $(GO) build $(GO_GCFLAGS)

OUT_DIR ?= bin

all: build

.PHONY: build
build:
$(GO_BUILD_RECIPE) -o $(OUT_DIR)/hypershift-agent-automation .

clean:
rm -rf $(OUT_DIR)/*
98 changes: 97 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,97 @@
# hypershift-agent-automation
# Hypershift Agent Automation

Cli tool to create and destroy agent based hypershift hosted cluster on PowerVC platform.

## Setup:
This tool is designed only to create and destroy the agent cluster.

### Pre-Req:
- **Management Cluster** - An OCP cluster which will be used to host the agent based hosted cluster. Only x86 type of management cluster is supported as of now. Need to set up below things in management cluster.
- **MCE** - Refer this [link](https://github.com/hypershift-on-power/hack/wiki/Agent-based-Hosted-Cluster-on-PowerVM-using-MCE-with-Assisted-Service-and-Hypershift#install-the-mce-operator) to install the MCE operator.
- **AgentServiceConfig** - Refer this [link](https://github.com/hypershift-on-power/hack/wiki/Agent-based-Hosted-Cluster-on-PowerVM-using-MCE-with-Assisted-Service-and-Hypershift#create-agentserviceconfig) to configure agentserviceconfig.
- A valid [pull secret](https://cloud.redhat.com/openshift/install/aws/installer-provisioned) file.
- The OpenShift CLI (oc) or Kubernetes CLI (kubectl).
- **Hypershift**
```shell
git clone https://github.com/openshift/hypershift.git
cd hypershift
make build
sudo install -m 0755 bin/hypershift /usr/local/bin/hypershift
```
- **Hypershift Agent Automation**
```shell
git clone https://github.com/ppc64le-cloud/hypershift-agent-automation
cd hypershift-agent-automation
make build
sudo install -m 0755 bin/hypershift-agent-automation /usr/local/bin/hypershift-agent-automation
```

### Infra:
Need to set below env vars to connect HMC, VIOS and PowerVC.

```shell
# To get authenticated with PowerVC(OpenStack Client)
export OS_USERNAME=''
export OS_PASSWORD=''
export OS_IDENTITY_API_VERSION=''
export OS_AUTH_URL=''
export OS_CACERT=''
export OS_REGION_NAME=''
export OS_PROJECT_DOMAIN_NAME=''
export OS_PROJECT_NAME=''
export OS_TENANT_NAME=''
export OS_USER_DOMAIN_NAME=''

# Required PowerVC resource names
export POWERVC_STORAGE_TEMPLATE=''
export POWERVC_HOST=''
export POWERVC_NETWORK_NAME=''

# HMC details
export HMC_IP=''
export HMC_USERNAME=''
export HMC_PASSWORD=''

# VIOS details
export VIOS_IP=''
export VIOS_USERNAME=''
export VIOS_PASSWORD=''
export VIOS_HOMEDIR=''
```



## Commands:

### Create Agent Cluster:
```shell
hypershift-agent-automation cluster create \
--name $CLUSTER_NAME \
--base-domain $BASE_DOMAIN \
--pull-secret $PULL_SECRET \
--release-image $RELEASE_IMAGE \
--ssh-key $SSH_KEY_FILE \
--node-count $NODE_COUNT
```

### Destroy Agent Cluster:
```shell
hypershift-agent-automation cluster destroy \
--name $CLUSTER_NAME \
--base-domain $BASE_DOMAIN \
--pull-secret $PULL_SECRET \
--release-image $RELEASE_IMAGE \
--ssh-key $SSH_KEY_FILE \
--node-count $NODE_COUNT
```

### Running e2e:
```shell
hypershift-agent-automation e2e \
--name $CLUSTER_NAME \
--base-domain $BASE_DOMAIN \
--pull-secret $PULL_SECRET \
--release-image $RELEASE_IMAGE \
--ssh-key $SSH_KEY_FILE \
--node-count $NODE_COUNT
```
22 changes: 22 additions & 0 deletions cmd/cluster/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cluster

import (
"github.com/spf13/cobra"

"github.com/ppc64le-cloud/hypershift-agent-automation/cmd/cluster/create"
"github.com/ppc64le-cloud/hypershift-agent-automation/cmd/cluster/destroy"
"github.com/ppc64le-cloud/hypershift-agent-automation/cmd/options"
)

func Command(options options.ClusterOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "cluster",
Short: "Commands to interact with hypershift agent cluster",
SilenceUsage: true,
}

cmd.AddCommand(create.Command(options))
cmd.AddCommand(destroy.Command(options))

return cmd
}
146 changes: 146 additions & 0 deletions cmd/cluster/create/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package create

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/ppc64le-cloud/hypershift-agent-automation/cmd/options"
cmdUtil "github.com/ppc64le-cloud/hypershift-agent-automation/cmd/util"
"github.com/ppc64le-cloud/hypershift-agent-automation/log"
"github.com/ppc64le-cloud/hypershift-agent-automation/pkg/cluster"
"github.com/ppc64le-cloud/hypershift-agent-automation/util"
)

func SetupPreReq(c *cluster.Cluster) (string, string, string, int, error) {
volumeID, err := c.PowerVC.SetupEmptyBootVol(c.Name)
if err != nil {
log.Logger.Errorf("error setup empty boot volume: %v", err)
return "", "", "", -1, fmt.Errorf("error setup empty boot volume: %v", err)
}
log.Logger.Infof("%s volume id will be used", volumeID)

imageID, err := c.PowerVC.SetupPreReqImage(c.Name, volumeID)
if err != nil {
log.Logger.Errorf("error setup image %v", err)
return "", "", "", -1, fmt.Errorf("error setup image: %v", err)
}
log.Logger.Infof("%s image id will be used", imageID)

if err = c.PowerVC.SetupFlavor(c.Name); err != nil {
log.Logger.Errorf("error setup flavor: %v", err)
return "", "", "", -1, fmt.Errorf("error setup flavor: %v", err)
}
log.Logger.Infof("%s flavor id will be used", util.GenerateFlavourID(c.Name))

networkID, gatewayIP, prefix, err := c.PowerVC.GetNetworkID()
if err != nil {
log.Logger.Errorf("unable to retrieve id for network, error: %v", err)
return "", "", "", -1, fmt.Errorf("unable to retrieve id for network, error: %v", err)
}
log.Logger.Infof("%s network id will be used", networkID)

return imageID, networkID, gatewayIP, prefix, nil
}

func SetupCluster(c *cluster.Cluster, imageID, networkID, gatewayIP string, prefix int) error {
agents, err := c.PowerVC.SetupAgents(c.GetWorkerName(), imageID, networkID, c.NodeCount)
if err != nil {
return fmt.Errorf("error setup agents: %v", err)
}
log.Logger.Infof("agent setup done. agent details: %+v", agents)

nmStateLabel := fmt.Sprintf("label: nmstate-config-%s", c.Name)
if err = os.Mkdir(util.GetManifestDir(c.Name), 0750); err != nil && !os.IsExist(err) {
log.Logger.Error("error creating output dir for manifests", err)
}
if err = c.SetupHC(); err != nil {
return fmt.Errorf("error setup hosted cluster: %v", err)
}
log.Logger.Info("hosted cluster setup done")
if err = c.SetupNMStateConfig(agents, prefix, gatewayIP, nmStateLabel); err != nil {
return fmt.Errorf("error setup nmstate config: %v", err)
}
log.Logger.Info("nmstate config setup done")

if err = c.SetupCISDNSRecords(agents[0].IP); err != nil {
return fmt.Errorf("error update cis dns records: %v", err)
}
log.Logger.Info("update cis dns records done")

if err = c.SetupInfraEnv(nmStateLabel); err != nil {
return fmt.Errorf("error setup infraenv: %v", err)
}
log.Logger.Info("infraenv setup done")

if err = c.DownloadISO(); err != nil {
return fmt.Errorf("error download iso: %v", err)
}
log.Logger.Info("download discovery iso done")

if err = c.CopyAndMountISO(agents); err != nil {
return fmt.Errorf("error copy iso: %v", err)
}
log.Logger.Info("mount iso on agents done")

if err = c.PowerVC.RestartAgents(agents); err != nil {
return fmt.Errorf("error restarting vm: %v", err)
}
log.Logger.Info("agents restarted")

if err = c.ApproveAgents(agents); err != nil {
return err
}
log.Logger.Info("agents approved")

if err = c.ScaleNodePool(); err != nil {
return err
}
log.Logger.Info("node pool scaled")

if err = c.DownloadKubeConfig(); err != nil {
return fmt.Errorf("error downloading kubeconfig: %v", err)
}
log.Logger.Info("kubeconfig downloaded")

if err = c.SetupIngressControllerNodeSelector(agents[0].Name); err != nil {
return err
}

if err = c.MonitorHC(); err != nil {
return fmt.Errorf("error monitor hosted cluster to reach completed state: %v", err)
}
log.Logger.Info("hosted cluster reached completed state")

return nil
}

func Command(opts options.ClusterOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Command to create a hypershift agent cluster",
SilenceUsage: true,
}

cmd.RunE = func(_ *cobra.Command, args []string) error {
c, err := cmdUtil.CreateClusterClient(opts)
if err != nil {
return fmt.Errorf("error create clients: %v", err)
}
imageID, networkID, gatewayIP, prefix, err := SetupPreReq(c)
if err != nil {
return fmt.Errorf("error setup pre req: %v", err)
}
log.Logger.Infof("retrieved prereq resource info imageID: %s, networkID: %s, gatewayIP: %s, prefix: %d", imageID, networkID, gatewayIP, prefix)

if err = SetupCluster(c, imageID, networkID, gatewayIP, prefix); err != nil {
return fmt.Errorf("error setup cluster: %v", err)
}
log.Logger.Info("setup cluster done")

return nil
}

return cmd
}
Loading

0 comments on commit 959323e

Please sign in to comment.