github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/rc/targets.go (about)

     1  package rc
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime"
    10  
    11  	"github.com/pf-qiu/concourse/v6/atc"
    12  
    13  	"sigs.k8s.io/yaml"
    14  )
    15  
    16  var (
    17  	ErrNoTargetSpecified = errors.New("no target specified")
    18  	ErrNoTargetFromURL   = errors.New("no target matching url")
    19  )
    20  
    21  type UnknownTargetError struct {
    22  	TargetName TargetName
    23  }
    24  
    25  func (err UnknownTargetError) Error() string {
    26  	return fmt.Sprintf("unknown target: %s", err.TargetName)
    27  }
    28  
    29  type Targets map[TargetName]TargetProps
    30  
    31  type RC struct {
    32  	Targets Targets `json:"targets"`
    33  }
    34  
    35  type TargetProps struct {
    36  	API            string       `json:"api"`
    37  	TeamName       string       `json:"team"`
    38  	Insecure       bool         `json:"insecure,omitempty"`
    39  	Token          *TargetToken `json:"token,omitempty"`
    40  	CACert         string       `json:"ca_cert,omitempty"`
    41  	ClientCertPath string       `json:"client_cert_path,omitempty"`
    42  	ClientKeyPath  string       `json:"client_key_path,omitempty"`
    43  }
    44  
    45  type TargetToken struct {
    46  	Type  string `json:"type"`
    47  	Value string `json:"value"`
    48  }
    49  
    50  func flyrcPath() string {
    51  	return filepath.Join(userHomeDir(), ".flyrc")
    52  }
    53  
    54  func LogoutTarget(targetName TargetName) error {
    55  	flyTargets, err := LoadTargets()
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	if target, ok := flyTargets[targetName]; ok {
    61  		if target.Token != nil {
    62  			*target.Token = TargetToken{}
    63  		}
    64  	}
    65  
    66  	return writeTargets(flyrcPath(), flyTargets)
    67  }
    68  
    69  func DeleteTarget(targetName TargetName) error {
    70  	flyTargets, err := LoadTargets()
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	delete(flyTargets, targetName)
    76  
    77  	return writeTargets(flyrcPath(), flyTargets)
    78  }
    79  
    80  func DeleteAllTargets() error {
    81  	return writeTargets(flyrcPath(), Targets{})
    82  }
    83  
    84  func UpdateTargetProps(targetName TargetName, targetProps TargetProps) error {
    85  	flyTargets, err := LoadTargets()
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	target := flyTargets[targetName]
    91  
    92  	if targetProps.API != "" {
    93  		target.API = targetProps.API
    94  	}
    95  
    96  	if targetProps.TeamName != "" {
    97  		target.TeamName = targetProps.TeamName
    98  	}
    99  
   100  	flyTargets[targetName] = target
   101  
   102  	return writeTargets(flyrcPath(), flyTargets)
   103  }
   104  
   105  func UpdateTargetName(targetName TargetName, newTargetName TargetName) error {
   106  	flyTargets, err := LoadTargets()
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	if newTargetName != "" {
   112  		flyTargets[newTargetName] = flyTargets[targetName]
   113  		delete(flyTargets, targetName)
   114  	}
   115  
   116  	return writeTargets(flyrcPath(), flyTargets)
   117  }
   118  
   119  func SaveTarget(
   120  	targetName TargetName,
   121  	api string,
   122  	insecure bool,
   123  	teamName string,
   124  	token *TargetToken,
   125  	caCert string,
   126  	clientCertPath string,
   127  	clientKeyPath string,
   128  ) error {
   129  	flyTargets, err := LoadTargets()
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	flyrc := flyrcPath()
   135  	newInfo := flyTargets[targetName]
   136  	newInfo.API = api
   137  	newInfo.Insecure = insecure
   138  	newInfo.Token = token
   139  	newInfo.TeamName = teamName
   140  	newInfo.CACert = caCert
   141  	newInfo.ClientCertPath = clientCertPath
   142  	newInfo.ClientKeyPath = clientKeyPath
   143  
   144  	flyTargets[targetName] = newInfo
   145  	return writeTargets(flyrc, flyTargets)
   146  }
   147  
   148  func selectTarget(selectedTarget TargetName) (TargetProps, error) {
   149  	if selectedTarget == "" {
   150  		return TargetProps{}, ErrNoTargetSpecified
   151  	}
   152  	flyTargets, err := LoadTargets()
   153  	if err != nil {
   154  		return TargetProps{}, err
   155  	}
   156  
   157  	target, ok := flyTargets[selectedTarget]
   158  	if !ok {
   159  		return TargetProps{}, UnknownTargetError{selectedTarget}
   160  	}
   161  	return target, nil
   162  }
   163  
   164  func userHomeDir() string {
   165  	home := os.Getenv("HOME")
   166  	if home != "" {
   167  		return home
   168  	}
   169  
   170  	if runtime.GOOS == "windows" {
   171  		home = os.Getenv("USERPROFILE")
   172  		if home != "" {
   173  			return home
   174  		}
   175  
   176  		home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
   177  		if home != "" {
   178  			return home
   179  		}
   180  	}
   181  
   182  	panic("could not detect home directory for .flyrc")
   183  }
   184  
   185  func LoadTargets() (Targets, error) {
   186  	var rc RC
   187  
   188  	flyrc := flyrcPath()
   189  	if _, err := os.Stat(flyrc); err == nil {
   190  		flyTargetsBytes, err := ioutil.ReadFile(flyrc)
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  		err = yaml.Unmarshal(flyTargetsBytes, &rc)
   195  		if err != nil {
   196  			return nil, fmt.Errorf("in the file '%s': %s", flyrc, err)
   197  		}
   198  	}
   199  
   200  	targets := rc.Targets
   201  	if targets == nil {
   202  		targets = map[TargetName]TargetProps{}
   203  	}
   204  
   205  	for name, targetProps := range targets {
   206  		if targetProps.TeamName == "" {
   207  			targetProps.TeamName = atc.DefaultTeamName
   208  			targets[name] = targetProps
   209  		}
   210  	}
   211  
   212  	return targets, nil
   213  }
   214  
   215  func writeTargets(configFileLocation string, targetsToWrite Targets) error {
   216  	yamlBytes, err := yaml.Marshal(RC{Targets: targetsToWrite})
   217  	if err != nil {
   218  		return err
   219  	}
   220  
   221  	err = ioutil.WriteFile(configFileLocation, yamlBytes, os.FileMode(0600))
   222  	if err != nil {
   223  		return err
   224  	}
   225  
   226  	return nil
   227  }