How to use Failf method of ui Package

Best Testkube code snippet using ui.Failf

cli-config.go

Source:cli-config.go Github

copy

Full Screen

1package cmd2import (3 "encoding/json"4 "fmt"5 "log"6 "net/http"7 "os"8 "path/filepath"9 "runtime"10 "strconv"11 "strings"12 "thy/auth"13 cst "thy/constants"14 "thy/errors"15 "thy/internal/pki"16 "thy/internal/predictor"17 "thy/paths"18 "thy/store"19 "thy/utils"20 "thy/vaultcli"21 "github.com/AlecAivazis/survey/v2"22 "github.com/mitchellh/cli"23 "github.com/spf13/viper"24)25func GetCliConfigCmd() (cli.Command, error) {26 return NewCommand(CommandArgs{27 Path: []string{cst.NounCliConfig},28 SynopsisText: "Manage the CLI configuration.",29 HelpText: "Execute an action on the cli config for " + cst.ProductName,30 NoPreAuth: true,31 RunFunc: func(args []string) int {32 return cli.RunResultHelp33 },34 })35}36func GetCliConfigInitCmd() (cli.Command, error) {37 homePath := "$HOME"38 if runtime.GOOS == "windows" {39 homePath = "%USERPROFILE%"40 }41 defaultConfigPath := filepath.Join(homePath, ".dsv.yml")42 return NewCommand(CommandArgs{43 Path: []string{cst.NounCliConfig, cst.Init},44 SynopsisText: "Initialize or add a new profile to the CLI configuration.",45 HelpText: `Command 'init' is an alias for 'cli-config init'.46For interactive mode provide no arguments.47Examples:48- Add profile that uses username/password for authentication:49 • init \50 --profile prof \51 --tenant demo \52 --domain secretsvaultcloud.com \53 --store-type file \54 --store-path ~/.thy \55 --cache-strategy server \56 --auth-type password \57 --auth-username 'demouser' \58 --auth-password 'demopassword'59- Add profile that uses client credentials for authentication:60 • init \61 --profile prof \62 --tenant demo \63 --domain secretsvaultcloud.com \64 --store-type file \65 --store-path ~/.thy \66 --cache-strategy server \67 --auth-type clientcred \68 --auth-client-id '11111111-2222-3333-4444-555555555555' \69 --auth-client-secret 'abcdefghijklmnopqrstuvwxyz012345'70`,71 NoPreAuth: true,72 FlagsPredictor: []*predictor.Params{73 // Configuration path and profile name.74 {Name: cst.Config, Shorthand: "c", Usage: fmt.Sprintf("Set config file path [default:%s]", defaultConfigPath)},75 {Name: cst.Profile, Usage: "Profile name to add to the config file"},76 // Tenant info.77 {Name: cst.Tenant, Usage: "Name of the tenant to connect to"},78 {Name: cst.DomainName, Usage: "Domain name, e.g. 'secretsvaultcloud.com'"},79 // Storing and Caching.80 {Name: cst.StoreType, Usage: "Store type (file|none|pass_linux|wincred)"},81 {Name: cst.StorePath, Usage: "Path to directory where to store. Only if store type is 'file'"},82 {Name: cst.CacheStrategy, Usage: "Cache strategy (server|server.cache|cache.server|cache.server.expired). Only if store type is not 'none'"},83 {Name: cst.CacheAge, Usage: "Cache age in minutes. Only if cache strategy is not 'server'"},84 // Authentication.85 {Name: cst.AuthType, Usage: "Authentication type (password|clientcred|thyone|aws|azure|gcp|oidc|cert)."},86 {Name: cst.Username, Usage: "Username for 'password' authentication type."},87 {Name: cst.Password, Usage: "Password for 'password' authentication type."},88 {Name: cst.AuthClientID, Usage: "Client ID for 'clientcred' authentication type."},89 {Name: cst.AuthClientSecret, Usage: "Client Secret for 'clientcred' authentication type."},90 {Name: cst.Dev, Hidden: true, Usage: "Specify dev domain upon initialization (ignored when '--domain' is used)"},91 },92 RunFunc: func(args []string) int {93 return handleCliConfigInitCmd(vaultcli.New(), args)94 },95 })96}97func GetCliConfigUpdateCmd() (cli.Command, error) {98 return NewCommand(CommandArgs{99 Path: []string{cst.NounCliConfig, cst.Update},100 SynopsisText: fmt.Sprintf("%s %s (<key> <value> | --key --value)", cst.NounCliConfig, cst.Update),101 HelpText: `Update a cli config setting for the specified profile. The key specifies the path to that setting.102Usage:103 • cli-config update --profile default --key auth.password --value *******104 • cli-config update profile2.auth.type clientcred --profile profile2105`,106 NoPreAuth: true,107 FlagsPredictor: []*predictor.Params{108 {Name: cst.Key, Usage: "Key of setting to be updated (required)"},109 {Name: cst.Value, Usage: "Value of setting to be udpated (required)"},110 },111 MinNumberArgs: 2,112 RunFunc: func(args []string) int {113 return handleCliConfigUpdateCmd(vaultcli.New(), args)114 },115 })116}117func GetCliConfigClearCmd() (cli.Command, error) {118 return NewCommand(CommandArgs{119 Path: []string{cst.NounCliConfig, cst.Clear},120 SynopsisText: strings.Join([]string{cst.NounCliConfig, cst.Clear}, " "),121 HelpText: "Clear the cli config for " + cst.ProductName,122 NoPreAuth: true,123 RunFunc: func(args []string) int {124 return handleCliConfigClearCmd(vaultcli.New(), args)125 },126 })127}128func GetCliConfigReadCmd() (cli.Command, error) {129 return NewCommand(CommandArgs{130 Path: []string{cst.NounCliConfig, cst.Read},131 SynopsisText: strings.Join([]string{cst.NounCliConfig, cst.Read}, " "),132 HelpText: "Read the cli config for " + cst.ProductName,133 NoPreAuth: true,134 RunFunc: func(args []string) int {135 return handleCliConfigReadCmd(vaultcli.New(), args)136 },137 })138}139func GetCliConfigEditCmd() (cli.Command, error) {140 return NewCommand(CommandArgs{141 Path: []string{cst.NounCliConfig, cst.Edit},142 SynopsisText: strings.Join([]string{cst.NounCliConfig, cst.Edit}, " "),143 HelpText: "Edit the cli config for " + cst.ProductName,144 NoPreAuth: true,145 RunFunc: func(args []string) int {146 return handleCliConfigEditCmd(vaultcli.New(), args)147 },148 })149}150func GetCliConfigUseProfileCmd() (cli.Command, error) {151 return NewCommand(CommandArgs{152 Path: []string{cst.NounCliConfig, cst.UseProfile},153 SynopsisText: "Set a profile name which will be used by default.",154 HelpText: `Usage:155 • cli-config use-profile admin156 • cli-config use-profile role1157For interactive mode provide no arguments:158 • cli-config use-profile`,159 NoPreAuth: true,160 RunFunc: func(args []string) int {161 return handleCliConfigUseProfileCmd(vaultcli.New(), args)162 },163 })164}165func handleCliConfigUseProfileCmd(vcli vaultcli.CLI, args []string) int {166 cfgPath := viper.GetString(cst.Config)167 cf, err := vaultcli.ReadConfigFile(cfgPath)168 if err != nil {169 vcli.Out().FailF("Error: failed to read config: %v.", err)170 return 1171 }172 existingProfiles := cf.ListProfiles()173 if len(existingProfiles) == 1 {174 vcli.Out().FailS("Default profile cannot be changed since only one profile defined in the configuration file.")175 return 0176 }177 log.Printf("Current profile used by default: %q.", cf.DefaultProfile)178 var profile string179 if len(args) > 0 && !strings.HasPrefix(args[0], "-") {180 profile = args[0]181 if _, ok := cf.GetProfile(profile); !ok {182 vcli.Out().FailF("Error: profile %q not found in config.", profile)183 return 1184 }185 } else {186 profiles := make([]string, 0, len(existingProfiles))187 for _, prof := range existingProfiles {188 repr := fmt.Sprintf("%s (tenant: %s; auth type: %s)",189 prof.Name, prof.Get(cst.Tenant), prof.Get(cst.NounAuth, cst.Type))190 if prof.Name == cf.DefaultProfile {191 profiles = append(profiles, repr+" <-- [current default]")192 } else {193 profiles = append(profiles, repr)194 }195 }196 var profileID int197 profilePrompt := &survey.Select{198 Message: "Please select default profile:",199 Options: profiles,200 PageSize: 10,201 }202 err = survey.AskOne(profilePrompt, &profileID)203 if err != nil {204 vcli.Out().Fail(err)205 return 1206 }207 profile = existingProfiles[profileID].Name208 }209 if profile == cf.DefaultProfile {210 return 0211 }212 cf.DefaultProfile = profile213 err = cf.Save()214 if err != nil {215 vcli.Out().FailF("Error: cannot save configuration: %v.", err)216 return 1217 }218 return 0219}220func handleCliConfigUpdateCmd(vcli vaultcli.CLI, args []string) int {221 key := strings.TrimSpace(viper.GetString(cst.Key))222 val := strings.TrimSpace(viper.GetString(cst.Value))223 if key == "" && len(args) > 0 && !strings.HasPrefix(args[0], "-") {224 key = args[0]225 }226 if val == "" && len(args) > 1 && !strings.HasPrefix(args[1], "-") {227 // Make value the same as the key name, as in "user:user", for example.228 val = args[1]229 }230 profile := viper.GetString(cst.Profile)231 if profile == "" {232 profile = cst.DefaultProfile233 }234 if key == cst.Password || key == cst.AuthClientSecret {235 storeType := viper.GetString(cst.StoreType)236 if storeType == store.PassLinux || storeType == store.WinCred {237 key = profile + "." + key238 err := store.StoreSecureSetting(key, val, storeType)239 if err != nil {240 vcli.Out().FailF("Error updating setting in store of type '%s'", string(storeType))241 return 1242 }243 return 0244 }245 }246 cfgPath := viper.GetString(cst.Config)247 cf, readErr := vaultcli.ReadConfigFile(cfgPath)248 if readErr != nil {249 vcli.Out().FailF("Error: failed to read config: %v.", readErr)250 return 1251 }252 prf, ok := cf.GetProfile(profile)253 if !ok {254 vcli.Out().FailF("profile %q not found in configuration file %q", profile, cf.GetPath())255 return 1256 }257 secure := "auth.securePassword"258 if strings.HasSuffix(key, secure) {259 vcli.Out().FailF("Cannot manually change the value of %q.", secure)260 return 1261 }262 if strings.HasSuffix(key, "auth.password") {263 key = secure264 cipherText, err := auth.EncipherPassword(val)265 if err != nil {266 vcli.Out().FailF("Error encrypting password: %v.", err)267 return 1268 }269 // Set in-memory value of plaintext password, so that the CLI can use it to try to authenticate before writing the config.270 viper.Set(cst.Password, val)271 if authError := tryAuthenticate(); authError != nil {272 vcli.Out().FailS("Failed to authenticate, restoring previous config.")273 vcli.Out().FailS("Please check your credentials and try again.")274 return 1275 }276 val = cipherText277 }278 keys := strings.Split(key, ".")279 if val != "" && val != "0" {280 prf.Set(val, keys...)281 } else {282 prf.Del(keys...)283 }284 cf.SetProfile(prf)285 saveErr := cf.Save()286 if saveErr != nil {287 vcli.Out().FailF("Error: cannot save configuration: %v", saveErr)288 return 1289 }290 return 0291}292func handleCliConfigReadCmd(vcli vaultcli.CLI, args []string) int {293 var didError int294 var dataOut []byte295 cfgPath := viper.GetString(cst.Config)296 cf, err := vaultcli.ReadConfigFile(cfgPath)297 if err != nil {298 vcli.Out().FailF("Error: failed to read config: %v", err)299 didError = 1300 } else {301 dataOut = []byte(fmt.Sprintf("CLI config (%s):\n", cf.GetPath()))302 dataOut = append(dataOut, cf.Bytes()...)303 }304 storeType := viper.GetString(cst.StoreType)305 if storeType == store.PassLinux || storeType == store.WinCred {306 dataOut = append(dataOut, fmt.Sprintf("\nSecure Store Settings (store type: %s):\n", storeType)...)307 if s, err := store.GetStore(string(storeType)); err != nil {308 vcli.Out().FailF("Error: failed to get store of type '%s'\n", string(storeType))309 didError = 1310 } else if keys, err := s.List(cst.CliConfigRoot); err != nil {311 vcli.Out().FailF("Error: failed to get store of type '%s'\n", string(storeType))312 didError = 1313 } else {314 if len(keys) > 0 {315 dataOut = append(dataOut, []byte(" ")...)316 }317 dataOut = append(dataOut, strings.ReplaceAll(strings.Join(keys, "\n "), "-", ".")...)318 }319 }320 vcli.Out().WriteResponse(dataOut, nil)321 return didError322}323func handleCliConfigEditCmd(vcli vaultcli.CLI, args []string) int {324 cfgPath := viper.GetString(cst.Config)325 cf, readErr := vaultcli.ReadConfigFile(cfgPath)326 if readErr != nil {327 vcli.Out().FailF("Error: failed to read config: %v", readErr)328 return 1329 }330 saveFunc := func(data []byte) (resp []byte, err *errors.ApiError) {331 updErr := cf.RawUpdate(data)332 if updErr != nil {333 return nil, errors.New(updErr)334 }335 return nil, errors.New(cf.Save())336 }337 _, err := vcli.Edit(cf.Bytes(), saveFunc)338 vcli.Out().WriteResponse(nil, err)339 return utils.GetExecStatus(err)340}341func handleCliConfigClearCmd(vcli vaultcli.CLI, args []string) int {342 var yes bool343 areYouSurePrompt := &survey.Confirm{Message: "Are you sure you want to delete CLI configuration?", Default: false}344 survErr := survey.AskOne(areYouSurePrompt, &yes)345 if survErr != nil {346 vcli.Out().WriteResponse(nil, errors.New(survErr))347 return utils.GetExecStatus(survErr)348 }349 if !yes {350 vcli.Out().WriteResponse([]byte("Exiting."), nil)351 return 0352 }353 didError := 0354 cfgPath := viper.GetString(cst.Config)355 deleteErr := vaultcli.DeleteConfigFile(cfgPath)356 if deleteErr != nil {357 vcli.Out().FailF("Error deleting CLI config: %v.", deleteErr)358 didError = 1359 }360 st := viper.GetString(cst.StoreType)361 s, err := store.GetStore(st)362 if err != nil {363 vcli.Out().FailF("Failed to get store: %v.", err)364 return 1365 }366 err = s.Wipe("")367 if err != nil {368 vcli.Out().FailF("Failed to clear store: %v.", err)369 return 1370 }371 return didError372}373func handleCliConfigInitCmd(vcli vaultcli.CLI, args []string) int {374 ui := cli.BasicUi{375 Writer: os.Stdout,376 Reader: os.Stdin,377 ErrorWriter: os.Stderr,378 }379 cfgPath := viper.GetString(cst.Config)380 if cfgPath != "" {381 // The `dsv init` command is the only command that allows path to a directory in `--config` flag.382 info, err := os.Stat(cfgPath)383 if err == nil && info != nil && info.IsDir() {384 cfgPath = vaultcli.LookupConfigPath(cfgPath)385 }386 }387 cf, err := vaultcli.NewConfigFile(cfgPath)388 if err != nil {389 vcli.Out().FailF("Error: %v.", err)390 return 1391 }392 err = cf.Read()393 if err != nil && err != vaultcli.ErrFileNotFound {394 vcli.Out().FailF("Error: could not read file at path %q: %v.", cf.GetPath(), err)395 return 1396 }397 cfgExists := err == nil398 if cfgExists {399 ui.Warn(fmt.Sprintf("Found an existing cli-config located at '%s'.", cf.GetPath()))400 }401 profile := viper.GetString(cst.Profile)402 if profile != "" {403 lowered := strings.ToLower(profile)404 if lowered != profile {405 profile = lowered406 ui.Warn(fmt.Sprintf("Profile name can only use lowercase letters. The name '%s' will be used instead.", profile))407 }408 if err := vaultcli.ValidateProfile(profile); err != nil {409 ui.Info(err.Error())410 return 1411 }412 if cfgExists {413 // The user specified --profile [name], so the intent is to add a profile to the config.414 if _, ok := cf.GetProfile(profile); ok {415 msg := fmt.Sprintf("Profile %q already exists in the config.", profile)416 ui.Info(msg)417 return 1418 }419 }420 }421 if !cfgExists && profile == "" {422 // If configuration file does not exist and profile name was not provided423 // then use default profile name to have better user experience with less424 // questions to answer.425 profile = cst.DefaultProfile426 }427 if cfgExists && profile == "" {428 var actionID int429 actionPrompt := &survey.Select{430 Message: "Select an option:",431 Options: []string{432 "Do nothing",433 "Overwrite the config",434 "Add a new profile to the config",435 },436 }437 survErr := survey.AskOne(actionPrompt, &actionID)438 if survErr != nil {439 vcli.Out().WriteResponse(nil, errors.New(survErr))440 return 1441 }442 if actionID == 0 { // "Do nothing".443 ui.Info("Exiting.")444 return 0445 }446 var profilePrompt *survey.Input447 switch actionID {448 case 1: // "Overwrite the config".449 cf, _ = vaultcli.NewConfigFile(cf.GetPath())450 profilePrompt = &survey.Input{Message: "Please enter profile name:", Default: cst.DefaultProfile}451 case 2: // "Add a new profile to the config".452 profilePrompt = &survey.Input{Message: "Please enter profile name:"}453 }454 validationOpt := survey.WithValidator(vaultcli.SurveyRequiredProfileName(cf.ListProfilesNames()))455 survErr = survey.AskOne(profilePrompt, &profile, validationOpt)456 if survErr != nil {457 vcli.Out().WriteResponse(nil, errors.New(survErr))458 return 1459 }460 profile = strings.TrimSpace(profile)461 }462 prf := vaultcli.NewProfile(profile)463 viper.Set(cst.Profile, profile)464 // Tenant name.465 tenant := viper.GetString(cst.Tenant)466 if tenant == "" {467 tenantPrompt := &survey.Input{Message: "Please enter tenant name:"}468 survErr := survey.AskOne(tenantPrompt, &tenant, survey.WithValidator(vaultcli.SurveyRequired))469 if survErr != nil {470 vcli.Out().WriteResponse(nil, errors.New(survErr))471 return utils.GetExecStatus(survErr)472 }473 tenant = strings.TrimSpace(tenant)474 viper.Set(cst.Tenant, tenant)475 }476 prf.Set(tenant, cst.Tenant)477 // Domain.478 domain := viper.GetString(cst.DomainName)479 var isDevDomain bool480 if domain == "" {481 devDomain := viper.GetString(cst.Dev)482 if devDomain != "" {483 isDevDomain = true484 domain = devDomain485 } else {486 domain, err = promptDomain()487 if err != nil {488 vcli.Out().WriteResponse(nil, errors.New(err))489 return 1490 }491 }492 viper.Set(cst.DomainKey, domain)493 }494 prf.Set(domain, cst.DomainKey)495 // Check if tenant has been setup yet.496 var setupRequired bool497 heartbeatURI := paths.CreateURI("heartbeat", nil)498 if respData, err := vcli.HTTPClient().DoRequest(http.MethodGet, heartbeatURI, nil); err != nil {499 ui.Error(fmt.Sprintf("Failed to contact %s to determine if initial admin setup is required.", cst.ProductName))500 return 1501 } else {502 var resp heartbeatResponse503 if err := json.Unmarshal(respData, &resp); err != nil {504 ui.Error(fmt.Sprintf("Failed to read the response from %s to determine if initial admin setup is required.", cst.ProductName))505 return 1506 } else if resp.StatusCode == 2 {507 setupRequired = true508 }509 }510 // Store configuration.511 storeType := viper.GetString(cst.StoreType)512 if storeType == "" {513 storeType, err = promptStoreType()514 if err != nil {515 vcli.Out().WriteResponse(nil, errors.New(err))516 return 1517 }518 }519 if err := store.ValidateCredentialStore(storeType); err != nil {520 ui.Error(fmt.Sprintf("Failed to get store: %v.", err))521 return 1522 }523 isSecureStore := storeType == store.PassLinux || storeType == store.WinCred524 prf.Set(storeType, cst.Store, cst.Type)525 viper.Set(cst.StoreType, storeType)526 if storeType == store.File {527 def := filepath.Join(utils.NewEnvProvider().GetHomeDir(), ".thy")528 fileStorePath := viper.GetString(cst.StorePath)529 if fileStorePath == "" {530 fileStorePathPrompt := &survey.Input{531 Message: "Please enter directory for file store:",532 Default: def,533 }534 survErr := survey.AskOne(fileStorePathPrompt, &fileStorePath, survey.WithValidator(vaultcli.SurveyRequired))535 if survErr != nil {536 vcli.Out().WriteResponse(nil, errors.New(survErr))537 return utils.GetExecStatus(survErr)538 }539 fileStorePath = strings.TrimSpace(fileStorePath)540 }541 if fileStorePath != def {542 prf.Set(fileStorePath, cst.Store, cst.Path)543 viper.Set(cst.StorePath, fileStorePath)544 }545 }546 // Caching strategy and cache age.547 if storeType != store.None {548 cacheStrategy := viper.GetString(cst.CacheStrategy)549 if cacheStrategy == "" {550 cacheStrategy, err = promptCacheStrategy()551 if err != nil {552 vcli.Out().WriteResponse(nil, errors.New(err))553 return 1554 }555 }556 prf.Set(cacheStrategy, cst.Cache, cst.Strategy)557 if cacheStrategy != cst.CacheStrategyNever {558 cacheAge := viper.GetString(cst.CacheAge)559 if cacheAge == "" {560 cacheAgePrompt := &survey.Input{Message: "Please enter cache age (minutes until expiration):"}561 cacheAgeValidation := func(ans interface{}) error {562 if err := vaultcli.SurveyRequired(ans); err != nil {563 return err564 }565 answer := strings.TrimSpace(ans.(string))566 if age, err := strconv.Atoi(answer); err != nil || age <= 0 {567 return errors.NewS("Unable to parse age. Must be strictly positive int")568 }569 return nil570 }571 survErr := survey.AskOne(cacheAgePrompt, &cacheAge, survey.WithValidator(cacheAgeValidation))572 if survErr != nil {573 vcli.Out().WriteResponse(nil, errors.New(survErr))574 return utils.GetExecStatus(survErr)575 }576 cacheAge = strings.TrimSpace(cacheAge)577 } else {578 if age, err := strconv.Atoi(cacheAge); err != nil || age <= 0 {579 vcli.Out().FailS("Unable to parse cache age. Must be strictly positive int")580 return 1581 }582 }583 prf.Set(cacheAge, cst.Cache, cst.Age)584 }585 }586 // Authentication type and authentication data.587 authType := viper.GetString(cst.AuthType)588 if authType == "" {589 authType, err = promptAuthType()590 if err != nil {591 vcli.Out().WriteResponse(nil, errors.New(err))592 return 1593 }594 viper.Set(cst.AuthType, authType)595 }596 prf.Set(authType, cst.NounAuth, cst.Type)597 var user, password, passwordKey, authProvider, encryptionKeyFileName string598 authProvider = viper.GetString(cst.AuthProvider)599 switch {600 case (storeType != store.None && auth.AuthType(authType) == auth.Password):601 user = viper.GetString(cst.Username)602 password = viper.GetString(cst.Password)603 if user == "" || password == "" {604 if setupRequired {605 user, password, err = promptInitialUsernamePassword(tenant)606 } else {607 user, password, err = promptUsernamePassword(tenant)608 }609 if err != nil {610 vcli.Out().WriteResponse(nil, errors.New(err))611 return 1612 }613 viper.Set(cst.Username, user)614 viper.Set(cst.Password, password)615 }616 prf.Set(user, cst.NounAuth, cst.DataUsername)617 encryptionKeyFileName = auth.GetEncryptionKeyFilename(viper.GetString(cst.Tenant), user)618 if isSecureStore {619 if err := store.StoreSecureSetting(strings.Join([]string{profile, cst.NounAuth, cst.DataPassword}, "."), password, storeType); err != nil {620 ui.Error(err.Error())621 return 1622 }623 } else {624 encrypted, key, err := auth.StorePassword(encryptionKeyFileName, password)625 if err != nil {626 ui.Error(err.Error())627 return 1628 }629 passwordKey = key630 prf.Set(encrypted, cst.NounAuth, cst.DataSecurePassword)631 }632 case (storeType != store.None && auth.AuthType(authType) == auth.ClientCredential):633 clientID := viper.GetString(cst.AuthClientID)634 clientSecret := viper.GetString(cst.AuthClientSecret)635 if clientID == "" || clientSecret == "" {636 clientID, clientSecret, err = promptClientCredentials()637 if err != nil {638 vcli.Out().WriteResponse(nil, errors.New(err))639 return 1640 }641 viper.Set(cst.AuthClientID, clientID)642 }643 prf.Set(clientID, cst.NounAuth, cst.NounClient, cst.ID)644 if isSecureStore {645 if err := store.StoreSecureSetting(strings.Join([]string{profile, cst.NounAuth, cst.NounClient, cst.NounSecret}, "."), clientSecret, storeType); err != nil {646 ui.Error(err.Error())647 return 1648 }649 } else {650 prf.Set(clientSecret, cst.NounAuth, cst.NounClient, cst.NounSecret)651 viper.Set(cst.AuthClientSecret, clientSecret)652 }653 case auth.AuthType(authType) == auth.FederatedAws:654 var awsProfile string655 awsProfilePrompt := &survey.Input{656 Message: "Please enter aws profile for federated aws auth:",657 Default: "default",658 }659 survErr := survey.AskOne(awsProfilePrompt, &awsProfile, survey.WithValidator(vaultcli.SurveyRequired))660 if survErr != nil {661 vcli.Out().WriteResponse(nil, errors.New(survErr))662 return utils.GetExecStatus(survErr)663 }664 awsProfile = strings.TrimSpace(awsProfile)665 prf.Set(awsProfile, cst.NounAuth, cst.NounAwsProfile)666 viper.Set(cst.AwsProfile, awsProfile)667 case auth.AuthType(authType) == auth.Oidc || auth.AuthType(authType) == auth.FederatedThyOne:668 if auth.AuthType(authType) == auth.Oidc {669 if authProvider == "" {670 authProviderPrompt := &survey.Input{671 Message: "Please enter auth provider name:",672 Default: cst.DefaultThyOneName,673 }674 survErr := survey.AskOne(authProviderPrompt, &authProvider, survey.WithValidator(vaultcli.SurveyRequired))675 if survErr != nil {676 vcli.Out().WriteResponse(nil, errors.New(survErr))677 return utils.GetExecStatus(survErr)678 }679 authProvider = strings.TrimSpace(authProvider)680 }681 } else {682 authProvider = cst.DefaultThyOneName683 if isDevDomain {684 authProviderPrompt := &survey.Input{685 Message: "Thycotic One authentication provider name:",686 Default: cst.DefaultThyOneName,687 }688 survErr := survey.AskOne(authProviderPrompt, &authProvider, survey.WithValidator(vaultcli.SurveyRequired))689 if survErr != nil {690 vcli.Out().WriteResponse(nil, errors.New(survErr))691 return utils.GetExecStatus(survErr)692 }693 authProvider = strings.TrimSpace(authProvider)694 }695 }696 var callback string697 if callback = viper.GetString(cst.Callback); callback == "" {698 callback = cst.DefaultCallback699 }700 prf.Set(authProvider, cst.NounAuth, cst.DataProvider)701 prf.Set(callback, cst.NounAuth, cst.DataCallback)702 viper.Set(cst.AuthProvider, authProvider)703 viper.Set(cst.Callback, callback)704 case auth.AuthType(authType) == auth.Certificate:705 clientCert, err := promptCertificate()706 if err != nil {707 vcli.Out().WriteResponse(nil, errors.New(err))708 return 1709 }710 clientPrivKey, err := promptPrivateKey()711 if err != nil {712 vcli.Out().WriteResponse(nil, errors.New(err))713 return 1714 }715 prf.Set(clientCert, cst.NounAuth, cst.NounCert)716 prf.Set(clientPrivKey, cst.NounAuth, cst.NounPrivateKey)717 viper.Set(cst.AuthCert, clientCert)718 viper.Set(cst.AuthPrivateKey, clientPrivKey)719 }720 if setupRequired {721 initializeURI := paths.CreateURI("initialize", nil)722 body := initializeRequest{723 UserName: user,724 Password: password,725 }726 if _, err := vcli.HTTPClient().DoRequest(http.MethodPost, initializeURI, body); err != nil {727 ui.Error(fmt.Sprintf("Failed to initialize tenant with %s. Please try again. Error:", cst.ProductName))728 vcli.Out().FailE(err)729 return 1730 }731 }732 if storeType != store.None {733 if authError := tryAuthenticate(); authError != nil {734 if isAccountLocked(authError) {735 ui.Output(authError.Error())736 return 1737 }738 ui.Output("Failed to authenticate, restoring previous config.")739 ui.Output("Please check your credentials, or tenant name, or domain name and try again.")740 return 1741 }742 // Store encryption key file (for auth type password).743 if auth.AuthType(authType) == auth.Password {744 st, apiError := store.GetStore(storeType)745 if apiError != nil {746 ui.Error(apiError.Error())747 return 1748 }749 apiError = st.StoreString(encryptionKeyFileName, passwordKey)750 if apiError != nil {751 ui.Error(apiError.Error())752 return 1753 }754 }755 } else {756 ui.Output("Authentication parameters are not checked since 'None (no caching)' was selected for the store type.")757 ui.Output("Each command that calls DSV API will trigger authentication first to get access token.")758 switch auth.AuthType(authType) {759 case auth.Password:760 ui.Output(`To authenticate using username and password use '--auth-username' and '--auth-password' flags.761Example:762 dsv secret search --auth-username "example-username" --auth-password "example-password"`)763 case auth.ClientCredential:764 ui.Output(`To authenticate using client credentials use '--auth-client-id' and '--auth-client-secret' flags.765Example:766 dsv secret search --auth-client-id "a71d...f0d4" --auth-client-secret "R8WzW...jWg"`)767 }768 }769 cf.SetProfile(prf)770 saveErr := cf.Save()771 if saveErr != nil {772 vcli.Out().FailF("Error: could not save configuration at path %q: %v.", cf.GetPath(), err)773 return 1774 }775 ui.Output("\nCLI configuration file successfully saved.")776 return 0777}778// tryAuthenticate attempts to authenticate with the current state of all constants, such as auth type, username, password, etc.779func tryAuthenticate() error {780 authenticator := auth.NewAuthenticatorDefault()781 apiError := authenticator.WipeCachedTokens()782 if apiError != nil {783 return apiError784 }785 _, apiError = authenticator.GetToken()786 if apiError != nil {787 return apiError788 }789 return nil790}791func isAccountLocked(err error) bool {792 return strings.Contains(err.Error(), "locked out")793}794type heartbeatResponse struct {795 StatusCode int796 Message string797}798type initializeRequest struct {799 UserName string800 Password string801}802func promptDomain() (string, error) {803 var domain string804 domainPrompt := &survey.Select{805 Message: "Please choose domain:",806 Options: []string{807 cst.Domain,808 cst.DomainEU,809 cst.DomainAU,810 cst.DomainCA,811 },812 }813 survErr := survey.AskOne(domainPrompt, &domain)814 if survErr != nil {815 return "", survErr816 }817 return domain, nil818}819func promptStoreType() (string, error) {820 var storeTypeID int821 storeTypePrompt := &survey.Select{822 Message: "Please select store type:",823 Options: []string{824 "File store",825 "None (no caching)",826 "Pass (Linux only)",827 "Windows Credential Manager (Windows only)",828 },829 }830 survErr := survey.AskOne(storeTypePrompt, &storeTypeID)831 if survErr != nil {832 return "", survErr833 }834 switch storeTypeID {835 case 0:836 return store.File, nil837 case 1:838 return store.None, nil839 case 2:840 return store.PassLinux, nil841 case 3:842 return store.WinCred, nil843 default:844 return "", errors.NewF("Unhandled case for store type id %d", storeTypeID)845 }846}847func promptCacheStrategy() (string, error) {848 var cacheStrategyID int849 cacheStrategyPrompt := &survey.Select{850 Message: "Please enter cache strategy for secrets:",851 Options: []string{852 "Never",853 "Server then cache",854 "Cache then server",855 "Cache then server, but allow expired cache if server unreachable",856 },857 }858 survErr := survey.AskOne(cacheStrategyPrompt, &cacheStrategyID)859 if survErr != nil {860 return "", survErr861 }862 switch cacheStrategyID {863 case 0:864 return cst.CacheStrategyNever, nil865 case 1:866 return cst.CacheStrategyServerThenCache, nil867 case 2:868 return cst.CacheStrategyCacheThenServer, nil869 case 3:870 return cst.CacheStrategyCacheThenServerThenExpired, nil871 default:872 return "", errors.NewF("Unhandled case for cache strategy id %d", cacheStrategyID)873 }874}875func promptAuthType() (string, error) {876 var authTypeID int877 authTypePrompt := &survey.Select{878 Message: "Please enter auth type:",879 Options: []string{880 "Password (local user)",881 "Client Credential",882 "Thycotic One (federated)",883 "AWS IAM (federated)",884 "Azure (federated)",885 "GCP (federated)",886 "OIDC (federated)",887 "x509 Certificate",888 },889 PageSize: 8,890 }891 survErr := survey.AskOne(authTypePrompt, &authTypeID)892 if survErr != nil {893 return "", survErr894 }895 switch authTypeID {896 case 0:897 return string(auth.Password), nil898 case 1:899 return string(auth.ClientCredential), nil900 case 2:901 return string(auth.FederatedThyOne), nil902 case 3:903 return string(auth.FederatedAws), nil904 case 4:905 return string(auth.FederatedAzure), nil906 case 5:907 return string(auth.FederatedGcp), nil908 case 6:909 return string(auth.Oidc), nil910 case 7:911 return string(auth.Certificate), nil912 default:913 return "", errors.NewF("Unhandled case for auth type id %d", authTypeID)914 }915}916func promptUsernamePassword(tenant string) (string, string, error) {917 answers := struct {918 Username string919 Password string920 }{}921 qs := []*survey.Question{922 {923 Name: "Username",924 Prompt: &survey.Input{925 Message: fmt.Sprintf("Please enter username for tenant %q:", tenant),926 },927 Validate: vaultcli.SurveyRequired,928 Transform: vaultcli.SurveyTrimSpace,929 },930 {931 Name: "Password",932 Prompt: &survey.Password{Message: "Please enter password:"},933 },934 }935 survErr := survey.Ask(qs, &answers)936 if survErr != nil {937 return "", "", survErr938 }939 return answers.Username, answers.Password, nil940}941func promptInitialUsernamePassword(tenant string) (string, string, error) {942 answers := struct {943 Username string944 Password string945 Confirm string946 }{}947 qs := []*survey.Question{948 {949 Name: "Username",950 Prompt: &survey.Input{951 Message: fmt.Sprintf("Please choose a username for initial local admin for tenant %q:", tenant),952 },953 Validate: vaultcli.SurveyRequired,954 Transform: vaultcli.SurveyTrimSpace,955 },956 {957 Name: "Password",958 Prompt: &survey.Password{Message: "Please choose password:"},959 },960 {961 Name: "Confirm",962 Validate: func(ans interface{}) error {963 if answers.Password != ans.(string) {964 return errors.NewS("Passwords do not match.")965 }966 return nil967 },968 Prompt: &survey.Password{Message: "Please choose password (confirm):"},969 },970 }971 survErr := survey.Ask(qs, &answers)972 if survErr != nil {973 return "", "", survErr974 }975 return answers.Username, answers.Password, nil976}977func promptClientCredentials() (string, string, error) {978 answers := struct {979 ClientID string980 ClientSecret string981 }{}982 qs := []*survey.Question{983 {984 Name: "ClientID",985 Prompt: &survey.Input{Message: "Please enter client id for client auth:"},986 Validate: vaultcli.SurveyRequired,987 },988 {989 Name: "ClientSecret",990 Prompt: &survey.Password{Message: "Please enter client secret for client auth:"},991 Validate: vaultcli.SurveyRequired,992 },993 }994 survErr := survey.Ask(qs, &answers)995 if survErr != nil {996 return "", "", survErr997 }998 return answers.ClientID, answers.ClientSecret, nil999}1000type cliCertificateOutput struct {1001 Certificate string `json:"certificate"`1002 PrivateKey string `json:"privateKey"`1003 SSHPublicKey string `json:"sshPublicKey"`1004}1005func promptCertificate() (string, error) {1006 var actionID int1007 actionPrompt := &survey.Select{1008 Message: "Select an option:",1009 Options: []string{1010 "Raw certificate",1011 "Certificate file path",1012 },1013 }1014 survErr := survey.AskOne(actionPrompt, &actionID)1015 if survErr != nil {1016 return "", survErr1017 }1018 var uncheckedCert string1019 answer := struct {1020 Cert string1021 }{}1022 switch actionID {1023 case 0: // "Raw certificate".1024 qs := []*survey.Question{1025 {1026 Name: "Cert",1027 Prompt: &survey.Input{Message: "Raw certificate:"},1028 Validate: vaultcli.SurveyRequired,1029 },1030 }1031 survErr := survey.Ask(qs, &answer)1032 if survErr != nil {1033 return "", survErr1034 }1035 uncheckedCert = answer.Cert1036 case 1: // "Certificate file path".1037 qs := []*survey.Question{1038 {1039 Name: "Cert",1040 Prompt: &survey.Input{Message: "Certificate file path:"},1041 Validate: vaultcli.SurveyRequired,1042 },1043 }1044 survErr := survey.Ask(qs, &answer)1045 if survErr != nil {1046 return "", survErr1047 }1048 fileData, err := os.ReadFile(answer.Cert)1049 if err != nil {1050 return "", fmt.Errorf("'%s' file cannot be read", answer.Cert)1051 }1052 body := cliCertificateOutput{}1053 if err := json.Unmarshal(fileData, &body); err == nil {1054 uncheckedCert = body.Certificate1055 } else {1056 uncheckedCert = string(fileData)1057 }1058 }1059 return pki.CertToBase64EncodedPEM(uncheckedCert)1060}1061func promptPrivateKey() (string, error) {1062 var actionID int1063 actionPrompt := &survey.Select{1064 Message: "Select an option:",1065 Options: []string{1066 "Raw private key",1067 "Private key file path",1068 },1069 }1070 survErr := survey.AskOne(actionPrompt, &actionID)1071 if survErr != nil {1072 return "", survErr1073 }1074 var uncheckedPrivKey string1075 answer := struct {1076 PrivKey string1077 }{}1078 switch actionID {1079 case 0: // "Raw private key".1080 qs := []*survey.Question{1081 {1082 Name: "PrivKey",1083 Prompt: &survey.Password{Message: "Private key:"},1084 Validate: vaultcli.SurveyRequired,1085 },1086 }1087 survErr := survey.Ask(qs, &answer)1088 if survErr != nil {1089 return "", survErr1090 }1091 uncheckedPrivKey = answer.PrivKey1092 case 1: // "Private key file path".1093 qs := []*survey.Question{1094 {1095 Name: "PrivKey",1096 Prompt: &survey.Input{Message: "Private key file path:"},1097 Validate: vaultcli.SurveyRequired,1098 },1099 }1100 survErr := survey.Ask(qs, &answer)1101 if survErr != nil {1102 return "", survErr1103 }1104 fileData, err := os.ReadFile(answer.PrivKey)1105 if err != nil {1106 return "", fmt.Errorf("'%s' file cannot be read", answer.PrivKey)1107 }1108 body := cliCertificateOutput{}1109 if err := json.Unmarshal(fileData, &body); err == nil {1110 uncheckedPrivKey = body.PrivateKey1111 } else {1112 uncheckedPrivKey = string(fileData)1113 }1114 }1115 return pki.PrivateKeyToBase64EncodedPEM(uncheckedPrivKey)1116}...

Full Screen

Full Screen

archive_pipeline.go

Source:archive_pipeline.go Github

copy

Full Screen

...22 return err23}24func (command *ArchivePipelineCommand) Execute(args []string) error {25 if command.Pipeline == nil && !command.All {26 displayhelpers.Failf("one of the flags '-p, --pipeline' or '-a, --all' is required")27 }28 if command.Pipeline != nil && command.All {29 displayhelpers.Failf("only one of the flags '-p, --pipeline' or '-a, --all' is allowed")30 }31 err := command.Validate()32 if err != nil {33 return err34 }35 target, err := rc.LoadTarget(Fly.Target, Fly.Verbose)36 if err != nil {37 return err38 }39 err = target.Validate()40 if err != nil {41 return err42 }43 var team concourse.Team44 team, err = command.Team.LoadTeam(target)45 if err != nil {46 return err47 }48 var pipelineRefs []atc.PipelineRef49 if command.Pipeline != nil {50 pipelineRefs = []atc.PipelineRef{command.Pipeline.Ref()}51 }52 if command.All {53 pipelines, err := team.ListPipelines()54 if err != nil {55 return err56 }57 for _, pipeline := range pipelines {58 if !pipeline.Archived {59 pipelineRefs = append(pipelineRefs, pipeline.Ref())60 }61 }62 }63 if len(pipelineRefs) == 0 {64 fmt.Println("there are no unarchived pipelines")65 fmt.Println("bailing out")66 return nil67 }68 if !command.confirmArchive(pipelineRefs) {69 fmt.Println("bailing out")70 return nil71 }72 for _, pipelineRef := range pipelineRefs {73 found, err := team.ArchivePipeline(pipelineRef)74 if err != nil {75 return err76 }77 if found {78 fmt.Printf("archived '%s'\n", pipelineRef.String())79 } else {80 displayhelpers.Failf("pipeline '%s' not found\n", pipelineRef.String())81 }82 }83 return nil84}85func (command ArchivePipelineCommand) confirmArchive(pipelines []atc.PipelineRef) bool {86 if command.SkipInteractive {87 return true88 }89 if len(pipelines) > 1 {90 command.printPipelinesTable(pipelines)91 }92 fmt.Printf("!!! archiving the pipeline will remove its configuration. Build history will be retained.\n\n")93 var confirm bool94 err := interact.NewInteraction(command.archivePrompt(pipelines)).Resolve(&confirm)...

Full Screen

Full Screen

error_handling.go

Source:error_handling.go Github

copy

Full Screen

...35 fmt.Fprintln(ui.Stderr, "identifier schema documentation: https://concourse-ci.org/config-basics.html#schema.identifier")36 fmt.Fprintln(ui.Stderr, "")37 }38}39func Failf(message string, args ...interface{}) {40 fmt.Fprintf(ui.Stderr, message+"\n", args...)41 os.Exit(1)42}43func FailWithErrorf(message string, err error, args ...interface{}) {44 templatedMessage := fmt.Sprintf(message, args...)45 Failf("%s: %s", templatedMessage, err.Error())46}...

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 err := termui.Init()4 if err != nil {5 panic(err)6 }7 defer termui.Close()8 par := termui.NewPar(":PRESS q TO QUIT DEMO")9 termui.Render(par)10 eventq := termui.EventQueue()11 termui.Handle("/sys/kbd/q", func(termui.Event) {12 termui.StopLoop()13 })14 termui.Handle("/sys/kbd/<escape>", func(termui.Event) {15 termui.StopLoop()16 })17 termui.Handle("/sys/wnd/resize", func(e termui.Event) {18 termui.Body.Width = termui.TermWidth()19 termui.Body.Align()20 termui.Render(termui.Body)21 })22 termui.Loop()23}

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ui := packer.BasicUi{4 }5 ui.Say("Hello World")6 ui.Message("Hello World")7 ui.Error("Hello World")

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ui := &ui.BasicUi{4 }5 ui.Say("Hello World")6 ui.Message("This is a message")7 ui.Error("This is an error")8 ui.Warn("This is a warning")9 ui.Machine("This is a machine output")10 ui.Details("This is a details output")11 ui.Error("

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2type stepTwo struct{}3func (s *stepTwo) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {4 ui := state.Get("ui").(packer.Ui)5 ui.Say("Hello from step 2!")6 ui.Message("Hello from step 2!")7 ui.Error("Hello from step 2!")8 ui.Error("Hello from step 2!")9 ui.Message("Hello from step 2!")10 ui.Say("Hello from step 2!")11 ui.Error("Hello from step 2!")12 ui.Message("Hello from step 2!")13 ui.Message("Hello from step 2!")14 ui.Error("Hello from step 2!")15 ui.Message("Hello from step 2!")16 ui.Say("Hello from step 2!")17 ui.Error("Hello from step 2!")18 ui.Message("Hello from step 2!")19 ui.Say("Hello from step 2!")20 ui.Error("Hello from step 2!")21 ui.Message("Hello from step 2!")22 ui.Message("Hello from step 2!")23 ui.Error("Hello from step 2!")24 ui.Message("Hello from step 2!")25 ui.Say("Hello from step 2!")26 ui.Error("Hello from step 2!")27 ui.Message("Hello from step 2!")28 ui.Say("Hello from step 2!")29 ui.Error("Hello from step 2!")30 ui.Message("Hello from step 2!")31 ui.Message("Hello from step 2!")32 ui.Error("Hello from step 2!")33 ui.Message("Hello from step 2!")34 ui.Say("Hello from step 2!")35 ui.Error("Hello from step 2!")36 ui.Message("Hello from step 2!")37 ui.Say("Hello from step 2!")38 ui.Error("Hello from step 2!")39 ui.Message("Hello from step 2!")40 ui.Message("Hello from step 2!")41 ui.Error("Hello from step 2!")42 ui.Message("Hello from step 2!")43 ui.Say("Hello from step 2!")44 ui.Error("Hello from step 2!")45 ui.Message("Hello from step 2!")46 ui.Say("Hello from step 2!")47 ui.Error("Hello from step 2!")48 ui.Message("Hello from step 2!")49 ui.Message("Hello from step 2!")50 ui.Error("

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2type MyBuilder struct{}3func (b *MyBuilder) Prepare(raws ...interface{}) ([]string, error) {4}5func (b *MyBuilder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {6 ui.Say("Hello, I'm the builder")7 ui.Message("I'm going to fail now")8 ui.Error("I'm failing now")9 ui.Error("I'm failing now again")10 ui.Error("I'm failing now again and again")11 ui.Error("I'm failing now again and again and again")12 ui.Error("I'm failing now again and again and again and again")13 ui.Error("I'm failing now again and again and again and again and again")14 ui.Error("I'm failing now again and again and again and again and again and again")15 ui.Error("I'm failing now again and again and again and again and again and again and again")16 ui.Error("I'm failing now again and again and again and again and again and again and again and again")17 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again")18 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again")19 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and again")20 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and again and again")21 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and again and again and again")22 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and again and again and again and again")23 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and again and again and again and again and again")24 ui.Error("I'm failing now again and again and again and again and again and again and again and again and again and again and

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2type MyProvisioner struct{}3func (p *MyProvisioner) Prepare(raws ...interface{}) error {4}5func (p *MyProvisioner) Provision(ui packer.Ui, comm packer.Communicator) error {6 ui.Say("Hello, I am a plugin")7 ui.Message("I am going to fail now")8 ui.Error("I am an error")9 ui.Error("I am another error")10 ui.Message("I am going to fail now")11 ui.Error("I am an error")12 ui.Error("I am another error")13 ui.Message("I am going to fail now")14 ui.Error("I am an error")15 ui.Error("I am another error")16 ui.Message("I am going to fail now")17 ui.Error("I am an error")18 ui.Error("I am another error")19 ui.Message("I am going to fail now")20 ui.Error("I am an error")21 ui.Error("I am another error")22 ui.Message("I am going to fail now")23 ui.Error("I am an error")24 ui.Error("I am another error")25 ui.Message("I am going to fail now")26 ui.Error("I am an error")27 ui.Error("I am another error")28 ui.Message("I am going to fail now")29 ui.Error("I am an error")30 ui.Error("I am another error")31 ui.Message("I am going to fail now")32 ui.Error("I am an error")33 ui.Error("I am another error")34 ui.Message("I am going to fail now")35 ui.Error("I am an error")36 ui.Error("I am another error")37 ui.Message("I am going to fail now")38 ui.Error("I am an error")39 ui.Error("I am another error")40 ui.Fail("I am failing now")41}42func main() {43 server, err := plugin.Server()44 if err != nil {45 panic(err)46 }47 server.RegisterProvisioner(new(MyProvisioner))48 server.Serve()49}

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ui := &cli.BasicUi{Writer: os.Stdout}4 ui.Output("Output")5 ui.Error("Error")6 ui.Info("Info")7 ui.Warn("Warn")8}9import (10func main() {11 ui := &cli.BasicUi{Writer: os.Stdout}12 ui.Output("Output")13 ui.Error("Error")14 ui.Info("Info")15 ui.Warn("Warn")16}17import (18func main() {19 ui := &cli.BasicUi{Writer: os.Stdout}20 ui.Output("Output")21 ui.Error("Error")22 ui.Info("Info")23 ui.Warn("Warn")24}25import (26func main() {27 ui := &cli.BasicUi{Writer: os.Stdout}28 ui.Output("Output")29 ui.Error("Error")30 ui.Info("Info")31 ui.Warn("Warn")32}33import (34func main() {35 ui := &cli.BasicUi{Writer: os.Stdout}36 ui.Output("Output")37 ui.Error("Error")38 ui.Info("Info")39 ui.Warn("Warn")40}41import (

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 plugin.Serve(&plugin.ServeOpts{4 UI: &ui.Failf{5 AllowedMethods: []string{6 },7 },8 })9}10import (11func main() {12 plugin.Serve(&plugin.ServeOpts{13 UI: &ui.Failf{14 AllowedMethods: []string{15 },16 },17 })18}19import (20func main() {21 plugin.Serve(&plugin.ServeOpts{22 UI: &ui.Failf{23 AllowedMethods: []string{24 },25 },26 })27}28import (29func main()

Full Screen

Full Screen

Failf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ui := new(packer.BasicUi)4 ui.Say("Hello, Packer")5 ui.Message("This is a message")6 ui.Error("This is an error")7 ui.Machine("ui", "machine-readable output")8 ui.MachineT("ui", "machine-readable output with {{.foo}}", map[string]string{"foo": "bar"})9 ui.Error(fmt.Sprintf("This is an error with %s", "string interpolation"))10 ui.Error("This is an error

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful