github.com/htcondor/osdf-client/v6@v6.13.0-rc1.0.20231009141709-766e7b4d1dc8/cmd/config_mgr/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/spf13/cobra"
     6  	"net/url"
     7  	"os"
     8  	"path"
     9  
    10  	config "github.com/htcondor/osdf-client/v6/config"
    11  	stashcp "github.com/htcondor/osdf-client/v6"
    12  	namespaces "github.com/htcondor/osdf-client/v6/namespaces"
    13  	log "github.com/sirupsen/logrus"
    14  	"gopkg.in/yaml.v3"
    15  )
    16  
    17  var (
    18  	version = "dev"
    19  	/*
    20  		commit  = "none"
    21  		date    = "unknown"
    22  		builtBy = "unknown"
    23  	*/
    24  )
    25  
    26  func printConfig() {
    27  	config, err := config.GetConfigContents()
    28  	if err != nil {
    29  		fmt.Fprintln(os.Stderr, "Failed to get configuration contents:", err)
    30  		os.Exit(1)
    31  	}
    32  	config_b, err := yaml.Marshal(&config)
    33  	if err != nil {
    34  		fmt.Fprintln(os.Stderr, "Failed to convert object to YAML:", err)
    35  		os.Exit(1)
    36  	}
    37  	fmt.Println(string(config_b))
    38  }
    39  
    40  func addConfigSubcommands(configCmd *cobra.Command) {
    41  
    42  	configCmd.AddCommand(&cobra.Command{
    43  		Use:   "print",
    44  		Short: "Print the configuration file",
    45  		Long:  "Print the configuration file",
    46  		Run: func(cmd *cobra.Command, args []string) {
    47  			printConfig()
    48  		},
    49  	})
    50  
    51  	configCmd.AddCommand(&cobra.Command{
    52  		Use:   "replace <file>",
    53  		Short: "Replace the configuration file",
    54  		Long:  "Replace the configuration file",
    55  		Args:  cobra.MinimumNArgs(1),
    56  		Run: func(cmd *cobra.Command, args []string) {
    57  			input_config_b, err := os.ReadFile(args[0])
    58  			if err != nil {
    59  				fmt.Fprintln(os.Stderr, "Failed to read config file:", err)
    60  				os.Exit(1)
    61  			}
    62  
    63  			input_config := config.OSDFConfig{}
    64  			err = yaml.Unmarshal(input_config_b, &input_config)
    65  			if err != nil {
    66  				fmt.Fprintln(os.Stderr, "Failed to parse config file:", err)
    67  				os.Exit(1)
    68  			}
    69  
    70  			err = config.SaveConfigContents(&input_config)
    71  			if err != nil {
    72  				fmt.Fprintln(os.Stderr, "Unable to save replaced configuration file:", err)
    73  				os.Exit(1)
    74  			}
    75  		},
    76  	})
    77  
    78  	configCmd.AddCommand(&cobra.Command{
    79  		Use:   "reset-password",
    80  		Short: "Reset the password for the current user",
    81  		Long:  "Reset the password for the current user",
    82  		Run: func(cmd *cobra.Command, args []string) {
    83  			err := config.ResetPassword()
    84  			if err != nil {
    85  				fmt.Fprintln(os.Stderr, "Failed to get reset password:", err)
    86  				os.Exit(1)
    87  			}
    88  		},
    89  	})
    90  
    91  }
    92  
    93  func printOauthConfig() {
    94  	config, err := config.GetConfigContents()
    95  	if err != nil {
    96  		fmt.Fprintln(os.Stderr, "Failed to get configuration contents:", err)
    97  		os.Exit(1)
    98  	}
    99  	clientList := &config.OSDF.OauthClient
   100  	config_b, err := yaml.Marshal(&clientList)
   101  	if err != nil {
   102  		fmt.Fprintln(os.Stderr, "Failed to convert object to YAML:", err)
   103  		os.Exit(1)
   104  	}
   105  	fmt.Println(string(config_b))
   106  
   107  }
   108  
   109  func addTokenSubcommands(tokenCmd *cobra.Command) {
   110  
   111  	tokenCmd.AddCommand(&cobra.Command{
   112  		Use:   "get <read|write> <prefix>",
   113  		Short: "Get a new token for a given prefix",
   114  		Long:  "Get a new token for a given prefix",
   115  		Args:  cobra.ExactArgs(2),
   116  		Run: func(cmd *cobra.Command, args []string) {
   117  
   118  			isWrite := false
   119  			switch args[0] {
   120  			case "read":
   121  			case "write":
   122  				isWrite = true
   123  			default:
   124  				fmt.Fprintln(os.Stderr, "Unknown value for operation type (must be 'read' or 'write')", args[0])
   125  				os.Exit(1)
   126  			}
   127  			dest := url.URL{Path: path.Clean("/" + args[1])}
   128  
   129  			namespace, err := namespaces.MatchNamespace(args[1])
   130  			if err != nil {
   131  				fmt.Fprintln(os.Stderr, "Failed to get namespace for path:", err)
   132  				os.Exit(1)
   133  			}
   134  
   135  			token, err := stashcp.AcquireToken(&dest, namespace, isWrite)
   136  			if err != nil {
   137  				fmt.Fprintln(os.Stderr, "Failed to get a token:", err)
   138  				os.Exit(1)
   139  			}
   140  
   141  			fmt.Println(token)
   142  		},
   143  	})
   144  }
   145  
   146  func addPrefixSubcommands(prefixCmd *cobra.Command) {
   147  
   148  	prefixCmd.AddCommand(&cobra.Command{
   149  		Use:   "print",
   150  		Short: "Print the oauth client configuration file",
   151  		Long:  "Print the oauth client configuration file",
   152  		Run: func(cmd *cobra.Command, args []string) {
   153  			printOauthConfig()
   154  		},
   155  	})
   156  
   157  	prefixCmd.AddCommand(&cobra.Command{
   158  		Use:   "add <prefix>",
   159  		Short: "Add a new oauth client",
   160  		Long:  "Add a new oauth client",
   161  		Args:  cobra.ExactArgs(1),
   162  		Run: func(cmd *cobra.Command, args []string) {
   163  			input_config, err := config.GetConfigContents()
   164  			if err != nil {
   165  				fmt.Fprintln(os.Stderr, "Failed to get configuration contents:", err)
   166  				os.Exit(1)
   167  			}
   168  
   169  			hasPrefix := false
   170  			for _, entry := range input_config.OSDF.OauthClient {
   171  				if entry.Prefix == args[0] {
   172  					hasPrefix = true
   173  					break
   174  				}
   175  			}
   176  			if !hasPrefix {
   177  				newPrefix := config.PrefixEntry{Prefix: args[0]}
   178  				input_config.OSDF.OauthClient = append(input_config.OSDF.OauthClient, newPrefix)
   179  			} else {
   180  				fmt.Fprintln(os.Stderr, "Prefix to add already exists")
   181  				return
   182  			}
   183  
   184  			err = config.SaveConfigContents(&input_config)
   185  			if err != nil {
   186  				fmt.Fprintln(os.Stderr, "Unable to save replaced configuration file:", err)
   187  				os.Exit(1)
   188  			}
   189  		},
   190  	})
   191  
   192  	prefixCmd.AddCommand(&cobra.Command{
   193  		Use:   "set <prefix> <client_id|client_secret> <value>",
   194  		Short: "Set the oauth client attributes",
   195  		Long:  "Set the oauth client attributes (client_id or client_secret)",
   196  		Args:  cobra.ExactArgs(3),
   197  		Run: func(cmd *cobra.Command, args []string) {
   198  			input_config, err := config.GetConfigContents()
   199  			if err != nil {
   200  				fmt.Fprintln(os.Stderr, "Failed to get configuration contents:", err)
   201  				os.Exit(1)
   202  			}
   203  
   204  			var existingPrefix *config.PrefixEntry
   205  			existingPrefix = nil
   206  			for idx := range input_config.OSDF.OauthClient {
   207  				if input_config.OSDF.OauthClient[idx].Prefix == args[0] {
   208  					existingPrefix = &input_config.OSDF.OauthClient[idx]
   209  					break
   210  				}
   211  			}
   212  			if existingPrefix == nil {
   213  				fmt.Fprintln(os.Stderr, "Prefix to set was not present")
   214  				os.Exit(1)
   215  			}
   216  
   217  			if args[1] == "client_id" {
   218  				existingPrefix.ClientID = args[2]
   219  			} else if args[1] == "client_secret" {
   220  				existingPrefix.ClientSecret = args[2]
   221  			} else {
   222  				fmt.Fprintln(os.Stderr, "Unknown attribute to set:", args[1])
   223  				os.Exit(1)
   224  			}
   225  
   226  			err = config.SaveConfigContents(&input_config)
   227  			if err != nil {
   228  				fmt.Fprintln(os.Stderr, "Unable to save replaced configuration file:", err)
   229  				os.Exit(1)
   230  			}
   231  		},
   232  	})
   233  
   234  	prefixCmd.AddCommand(&cobra.Command{
   235  		Use:   "delete <prefix>",
   236  		Short: "Delete the oauth client",
   237  		Long:  "Delete the oauth client",
   238  		Args:  cobra.ExactArgs(1),
   239  		Run: func(cmd *cobra.Command, args []string) {
   240  			input_config, err := config.GetConfigContents()
   241  			if err != nil {
   242  				fmt.Fprintln(os.Stderr, "Failed to get configuration contents:", err)
   243  				os.Exit(1)
   244  			}
   245  
   246  			prefix_list := input_config.OSDF.OauthClient
   247  			new_prefix_list := make([]config.PrefixEntry, 0, len(prefix_list)-1)
   248  			for _, entry := range prefix_list {
   249  				if entry.Prefix != args[0] {
   250  					new_prefix_list = append(new_prefix_list, entry)
   251  				}
   252  			}
   253  			input_config.OSDF.OauthClient = new_prefix_list
   254  
   255  			err = config.SaveConfigContents(&input_config)
   256  			if err != nil {
   257  				fmt.Fprintln(os.Stderr, "Unable to save replaced configuration file:", err)
   258  				os.Exit(1)
   259  			}
   260  		},
   261  	})
   262  
   263  }
   264  
   265  func main() {
   266  
   267  	// Define the config commands
   268  	configCmd := &cobra.Command{
   269  		Use:   "config",
   270  		Short: "Manage the configuration file",
   271  		Long:  "Manage the configuration file",
   272  		Run: func(cmd *cobra.Command, args []string) {
   273  			printConfig()
   274  		},
   275  	}
   276  	addConfigSubcommands(configCmd)
   277  
   278  	// Define the prefix commands
   279  	prefixCmd := &cobra.Command{
   280  		Use:   "prefix",
   281  		Short: "Manage the prefix configuration",
   282  		Long:  "Manage the prefix configuration",
   283  	}
   284  	addPrefixSubcommands(prefixCmd)
   285  
   286  	// Define the token commands
   287  	tokenCmd := &cobra.Command{
   288  		Use: "token",
   289  		Short: "Manage the available tokens",
   290  		Long: "Manage the available tokens",
   291  	}
   292  	addTokenSubcommands(tokenCmd)
   293  
   294  	// Add the config and prefix commands
   295  	var rootCmd = &cobra.Command{
   296  		Use:     "config_mgr",
   297  		Version: version,
   298  	}
   299  	var Debug bool
   300  	rootCmd.PersistentFlags().BoolVarP(&Debug, "debug", "d", false, "Debug output")
   301  	rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
   302  		if Debug {
   303  			setLogging(log.DebugLevel)
   304  		} else {
   305  			setLogging(log.ErrorLevel)
   306  		}
   307  	}
   308  
   309  	rootCmd.CompletionOptions.DisableDefaultCmd = true
   310  	rootCmd.AddCommand(configCmd)
   311  	rootCmd.AddCommand(prefixCmd)
   312  	rootCmd.AddCommand(tokenCmd)
   313  	err := rootCmd.Execute()
   314  	if err != nil {
   315  		log.Errorln(err)
   316  	}
   317  
   318  }
   319  
   320  func setLogging(logLevel log.Level) {
   321  	textFormatter := log.TextFormatter{}
   322  	textFormatter.DisableLevelTruncation = true
   323  	textFormatter.FullTimestamp = true
   324  	log.SetFormatter(&textFormatter)
   325  	log.SetLevel(logLevel)
   326  }