code.vegaprotocol.io/vega@v0.79.0/cmd/vegawallet/commands/network_import.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package cmd
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  
    24  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/cli"
    25  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/flags"
    26  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/printer"
    27  	"code.vegaprotocol.io/vega/paths"
    28  	"code.vegaprotocol.io/vega/wallet/api"
    29  	netstore "code.vegaprotocol.io/vega/wallet/network/store/v1"
    30  
    31  	"github.com/spf13/cobra"
    32  )
    33  
    34  var (
    35  	importNetworkLong = cli.LongDesc(`
    36  		Import a network configuration from a file or an URL.
    37  	`)
    38  
    39  	importNetworkExample = cli.Examples(`
    40  		# import a network configuration from a file
    41  		{{.Software}} network import --from-file PATH_TO_NETWORK
    42  
    43  		# import a network configuration from an URL
    44  		{{.Software}} network import --from-url URL_TO_NETWORK
    45  
    46  		# overwrite existing network configuration
    47  		{{.Software}} network import --from-url URL_TO_NETWORK --force
    48  
    49  		# import a network configuration with a different name
    50  		{{.Software}} network import --from-url URL_TO_NETWORK --with-name NEW_NAME
    51  	`)
    52  )
    53  
    54  type adminImportNetworkResult struct {
    55  	api.AdminImportNetworkResult
    56  	FilePath string `json:"filePath"`
    57  }
    58  
    59  type ImportNetworkFromSourceHandler func(api.AdminImportNetworkParams) (adminImportNetworkResult, error)
    60  
    61  func NewCmdImportNetwork(w io.Writer, rf *RootFlags) *cobra.Command {
    62  	h := func(params api.AdminImportNetworkParams) (adminImportNetworkResult, error) {
    63  		vegaPaths := paths.New(rf.Home)
    64  
    65  		s, err := netstore.InitialiseStore(vegaPaths)
    66  		if err != nil {
    67  			return adminImportNetworkResult{}, fmt.Errorf("couldn't initialise networks store: %w", err)
    68  		}
    69  		importNetwork := api.NewAdminImportNetwork(s)
    70  		rawResult, errorDetails := importNetwork.Handle(context.Background(), params)
    71  		if errorDetails != nil {
    72  			return adminImportNetworkResult{}, errors.New(errorDetails.Data)
    73  		}
    74  
    75  		result := rawResult.(api.AdminImportNetworkResult)
    76  		return adminImportNetworkResult{
    77  			AdminImportNetworkResult: result,
    78  			FilePath:                 s.GetNetworkPath(result.Name),
    79  		}, nil
    80  	}
    81  
    82  	return BuildCmdImportNetwork(w, h, rf)
    83  }
    84  
    85  func BuildCmdImportNetwork(w io.Writer, handler ImportNetworkFromSourceHandler, rf *RootFlags) *cobra.Command {
    86  	f := &ImportNetworkFlags{}
    87  
    88  	cmd := &cobra.Command{
    89  		Use:     "import",
    90  		Short:   "Import a network configuration",
    91  		Long:    importNetworkLong,
    92  		Example: importNetworkExample,
    93  		RunE: func(_ *cobra.Command, _ []string) error {
    94  			req, err := f.Validate()
    95  			if err != nil {
    96  				return err
    97  			}
    98  
    99  			resp, err := handler(req)
   100  			if err != nil {
   101  				return err
   102  			}
   103  
   104  			switch rf.Output {
   105  			case flags.InteractiveOutput:
   106  				PrintImportNetworkResponse(w, resp)
   107  			case flags.JSONOutput:
   108  				return printer.FprintJSON(w, resp)
   109  			}
   110  
   111  			return nil
   112  		},
   113  	}
   114  
   115  	cmd.Flags().StringVar(&f.FilePath,
   116  		"from-file",
   117  		"",
   118  		"Path to the file containing the network configuration to import",
   119  	)
   120  	cmd.Flags().StringVar(&f.URL,
   121  		"from-url",
   122  		"",
   123  		"URL of the file containing the network configuration to import",
   124  	)
   125  	cmd.Flags().StringVar(&f.Name,
   126  		"with-name",
   127  		"",
   128  		"Change the name of the imported network",
   129  	)
   130  	cmd.Flags().BoolVarP(&f.Force,
   131  		"force", "f",
   132  		false,
   133  		"Overwrite the existing network if it has the same name",
   134  	)
   135  
   136  	return cmd
   137  }
   138  
   139  type ImportNetworkFlags struct {
   140  	FilePath string
   141  	URL      string
   142  	Name     string
   143  	Force    bool
   144  }
   145  
   146  func (f *ImportNetworkFlags) Validate() (api.AdminImportNetworkParams, error) {
   147  	if len(f.FilePath) == 0 && len(f.URL) == 0 {
   148  		return api.AdminImportNetworkParams{}, flags.OneOfFlagsMustBeSpecifiedError("from-file", "from-url")
   149  	}
   150  
   151  	if len(f.FilePath) != 0 && len(f.URL) != 0 {
   152  		return api.AdminImportNetworkParams{}, flags.MutuallyExclusiveError("from-file", "from-url")
   153  	}
   154  
   155  	url := f.URL
   156  	if len(f.FilePath) != 0 {
   157  		url = api.FileSchemePrefix + f.FilePath
   158  	}
   159  	return api.AdminImportNetworkParams{
   160  		URL:       url,
   161  		Name:      f.Name,
   162  		Overwrite: f.Force,
   163  	}, nil
   164  }
   165  
   166  func PrintImportNetworkResponse(w io.Writer, resp adminImportNetworkResult) {
   167  	p := printer.NewInteractivePrinter(w)
   168  
   169  	str := p.String()
   170  	defer p.Print(str)
   171  
   172  	str.CheckMark().SuccessText("Importing the network succeeded").NextSection()
   173  	str.Text("Name:").NextLine().WarningText(resp.Name).NextLine()
   174  	str.Text("File path:").NextLine().WarningText(resp.FilePath).NextLine()
   175  }