Merge branch 'master' into v0.2.0

Conflicts:
	acceptance/19-list-addresses-0.1.go
	servers.go

I really need to do this more often.
diff --git a/README.asciidoc b/README.asciidoc
index a9352b7..5839a99 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -1,139 +1,42 @@
-== Gophercloud -- V0.0.0 image:https://secure.travis-ci.org/rackspace/gophercloud.png?branch=master["build status",link="https://travis-ci.org/rackspace/gophercloud"]
-The Go ecosystem seems to lack a comprehensive cloud services API (at the time this README was first written). As both Go and cloud services are trending in many businesses, and with Go used increasingly in infrastructure, it seems like an odd omission. To fill this gap, Gophercloud provides a Go binding to OpenStack cloud APIs.  Many providers offer many APIs that are compatible with OpenStack; thus, building your infrastructure automation projects around Openstack is a natural way to avoid vendor lock-in.
+== Gophercloud -- V0.1.0 image:https://secure.travis-ci.org/rackspace/gophercloud.png?branch=master["build status",link="https://travis-ci.org/rackspace/gophercloud"]
 
-WARNING: This library is still in the very early stages of development. Unless you want to contribute, it probably isn't what you want.
+Gophercloud currently lets you authenticate with OpenStack providers to create and manage servers.
+We are working on extending the API to further include cloud files, block storage, DNS, databases, security groups, and other features.
 
-The documentation below is obsolete, and will be updated with something shorter and more reasonable soon.  In the meantime, the most up to date documentation can be found at link:http://godoc.org/github.com/rackspace/gophercloud[our Godoc.org documentation].
+WARNING: This library is still in the very early stages of development. Unless you want to contribute, it probably isn't what you want.  Yet.
 
-=== Getting Started
-==== Install the Go Programming Language
-Gophercloud provides an Openstack-compatible SDK binding to the Go community.
-As such, to either use it or contribute code, you'll need to have Go installed.  Please http://golang.org/doc/install[refer to the Go installation instructions] for detailed steps to install the latest stable release of Go.
+=== Outstanding Features
 
-==== Familiarize Yourself with Go
-To use or contribute to Gophercloud, you'll need some passing familiarity with Go, and how it uses certain concepts.  If you've never worked with Go before, I _strongly_ encourage the interested reader to follow through the excellent online book titled http://golang.org/doc/effective_go.html[Effective Go].
+1.  Apache 2.0 License, making Gophercloud friendly to commercial and open-source enterprises alike.
+2.  Gophercloud is one of the most actively maintained Go SDKs for OpenStack.
+3.  Gophercloud supports Identity V2 and Nova V2 APIs.  More coming soon!
+4.  The up-coming Gophercloud 0.2.0 release supports API extensions, and makes writing support for new extensions easy.
+5.  Gophercloud supports automatic reauthentication upon auth token timeout, if enabled by your software.
+6.  Gophercloud is the only SDK implementation with actual acceptance-level integration tests.
 
-==== Installing Gophercloud in a Workspace
+=== What Does it Look Like?
 
-IMPORTANT: *Please* do not just clone this repository expecting it to work like any other Python, Ruby, Java, or C/C++ repo.  Go packages don't work that way!  (You _did_ read Effective Go, right?)
+The Gophercloud 0.1.0 and earlier APIs are now deprecated and obsolete.
+No new feature development will occur for 0.1.0 or 0.0.0.
+However, we will accept and provide bug fixes for these APIs.
+Please refer to the acceptance tests in the master brach for code examples using the v0.1.0 API.
+The most up to date documentation for version 0.1.x can be found at link:http://godoc.org/github.com/rackspace/gophercloud[our Godoc.org documentation].
 
-===== Installing Into an Existing Project
-Assuming you have a project underway already and its `$GOPATH` environment variable holds the correct path, you can include the Gophercloud package in the usual manner using `go get`:
+We are working on a new API that provides much better support for extensions, pagination, and other features that proved difficult to implement before.
+This new API will be substantially more Go-idiomatic as well; one of the complaints received about 0.1.x and earlier is that it didn't "feel" right.
+To see what this new API is going to look like, you can look at the code examples up on the link:http://gophercloud.io/docs.html[Gophercloud website].
+If you're interested in tracking progress, note that features for version 0.2.0 will appear in the `v0.2.0` branch until merged to master.
 
-    go get github.com/rackspace/gophercloud
+=== How can I Contribute?
 
