| Index: go/src/infra/crimson/cmd/crimson/main.go
|
| diff --git a/go/src/infra/crimson/cmd/crimson/main.go b/go/src/infra/crimson/cmd/crimson/main.go
|
| index ca5910b29d63f243283c27f14a0a62726b9fcc76..433307ef5abcffce635731cc224187ed80b9d6b9 100644
|
| --- a/go/src/infra/crimson/cmd/crimson/main.go
|
| +++ b/go/src/infra/crimson/cmd/crimson/main.go
|
| @@ -39,12 +39,33 @@ type addVlanRun struct {
|
|
|
| type queryVlanRun struct {
|
| commonFlags
|
| + limit int
|
| site string
|
| vlan string
|
| ip string
|
| - limit int
|
| }
|
|
|
| +type addHostRun struct {
|
| + commonFlags
|
| + site string
|
| + hostname string
|
| + macAddr string
|
| + ip string
|
| + bootClass string
|
| +}
|
| +
|
| +type queryHostRun struct {
|
| + commonFlags
|
| + limit int
|
| + site string
|
| + hostname string
|
| + macAddr string
|
| + ip string
|
| + bootClass string
|
| +}
|
| +
|
| +const backendHost = "crimson-staging.appspot.com"
|
| +
|
| var (
|
| cmdCreateIPRange = &subcommands.Command{
|
| UsageLine: "add-vlan <start ip>-<end ip>",
|
| @@ -53,7 +74,7 @@ var (
|
| CommandRun: func() subcommands.CommandRun {
|
| c := &addVlanRun{}
|
| c.Flags.StringVar(&c.backendHost, "backend-host",
|
| - "crimson-staging.appspot.com", "Host to talk to")
|
| + backendHost, "Host to talk to")
|
| c.Flags.StringVar(&c.site, "site", "", "Name of the site")
|
| c.Flags.StringVar(&c.vlan, "vlan", "", "Name of the vlan")
|
| c.Flags.StringVar(&c.inputFileDHCP, "input-file-dhcp", "",
|
| @@ -65,7 +86,7 @@ var (
|
| },
|
| }
|
|
|
| - cmdReadIPRange = &subcommands.Command{
|
| + cmdQueryIPRange = &subcommands.Command{
|
| UsageLine: "query-vlan",
|
| ShortDesc: "Reads an IP range.",
|
| LongDesc: "Reads an IP range.",
|
| @@ -73,17 +94,63 @@ var (
|
| c := &queryVlanRun{}
|
| c.format = cmdhelper.DefaultFormat
|
| c.Flags.StringVar(&c.backendHost, "backend-host",
|
| - "crimson-staging.appspot.com", "Host to talk to")
|
| + backendHost, "Host to talk to")
|
| c.Flags.StringVar(&c.site, "site", "", "Name of the site")
|
| c.Flags.StringVar(&c.vlan, "vlan", "", "Name of the vlan")
|
| c.Flags.StringVar(&c.ip, "ip", "", "IP contained within the range")
|
| - c.Flags.IntVar(&c.limit, "limit", 10,
|
| + // TODO(pgervais): tell the user when more results are available.
|
| + c.Flags.IntVar(&c.limit, "limit", 1000,
|
| "Maximum number of results to return")
|
| c.Flags.Var(&c.format, "format", "Output format: "+
|
| cmdhelper.FormatTypeEnum.Choices())
|
| return c
|
| },
|
| }
|
| +
|
| + cmdCreateHost = &subcommands.Command{
|
| + UsageLine: "add-host",
|
| + ShortDesc: "Creates host entries.",
|
| + LongDesc: "Creates host entries",
|
| + CommandRun: func() subcommands.CommandRun {
|
| + c := &addHostRun{}
|
| + c.Flags.StringVar(&c.backendHost, "backend-host",
|
| + backendHost, "Host to talk to")
|
| + c.Flags.StringVar(&c.site, "site", "", "Name of the site")
|
| + c.Flags.StringVar(&c.hostname, "hostname", "", "Name of the host")
|
| + c.Flags.StringVar(&c.macAddr, "mac", "",
|
| + "Host MAC address, as xx:xx:xx:xx:xx")
|
| + c.Flags.StringVar(&c.ip, "ip", "", "IP address")
|
| + // The valid values here are application-specific and must be checked
|
| + // server-side.
|
| + c.Flags.StringVar(&c.bootClass, "boot-class", "", "Host boot class")
|
| + return c
|
| + },
|
| + }
|
| +
|
| + cmdQueryHost = &subcommands.Command{
|
| + UsageLine: "query-host",
|
| + ShortDesc: "Reads hosts.",
|
| + LongDesc: "Fetches a filtered list of hosts.",
|
| + CommandRun: func() subcommands.CommandRun {
|
| + c := &queryHostRun{}
|
| + c.format = cmdhelper.DefaultFormat
|
| + c.Flags.StringVar(&c.backendHost, "backend-host",
|
| + backendHost, "Host to talk to")
|
| + c.Flags.StringVar(&c.site, "site", "", "Name of the site")
|
| + c.Flags.StringVar(&c.hostname, "hostname", "", "Name of the host")
|
| + c.Flags.StringVar(&c.macAddr, "mac", "",
|
| + "Host MAC address, as xx:xx:xx:xx:xx")
|
| + c.Flags.StringVar(&c.ip, "ip", "", "IP address")
|
| + // The valid values here are application-specific and must be checked
|
| + // server-side.
|
| + c.Flags.StringVar(&c.bootClass, "boot-class", "", "Host boot class")
|
| + c.Flags.Var(&c.format, "format", "Output format: "+
|
| + cmdhelper.FormatTypeEnum.Choices())
|
| + c.Flags.IntVar(&c.limit, "limit", 1000,
|
| + "Maximum number of results to return")
|
| + return c
|
| + },
|
| + }
|
| )
|
|
|
| func ipRangeFromSiteAndVlan(c *addVlanRun) ([]*crimson.IPRange, error) {
|
| @@ -207,6 +274,77 @@ func (c *queryVlanRun) Run(a subcommands.Application, args []string) int {
|
| return 0
|
| }
|
|
|
| +func hostListFromRangeFromArgs(c *addHostRun) (*crimson.HostList, error) {
|
| + if c.site == "" {
|
| + return nil, fmt.Errorf("missing required -site option")
|
| + }
|
| +
|
| + if c.hostname == "" {
|
| + return nil, fmt.Errorf("missing required -hostname option")
|
| + }
|
| +
|
| + if c.macAddr == "" {
|
| + return nil, fmt.Errorf("missing required -mac option")
|
| + }
|
| +
|
| + if c.ip == "" {
|
| + return nil, fmt.Errorf("missing required -ip option")
|
| + }
|
| +
|
| + hostList := crimson.HostList{
|
| + Hosts: []*crimson.Host{{
|
| + Site: c.site,
|
| + Hostname: c.hostname,
|
| + MacAddr: c.macAddr,
|
| + Ip: c.ip,
|
| + BootClass: c.bootClass,
|
| + }}}
|
| + return &hostList, nil
|
| +}
|
| +
|
| +func (c *addHostRun) Run(a subcommands.Application, args []string) int {
|
| + ctx := cli.GetContext(a, c)
|
| + client := c.newCrimsonClient(ctx)
|
| +
|
| + hostList, err := hostListFromRangeFromArgs(c)
|
| + if err != nil {
|
| + fmt.Fprintf(os.Stderr, "%s\n", err)
|
| + return 1
|
| + }
|
| +
|
| + _, err = client.CreateHost(ctx, hostList)
|
| + if err != nil {
|
| + fmt.Fprintln(os.Stderr, err)
|
| + return 1
|
| + }
|
| + // TODO(pgervais): provide some more useful feedback to the user.
|
| + fmt.Println("Success.")
|
| + return 0
|
| +}
|
| +
|
| +func (c *queryHostRun) Run(a subcommands.Application, args []string) int {
|
| + ctx := cli.GetContext(a, c)
|
| + client := c.newCrimsonClient(ctx)
|
| +
|
| + req := &crimson.HostQuery{
|
| + Limit: uint32(c.limit),
|
| + Site: c.site,
|
| + Hostname: c.hostname,
|
| + MacAddr: c.macAddr,
|
| + Ip: c.ip,
|
| + BootClass: c.bootClass,
|
| + }
|
| +
|
| + hostList, err := client.ReadHost(ctx, req)
|
| + if err != nil {
|
| + fmt.Fprintln(os.Stderr, err)
|
| + return 1
|
| + }
|
| +
|
| + cmdhelper.PrintHostList(hostList, c.format)
|
| + return 0
|
| +}
|
| +
|
| func (c *commonFlags) newCrimsonClient(ctx context.Context) crimson.CrimsonClient {
|
| authOpts, err := c.authFlags.Options()
|
| if err != nil {
|
| @@ -241,7 +379,9 @@ func main() {
|
| authcli.SubcommandLogin(opts, "login"),
|
| authcli.SubcommandLogout(opts, "logout"),
|
| cmdCreateIPRange,
|
| - cmdReadIPRange,
|
| + cmdQueryIPRange,
|
| + cmdCreateHost,
|
| + cmdQueryHost,
|
| },
|
| }
|
| os.Exit(subcommands.Run(application, nil))
|
|
|