istio.io/istio@v0.0.0-20240520182934-d79c90f27776/istioctl/pkg/writer/compare/sds/writer.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sdscompare
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"io"
    21  	"strings"
    22  	"text/tabwriter"
    23  )
    24  
    25  // SDSWriter takes lists of SecretItem or SecretItemDiff and prints them through supplied output writer
    26  type SDSWriter interface {
    27  	PrintSecretItems([]SecretItem) error
    28  	PrintDiffs([]SecretItemDiff) error
    29  }
    30  
    31  type Format int
    32  
    33  const (
    34  	JSON Format = iota
    35  	TABULAR
    36  )
    37  
    38  // includeConfigType is a flag to indicate whether to include the config type in the output
    39  var includeConfigType bool
    40  
    41  func SetPrintConfigTypeInSummary(p bool) {
    42  	includeConfigType = p
    43  }
    44  
    45  // NewSDSWriter generates a new instance which conforms to SDSWriter interface
    46  func NewSDSWriter(w io.Writer, format Format) SDSWriter {
    47  	return &sdsWriter{
    48  		w:      w,
    49  		output: format,
    50  	}
    51  }
    52  
    53  // sdsWriter is provided concrete implementation of SDSWriter
    54  type sdsWriter struct {
    55  	w      io.Writer
    56  	output Format
    57  }
    58  
    59  // PrintSecretItems uses the user supplied output format to determine how to display the diffed secrets
    60  func (w *sdsWriter) PrintSecretItems(secrets []SecretItem) error {
    61  	var err error
    62  	switch w.output {
    63  	case JSON:
    64  		err = w.printSecretItemsJSON(secrets)
    65  	case TABULAR:
    66  		err = w.printSecretItemsTabular(secrets)
    67  	}
    68  	return err
    69  }
    70  
    71  var (
    72  	secretItemColumns = []string{"RESOURCE NAME", "TYPE", "STATUS", "VALID CERT", "SERIAL NUMBER", "NOT AFTER", "NOT BEFORE"}
    73  	secretDiffColumns = []string{"RESOURCE NAME", "TYPE", "VALID CERT", "NODE AGENT", "PROXY", "SERIAL NUMBER", "NOT AFTER", "NOT BEFORE"}
    74  )
    75  
    76  // printSecretItemsTabular prints the secret in table format
    77  func (w *sdsWriter) printSecretItemsTabular(secrets []SecretItem) error {
    78  	if len(secrets) == 0 {
    79  		fmt.Fprintln(w.w, "No secret items to show.")
    80  		return nil
    81  	}
    82  	tw := new(tabwriter.Writer).Init(w.w, 0, 5, 5, ' ', 0)
    83  	fmt.Fprintln(tw, strings.Join(secretItemColumns, "\t"))
    84  	for _, s := range secrets {
    85  		if includeConfigType {
    86  			s.Name = fmt.Sprintf("secret/%s", s.Name)
    87  		}
    88  		fmt.Fprintf(tw, "%s\t%s\t%s\t%t\t%s\t%s\t%s\n",
    89  			s.Name, s.Type, s.State, s.Valid, s.SerialNumber, s.NotAfter, s.NotBefore)
    90  	}
    91  	return tw.Flush()
    92  }
    93  
    94  // printSecretItemsJSON prints secret in JSON format, and dumps the raw certificate data with the output
    95  func (w *sdsWriter) printSecretItemsJSON(secrets []SecretItem) error {
    96  	out, err := json.MarshalIndent(secrets, "", " ")
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	_, err = w.w.Write(out)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	return nil
   107  }
   108  
   109  // PrintDiffs uses the user supplied output format to determine how to display the diffed secrets
   110  func (w *sdsWriter) PrintDiffs(statuses []SecretItemDiff) error {
   111  	var err error
   112  	switch w.output {
   113  	case JSON:
   114  		err = w.printDiffsJSON(statuses)
   115  	case TABULAR:
   116  		err = w.printDiffsTabular(statuses)
   117  	}
   118  	return err
   119  }
   120  
   121  // printDiffsTabular prints the secret in table format
   122  func (w *sdsWriter) printDiffsTabular(statuses []SecretItemDiff) error {
   123  	if len(statuses) == 0 {
   124  		fmt.Fprintln(w.w, "No secrets found to diff.")
   125  		return nil
   126  	}
   127  	tw := new(tabwriter.Writer).Init(w.w, 0, 5, 5, ' ', 0)
   128  	fmt.Fprintln(tw, strings.Join(secretDiffColumns, "\t"))
   129  	for _, status := range statuses {
   130  		fmt.Fprintf(tw, "%s\t%s\t%t\t%s\t%s\t%s\t%s\t%s\n",
   131  			status.Name, status.Type, status.Valid, status.Source, status.Proxy, status.SerialNumber, status.NotAfter, status.NotBefore)
   132  	}
   133  	return tw.Flush()
   134  }
   135  
   136  // printDiffsJSON prints secret in JSON format, and dumps the raw certificate data with the output
   137  func (w *sdsWriter) printDiffsJSON(statuses []SecretItemDiff) error {
   138  	out, err := json.MarshalIndent(statuses, "", " ")
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	_, err = w.w.Write(out)
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	return nil
   149  }