-The remainder of this document, and supporting materials, assumes a correct `$GOPATH` configuration, but further assumes that an environment variable `$GOPHERCLOUD` points to the Gophercloud installation directory as well.  E.g.,
+After using Gophercloud for a while, you might find that it lacks some useful feature, or that existing behavior seems buggy.  We welcome contributions from our users for both missing functionality as well as for bug fixes.  We encourage contributors to collaborate with the link:http://gophercloud.io/community.html[Gophercloud community.]
 
-    export GOPHERCLOUD=$GOPATH/src/github.com/rackspace/gophercloud
+Finally, Gophercloud maintains its own link:http://gophercloud.io[announcements and updates blog.]
+Feel free to check back now and again to see what's new.
 
-===== Creating a New Gophercloud Project
-If you're just starting out with Go, a convenience script exists which lets you create a new Go workspace preconfigured with Gophercloud for you.
+== License
 
------------------------------------------------------------------------------------------------------
-You can execute the following command to create a brand new Go workspace that is minimally configured for use with Gophercloud.  This should work for any reasonable POSIX-compatible environment.
+Copyright (C) 2013, 2014 Rackspace, Inc.
 
-	source <(curl "https://raw.github.com/rackspace/Gophercloud/master/scripts/create-environment.sh")
------------------------------------------------------------------------------------------------------
+Licensed under the Apache License, Version 2.0
 
