Merge pull request #131 from rackspace/security-groups-api
Attempt the security group API.
diff --git a/interfaces.go b/interfaces.go
index 6340c1c..b038aa7 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -193,4 +193,25 @@
// ShowKeyPair will yield the named keypair.
ShowKeyPair(name string) (KeyPair, error)
+
+ // ListSecurityGroups provides a listing of security groups for the tenant.
+ // This method works only if the provider supports the os-security-groups extension.
+ ListSecurityGroups() ([]SecurityGroup, error)
+
+ // CreateSecurityGroup lets a tenant create a new security group.
+ // Only the SecurityGroup fields which are specified will be marshalled to the API.
+ // This method works only if the provider supports the os-security-groups extension.
+ CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error)
+
+ // ListSecurityGroupsByServerId provides a list of security groups which apply to the indicated server.
+ // This method works only if the provider supports the os-security-groups extension.
+ ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error)
+
+ // SecurityGroupById returns a security group corresponding to the provided ID number.
+ // This method works only if the provider supports the os-security-groups extension.
+ SecurityGroupById(id int) (*SecurityGroup, error)
+
+ // 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
}
diff --git a/servers.go b/servers.go
index 92bb370..a66e9f2 100644
--- a/servers.go
+++ b/servers.go
@@ -397,6 +397,114 @@
return locationArr[len(locationArr)-1], err
}
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) ListSecurityGroups() ([]SecurityGroup, error) {
+ var sgs []SecurityGroup
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
+ return perigee.Get(ep, perigee.Options{
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ Results: &struct {
+ SecurityGroups *[]SecurityGroup `json:"security_groups"`
+ }{&sgs},
+ })
+ })
+ return sgs, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error) {
+ var actual *SecurityGroup
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
+ return perigee.Post(ep, perigee.Options{
+ ReqBody: struct {
+ AddSecurityGroup SecurityGroup `json:"security_group"`
+ }{desired},
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ Results: &struct {
+ SecurityGroup **SecurityGroup `json:"security_group"`
+ }{&actual},
+ })
+ })
+ return actual, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error) {
+ var sgs []SecurityGroup
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/servers/%s/os-security-groups", gsp.endpoint, id)
+ return perigee.Get(ep, perigee.Options{
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ Results: &struct {
+ SecurityGroups *[]SecurityGroup `json:"security_groups"`
+ }{&sgs},
+ })
+ })
+ return sgs, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) SecurityGroupById(id int) (*SecurityGroup, error) {
+ var actual *SecurityGroup
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
+ return perigee.Get(ep, perigee.Options{
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ Results: &struct {
+ SecurityGroup **SecurityGroup `json:"security_group"`
+ }{&actual},
+ })
+ })
+ return actual, err
+}
+
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) DeleteSecurityGroupById(id int) error {
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
+ return perigee.Delete(ep, perigee.Options{
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ OkCodes: []int{202},
+ })
+ })
+ return err
+}
+
+// SecurityGroup provides a description of a security group, including all its rules.
+type SecurityGroup struct {
+ Description string `json:"description,omitempty"`
+ Id int `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Rules []SGRule `json:"rules,omitempty"`
+ TenantId string `json:"tenant_id,omitempty"`
+}
+
+// SGRule encapsulates a single rule which applies to a security group.
+// This definition is just a guess, based on the documentation found in another extension here: http://docs.openstack.org/api/openstack-compute/2/content/GET_os-security-group-default-rules-v2_listSecGroupDefaultRules_v2__tenant_id__os-security-group-rules_ext-os-security-group-default-rules.html
+type SGRule struct {
+ FromPort int `json:"from_port,omitempty"`
+ Id int `json:"id,omitempty"`
+ IpProtocol string `json:"ip_protocol,omitempty"`
+ IpRange map[string]interface{} `json:"ip_range,omitempty"`
+ ToPort int `json:"to_port,omitempty"`
+}
+
// RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
type RaxBandwidth struct {
AuditPeriodEnd string `json:"audit_period_end"`