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)) |