-This script will not only install the software, but also create a shell script `env.sh` which, when executed, restores both `$GOPATH` and `$GOPHERCLOUD` to their correct values.  The project will be installed in `$HOME/go/gophercloud`.
-
-==== Make Sure Gophercloud Works For You
-You should follow these steps to make sure your local installation works as expected.
-
------
-export SDK_USERNAME=jack_frost                             <1>
-export SDK_PROVIDER=santa-telecom                          <2>
-SDK_PASSWORD=c0ldnbr33zy $GOPHERCLOUD/scripts/test-all.sh  <3>
------
-<1> Use your cloud provider's API user name.
-<2> Use your provider's unique Gophercloud identifier.  This is how Gophercloud will know which API endpoints to use.
-<3> Do not export your password unless you don't care that it may reside in memory after the tests have all run.  You might want to remove it from your shell's history file afterwards too.
-
-If everything goes well, you should only see output indicating the Go commands for each of the acceptance tests being run.  Errors can be caused by several factors:
-
-1. Your provider diverges from established Openstack standards.
-2. Gophercloud incorrectly implements the relevant Openstack standards.
-3. Mistake in setting up the `SDK_*` environment variables above.
-
-If a problem occurs, https://github.com/rackspace/gophercloud/issues[we'd love to hear about it in the issue tracker!]
-
-==== Using Gophercloud
-Simply list Gophercloud in the import section of relevant source listings, and you will be able to issue cloud requests through Gophercloud.  For examples, either refer to the detailed SDK documentation, or https://github.com/rackspace/gophercloud/tree/master/acceptance[take a look at the acceptance-level tests in the `acceptance` subdirectory.]
-
-==== Contributing Features or Bug-Fixes
-After using Gophercloud for a while, you might find that it lacks some useful feature, or that existing behavior seems buggy.  We welcome contributions from our users for both missing functionality as well as for bug fixes.
-
-After installing Gophercloud and after running its `env.sh` script (only needed once per shell session), you will find the source files in the `$GOPHERCLOUD` directory.  Feel free to open your favorite editor inside that directory and poke around.
-
-Features and bug-fixes *must* appear on their own *feature branches*, even if you fork the Gophercloud repository.  The name of the branch should be fairly descriptive, but try to avoid verbosity for verbosity's sake.  Examples of good feature branch names include:
-
-.........................
-script-environment-setup 
-server-creation
-issue-43-memory-leak-fix
-.........................
-
-Some examples of not-so-good branch names include:
-
-.........................
-cloud-server-api-server-creation-endpoint-support   <1>
-tk                                                  <2>
-anything/with/slashes                               <3>
-.........................
-<1>  This branch name is lengthy without delivering much value.
-<2>  This branch name is too short to be useful to anyone other than the submitter.
-<3>  This branch name exacerbates some Git usability issues, where some commands separate origins from branch names using slashes and others do not.  Thus, using these kinds of branch names increases chances for easily preventable errors.
-
-For example, if you're looking to fix a memory leak that is documented in, just to pick a number, issue 42, you might follow a sequence of commands such as the following:
-
-............................................
-cd $GOPHERCLOUD
-git checkout working
-git checkout -b issue-42-fix-memory-leak
-# edit edit edit ...
-# commits happen here ...
-git push -u origin issue-42-fix-memory-leak
-............................................
-
-At this point, you may now switch to the GitHub user interface, and open a pull-request for the feature branch.  This pull request should be descriptive.  Basically, you want to give a small code walkthrough in the pull request summary.  You should be able to answer, at a minimum, four basic questions, as appropriate for the nature of the patch:
-
-1.  What is the problem?
-2.  Why is it a problem?
-3.  What is your solution?
-4.  How does your solution actually work?
-
-Here's a made-up example:
-
-......................................................................
-Fix memory leak detailed in issue #42.
-
-The Rackspace provider interface tended to leak memory every fifth
-Saturday of February.  Over the course of several decades, we find
-we run out of memory.  Killing and restarting the process periodically
-restores service, but is a burden on the ops team.  This PR fixes this
-bug permanently.
-
-The barProvider structure found in
-provider/barisp.go defines a FooSet as a slice, as seen on line 314.
-Per services/auth/keystone2.go line 628, Keystone authentication
-only ever uses the first three	elements of this FooSet.  Line 42 shows
-where FooSet is initialized to an empty slice, but on line 512, we see
-a function that appends to this slice unconditionally.
-
-I'm not sure where the logic exists to determine where this function is
-called; so, I've adjusted the provider/barisp.go file to truncate this
-FooSet to only three items, maximum on behalf of the caller.  This seems
-to solve the problem in my test cases.  See included tests.
-......................................................................
-
-Obviously, please use common sense!  In situations where these questions do not apply, please don't make up filler information.
-
-NOTE: All bug-fix PRs **MUST** reference at least one open issue.  New feature PRs **SHOULD** reference at least one open issue.  This convention helps track *why* certain code is written the way it is, and maintains historical context.  Lengthy design discussions should be moved to the https://groups.google.com/forum/#!forum/gophercloud-dev[gophercloud-dev mailing list] if they occur; links to appropriate discussions should be made in the issue, again to maintain context.
-
-TIP: You may elide answers to the questions above if the answers already appear in the referenced PR(s), issues, or mailing list discussions.  We care that the answers exist and may be easily found, not so much about *where* the answers may be found.
-
-==== Master Branch vs. Working Branch
-
-Many projects will happily let you create a feature branch off the master branch.  However, Go environments place special significance on master branches of packages.  Because the `go get` command *is not* intended to perform complete package management tasks, but merely serve as a convenience for establishing your Go work environment, it will always fetch from the master branch of any repository you specify.  *Therefore, the master branch MUST always represent a customer-installable package.*  Not only that, but interface changes **must** be backward compatible at all times.
-
-To facilitate development efforts, then, we maintain a *working* branch.  New features and bug fixes merge into the `working` branch, where it remains staged for some future release date.  Ideally, every push to github and every merge to `working` should kick off a batch of tests to validate the product still works.  Assuming that `working` tests all pass, *and* your features or bug-fixes are both code- and feature-complete, then and only then should `working` be merged into `master`.
diff --git a/acceptance/00-authentication.go b/acceptance/00-authentication.go
index 2374efb..6467203 100644
--- a/acceptance/00-authentication.go
+++ b/acceptance/00-authentication.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/01-authentication.go b/acceptance/01-authentication.go
index bcd3545..5cc9d38 100644
--- a/acceptance/01-authentication.go
+++ b/acceptance/01-authentication.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/02-list-servers.go b/acceptance/02-list-servers.go
index db33203..772852e 100644
--- a/acceptance/02-list-servers.go
+++ b/acceptance/02-list-servers.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/03-get-server-details.go b/acceptance/03-get-server-details.go
index eae1775..01140a9 100644
--- a/acceptance/03-get-server-details.go
+++ b/acceptance/03-get-server-details.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/04-create-server.go b/acceptance/04-create-server.go
index ff2174e..03fd606 100644
--- a/acceptance/04-create-server.go
+++ b/acceptance/04-create-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/05-list-images.go b/acceptance/05-list-images.go
index 8cdd6c4..5ead18b 100644
--- a/acceptance/05-list-images.go
+++ b/acceptance/05-list-images.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/06-list-flavors.go b/acceptance/06-list-flavors.go
index 109d018..65db7da 100644
--- a/acceptance/06-list-flavors.go
+++ b/acceptance/06-list-flavors.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/07-change-admin-password.go b/acceptance/07-change-admin-password.go
index 6f078ee..880fbe8 100644
--- a/acceptance/07-change-admin-password.go
+++ b/acceptance/07-change-admin-password.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/08-reauthentication.go b/acceptance/08-reauthentication.go
index 1bcf4fc..c46f5bb 100644
--- a/acceptance/08-reauthentication.go
+++ b/acceptance/08-reauthentication.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/09-resize-server.go b/acceptance/09-resize-server.go
index 8582ad3..a2ef3c8 100644
--- a/acceptance/09-resize-server.go
+++ b/acceptance/09-resize-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/10-reboot-server.go b/acceptance/10-reboot-server.go
index eff9963..ba6215a 100644
--- a/acceptance/10-reboot-server.go
+++ b/acceptance/10-reboot-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/11-rescue-unrescue-server.go b/acceptance/11-rescue-unrescue-server.go
index 657c7c8..008ad9d 100644
--- a/acceptance/11-rescue-unrescue-server.go
+++ b/acceptance/11-rescue-unrescue-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/12-update-server.go b/acceptance/12-update-server.go
index 8b9e73f..c0191f1 100644
--- a/acceptance/12-update-server.go
+++ b/acceptance/12-update-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/13-rebuild-server.go b/acceptance/13-rebuild-server.go
index 48745a6..ae7e19f 100644
--- a/acceptance/13-rebuild-server.go
+++ b/acceptance/13-rebuild-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/14-list-addresses.go b/acceptance/14-list-addresses.go
index 705d72d..1d7d26b 100644
--- a/acceptance/14-list-addresses.go
+++ b/acceptance/14-list-addresses.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/15-list-keypairs.go b/acceptance/15-list-keypairs.go
index da526e2..1a617ed 100644
--- a/acceptance/15-list-keypairs.go
+++ b/acceptance/15-list-keypairs.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/16-create-delete-keypair.go b/acceptance/16-create-delete-keypair.go
index e292473..f59e51c 100644
--- a/acceptance/16-create-delete-keypair.go
+++ b/acceptance/16-create-delete-keypair.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/17-create-delete-image.go b/acceptance/17-create-delete-image.go
index 25d8c72..b3d80a3 100644
--- a/acceptance/17-create-delete-image.go
+++ b/acceptance/17-create-delete-image.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/18-osutil-authentication.go b/acceptance/18-osutil-authentication.go
index 936f376..01ff4e9 100644
--- a/acceptance/18-osutil-authentication.go
+++ b/acceptance/18-osutil-authentication.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/19-list-addresses-0.1.go b/acceptance/19-list-addresses-0.1.go
new file mode 100644
index 0000000..d60557b
--- /dev/null
+++ b/acceptance/19-list-addresses-0.1.go
@@ -0,0 +1,58 @@
+// +build acceptance,old
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"github.com/rackspace/gophercloud"
+)
+
+var quiet = flag.Bool("quiet", false, "Quiet mode, for acceptance testing.  $? still indicates errors though.")
+
+func main() {
+	flag.Parse()
+	withIdentity(false, func(acc gophercloud.AccessProvider) {
+		withServerApi(acc, func(api gophercloud.CloudServersProvider) {
+			log("Creating server")
+			id, err := createServer(api, "", "", "", "")
+			if err != nil {
+				panic(err)
+			}
+			waitForServerState(api, id, "ACTIVE")
+			defer api.DeleteServerById(id)
+
+			tryAllAddresses(id, api)
+
+			log("Done")
+		})
+	})
+}
+
+func tryAllAddresses(id string, api gophercloud.CloudServersProvider) {
+	log("Getting the server instance")
+	s, err := api.ServerById(id)
+	if err != nil {
+		panic(err)
+	}
+
+	log("Getting the complete set of pools")
+	ps, err := s.AllAddressPools()
+	if err != nil {
+		panic(err)
+	}
+
+	log("Listing IPs for each pool")
+	for k, v := range ps {
+		log(fmt.Sprintf("  Pool %s", k))
+		for _, a := range v {
+			log(fmt.Sprintf("    IP: %s, Version: %d", a.Addr, a.Version))
+		}
+	}
+}
+
+func log(s ...interface{}) {
+	if !*quiet {
+		fmt.Println(s...)
+	}
+}
diff --git a/acceptance/99-delete-server.go b/acceptance/99-delete-server.go
index 55b8798..3e38ba4 100644
--- a/acceptance/99-delete-server.go
+++ b/acceptance/99-delete-server.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/acceptance/libargs.go b/acceptance/libargs.go
index 0c1d539..a9bb92f 100644
--- a/acceptance/libargs.go
+++ b/acceptance/libargs.go
@@ -1,3 +1,5 @@
+// +build acceptance,old
+
 package main
 
 import (
diff --git a/api_fetch.go b/api_fetch.go
index 493f61e..353df75 100644
--- a/api_fetch.go
+++ b/api_fetch.go
@@ -6,6 +6,7 @@
 
 //The default generic openstack api
 var OpenstackApi = map[string]interface{}{
+        "Name":      "nova",
 	"UrlChoice": PublicURL,
 }
 
diff --git a/authenticate.go b/authenticate.go
index 0f7c633..ff609aa 100644
--- a/authenticate.go
+++ b/authenticate.go
@@ -1,6 +1,7 @@
 package gophercloud
 
 import (
+	"fmt"
 	"github.com/racker/perigee"
 )
 
@@ -108,6 +109,20 @@
 	VersionId, VersionInfo, VersionList string
 }
 
