github.com/verrazzano/verrazzano@v1.7.0/tools/vz/cmd/status/status.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package status
     5  
     6  import (
     7  	"fmt"
     8  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
     9  	"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/registry"
    10  	"reflect"
    11  	"strings"
    12  
    13  	"github.com/spf13/cobra"
    14  	vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    15  	cmdhelpers "github.com/verrazzano/verrazzano/tools/vz/cmd/helpers"
    16  	"github.com/verrazzano/verrazzano/tools/vz/pkg/helpers"
    17  	"github.com/verrazzano/verrazzano/tools/vz/pkg/templates"
    18  )
    19  
    20  const (
    21  	CommandName = "status"
    22  	helpShort   = "Status of the Verrazzano installation and access endpoints"
    23  	helpLong    = `The command 'status' returns summary information about a Verrazzano installation`
    24  	helpExample = `
    25  vz status
    26  vz status --context minikube
    27  vz status --kubeconfig ~/.kube/config --context minikube`
    28  )
    29  
    30  // The component output is disabled pending the resolution some issues with
    31  // the content of the Verrazzano status block
    32  var componentOutputEnabled = false
    33  
    34  type TemplateInput struct {
    35  	Endpoints         map[string]string
    36  	Components        map[string]string
    37  	ComponentsEnabled bool
    38  
    39  	Name                string
    40  	Namespace           string
    41  	Version             string
    42  	State               string
    43  	Profile             string
    44  	AvailableComponents string
    45  }
    46  
    47  // statusOutputTemplate - template for output of status command
    48  const statusOutputTemplate = `
    49  Verrazzano Status
    50    Name: {{.Name}}
    51    Namespace: {{.Namespace}}
    52    Profile: {{.Profile}}
    53    Version: {{.Version}}
    54    State: {{.State}}
    55  {{- if .AvailableComponents }}
    56    Available Components: {{.AvailableComponents}}
    57  {{- end }}
    58  {{- if .Endpoints }}
    59    Access Endpoints:
    60  {{- range $key, $value := .Endpoints }}
    61      {{ $key }}: {{ $value }}
    62  {{- end }}
    63  {{- end }}
    64  {{- if .ComponentsEnabled }}
    65    Components:
    66  {{- range $key, $value := .Components }}
    67      {{ $key }}: {{ $value }}
    68  {{- end }}
    69  {{- end }}
    70  `
    71  
    72  func NewCmdStatus(vzHelper helpers.VZHelper) *cobra.Command {
    73  	cmd := cmdhelpers.NewCommand(vzHelper, CommandName, helpShort, helpLong)
    74  	cmd.RunE = func(cmd *cobra.Command, args []string) error {
    75  		return runCmdStatus(cmd, vzHelper)
    76  	}
    77  	cmd.Example = helpExample
    78  
    79  	// Verifies that the CLI args are not set at the creation of a command
    80  	vzHelper.VerifyCLIArgsNil(cmd)
    81  
    82  	return cmd
    83  }
    84  
    85  // runCmdStatus - run the "vz status" command
    86  func runCmdStatus(cmd *cobra.Command, vzHelper helpers.VZHelper) error {
    87  	client, err := vzHelper.GetClient(cmd)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	// Get the VZ resource
    93  	vz, err := helpers.FindVerrazzanoResource(client)
    94  	if err != nil {
    95  		return err
    96  	}
    97  	templateValues := TemplateInput{
    98  		Endpoints:           getEndpoints(vz.Status.VerrazzanoInstance),
    99  		Components:          getComponents(vz.Status.Components),
   100  		Name:                vz.Name,
   101  		Namespace:           vz.Namespace,
   102  		Version:             vz.Status.Version,
   103  		State:               string(vz.Status.State),
   104  		AvailableComponents: getAvailableComponents(vz.Status.Available),
   105  		Profile:             getProfile(vz.Spec.Profile),
   106  	}
   107  	result, err := templates.ApplyTemplate(statusOutputTemplate, templateValues)
   108  	if err != nil {
   109  		return fmt.Errorf("Failed to generate %s command output: %s", CommandName, err.Error())
   110  	}
   111  	fmt.Fprintf(vzHelper.GetOutputStream(), result)
   112  
   113  	return nil
   114  }
   115  
   116  func getAvailableComponents(available *string) string {
   117  	if available == nil {
   118  		return ""
   119  	}
   120  	return *available
   121  }
   122  
   123  func getProfile(profile v1beta1.ProfileType) string {
   124  	if profile == "" {
   125  		return string(vzapi.Prod)
   126  	}
   127  	return string(profile)
   128  }
   129  
   130  func getEndpoints(instance *v1beta1.InstanceInfo) map[string]string {
   131  	values := map[string]string{}
   132  	if instance == nil {
   133  		return values
   134  	}
   135  	instanceValue := reflect.Indirect(reflect.ValueOf(instance))
   136  	instanceType := reflect.TypeOf(instance).Elem()
   137  	for i := 0; i < instanceType.NumField(); i++ {
   138  		fieldValue := instanceValue.Field(i)
   139  		v, ok := fieldValue.Interface().(*string)
   140  		if ok && v != nil {
   141  			k := getJSONTagNameForField(instanceType.Field(i))
   142  			values[k] = *v
   143  		}
   144  	}
   145  	return values
   146  }
   147  
   148  func getJSONTagNameForField(field reflect.StructField) string {
   149  	return strings.Split(field.Tag.Get("json"), ",")[0]
   150  }
   151  
   152  // addComponents - add the component status information
   153  func getComponents(components v1beta1.ComponentStatusMap) map[string]string {
   154  	values := map[string]string{}
   155  	if componentOutputEnabled {
   156  		for _, component := range components {
   157  			ok, c := registry.FindComponent(component.Name)
   158  			if !ok {
   159  				continue
   160  			}
   161  			values[c.GetJSONName()] = string(component.State)
   162  		}
   163  	}
   164  	return values
   165  }