Example #1
0
func makeCommandTree(singularName string,
	maker func() client.Crudder) (res *cobra.Command) {
	name := singularName + "s"
	d("Making command tree for %v\n", name)
	res = &cobra.Command{
		Use:   name,
		Short: fmt.Sprintf("Access CLI commands relating to %v", name),
	}
	commands := make([]*cobra.Command, 8)
	commands[0] = &cobra.Command{
		Use:   "list",
		Short: fmt.Sprintf("List all %v", name),
		Run: func(c *cobra.Command, args []string) {
			objs := []interface{}{}
			if err := client.List(maker().ApiName(), &objs); err != nil {
				log.Fatalf("Error listing %v: %v", name, err.Error())
			}
			fmt.Println(prettyJSON(objs))
		},
	}
	commands[1] = &cobra.Command{
		Use:   "match [json]",
		Short: fmt.Sprintf("List all %v that match the template in [json]", name),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 1 {
				log.Fatalf("%v requires 1 argument\n", c.UseLine())
			}
			objs := []interface{}{}
			vals := map[string]interface{}{}
			if err := json.Unmarshal([]byte(args[0]), &vals); err != nil {
				log.Fatalf("Matches not valid JSON\n%v", err)
			}
			if err := client.Match(maker().ApiName(), vals, &objs); err != nil {
				log.Fatalf("Error getting matches for %v\nError:%v\n", singularName, err.Error())
			}
			fmt.Println(prettyJSON(objs))
		},
	}
	commands[2] = &cobra.Command{
		Use:   "show [id]",
		Short: fmt.Sprintf("Show a single %v by id", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 1 {
				log.Fatalf("%v requires 1 argument\n", c.UseLine())
			}
			obj := maker()
			if client.Fetch(obj, args[0]) != nil {
				log.Fatalf("Failed to fetch %v\n", singularName, args[0])
			}
			fmt.Println(prettyJSON(obj))
		},
	}
	commands[3] = &cobra.Command{
		Use:   "sample",
		Short: fmt.Sprintf("Get the default values for a %v", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 0 {
				log.Fatalf("%v takes no arguments", c.UseLine())
			}
			obj := maker()
			if err := client.Init(obj); err != nil {
				log.Fatalf("Unable to fetch defaults for %v: %v\n", singularName, err.Error())
			}
			fmt.Println(prettyJSON(obj))
		},
	}
	commands[4] = &cobra.Command{
		Use:   "create [json]",
		Short: fmt.Sprintf("Create a new %v with the passed-in JSON", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 1 {
				log.Fatalf("%v requires 1 argument\n", c.UseLine())
			}
			obj := maker()
			if err := client.Import(obj, []byte(args[0])); err != nil {
				log.Fatalf("Unable to create new %v: %v\n", singularName, err.Error())
			}
			fmt.Println(prettyJSON(obj))
		},
	}
	commands[5] = &cobra.Command{
		Use:   "update [id] [json]",
		Short: fmt.Sprintf("Unsafely update %v by id with the passed-in JSON", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 2 {
				log.Fatalf("%v requires 2 arguments\n", c.UseLine())
			}
			obj := maker()
			if err := client.Fetch(obj, args[0]); err != nil {
				log.Fatalf("Failed to fetch %v\n%v\n", singularName, err)
			}
			if err := client.UpdateJSON(obj, []byte(args[1])); err != nil {
				log.Fatalf("Unable to patch %v\n%v\n", args[0], err)
			}

			fmt.Println(prettyJSON(obj))
		},
	}
	commands[6] = &cobra.Command{
		Use:   "patch [objectJson] [changesJson]",
		Short: fmt.Sprintf("Patch %v with the passed-in JSON", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 2 {
				log.Fatalf("%v requires 2 arguments\n", c.UseLine())
			}
			obj := maker()
			if err := json.Unmarshal([]byte(args[0]), obj); err != nil {
				log.Fatalf("Unable to parse %v JSON %v\nError: %v\n", args[0], err)
			}
			newObj := maker()
			json.Unmarshal([]byte(args[0]), newObj)
			if err := json.Unmarshal([]byte(args[1]), newObj); err != nil {
				log.Fatalf("Unable to parse %v JSON %v\nError: %v\n", args[1], err)
			}
			newBuf, _ := json.Marshal(newObj)
			patch, err := jsonpatch.GenerateJSON([]byte(args[0]), newBuf, true)
			if err != nil {
				log.Fatalf("Cannot generate JSON Patch\n%v\n", err)
			}

			if err := client.Patch(obj, patch); err != nil {
				log.Fatalf("Unable to patch %v\n%v\n", args[0], err)
			}

			fmt.Println(prettyJSON(obj))
		},
	}
	commands[7] = &cobra.Command{
		Use:   "destroy [id]",
		Short: fmt.Sprintf("Destroy %v by id", singularName),
		Run: func(c *cobra.Command, args []string) {
			if len(args) != 1 {
				log.Fatalf("%v requires 1 argument\n", c.UseLine())
			}
			obj := maker()
			if client.SetId(obj, args[0]) != nil {
				log.Fatalf("Failed to parse ID %v for an %v\n", args[0], singularName)
			}
			if err := client.Destroy(obj); err != nil {
				log.Fatalf("Unable to destroy %v %v\nError: %v\n", singularName, args[0], err.Error())
			}
			fmt.Printf("Deleted %v %v\n", singularName, args[0])
		},
	}

	res.AddCommand(commands...)
	// Add relavent subcommands as needed.
	addAttriberCommands(singularName, maker, res)
	addDeploymenterCommands(singularName, maker, res)
	addDeploymentRolerCommands(singularName, maker, res)
	addNetworkerCommands(singularName, maker, res)
	addNetworkRangerCommands(singularName, maker, res)
	addNetworkAllocaterCommands(singularName, maker, res)
	addNoderCommands(singularName, maker, res)
	addRolerCommands(singularName, maker, res)
	addHammererCommands(singularName, maker, res)
	addJiggerCommands(singularName, maker, res)
	return res
}
Example #2
0
func init() {
	maker := func() client.Crudder { return &client.Network{} }
	network := makeCommandTree("network", maker)
	cmds := []*cobra.Command{
		&cobra.Command{
			Use:   "import [json]",
			Short: "Import a network + optional ranges and routers into Crowbar",
			Run: func(c *cobra.Command, args []string) {
				if len(args) != 1 {
					log.Fatalf("%v requires 1 argument\n", c.UseLine())
				}
				obj := &client.Network{}
				if err := client.Import(obj, []byte(args[0])); err != nil {
					log.Fatalf("Unable to import network: %v\n", err)
				}
				fmt.Println(prettyJSON(obj))
			},
		},
		&cobra.Command{
			Use:   "add [id] to [nodeId]",
			Short: "Add a Network to a Node.  This will implicitly allocate an address from the default host ranges in the network.",
			Run: func(c *cobra.Command, args []string) {
				if len(args) != 3 {
					log.Fatalf("%v requires 2 arguments\n", c.UseLine())
				}
				node := &client.Node{}
				network := &client.Network{}
				if err := client.Fetch(node, args[2]); err != nil {
					log.Fatalf("Unable to fetch node\n%v\n", err)
				}
				if err := client.Fetch(network, args[0]); err != nil {
					log.Fatalf("Unable to fetch network\n%v\n", err)
				}
				ranges, err := network.AutoRanges(node)
				if err != nil {
					log.Fatalln("Failed to get auto ranges for network", err)
				}
				res := make([]*client.NetworkAllocation, len(ranges))
				unwind := true
				defer func() {
					if unwind {
						for _, allocation := range res {
							if allocation != nil {
								client.Destroy(allocation)
							}
						}
					}
				}()

				for i, netRange := range ranges {
					alloc := &client.NetworkAllocation{}
					alloc.NodeID = null.IntFrom(node.ID)
					alloc.NetworkID = null.IntFrom(network.ID)
					alloc.NetworkRangeID = null.IntFrom(netRange.ID)

					if err := client.BaseCreate(alloc); err != nil {
						log.Fatalf("Unable to create new NetworkAllocation: %v", err)
					}
					res[i] = alloc
				}
				unwind = false
				fmt.Println(prettyJSON(res))
			},
		},
		&cobra.Command{
			Use:   "alloc [id] on [nodeId] from [rangeId] hint [address]",
			Short: "Add a Network to a Node with an address allocated from a specific Range.",
			Run: func(c *cobra.Command, args []string) {
				if len(args) != 5 && len(args) != 7 {
					log.Fatalf("%v requires 3 or 4 arguments", c.UseLine())
				}
				node := &client.Node{}
				if err := client.Fetch(node, args[0]); err != nil {
					log.Fatalln("Unable to fetch node from Crowbar\n%v\n", err)
				}
				netRange := &client.NetworkRange{}
				if err := client.SetId(netRange, args[4]); err != nil {
					vals := map[string]interface{}{}
					vals["name"] = args[4]
					network := &client.Network{}
					if err := client.Fetch(network, args[2]); err != nil {
						log.Fatalln("Unable to fetch network from Crowbar\n%v\n", err)
					}
					vals["network_id"] = network.ID
					netRanges := []*client.NetworkRange{}
					if err := client.Match(netRange.ApiName(), vals, &netRanges); err != nil {
						log.Fatalf("Unable to fetch ranges matching %#v\n%v\n", netRange, err)
					}
					if len(netRanges) != 1 {
						log.Fatalln("Supplied network range information is ambiguous")
					}
					netRange = netRanges[0]
				} else {
					if err := client.Read(netRange); err != nil {
						log.Fatalln("Unable to fetch network range\n%v\n", err)
					}
				}
				alloc := &client.NetworkAllocation{}
				alloc.NetworkID = null.IntFrom(netRange.NetworkID)
				alloc.NetworkRangeID = null.IntFrom(netRange.ID)
				alloc.NodeID = null.IntFrom(node.ID)
				if len(args) == 7 {
					alloc.Address = args[6]
				}
				if err := client.BaseCreate(alloc); err != nil {
					log.Fatalf("Unable to add node to network\n%v\n", err)
				}
				fmt.Println(prettyJSON(alloc))
			},
		},
	}
	network.AddCommand(cmds...)
	app.AddCommand(network)
	maker = func() client.Crudder { return &client.NetworkRange{} }
	networkrange := makeCommandTree("networkrange", maker)
	app.AddCommand(networkrange)
	maker = func() client.Crudder { return &client.NetworkAllocation{} }
	app.AddCommand(makeCommandTree("networkallocation", maker))
	maker = func() client.Crudder { return &client.NetworkRouter{} }
	app.AddCommand(makeCommandTree("networkrouter", maker))
}