+type AuthError struct {
+	StatusCode int
+}
+
+func (ae *AuthError) Error() string {
+	switch ae.StatusCode {
+	case 401:
+		return "Auth failed. Bad credentials."
+
+	default:
+		return fmt.Sprintf("Auth failed. Status code is: %s.", ae.StatusCode)
+	}
+}
+
 //
 func getAuthCredentials(options AuthOptions) Auth {
 	if options.ApiKey == "" {
@@ -137,12 +152,13 @@
 // I didn't need another one.
 func (c *Context) papersPlease(p Provider, options AuthOptions) (*Access, error) {
 	var access *Access
+	access = new(Access)
 
 	if (options.Username == "") || (options.Password == "" && options.ApiKey == "") {
 		return nil, ErrCredentials
 	}
 
-	err := perigee.Post(p.AuthEndpoint, perigee.Options{
+	resp, err := perigee.Request("POST", p.AuthEndpoint, perigee.Options{
 		CustomClient: c.httpClient,
 		ReqBody: &AuthContainer{
 			Auth: getAuthCredentials(options),
@@ -153,11 +169,21 @@
 			&access,
 		},
 	})
+
 	if err == nil {
-		access.options = options
-		access.provider = p
-		access.context = c
+		switch resp.StatusCode {
+		case 200:
+			access.options = options
+			access.provider = p
+			access.context = c
+
+		default:
+			err = &AuthError {
+				StatusCode: resp.StatusCode,
+			}
+		}
 	}
+
 	return access, err
 }
 
diff --git a/global_context.go b/global_context.go
index 45f06f8..89d283b 100644
--- a/global_context.go
+++ b/global_context.go
@@ -57,9 +57,11 @@
 // ActualResponseCode inspects a returned error, and discovers the actual response actual
 // response code that caused the error to be raised.
 func ActualResponseCode(e error) (int, error) {
-	err, ok := e.(*perigee.UnexpectedResponseCodeError)
-	if !ok {
-		return 0, ErrError
+	if err, typeOk := e.(*perigee.UnexpectedResponseCodeError); typeOk {
+		return err.Actual, nil
+	} else if err, typeOk := e.(*AuthError); typeOk{
+		return err.StatusCode, nil
 	}
-	return err.Actual, nil
+
+	return 0, ErrError
 }
diff --git a/interfaces.go b/interfaces.go
index b038aa7..71c0be4 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -214,4 +214,16 @@
 	// DeleteSecurityGroupById disposes of a security group corresponding to the provided ID number.
 	// This method works only if the provider supports the os-security-groups extension.
 	DeleteSecurityGroupById(id int) error
+
+	// ListDefaultSGRules lists default security group rules.
+	// This method only works if the provider supports the os-security-groups-default-rules extension.
+	ListDefaultSGRules() ([]SGRule, error)
+
+	// CreateDefaultSGRule creates a default security group rule.
+	// This method only works if the provider supports the os-security-groups-default-rules extension.
+	CreateDefaultSGRule(SGRule) (*SGRule, error)
+
+	// GetSGRule obtains information for a specified security group rule.
+	// This method only works if the provider supports the os-security-groups-default-rules extension.
+	GetSGRule(string) (*SGRule, error)
 }
diff --git a/servers.go b/servers.go
index 57f1532..c102169 100644
--- a/servers.go
+++ b/servers.go
@@ -69,6 +69,7 @@
 			MoreHeaders: map[string]string{
 				"X-Auth-Token": gsp.access.AuthToken(),
 			},
+			OkCodes: []int{200},
 		})
 	})
 	return s, err
