Ejemplo n.º 1
0
//simple CLI interface. Sample usage:
//goner -min=8 -max=10 -digits=3 -punctuation=3 -uppercase=4
//Flags:
//  -l: minimum length
//  -L: maximum length
//  -d: digits
//  -p: punctuation
//  -u: uppercase
func main() {
	min := flag.Int("min", 12, "minimum password length")
	max := flag.Int("max", 0, "maximum password length")
	digits := flag.Int("digits", 3, "number of digits")
	punctuation := flag.Int("punctuation", 1, "number of punctuation symbols")
	uppercase := flag.Int("uppercase", 1, "number of uppercase characters")
	flag.Parse()
	reqs := garbler.PasswordStrengthRequirements{
		MinimumTotalLength: *min,
		MaximumTotalLength: *max,
		Uppercase:          *uppercase,
		Digits:             *digits,
		Punctuation:        *punctuation,
	}
	pass, err := garbler.NewPassword(&reqs)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(pass)
}
Ejemplo n.º 2
0
func (_ Test) Garbler() {
	g := &garbler.PasswordStrengthRequirements{MinimumTotalLength: 6, MaximumTotalLength: 9,
		Uppercase: 0, Digits: 4, Punctuation: 0}
	s, _ := garbler.NewPassword(g)
	e.InfoLog.Println(s)
}
Ejemplo n.º 3
0
func main() {
	var (
		location       = flag.String("l", os.Getenv("CLC_LOCATION"), "Data centre alias (needed to resolve IDs)")
		intvl          = flag.Duration("i", 1*time.Second, "Poll interval for status updates (use 0 to disable)")
		handlingServer bool   // what to act on
		action, where  string // what to do and where
		reqID          string // request ID of the action
	)

	/*
	 * Argument Validation
	 */
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() >= 1 {
		action = flag.Arg(0)
		if flag.NArg() > 1 {
			where = flag.Arg(1)
		}
	} else {
		usage()
	}

	switch action {
	case "help":
		usage()
	case "networks", "templates", "show":
		// Omit location warning here, will be displayed after client is initialized.
	case "credentials":
		handlingServer = true
	case "memory":
		handlingServer = true
		if flag.NArg() != 3 {
			exit.Errorf("usage: password <serverName> <memoryGB>")
		}
	case "password":
		handlingServer = true
		if flag.NArg() < 2 {
			exit.Errorf("usage: password <serverName> [<new-password>]")
		}
	case "description":
		handlingServer = true
		if flag.NArg() < 2 {
			exit.Errorf("usage: description <serverName> <descriptive-text")
		}
	case "rawdisk":
		handlingServer = true
		if flag.NArg() != 3 {
			exit.Errorf("usage: rawdisk <serverName> <diskGB>")
		}
	case "mv":
		if flag.NArg() != 3 {
			exit.Errorf("usage: mv <server|group> <new-Group>")
		}
	case "mkdir":
		if flag.NArg() != 3 {
			exit.Errorf("usage: mkdir <parentGroup> <newGroupName>")
		}
	case "rename":
		if flag.NArg() != 3 {
			exit.Errorf("usage: rename <oldGroupName> <newGroupName>")
		}
	case "ip", "on", "start", "off", "shutdown", "stop", "pause", "reset", "reboot", "snapshot",
		"delsnapshot", "revert", "archive", "delete", "remove", "wait":
		/* FIXME: use map for usage, and use keys here, i.e. _, ok := map[action] */
		if where == "" {
			exit.Errorf("Action %q requires an argument (try -h).", action)
		}
	default:
		exit.Errorf("Unsupported action %q", action)
	}

	client, err := clcv2.NewCLIClient()
	if err != nil {
		exit.Fatal(err.Error())
	}

	if *location == "" {
		if action == "networks" || action == "show" || action == "templates" {
			fmt.Fprintf(os.Stderr, "Note: no location argument (-l) given, defaulting to %s.\n", client.LocationAlias)
		}
		*location = client.LocationAlias
	}

	if !handlingServer && action != "wait" {
		/*
		 * Decide if arguments refer to a server or a hardware group.
		 */
		if _, err := hex.DecodeString(where); err == nil {
			/* If the first argument decodes as a hex value, assume it is a Hardware Group UUID */
		} else if utils.LooksLikeServerName(where) { /* Starts with a location identifier and is not hex ... */
			where = strings.ToUpper(where)
			handlingServer = true
		} else if *location != "" && where != "" {
			if group, err := client.GetGroupByName(where, *location); err != nil {
				exit.Errorf("failed to resolve group name %q: %s", where, err)
			} else if group == nil {
				exit.Errorf("No group named %q was found in %s", where, *location)
			} else {
				where = group.Id
			}
		} else if *location == "" {
			exit.Errorf("%q looks like a group name - need a location (-l argument) to resolve it.", where)
		} else {
			exit.Errorf("Unable to determine whether %q is a server or a group", where)
		}
	}

	if action == "templates" { /* where="" - neither server nor group action; print regional templates */
		showTemplates(client, *location)
		os.Exit(0)
	} else if action == "networks" { /* similar, neither server nor group action; print regional networks */
		showNetworks(client, *location)
		os.Exit(0)
	} else if action == "wait" {
		reqID = flag.Arg(1)
	} else if handlingServer { /* Server Action */
		switch action {
		case "ip":
			printServerIP(client, where)
			os.Exit(0)
		case "show":
			// FIXME: deal with multiple servers
			if flag.NArg() == 2 {
				showServer(client, where)
			} else {
				showServers(client, flag.Args()[1:]...)
			}
			os.Exit(0)
		case "mv":
			var newParent = flag.Arg(2)

			if _, err := hex.DecodeString(newParent); err == nil {
				/* Looks like a Group UUID */
			} else if *location == "" {
				exit.Errorf("Need a location argument (-l) if destination group (%s) is not a UUID", newParent)
			} else {
				if grp, err := client.GetGroupByName(newParent, *location); err != nil {
					exit.Errorf("failed to resolve group name %q: %s", newParent, err)
				} else if grp == nil {
					exit.Errorf("No group named %q was found in %s", newParent, *location)
				} else {
					newParent = grp.Id
				}
			}

			if err = client.ServerSetGroup(where, newParent); err != nil {
				exit.Fatalf("failed to change the parent group on %q: %s", where, err)
			}

			fmt.Printf("Successfully changed the parent group of %s to %s.\n", where, flag.Arg(2))
			os.Exit(0)
		case "memory":
			fmt.Printf("Setting %s memory to %s GB ...\n", where, flag.Arg(2))

			reqID, err = client.ServerSetMemory(where, flag.Arg(2))
			if err != nil {
				exit.Fatalf("failed to change the amount of Memory on %q: %s", where, err)
			}
		case "description":
			fmt.Printf("Setting %s description to to %q.\n", where, flag.Arg(2))

			if err = client.ServerSetDescription(where, flag.Arg(2)); err != nil {
				exit.Fatalf("failed to change the description of %q: %s", where, err)
			}
		case "password":
			var newPassword string

			log.Printf("Looking up existing password of %s", where)

			credentials, err := client.GetServerCredentials(where)
			if err != nil {
				exit.Fatalf("failed to obtain the credentials of %q: %s", where, err)
			}
			log.Printf("Existing %s password: %q", where, credentials.Password)

			if flag.NArg() == 3 {
				newPassword = flag.Arg(2)
			} else if newPassword, err = garbler.NewPassword(&garbler.Paranoid); err != nil {
				exit.Fatalf("failed to generate new 'garbler' password: %s", err)
			} else {
				// The 'Paranoid' mode in garbler more than satisfies CLC requirements.
				// However, the symbols may contain unsupported characters.
				newPassword = strings.Map(func(r rune) rune {
					if strings.Index(clcv2.InvalidPasswordCharacters, string(r)) > -1 {
						return '@'
					}
					return r
				}, newPassword)
				log.Printf("New paranoid 'garbler' password: %q", newPassword)
			}

			if newPassword == credentials.Password {
				log.Printf("%s password is already set to %q", where, newPassword)
				os.Exit(0)
			}

			reqID, err = client.ServerChangePassword(where, credentials.Password, newPassword)
			if err != nil {
				exit.Fatalf("failed to change the password on %q: %s", where, err)
			}
		case "credentials":
			credentials, err := client.GetServerCredentials(where)
			if err != nil {
				exit.Fatalf("failed to obtain the credentials of server %q: %s", where, err)
			}

			fmt.Printf("Credentials for %s:\n", where)
			fmt.Printf("User:     %s\n", credentials.Username)
			fmt.Printf("Password: \"%s\"\n", credentials.Password)
			os.Exit(0)
		case "rawdisk":
			diskGB, err := strconv.ParseUint(flag.Arg(2), 10, 32)
			if err != nil {
				exit.Errorf("rawdisk: invalid disk size in GB %q for %s", flag.Arg(2), where)
			}
			reqID = addRawDisk(client, where, uint32(diskGB))
		default:
			var serverAction = map[string]func(string) (string, error){
				"on":          client.PowerOnServer,
				"start":       client.PowerOnServer, // Alias
				"off":         client.PowerOffServer,
				"pause":       client.PauseServer,
				"reset":       client.ResetServer,
				"reboot":      client.RebootServer,
				"shutdown":    client.ShutdownServer,
				"stop":        client.ShutdownServer, // Alias
				"archive":     client.ArchiveServer,
				"delete":      client.DeleteServer,
				"remove":      client.DeleteServer, // Alias
				"snapshot":    client.SnapshotServer,
				"delsnapshot": client.DeleteSnapshot,
				"revert":      client.RevertToSnapshot,
			}

			/* Long-running commands that return a RequestID */
			handler, ok := serverAction[action]
			if !ok {
				exit.Fatalf("Unsupported server action %s", action)
			}

			reqID, err = handler(where)
			if err != nil {
				exit.Fatalf("Server command %q failed: %s", action, err)
			}
		}
	} else if action == "show" || action == "ip" {
		/* Printing group trees: requires to resolve the root first. */
		var start *clcv2.Group

		if *location == "" {
			exit.Errorf("Location argument (-l) is required in order to traverse nested groups.")
		}

		root, err := client.GetGroups(*location)
		if err != nil {
			exit.Fatalf("failed to look up groups at %s: %s", *location, err)
		}

		start = &root
		if where != "" {
			start = clcv2.FindGroupNode(start, func(g *clcv2.Group) bool {
				return g.Id == where
			})
			if start == nil {
				exit.Fatalf("failed to look up UUID %s in %s - is this the correct value?", where, *location)
			}
		}

		switch action {
		case "show":
			showGroup(client, start)
		case "ip":
			printGroupIPs(client, start)
		}
		os.Exit(0)
	} else {
		/* Other Group Action */
		switch action {
		case "archive":
			reqID, err = client.ArchiveGroup(where)
		case "mkdir":
			g, err := client.CreateGroup(flag.Arg(2), where, flag.Arg(2), nil)
			if err == nil {
				fmt.Printf("New subfolder of %s: %q (UUID: %s)\n", flag.Arg(1), g.Name, g.Id)
			}
		case "delete", "remove":
			reqID, err = client.DeleteGroup(where)
		case "mv":
			var newParent = flag.Arg(2)

			if _, err := hex.DecodeString(newParent); err == nil {
				/* Looks like a Group UUID */
			} else if *location == "" {
				exit.Errorf("Need a location argument (-l) if destination group (%s) is not a UUID", newParent)
			} else {
				if grp, err := client.GetGroupByName(newParent, *location); err != nil {
					exit.Errorf("failed to resolve group name %q: %s", newParent, err)
				} else if grp == nil {
					exit.Errorf("No group named %q was found in %s", newParent, *location)
				} else {
					newParent = grp.Id
				}
			}

			if err = client.GroupSetParent(where, newParent); err != nil {
				exit.Fatalf("failed to change the parent group on %q: %s", where, err)
			}

			fmt.Printf("Successfully changed the parent group of %s to %s.\n", where, flag.Arg(2))
			os.Exit(0)
		case "rename":
			if err = client.GroupSetName(where, flag.Arg(2)); err == nil {
				fmt.Println("OK")
			}
		default:
			exit.Errorf("Unsupported group action %q", action)
		}
		if err != nil {
			exit.Fatalf("Group command %q failed: %s", action, err)
		}
	}

	if reqID != "" {
		client.PollStatus(reqID, *intvl)
	}
}