rackspace / rack Goto Github PK
View Code? Open in Web Editor NEWA CLI for Rackspace (unmaintained)
License: Other
A CLI for Rackspace (unmaintained)
License: Other
We have an inconsistency in naming, in that we force users to use --image-ref
(previously --imageRef
) when we call it an ID in the table:
$ rack servers image list
ID Name Status MinDisk MinRAM
c199db85-c6f9-4284-b9ec-16327ee2fc84 OnMetal - Ubuntu 14.04 LTS (Trusty Tahr) ACTIVE 20 512
41e85e59-dea0-410f-a5f6-0ca92c3b3322 OnMetal - CoreOS (Stable) ACTIVE 20 512
and in the get
:
$ rack servers image get --id c199db85-c6f9-4284-b9ec-16327ee2fc84
PROPERTYVALUE
ID c199db85-c6f9-4284-b9ec-16327ee2fc84
Name OnMetal - Ubuntu 14.04 LTS (Trusty Tahr)
Status ACTIVE
Progress100
MinDisk 20
MinRAM 512
Created 2015-06-16T03:02:41Z
Updated 2015-06-16T14:33:18Z
I don't know the effort level involved in this, but it's probably worth looking into.
See #59 for the changes. Need docs for this.
Given the following call:
rack servers instances delete --id 12345 --name foo
What should happen?
Options
id
name
name
and id
Thoughts?
How does someone add a new service? How do we make this self-service for command additions, features? How much is upstream gophercloud?
Should this be possible (providing multiple id values to the id
flag) ?:
rack servers get --id 12345,5678,12395
Should this be possible (providing multiple id values to a new ids
flag) ?:
rack servers get --ids 12345,5678,12395
Or should multiple values of anything have to be piped in on STDIN?
The question arises because the logic for handling the piping of multiple values necessitates looping over multiple values. Processing the requests for multiple values from STDIN is logically very similar to the above commands. The question is do we want to offer that to users and, if so, via which format.
I'm not sure there's a way to generalize the tabular output for the different commands. Tables are tricky because they have different headers, different value types, sometimes we'll want a nested value, etc. We'll be able to extract the shell of the table, but the headers and values may have to be command-specific.
Currently, Swift is the only API that when given a GET request, I.e. /mycontainer/myfile.txt
it returns the contents of the file, not the metadata.
Should we follow this discrepancy in the CLI? or should we provide consistency.
For example:
rack files object get --container mycontainer --file myfile.txt
could return the metadata and
rack files object download --container mycontainer --file myfile.txt
would then return the contents?
Pros: Consistent calling convention across all services.
Cons: Most likely use of files will involve getting the file, not the metadata, leading to more typing in the default case.
Thoughts?
Currently, the format is:
<cliName> <service> <subservice> <action> <flags>
Example: rackcli compute servers list --name server1
Personally, I prefer being explicit like above. However, I know some people prefer terse commands:
<cliName> <subservice> <action> <flags>
Example: rackcli servers list --name server1
Though it's true that in the above example removing the service leaves no ambiguity, there are services like load balancers where you'd have rackcli members list <lbID>
. It's not obvious that the command is for listing members of a load balancer and though we could have something like rackcli lb-members list <lbID>
, that seems to lack consistency.
With bash completion for commands (and in time, flags), I don't think being explicit is much of an inconvenience, but I'd like to hear what others think.
I think we should seriously consider not using spaces in JSON keys. When people are parsing/selecting on JSON keys, any spaces in the key can require annoying escaping. It becomes a papercut.
For example, if you were to try to get the private IP address of 2 servers that are named the same ("rum") using jq.
$ rack --json servers instance list | jq -r '.[] | select(.Name == "rum").Private IPv4'
error: syntax error, unexpected IDENT, expecting $end
.[] | select(.Name == "rum").Private IPv4 1 compile error
$ rack --json servers instance list | jq -r '.[] | select(.Name == "rum").Private\ IPv4'
error: syntax error, unexpected INVALID_CHARACTER, expecting $end
.[] | select(.Name == "rum").Private\ IPv4 1 compile error
I'm sure there's some escaping I can do to fix this or use some other tool that maybe handles spaces in keys better but it feels like there will always be some amount of having to work around spaces in key names.
Currently, in rack-configure
branch, you can over-write an existing config profile without a prompt.
Options:
Thoughts?
For example, if I run this command with invalid credentials, it won't show anything, and will run grep because the previous command exited with 0
.
/data/src/rack [design] $ rack servers image list | grep ubuntu
Currently if I don't use a profile or export env variables, we get a generic error:
"PROPERTYVALUE
error Error creating ProviderClient: You must supply a Username in your AuthOptions."
I think at a minimum the error should be more friendly. In the bigger picture, this ties into whether a "default' profile (and/or the only defined profile if there is one) should be consumed by default when a profile isn't specified. It feels a little weird to use configure to make a config file, but then have to specify it all of the time with the --profile flag if it's the only one you're using. We could either hint in the configure process about using Default, or make it dummy proof by automatically consuming the profile if there is only a single profile saved. Actually both are probably good ideas. (Says the guy who suggested them.)
servers:
flavors:
images:
keypairs:
One important feature from the Nova CLI, used in PerfKitBenchmarker, is the ability to view the extra_specs from a flavor. This property lists number_of_data_disks
included, the class of the flavor, etc.
e.g.
$ nova flavor-show io1-15
+-----------------------------------+---------------------------------------------------------------------------------------------------+
| Property | Value |
+-----------------------------------+---------------------------------------------------------------------------------------------------+
| OS-FLV-EXT-DATA:ephemeral | 150 |
| OS-FLV-WITH-EXT-SPECS:extra_specs | {"number_of_data_disks": "1", "class": "io1", "disk_io_index": "40", "policy_class": "io_flavor"} |
| disk | 40 |
| extra_specs | {"number_of_data_disks": "1", "class": "io1", "disk_io_index": "40", "policy_class": "io_flavor"} |
| id | io1-15 |
| name | 15 GB I/O v1 |
| ram | 15360 |
| rxtx_factor | 1250.0 |
| swap | |
| vcpus | 4 |
+-----------------------------------+---------------------------------------------------------------------------------------------------+
The rack CLI as of today, doesn't output this data, neither in the table format nor the json format outputs.
$ rack servers flavor get io1-15 --json
{"ID":"io1-15","Disk":40,"RAM":15360,"Name":"15 GB I/O v1","RxTxFactor":1250,"Swap":0,"VCPUs":4}
$ rack servers flavor get io1-15
PROPERTY VALUE
ID io1-15
Name 15 GB I/O v1
Disk 40
RAM 15360
RxTxFactor 1250
Swap 0
VCPUs 4
One proposal, is to include the extra_specs
on the JSON output as a nested JSON object, something like:
{
"ID": "io1-15",
"Disk": 40,
"RAM": 15360,
"Name": "15 GB I/O v1",
"RxTxFactor": 1250,
"Swap": 0,
"VCPUs": 4,
"ExtraSpecs": {
"number_of_data_disks": "1",
"class": "io1",
"disk_io_index": "40",
"policy_class": "io_flavor"
}
}
and for table output, perhaps unpack the values, perhaps something like:
PROPERTY VALUE
ID io1-15
Name 15 GB I/O v1
Disk 40
RAM 15360
RxTxFactor 1250
Swap 0
VCPUs 4
DataDisks 1
FlavorClass io1
DiskIOIndex 40
PolicyClass io_flavor
or print the JSON object in the table as Nova does (ugly, IMHO), or just simply not show them on the table output.
We can provide aliases for commands like ls
for list
easily enough. The question is if we want to or not. Off the top of my head, the only reason I can think not to would be that when using bash completion, the options available could be large. For example, with aliases, if I typed rackcli compute servers [tab]
, I might see something like:
mk create update get ls list delete rm
as opposed to
create update get delete list
.
Not really a big difference, but users may wonder if there's a difference between, say, ls
and list
.
We should make a downloads page with builds of what's on master for people to consume (we also have branches and some commits but I digress).
Update: Installation/configuration instructions are now on ReadTheDocs.
@jrperritt and I have spent some time ideating on possible strategies for piping. We've got a proposal that we want to try out with everyone.
All commands that allow piped inputs require an explicit --stdin
flag.
All commands that allow piped inputs require the caller to explicitly declare what flag is coming in on stdin.
These are all examples where we'd use stdin
and a combination of required flags.
cat ids.txt | rack servers instance delete --id --stdin
cat names.txt | rack servers instance delete --name --stdin
cat foo.txt | rack files object create --container mycontainer name foo.txt --contents --stdin
cat ~/.ssh/id_rsa.pub | rack servers keys create --name my-key --public-key --stdin
This approach maintains consistency on functions like upload on keys or object when not using --stdin
:
rack files object create --container mycontainer name foo.txt --contents "{\"data\":\"asdf1234\"}"
rack servers keys create --name my-key --public-key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOltMjiD35ZteXKGIqkSVDLwnj8n5ZCuoB9Lb7yf23/nCfdUsp1Yw1sjsaWege7969bRWMSx0nB7r9b3rbJAISKfaA4wSSswKI4eaU1fKAN6JSf3kvCI8y12cqC2bsFY0FIakiVrO4gewBzo/JH5f0QqwKIsj2QDg2m8d/jZkHxAcY0jrIa1PHbP51B35KrgV1+ga6kzVmYMqzR/jhURJzRhlb3yn0oLhBOLpC2dsnS2cnTTqsdgaHFV8927bWJA0sYnkv2vJqetqAu/9E4WJZQD36IjWoNKT+4uOIU58PefOhhttUu5NPa0vVruADSlVH+N5ULoIZb0oYqvZjX3Wj [email protected]
To provide the capability to use local files as inputs, but not being piped, we'll use explicit flags to differentiate inline content from local files:
rack files object create --container mycontainer --name foo.txt --file ./foo.txt
rack servers keys create --name my-key --file ~/.ssh/id_rsa.pub
What do ya'll think?
containers:
objects:
$ rack --profile does-not-exist servers instance list
This successfully used environment variables I had specified, but it seems contrary to a users expectation.
Thoughts?
We should be able to pipe in and out from this tool. Currently, only out is possible.
Also, we should look into being opinionated about piping from this tool to itself (see here: https://github.com/jrperritt/rack/issues/17#issuecomment-109850039)
Should we be able to specify global defaults in the config?
[Global]
no-cache=true
output=json
debug=true
[Default]
region=iad
username=asdf
api-key=asdf1234
[Test]
region=iad
username=asdf
api-key=asdf1234
output=table
A couple of other thoughts? Should there be a default profile? or should [Global]
be able to be overriden?
folks might do any combination of case on a region, i.e. export RS_REGION=iad
, we should uppercase all inputs.
Is this the only authentication endpoint now: https://identity.api.rackspacecloud.com/v2.0?
If so, we can remove the RS_AUTH_URL
from the required parameters the user has to set.
Right now in order to build the output we buffer all of the response payload in memory before outputting to the user. This means for command chains or just lots of output the memory usage could get ghastly for end users and potentially trigger the oom killer on the CLI process itself (or fall into swap). We should consider using a streaming interface for output when possible.
Issue to be researched: To date, it has been best practice with Cloud Servers and Cloud Images to not have customers building images by specifying (or fuzzy matching) the image name. Often the images are changed or updated silently, and the name stays the same, which has led to customer confusion and breakage in more than a couple of instances. This might need to be deprecated; should follow up with Ari Liberman, Amanda Clark on Servers/Images team when builds are more widely distributed.
Feature request: As a CLI user I need to know the underlying API calls so that I can learn the reference information or debug why the command isn't working as expected.
Proposal: display some relevant information about your request:
$ rack --region syd servers instance list
Profile: Default Username: kpraxtest Region: SYD
ID Name Status Public IPv4 Private IPv4 Image Flavor
I've found when using lots of profiles and overriding values like region
that it gets confusing looking at the output without some feedback of which account I'm actually using.
Maybe this would be best as a config option that could be globally set?
Thoughts?
This is pretty awesome. There are some issues I'm taking with the current verbage when reading left to right.
rack compute flavors
Read directly, I see compute
as a verb which is a cognitive disconnect for me.
For non-server sections, it would flow as a resource with server
at the front:
rack server flavors list
rack server images list
rack server keypairs list
I'll come back to this. The weird thing is that Rackspace mycloud lists "Servers" under "Servers".
It's really great to see that json dump is available. Some kind of planar tab delimited format would be great as well, so that I can chain it together with other *nix commands (or even PowerShell). --plain
?
We may want to consider name
and id
flags for most of the commands (get
, update
, delete
) so that users can provide, for example, a server name rather than a server ID. I'm not sure how people feel about flags vs arguments. With arguments, we'd have something like:
rackcli compute servers get <serverID>
and with flags it'd look like:
rackcli compute servers get --id <serverID>
or
rackcli compute servers get --name <serverName>
Another option is to combine the 2 and assume that if an argument is provided that it's an ID. If not provided, look for flags. I know that using arguments for IDs is customary, but I suspect people more often than not would prefer to provide a name.
Though the binary will be all-inclusive, bash completion, at least at the moment, has to be activated manually. We may want to write a script that will do it.
Returning info in a machine readable format is a great start but typically people need to get some very specific piece of information out of a result return by rack.
For example, I need to get the ID of 2 servers that are named the same ("rum").
$ rack --json servers instance list
[
{
"Flavor": "general1-1",
"ID": "2f9657df-68aa-4b26-b779-fb6e3c1fbe52",
"Image": "055143e8-2da9-439a-a52d-8063f845dec6",
"Name": "rum",
"Private IPv4": "10.176.213.132",
"Public IPv4": "104.249.230.215",
"Status": "ACTIVE"
},
{
"Flavor": "performance1-8",
"ID": "c2e791b2-2e1d-4df8-b66c-bcf8c7e8bc96",
"Image": "c11e2d37-bd93-44f0-b17e-bb87d1022975",
"Name": "devstack-juno",
"Private IPv4": "10.229.128.42",
"Public IPv4": "104.130.165.90",
"Status": "ACTIVE"
},
{
"Flavor": "general1-2",
"ID": "3b0c83f9-5cb3-4891-805c-30007a213db3",
"Image": "6f29d6a6-9972-4ae0-aa80-040fa2d6a9cf",
"Name": "rum",
"Private IPv4": "10.172.161.82",
"Public IPv4": "192.252.228.165",
"Status": "ACTIVE"
}
]
One option is to provide the ability to do this within rack itself. It could be done using go templates (ala docker inspect) or some other mechanism.
Another option is to simply document the solution using a favoured third party tool. My preference is jq.
For example.
$ rack --json servers instance list | jq -r '.[] | select(.Name == "rum").ID'
2f9657df-68aa-4b26-b779-fb6e3c1fbe52
3b0c83f9-5cb3-4891-805c-30007a213db3
rack servers image get 00341bad-631f-42b6-bc3c-7a861f9cd637
:
PROPERTYVALUE
ID 00341bad-631f-42b6-bc3c-7a861f9cd637
Name CentOS 6 (PVHVM)
Status ACTIVE
Progress100
MinDisk 20
MinRAM 512
Created 2015-06-01T00:50:37Z
Updated 2015-06-10T21:02:10Z
11:46:51 (master=) kyle6475@puter ~/go/src/github.com/jrperritt/rack$ go build -o $GOPATH/bin/rack && rack servers instance rebuild
rebuild flag redefined: name
panic: rebuild flag redefined: name
goroutine 1 [running]:
flag.(*FlagSet).Var(0xc20805c5a0, 0x67e010, 0xc20802d8b0, 0x3d5b50, 0x4, 0x45df50, 0x4d)
/usr/local/Cellar/go/1.4.2/libexec/src/flag/flag.go:679 +0x494
flag.(*FlagSet).StringVar(0xc20805c5a0, 0xc20802d8b0, 0x3d5b50, 0x4, 0x0, 0x0, 0x45df50, 0x4d)
/usr/local/Cellar/go/1.4.2/libexec/src/flag/flag.go:582 +0xcf
flag.(*FlagSet).String(0xc20805c5a0, 0x3d5b50, 0x4, 0x0, 0x0, 0x45df50, 0x4d, 0x4)
/usr/local/Cellar/go/1.4.2/libexec/src/flag/flag.go:595 +0x86
github.com/codegangsta/cli.funcยท013(0x3d5b50, 0x4)
/Users/kyle6475/go/src/github.com/codegangsta/cli/flag.go:348 +0x62
github.com/codegangsta/cli.eachName(0x3d5b50, 0x4, 0xc208092838)
/Users/kyle6475/go/src/github.com/codegangsta/cli/flag.go:54 +0x11e
github.com/codegangsta/cli.StringFlag.Apply(0x3d5b50, 0x4, 0x0, 0x0, 0x45df50, 0x4d, 0x0, 0x0, 0xc20805c5a0)
/Users/kyle6475/go/src/github.com/codegangsta/cli/flag.go:349 +0x18f
github.com/codegangsta/cli.(*StringFlag).Apply(0xc20800a6c0, 0xc20805c5a0)
<autogenerated>:33 +0xaa
github.com/codegangsta/cli.flagSet(0x3d76b0, 0x7, 0xc20807a280, 0xc, 0x14, 0xc20803fa70)
/Users/kyle6475/go/src/github.com/codegangsta/cli/flag.go:45 +0x133
github.com/codegangsta/cli.Command.Run(0x3d76b0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc208064120, 0x86, 0x4182d0, ...)
/Users/kyle6475/go/src/github.com/codegangsta/cli/command.go:60 +0x3d2
github.com/codegangsta/cli.(*App).RunAsSubcommand(0xc2080821e0, 0xc2080880e0, 0x0, 0x0)
/Users/kyle6475/go/src/github.com/codegangsta/cli/app.go:255 +0xc2a
github.com/codegangsta/cli.Command.startApp(0x3ebdb0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42d390, 0x23, 0x0, ...)
/Users/kyle6475/go/src/github.com/codegangsta/cli/command.go:183 +0x505
github.com/codegangsta/cli.Command.Run(0x3ebdb0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42d390, 0x23, 0x0, ...)
/Users/kyle6475/go/src/github.com/codegangsta/cli/command.go:45 +0x14ee
github.com/codegangsta/cli.(*App).RunAsSubcommand(0xc2080820f0, 0xc208088000, 0x0, 0x0)
/Users/kyle6475/go/src/github.com/codegangsta/cli/app.go:255 +0xc2a
github.com/codegangsta/cli.Command.startApp(0x3d80b0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4186d0, 0x1c, 0x0, ...)
/Users/kyle6475/go/src/github.com/codegangsta/cli/command.go:183 +0x505
github.com/codegangsta/cli.Command.Run(0x3d80b0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4186d0, 0x1c, 0x0, ...)
/Users/kyle6475/go/src/github.com/codegangsta/cli/command.go:45 +0x14ee
github.com/codegangsta/cli.(*App).Run(0xc208082000, 0xc20800a000, 0x4, 0x4, 0x0, 0x0)
/Users/kyle6475/go/src/github.com/codegangsta/cli/app.go:158 +0xd0c
main.main()
/Users/kyle6475/go/src/github.com/jrperritt/rack/main.go:23 +0x16c
goroutine 2 [runnable]:
runtime.forcegchelper()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/proc.go:90
runtime.goexit()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1
goroutine 3 [runnable]:
runtime.bgsweep()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/mgc0.go:82
runtime.goexit()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1
goroutine 4 [runnable]:
runtime.runfinq()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/malloc.go:712
runtime.goexit()
/usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1
Not all systems have bash (e.g. Windows) and not everyone uses bash completion. One helpful thing a lot of client bindings do is provide suggestions. Example for us:
$ rack server instance list
rack: 'server' is not a rack command. Did you mean "rack servers instance list"?
Assuming users could get LOTS of results back from a given call, do we add a --paginate or default to pagination and offer a --no-paginate?
This is essential for CoreOS clusters.
Make sure go get github.com/jrperritt/rack
works across operating systems. It seems to work on Linux, but Maverick may be having issues with the repo name change.
Methods to support:
Also, token caching:
We should create error types for the errors that can be encountered. It'll reduce lines of code and make it easier for writing unit tests.
I want to open this up to discussion as well. There are some flags that every command can provide (such as output format and auth credentials. Currently, those flags exist with all the others in a command (namely, anywhere after the last subcommand). I did it this way originally so that users wouldn't have to know exactly where to put certain flags within the command, but I can understand how some may like the idea of global flags.
rack configure
would provide an interactive environment from the command-line that walks a user through creating authentication credentials.
if I run:
rack servers image list --json
I get:
[{"Created":"2015-06-11T14:57:28Z","ID":"41e85e59-dea0-410f-a5f6-0ca92c3b3322","MinDisk":20,"MinRAM":512,"Name":"OnMetal - CoreOS (Stable)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-11T17:33:54Z"},{"Created":"2015-06-11T14:51:59Z","ID":"cfb643d5-f48d-4988-9ca8-8689c1fc877b","MinDisk":20,"MinRAM":512,"Name":"CoreOS (Stable)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-11T17:23:35Z"},{"Created":"2015-06-11T14:50:04Z","ID":"359123c7-3610-499c-9e7d-3d8ba4b38856","MinDisk":20,"MinRAM":512,"Name":"OnMetal - CoreOS (Beta)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-11T17:29:12Z"},{"Created":"2015-06-11T14:44:39Z","ID":"de7ec65d-51c6-4c4f-b47a-72ec9806bcb1","MinDisk":20,"MinRAM":512,"Name":"CoreOS (Beta)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-11T17:18:52Z"},{"Created":"2015-06-09T12:42:22Z","ID":"58daf745-3146-45fb-b6b1-938aa8240eaa","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Ubuntu 15.04 (Vivid Vervet)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:44:54Z"},{"Created":"2015-06-05T22:26:38Z","ID":"03f6b840-7d5e-4c31-b961-afb55dd4e598","MinDisk":20,"MinRAM":512,"Name":"OnMetal - CentOS 6","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:55:30Z"},{"Created":"2015-06-05T13:43:10Z","ID":"a3e7066e-18fa-4cdd-bc53-7eb9f90e66a7","MinDisk":20,"MinRAM":512,"Name":"Fedora 22 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:39:55Z"},{"Created":"2015-06-04T14:50:02Z","ID":"24971b77-0192-46b6-bfe7-5b51d1f5713d","MinDisk":20,"MinRAM":512,"Name":"OnMetal - CoreOS (Alpha)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-04T19:41:58Z"},{"Created":"2015-06-04T14:44:43Z","ID":"587ee022-8dfe-43e8-ad8b-b4efb1fc1d71","MinDisk":20,"MinRAM":512,"Name":"CoreOS (Alpha)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-04T19:33:11Z"},{"Created":"2015-06-04T09:00:36Z","ID":"2b0ebb8f-c3fd-4677-8abe-583fae74778a","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2012 + SQL Server 2012 SP1 Web","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T18:20:20Z"},{"Created":"2015-06-03T20:27:35Z","ID":"4b4beb50-fea5-43b1-9609-deda8cf8aae2","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Ubuntu 12.04 LTS (Precise Pangolin)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:34:24Z"},{"Created":"2015-06-03T14:14:20Z","ID":"4d6707f0-abed-4a25-b900-47ebaed69f24","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2012 + SQL Server 2012 SP1 Standard","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T18:18:57Z"},{"Created":"2015-06-01T19:14:08Z","ID":"a0642156-1491-48e3-95f1-27a0873bd5a5","MinDisk":20,"MinRAM":512,"Name":"Arch 2015.6 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T20:50:58Z"},{"Created":"2015-06-01T15:40:13Z","ID":"bf73f877-c24d-4288-bba2-14dcd13c5e02","MinDisk":20,"MinRAM":512,"Name":"Ubuntu 15.04 (Vivid Vervet) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:41:28Z"},{"Created":"2015-06-01T15:25:39Z","ID":"4d421e39-c0de-4b2d-bcee-3ebd6b66c01f","MinDisk":20,"MinRAM":512,"Name":"Debian Unstable (Sid) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:28:27Z"},{"Created":"2015-06-01T14:31:09Z","ID":"a41b3d62-5f7b-4697-a4a7-ca2bbf965a06","MinDisk":20,"MinRAM":512,"Name":"Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:36:13Z"},{"Created":"2015-06-01T08:16:49Z","ID":"54885939-c176-48b1-bf7b-6d4039ab6696","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Fedora 22","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:29:09Z"},{"Created":"2015-06-01T08:09:54Z","ID":"6042c5be-00ec-476b-9f6a-729996eaba49","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Fedora 21","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:22:00Z"},{"Created":"2015-06-01T08:02:17Z","ID":"f45e963e-2707-4658-b042-fbb72a294aed","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Debian Unstable (Sid)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:16:45Z"},{"Created":"2015-06-01T07:49:04Z","ID":"5684389d-eaab-4e8e-9ce9-e042ff4ef9f8","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Debian Testing (Stretch)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:11:30Z"},{"Created":"2015-06-01T07:38:02Z","ID":"4410a770-0c5a-4336-aa28-5348d13de669","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Debian 8 (Jessie)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:06:15Z"},{"Created":"2015-06-01T07:12:17Z","ID":"1774d5b0-7452-408f-bba9-721e5cdf5e5d","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Debian 7 (Wheezy)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:01:01Z"},{"Created":"2015-06-01T06:52:04Z","ID":"d7c7c7c9-2c31-4a09-950a-3876ae5eedf4","MinDisk":20,"MinRAM":512,"Name":"OnMetal - Ubuntu 14.04 LTS (Trusty Tahr)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:39:39Z"},{"Created":"2015-06-01T06:22:59Z","ID":"83959dc5-d75c-45be-a096-f938ea382b93","MinDisk":20,"MinRAM":512,"Name":"OnMetal - CentOS 7","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:55:45Z"},{"Created":"2015-06-01T05:55:50Z","ID":"7f78d71e-52a1-474b-a70f-c8d41734f743","MinDisk":20,"MinRAM":512,"Name":"Scientific Linux 7 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:20:13Z"},{"Created":"2015-06-01T05:47:54Z","ID":"51cdc9aa-803b-4bdf-9478-b5f27d21107f","MinDisk":20,"MinRAM":512,"Name":"Scientific Linux 6 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:11:34Z"},{"Created":"2015-06-01T05:21:41Z","ID":"bdc7f23b-83bc-4bb6-b1e7-4a42a1b91cbf","MinDisk":20,"MinRAM":512,"Name":"Gentoo 15.2 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:50:25Z"},{"Created":"2015-06-01T05:07:17Z","ID":"bb50954a-d069-4b32-8dc7-706618a28588","MinDisk":20,"MinRAM":512,"Name":"OpenSUSE 13.2 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:50:19Z"},{"Created":"2015-06-01T04:46:20Z","ID":"c4f76fa3-6f22-429a-a9e8-d5b0a06bcc98","MinDisk":20,"MinRAM":512,"Name":"FreeBSD 10 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:45:12Z"},{"Created":"2015-06-01T03:26:29Z","ID":"62e10fca-7a2f-48fc-8eb6-dda1595de7f7","MinDisk":20,"MinRAM":512,"Name":"Red Hat Enterprise Linux 7 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:06:19Z"},{"Created":"2015-06-01T03:25:23Z","ID":"ec3389c8-b2e2-46e0-9b33-c4938d2795ae","MinDisk":20,"MinRAM":512,"Name":"Red Hat Enterprise Linux 6 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:01:03Z"},{"Created":"2015-06-01T03:05:03Z","ID":"3017ebae-ecfc-4c0d-8042-5fd3485aa90d","MinDisk":20,"MinRAM":512,"Name":"Red Hat Enterprise Linux 6 (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:00:48Z"},{"Created":"2015-06-01T03:01:27Z","ID":"103e1ab4-4749-4da2-a373-7df2376714c6","MinDisk":20,"MinRAM":512,"Name":"Red Hat Enterprise Linux 5 (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T22:55:34Z"},{"Created":"2015-06-01T02:39:42Z","ID":"6a6b878e-c6a2-4a72-a096-bd388800c45a","MinDisk":20,"MinRAM":512,"Name":"Fedora 21 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:33:41Z"},{"Created":"2015-06-01T02:14:43Z","ID":"a0a71b6a-55e9-4f49-a053-f398337c9a9b","MinDisk":20,"MinRAM":512,"Name":"Debian Testing (Stretch) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:23:11Z"},{"Created":"2015-06-01T02:08:32Z","ID":"40982f53-c731-4227-8215-bd5afda8a2fe","MinDisk":20,"MinRAM":512,"Name":"Debian 8 (Jessie) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:17:56Z"},{"Created":"2015-06-01T01:43:37Z","ID":"0f7838c3-5b27-4950-81b3-53baaf84c9ce","MinDisk":20,"MinRAM":512,"Name":"Debian 7 (Wheezy) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:12:41Z"},{"Created":"2015-06-01T01:41:53Z","ID":"a743dd3b-e409-4833-be55-d85f6192817e","MinDisk":20,"MinRAM":512,"Name":"Ubuntu 12.04 LTS (Precise Pangolin) (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:30:43Z"},{"Created":"2015-06-01T01:41:44Z","ID":"c9659075-d425-4823-b9ab-a3b9761ac030","MinDisk":20,"MinRAM":512,"Name":"Ubuntu 12.04 LTS (Precise Pangolin) (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:25:29Z"},{"Created":"2015-06-01T01:23:50Z","ID":"296e3de7-8e75-45ca-8e43-3b46a668576a","MinDisk":20,"MinRAM":512,"Name":"Ubuntu 14.04 LTS (Trusty Tahr) (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T23:30:58Z"},{"Created":"2015-06-01T00:56:33Z","ID":"7dc47eb8-5b4a-4ce4-9b1d-744d93b92c89","MinDisk":20,"MinRAM":512,"Name":"CentOS 7 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:07:26Z"},{"Created":"2015-06-01T00:50:38Z","ID":"4b0c4c69-5d5a-4140-8d22-3813eef9292f","MinDisk":20,"MinRAM":512,"Name":"CentOS 5 (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T20:56:10Z"},{"Created":"2015-06-01T00:50:38Z","ID":"1dc14b15-707b-4a93-af23-2ef1fd57828c","MinDisk":20,"MinRAM":512,"Name":"CentOS 6 (PV)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:01:56Z"},{"Created":"2015-06-01T00:50:38Z","ID":"00341bad-631f-42b6-bc3c-7a861f9cd637","MinDisk":20,"MinRAM":512,"Name":"CentOS 6 (PVHVM)","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T21:02:10Z"},{"Created":"2015-05-23T00:14:28Z","ID":"abb67d66-94b6-4a91-a234-6b1a952fd60b","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2008 R2 SP1 + SQL Server 2008 R2 SP2 Web","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T12:15:20Z"},{"Created":"2015-05-22T10:17:32Z","ID":"a6fc998a-f4ba-4613-8bf1-5afa51d4474d","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2008 R2 SP1 + SQL Server 2008 R2 SP2 Standard","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T12:09:59Z"},{"Created":"2015-05-21T08:16:07Z","ID":"cbb2aff3-77d9-448e-9c63-157aaef5a28e","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2012","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T15:41:06Z"},{"Created":"2015-05-21T05:23:36Z","ID":"ce1fa266-3914-4ffd-83f3-97d0e34fc9cb","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2008 R2 SP1","Progress":100,"Status":"ACTIVE","Updated":"2015-06-10T02:48:20Z"},{"Created":"2015-04-16T06:19:22Z","ID":"e788cfc4-a2ec-4f0d-bce2-6dd961dc7899","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2012 R2 + SQL Server 2014 Standard","Progress":100,"Status":"ACTIVE","Updated":"2015-04-22T15:59:19Z"},{"Created":"2015-04-16T05:49:48Z","ID":"5109f615-adcc-44ac-9a8e-7697d07d7d28","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2012 R2 + SQL Server 2014 Web","Progress":100,"Status":"ACTIVE","Updated":"2015-04-22T16:04:35Z"},{"Created":"2015-04-15T02:16:42Z","ID":"e3caa20a-ab9a-48ee-a0c6-02561806616d","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2012 R2","Progress":100,"Status":"ACTIVE","Updated":"2015-04-22T15:43:30Z"},{"Created":"2015-03-05T15:06:54Z","ID":"07c16842-db34-449a-90ac-e8f05dd8564e","MinDisk":20,"MinRAM":1024,"Name":"Vyatta Network OS 6.7R6","Progress":100,"Status":"ACTIVE","Updated":"2015-04-21T13:58:14Z"},{"Created":"2015-01-27T16:36:14Z","ID":"811ffa1f-97f8-46f6-9893-6fc36c09a0b6","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1422376573","Progress":100,"Status":"ACTIVE","Updated":"2015-01-27T17:07:49Z"},{"Created":"2015-01-26T16:36:15Z","ID":"2ed99d72-96c6-4aab-9a4c-cf9f8210ae26","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1422290174","Progress":100,"Status":"ACTIVE","Updated":"2015-01-26T16:48:09Z"},{"Created":"2015-01-25T16:36:12Z","ID":"e877987a-6145-4d2b-a14d-d3f9b03f08a6","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1422203771","Progress":100,"Status":"ACTIVE","Updated":"2015-01-25T16:40:25Z"},{"Created":"2015-01-24T16:36:15Z","ID":"a7721b21-0435-4a7f-a46f-d3797504ddc6","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1422117374","Progress":100,"Status":"ACTIVE","Updated":"2015-01-24T16:44:49Z"},{"Created":"2015-01-23T16:36:10Z","ID":"a113bada-bf84-430a-80b8-baa653ca776d","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1422030969","Progress":100,"Status":"ACTIVE","Updated":"2015-01-23T16:48:09Z"},{"Created":"2015-01-22T16:53:08Z","ID":"4378750e-6bb6-490f-950c-012007396fc1","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1421945587","Progress":100,"Status":"ACTIVE","Updated":"2015-01-22T16:57:53Z"},{"Created":"2015-01-21T16:36:14Z","ID":"4927bcb0-4c38-46ef-b765-09b93c898519","MinDisk":40,"MinRAM":512,"Name":"Daily-minecraft-1421858173","Progress":100,"Status":"ACTIVE","Updated":"2015-01-21T16:39:57Z"},{"Created":"2014-12-23T16:45:24Z","ID":"07cef8c2-1f49-4eb9-b98f-ebe47d778f4c","MinDisk":40,"MinRAM":512,"Name":"minecraft","Progress":100,"Status":"ACTIVE","Updated":"2014-12-23T16:48:35Z"},{"Created":"2014-10-17T04:11:30Z","ID":"959aee20-e0b8-42a7-9201-10057c2b7e05","MinDisk":40,"MinRAM":8192,"Name":"Windows Server 2008 R2 SP1 + SharePoint 2010 Foundation with SQL Server 2008 R2 SP1 Standard","Progress":100,"Status":"ACTIVE","Updated":"2014-10-25T01:57:40Z"},{"Created":"2014-10-17T00:30:25Z","ID":"b28d7079-c4e8-41cf-94ce-9c4b57cf6f23","MinDisk":40,"MinRAM":4096,"Name":"Windows Server 2008 R2 SP1 + SharePoint 2010 Foundation with SQL Server 2008 R2 Express","Progress":100,"Status":"ACTIVE","Updated":"2014-10-28T23:08:40Z"},{"Created":"2014-10-16T19:16:21Z","ID":"fe486888-6890-47ac-a02d-b740868f143b","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2012 R2 (base install without updates)","Progress":100,"Status":"ACTIVE","Updated":"2014-10-16T22:50:44Z"},{"Created":"2014-10-16T18:14:38Z","ID":"c81a65a3-8217-4520-96de-1d9313ae3094","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2012 (base install without updates)","Progress":100,"Status":"ACTIVE","Updated":"2014-10-16T23:12:05Z"},{"Created":"2014-10-16T16:04:28Z","ID":"b41c2705-f820-4b6f-8d32-d04b5f57a4f7","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2008 R2 SP1 + SQL Server 2012 SP1 Standard","Progress":100,"Status":"ACTIVE","Updated":"2014-10-16T22:55:55Z"},{"Created":"2014-10-16T15:58:17Z","ID":"c6301f02-1388-4a4a-ba7c-b52e1bff7813","MinDisk":40,"MinRAM":2048,"Name":"Windows Server 2008 R2 SP1 + SQL Server 2012 SP1 Web","Progress":100,"Status":"ACTIVE","Updated":"2014-10-16T23:06:12Z"},{"Created":"2014-10-16T15:27:20Z","ID":"f46e9237-9971-44b1-b92f-3a5a03592d3e","MinDisk":40,"MinRAM":1024,"Name":"Windows Server 2008 R2 SP1 (base install without updates)","Progress":100,"Status":"ACTIVE","Updated":"2014-10-21T22:30:00Z"},{"Created":"2014-06-18T05:01:13Z","ID":"d69d55ef-cb4c-4787-9f1b-2de41ecac9a1","MinDisk":40,"MinRAM":8192,"Name":"Windows Server 2012 + SharePoint 2013 with SQL Server 2012 SP1 Standard","Progress":100,"Status":"ACTIVE","Updated":"2014-07-18T14:00:24Z"},{"Created":"2014-02-01T18:22:30Z","ID":"49e7c8db-8923-4356-89c7-2e2d84dbf90d","MinDisk":40,"MinRAM":512,"Name":"perf30GB-PVHVM","Progress":100,"Status":"ACTIVE","Updated":"2014-02-01T18:25:00Z"},{"Created":"2014-02-01T18:22:21Z","ID":"3669d670-cb74-449b-9795-e7fa8d267bf0","MinDisk":40,"MinRAM":512,"Name":"perf30GB-PV","Progress":100,"Status":"ACTIVE","Updated":"2014-02-01T18:24:02Z"},{"Created":"2014-02-01T18:22:05Z","ID":"03051d2e-ce2a-458f-8166-0b1256a6f552","MinDisk":1200,"MinRAM":512,"Name":"nextgen30GB-PV","Progress":100,"Status":"ACTIVE","Updated":"2014-02-01T18:32:30Z"},{"Created":"2013-07-19T21:37:17Z","ID":"9aa0d346-c06f-4652-bbb1-4342a7d2d017","MinDisk":0,"MinRAM":0,"Name":"iPXE Boot (boot.rackspace.com)","Progress":100,"Status":"ACTIVE","Updated":"2014-07-07T17:51:33Z"}]
A good feature request: pretty print the JSON output
I think we should be able to reduce installation on OSX and Linux to 2 commands.
$ curl -L https://rack.developer.rackspace.com/rack-`uname -s`-`uname -m` > /usr/local/bin/rack
$ chmod +x /usr/local/bin/rack
This assumes a few things:
uname -s
uname -m
I also see we mkdir -p /usr/local/bin/
and export PATH=$PATH:/usr/local/bin
. What OSX and Linux distros don't come with /usr/local/bin/
already?
I picked this stuff up from the installation instructions for docker-compose.
Should we verify regions in the interactive rack configure
command? rack configure
walks users through setting up a config file to be used for authentication. Currently, for users to authenticate against the production Rackspace endpoint, they only have 6 options: "DFW", "IAD", "ORD", "LON", "SYD", "HKG".
It is possible though that internal users may want to test against other regions. Because of that, we wouldn't want to force one of the above regions on all users (doing region verification during client creation, for instance). However, I'd expect the users using rack configure
to be Rackspace customers who would only be able to use one of the above regions.
One possible downside of region verification is that if/when Rackspace does add another public region, we'd have to update this repo with the new region, and users would have to re-download the CLI in order to authenticate against the new region.
Currently the flags are named like Go varaibles: flavorID
, publicKey
. We should probably move to a more conventional naming method like kebab-case: flavor-id
, public-key
.
Currently, only bash completion for commands and subcommands is supported. We should add it for flags as well.
The current name rackcli is quite redundant. Imagine typing "rackcli" on the CLI over and over and over, thousands of times in your careers as an operator or support floor admin. Sooner than later the redundancy of typing "cli" on the CLI will become painful. It's a papercut we can avoid.
Also note how no other CLI app ever has appended "cli" to the actual command name.
The package name also appears to be available!
http://packages.ubuntu.com/search?keywords=rack&searchon=names&suite=trusty§ion=all
and
$ brew install rack
Error: No available formula for rack
Searching formulae...
aircrack-ng cracklib-words git-tracker lcrack nutcracker pdfcrack tcptrack
cracklib fcrackzip httrack ncrack ophcrack plt-racket truecrack
Searching taps...
Caskroom/cask/8tracksradiohelper Caskroom/cask/klystrack Caskroom/cask/racket
Caskroom/cask/actotracker Caskroom/cask/loadmytracks Caskroom/cask/rubitrack
Caskroom/cask/brackets Caskroom/cask/mactracker Caskroom/cask/time-tracker
Caskroom/cask/charlessoft-timetracker Caskroom/cask/milkytracker Caskroom/cask/track-o-bot
Caskroom/cask/kensington-trackball-works Caskroom/cask/pokertracker Caskroom/cask/youtrack-workflow
We are the rack. Let's name our kickass CLI "rack".
volumes:
snapshots:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.