@@ -458,6 +459,52 @@
 	return err
 }
 
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) ListDefaultSGRules() ([]SGRule, error) {
+	var sgrs []SGRule
+	err := gsp.context.WithReauth(gsp.access, func() error {
+		ep := fmt.Sprintf("%s/os-security-group-default-rules", gsp.endpoint)
+		return perigee.Get(ep, perigee.Options{
+			MoreHeaders: map[string]string{
+				"X-Auth-Token": gsp.access.AuthToken(),
+			},
+			Results: &struct{Security_group_default_rules *[]SGRule}{&sgrs},
+		})
+	})
+	return sgrs, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) CreateDefaultSGRule(r SGRule) (*SGRule, error) {
+	var sgr *SGRule
+	err := gsp.context.WithReauth(gsp.access, func() error {
+		ep := fmt.Sprintf("%s/os-security-group-default-rules", gsp.endpoint)
+		return perigee.Post(ep, perigee.Options{
+			MoreHeaders: map[string]string{
+				"X-Auth-Token": gsp.access.AuthToken(),
+			},
+			Results: &struct{Security_group_default_rule **SGRule}{&sgr},
+			ReqBody: struct{Security_group_default_rule SGRule `json:"security_group_default_rule"`}{r},
+		})
+	})
+	return sgr, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) GetSGRule(id string) (*SGRule, error) {
+	var sgr *SGRule
+	err := gsp.context.WithReauth(gsp.access, func() error {
+		ep := fmt.Sprintf("%s/os-security-group-default-rules/%s", gsp.endpoint, id)
+		return perigee.Get(ep, perigee.Options{
+			MoreHeaders: map[string]string{
+				"X-Auth-Token": gsp.access.AuthToken(),
+			},
+			Results: &struct{Security_group_default_rule **SGRule}{&sgr},
+		})
+	})
+	return sgr, err
+}
+
 // SecurityGroup provides a description of a security group, including all its rules.
 type SecurityGroup struct {
 	Description string   `json:"description,omitempty"`
@@ -658,17 +705,20 @@
 // Any Links provided are used to refer to the server specifically by URL.
 // These links are useful for making additional REST calls not explicitly supported by Gorax.
 type NewServer struct {
-	Name            string            `json:"name,omitempty"`
-	ImageRef        string            `json:"imageRef,omitempty"`
-	FlavorRef       string            `json:"flavorRef,omitempty"`
-	Metadata        map[string]string `json:"metadata,omitempty"`
-	Personality     []FileConfig      `json:"personality,omitempty"`
-	Networks        []NetworkConfig   `json:"networks,omitempty"`
-	AdminPass       string            `json:"adminPass,omitempty"`
-	KeyPairName     string            `json:"key_name,omitempty"`
-	Id              string            `json:"id,omitempty"`
-	Links           []Link            `json:"links,omitempty"`
-	OsDcfDiskConfig string            `json:"OS-DCF:diskConfig,omitempty"`
+	Name            string                   `json:"name,omitempty"`
+	ImageRef        string                   `json:"imageRef,omitempty"`
+	FlavorRef       string                   `json:"flavorRef,omitempty"`
+	Metadata        map[string]string        `json:"metadata,omitempty"`
+	Personality     []FileConfig             `json:"personality,omitempty"`
+	Networks        []NetworkConfig          `json:"networks,omitempty"`
+	AdminPass       string                   `json:"adminPass,omitempty"`
+	KeyPairName     string                   `json:"key_name,omitempty"`
+	Id              string                   `json:"id,omitempty"`
+	Links           []Link                   `json:"links,omitempty"`
+	OsDcfDiskConfig string                   `json:"OS-DCF:diskConfig,omitempty"`
+	SecurityGroup   []map[string]interface{} `json:"security_groups,omitempty"`
+	ConfigDrive     bool                     `json:"config_drive"`
+	UserData        string                   `json:"user_data"`
 }
 
 // ResizeRequest structures are used internally to encode to JSON the parameters required to resize a server instance.