Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
45cf5636
Commit
45cf5636
authored
Sep 24, 2015
by
Brian Grant
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14364 from spothanis/dep-update
Updated Gophercloud to fix indirect dependency issues
parents
e7fa5d4d
63ba88a2
Hide whitespace changes
Inline
Side-by-side
Showing
88 changed files
with
2372 additions
and
217 deletions
+2372
-217
Godeps.json
Godeps/Godeps.json
+2
-2
CONTRIBUTING.md
...pace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md
+2
-3
network_test.go
...phercloud/acceptance/openstack/compute/v2/network_test.go
+78
-0
servergroup_test.go
...cloud/acceptance/openstack/compute/v2/servergroup_test.go
+86
-1
servers_test.go
...phercloud/acceptance/openstack/compute/v2/servers_test.go
+6
-0
tokens_test.go
...phercloud/acceptance/rackspace/identity/v2/tokens_test.go
+61
-0
auth_options.go
...pace/src/github.com/rackspace/gophercloud/auth_options.go
+4
-0
requests.go
...phercloud/openstack/blockstorage/v1/snapshots/requests.go
+33
-0
requests.go
...gophercloud/openstack/blockstorage/v1/volumes/requests.go
+33
-0
requests_test.go
...rcloud/openstack/blockstorage/v1/volumes/requests_test.go
+7
-6
doc.go
...hercloud/openstack/blockstorage/v1/volumes/testing/doc.go
+7
-0
fixtures.go
...oud/openstack/blockstorage/v1/volumes/testing/fixtures.go
+1
-1
requests_test.go
...ack/compute/v2/extensions/bootfromvolume/requests_test.go
+2
-0
requests_test.go
...enstack/compute/v2/extensions/diskconfig/requests_test.go
+2
-0
doc.go
...phercloud/openstack/compute/v2/extensions/networks/doc.go
+2
-0
fixtures.go
...loud/openstack/compute/v2/extensions/networks/fixtures.go
+209
-0
requests.go
...loud/openstack/compute/v2/extensions/networks/requests.go
+22
-0
requests_test.go
...openstack/compute/v2/extensions/networks/requests_test.go
+37
-0
results.go
...cloud/openstack/compute/v2/extensions/networks/results.go
+222
-0
urls.go
...hercloud/openstack/compute/v2/extensions/networks/urls.go
+17
-0
urls_test.go
...oud/openstack/compute/v2/extensions/networks/urls_test.go
+25
-0
doc.go
...oud/openstack/compute/v2/extensions/schedulerhints/doc.go
+3
-0
requests.go
...penstack/compute/v2/extensions/schedulerhints/requests.go
+134
-0
requests_test.go
...ack/compute/v2/extensions/schedulerhints/requests_test.go
+130
-0
fixtures.go
...oud/openstack/compute/v2/extensions/secgroups/fixtures.go
+2
-0
requests_test.go
...stack/compute/v2/extensions/volumeattach/requests_test.go
+33
-4
doc.go
...enstack/compute/v2/extensions/volumeattach/testing/doc.go
+7
-0
fixtures.go
...ck/compute/v2/extensions/volumeattach/testing/fixtures.go
+1
-29
requests.go
...pace/gophercloud/openstack/compute/v2/flavors/requests.go
+35
-0
requests.go
...space/gophercloud/openstack/compute/v2/images/requests.go
+37
-0
requests.go
...pace/gophercloud/openstack/compute/v2/servers/requests.go
+127
-20
requests_test.go
...gophercloud/openstack/compute/v2/servers/requests_test.go
+37
-0
errors.go
...kspace/gophercloud/openstack/identity/v2/tokens/errors.go
+1
-1
requests.go
...pace/gophercloud/openstack/identity/v2/tokens/requests.go
+20
-12
requests_test.go
...gophercloud/openstack/identity/v2/tokens/requests_test.go
+3
-2
doc.go
.../rackspace/gophercloud/openstack/identity/v3/roles/doc.go
+3
-0
requests.go
...space/gophercloud/openstack/identity/v3/roles/requests.go
+50
-0
requests_test.go
.../gophercloud/openstack/identity/v3/roles/requests_test.go
+104
-0
results.go
...kspace/gophercloud/openstack/identity/v3/roles/results.go
+81
-0
urls.go
...rackspace/gophercloud/openstack/identity/v3/roles/urls.go
+7
-0
urls_test.go
...pace/gophercloud/openstack/identity/v3/roles/urls_test.go
+15
-0
requests_test.go
...networking/v2/extensions/fwaas/firewalls/requests_test.go
+2
-2
requests_test.go
...ack/networking/v2/extensions/lbaas/pools/requests_test.go
+1
-0
requests.go
...tack/networking/v2/extensions/security/groups/requests.go
+38
-0
requests.go
...stack/networking/v2/extensions/security/rules/requests.go
+5
-0
requests.go
.../gophercloud/openstack/networking/v2/networks/requests.go
+35
-0
requests_test.go
...ercloud/openstack/networking/v2/networks/requests_test.go
+1
-0
requests.go
...ace/gophercloud/openstack/networking/v2/ports/requests.go
+35
-0
requests.go
...e/gophercloud/openstack/networking/v2/subnets/requests.go
+37
-2
results.go
...ce/gophercloud/openstack/networking/v2/subnets/results.go
+2
-2
results_test.go
...phercloud/openstack/networking/v2/subnets/results_test.go
+54
-0
requests.go
...phercloud/openstack/objectstorage/v1/accounts/requests.go
+6
-2
requests.go
...ercloud/openstack/objectstorage/v1/containers/requests.go
+9
-3
fixtures.go
...ophercloud/openstack/objectstorage/v1/objects/fixtures.go
+15
-2
requests.go
...ophercloud/openstack/objectstorage/v1/objects/requests.go
+47
-12
requests_test.go
...cloud/openstack/objectstorage/v1/objects/requests_test.go
+29
-6
fixtures.go
...rcloud/openstack/orchestration/v1/stackevents/fixtures.go
+7
-7
results.go
...ercloud/openstack/orchestration/v1/stackevents/results.go
+3
-3
fixtures.go
...oud/openstack/orchestration/v1/stackresources/fixtures.go
+3
-3
requests.go
...oud/openstack/orchestration/v1/stackresources/requests.go
+1
-9
results.go
...loud/openstack/orchestration/v1/stackresources/results.go
+4
-4
fixtures.go
...gophercloud/openstack/orchestration/v1/stacks/fixtures.go
+4
-4
results.go
.../gophercloud/openstack/orchestration/v1/stacks/results.go
+6
-6
http.go
...e/src/github.com/rackspace/gophercloud/pagination/http.go
+8
-2
pager.go
.../src/github.com/rackspace/gophercloud/pagination/pager.go
+4
-2
provider_client.go
...e/src/github.com/rackspace/gophercloud/provider_client.go
+12
-7
delegate_test.go
...rcloud/rackspace/blockstorage/v1/volumes/delegate_test.go
+5
-4
delegate_test.go
...loud/rackspace/compute/v2/bootfromvolume/delegate_test.go
+2
-0
delegate.go
...pace/gophercloud/rackspace/compute/v2/flavors/delegate.go
+4
-7
fixtures.go
...pace/gophercloud/rackspace/compute/v2/flavors/fixtures.go
+15
-7
results.go
...space/gophercloud/rackspace/compute/v2/flavors/results.go
+104
-0
urls.go
...ackspace/gophercloud/rackspace/compute/v2/flavors/urls.go
+9
-0
requests.go
...pace/gophercloud/rackspace/compute/v2/servers/requests.go
+26
-11
requests_test.go
...gophercloud/rackspace/compute/v2/servers/requests_test.go
+2
-0
delegate_test.go
...rcloud/rackspace/compute/v2/volumeattach/delegate_test.go
+39
-10
fixtures.go
...m/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go
+36
-0
requests.go
...m/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go
+1
-6
requests_test.go
...kspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go
+32
-0
results.go
...om/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go
+3
-0
fixtures.go
...ackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go
+1
-0
fixtures.go
...com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go
+1
-0
fixtures.go
...ackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go
+1
-0
delegate_test.go
...ercloud/rackspace/networking/v2/networks/delegate_test.go
+10
-1
requests.go
...e/gophercloud/rackspace/objectstorage/v1/bulk/requests.go
+3
-1
requests.go
...loud/rackspace/objectstorage/v1/cdncontainers/requests.go
+9
-3
delegate.go
...ophercloud/rackspace/objectstorage/v1/objects/delegate.go
+1
-1
delegate_test.go
...cloud/rackspace/objectstorage/v1/objects/delegate_test.go
+9
-7
results.go
...workspace/src/github.com/rackspace/gophercloud/results.go
+3
-0
No files found.
Godeps/Godeps.json
View file @
45cf5636
...
...
@@ -489,8 +489,8 @@
},
{
"ImportPath"
:
"github.com/rackspace/gophercloud"
,
"Comment"
:
"v1.0.0-
569-gf3ced00
"
,
"Rev"
:
"f
3ced00552c1c7d4a6184500af9062cfb4ff4463
"
"Comment"
:
"v1.0.0-
665-gf928634
"
,
"Rev"
:
"f
92863476c034f851073599c09d90cd61ee95b3d
"
},
{
"ImportPath"
:
"github.com/russross/blackfriday"
,
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md
View file @
45cf5636
...
...
@@ -28,11 +28,10 @@ fork as `origin` instead:
git remote add origin git@github.com/<my_username>/gophercloud
```
4. Checkout the latest development branch
([
click here]
(
/branches
)
to see all
the branches
)
:
4. Checkout the latest development branch:
```
bash
git checkout
release/v1.0.1
git checkout
master
```
5. If you
're working on something (discussed more in detail below), you will
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/network_test.go
0 → 100644
View file @
45cf5636
// +build acceptance compute servers
package
v2
import
(
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
th
"github.com/rackspace/gophercloud/testhelper"
)
func
getNetworkIDFromNetworkExtension
(
t
*
testing
.
T
,
client
*
gophercloud
.
ServiceClient
,
networkName
string
)
(
string
,
error
)
{
allPages
,
err
:=
networks
.
List
(
client
)
.
AllPages
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to list networks: %v"
,
err
)
}
networkList
,
err
:=
networks
.
ExtractNetworks
(
allPages
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to list networks: %v"
,
err
)
}
networkID
:=
""
for
_
,
network
:=
range
networkList
{
t
.
Logf
(
"Network: %v"
,
network
)
if
network
.
Label
==
networkName
{
networkID
=
network
.
ID
}
}
t
.
Logf
(
"Found network ID for %s: %s
\n
"
,
networkName
,
networkID
)
return
networkID
,
nil
}
func
TestNetworks
(
t
*
testing
.
T
)
{
networkName
:=
os
.
Getenv
(
"OS_NETWORK_NAME"
)
if
networkName
==
""
{
t
.
Fatalf
(
"OS_NETWORK_NAME must be set"
)
}
choices
,
err
:=
ComputeChoicesFromEnv
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
client
,
err
:=
newClient
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create a compute client: %v"
,
err
)
}
networkID
,
err
:=
getNetworkIDFromNetworkExtension
(
t
,
client
,
networkName
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to get network ID: %v"
,
err
)
}
// createNetworkServer is defined in tenantnetworks_test.go
server
,
err
:=
createNetworkServer
(
t
,
client
,
choices
,
networkID
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create server: %v"
,
err
)
}
defer
func
()
{
servers
.
Delete
(
client
,
server
.
ID
)
t
.
Logf
(
"Server deleted."
)
}()
if
err
=
waitForStatus
(
client
,
server
,
"ACTIVE"
);
err
!=
nil
{
t
.
Fatalf
(
"Unable to wait for server: %v"
,
err
)
}
allPages
,
err
:=
networks
.
List
(
client
)
.
AllPages
()
allNetworks
,
err
:=
networks
.
ExtractNetworks
(
allPages
)
th
.
AssertNoErr
(
t
,
err
)
t
.
Logf
(
"Retrieved all %d networks: %+v"
,
len
(
allNetworks
),
allNetworks
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servergroup_test.go
View file @
45cf5636
...
...
@@ -3,10 +3,15 @@
package
v2
import
(
"fmt"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
th
"github.com/rackspace/gophercloud/testhelper"
)
func
createServerGroup
(
t
*
testing
.
T
,
computeClient
*
gophercloud
.
ServiceClient
)
(
*
servergroups
.
ServerGroup
,
error
)
{
...
...
@@ -36,7 +41,53 @@ func getServerGroup(t *testing.T, computeClient *gophercloud.ServiceClient, sgID
return
nil
}
func
createServerInGroup
(
t
*
testing
.
T
,
computeClient
*
gophercloud
.
ServiceClient
,
choices
*
ComputeChoices
,
serverGroup
*
servergroups
.
ServerGroup
)
(
*
servers
.
Server
,
error
)
{
if
testing
.
Short
()
{
t
.
Skip
(
"Skipping test that requires server creation in short mode."
)
}
name
:=
tools
.
RandomString
(
"ACPTTEST"
,
16
)
t
.
Logf
(
"Attempting to create server: %s
\n
"
,
name
)
pwd
:=
tools
.
MakeNewPassword
(
""
)
serverCreateOpts
:=
servers
.
CreateOpts
{
Name
:
name
,
FlavorRef
:
choices
.
FlavorID
,
ImageRef
:
choices
.
ImageID
,
AdminPass
:
pwd
,
}
server
,
err
:=
servers
.
Create
(
computeClient
,
schedulerhints
.
CreateOptsExt
{
serverCreateOpts
,
schedulerhints
.
SchedulerHints
{
Group
:
serverGroup
.
ID
,
},
})
.
Extract
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create server: %v"
,
err
)
}
th
.
AssertEquals
(
t
,
pwd
,
server
.
AdminPass
)
return
server
,
err
}
func
verifySchedulerWorked
(
t
*
testing
.
T
,
firstServer
,
secondServer
*
servers
.
Server
)
error
{
t
.
Logf
(
"First server hostID: %v"
,
firstServer
.
HostID
)
t
.
Logf
(
"Second server hostID: %v"
,
secondServer
.
HostID
)
if
firstServer
.
HostID
==
secondServer
.
HostID
{
return
nil
}
return
fmt
.
Errorf
(
"%s and %s were not scheduled on the same host."
,
firstServer
.
ID
,
secondServer
.
ID
)
}
func
TestServerGroups
(
t
*
testing
.
T
)
{
choices
,
err
:=
ComputeChoicesFromEnv
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
computeClient
,
err
:=
newClient
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create a compute client: %v"
,
err
)
...
...
@@ -48,11 +99,45 @@ func TestServerGroups(t *testing.T) {
}
defer
func
()
{
servergroups
.
Delete
(
computeClient
,
sg
.
ID
)
t
.
Logf
(
"ServerGroup deleted."
)
t
.
Logf
(
"Server
Group deleted."
)
}()
err
=
getServerGroup
(
t
,
computeClient
,
sg
.
ID
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to get server group: %v"
,
err
)
}
firstServer
,
err
:=
createServerInGroup
(
t
,
computeClient
,
choices
,
sg
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create server: %v"
,
err
)
}
defer
func
()
{
servers
.
Delete
(
computeClient
,
firstServer
.
ID
)
t
.
Logf
(
"Server deleted."
)
}()
if
err
=
waitForStatus
(
computeClient
,
firstServer
,
"ACTIVE"
);
err
!=
nil
{
t
.
Fatalf
(
"Unable to wait for server: %v"
,
err
)
}
firstServer
,
err
=
servers
.
Get
(
computeClient
,
firstServer
.
ID
)
.
Extract
()
secondServer
,
err
:=
createServerInGroup
(
t
,
computeClient
,
choices
,
sg
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create server: %v"
,
err
)
}
defer
func
()
{
servers
.
Delete
(
computeClient
,
secondServer
.
ID
)
t
.
Logf
(
"Server deleted."
)
}()
if
err
=
waitForStatus
(
computeClient
,
secondServer
,
"ACTIVE"
);
err
!=
nil
{
t
.
Fatalf
(
"Unable to wait for server: %v"
,
err
)
}
secondServer
,
err
=
servers
.
Get
(
computeClient
,
secondServer
.
ID
)
.
Extract
()
if
err
=
verifySchedulerWorked
(
t
,
firstServer
,
secondServer
);
err
!=
nil
{
t
.
Fatalf
(
"Scheduling did not work: %v"
,
err
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go
View file @
45cf5636
...
...
@@ -107,6 +107,12 @@ func createServer(t *testing.T, client *gophercloud.ServiceClient, choices *Comp
servers
.
Network
{
UUID
:
network
.
ID
},
},
AdminPass
:
pwd
,
Personality
:
servers
.
Personality
{
&
servers
.
File
{
Path
:
"/etc/test"
,
Contents
:
[]
byte
(
"hello world"
),
},
},
})
.
Extract
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create server: %v"
,
err
)
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tokens_test.go
0 → 100644
View file @
45cf5636
// +build acceptance
package
v2
import
(
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/rackspace"
"github.com/rackspace/gophercloud/rackspace/identity/v2/tokens"
th
"github.com/rackspace/gophercloud/testhelper"
)
func
rackspaceAuthOptions
(
t
*
testing
.
T
)
gophercloud
.
AuthOptions
{
// Obtain credentials from the environment.
options
,
err
:=
rackspace
.
AuthOptionsFromEnv
()
th
.
AssertNoErr
(
t
,
err
)
options
=
tools
.
OnlyRS
(
options
)
if
options
.
Username
==
""
{
t
.
Fatal
(
"Please provide a Rackspace username as RS_USERNAME."
)
}
if
options
.
APIKey
==
""
{
t
.
Fatal
(
"Please provide a Rackspace API key as RS_API_KEY."
)
}
return
options
}
func
createClient
(
t
*
testing
.
T
,
auth
bool
)
*
gophercloud
.
ServiceClient
{
ao
:=
rackspaceAuthOptions
(
t
)
provider
,
err
:=
rackspace
.
NewClient
(
ao
.
IdentityEndpoint
)
th
.
AssertNoErr
(
t
,
err
)
if
auth
{
err
=
rackspace
.
Authenticate
(
provider
,
ao
)
th
.
AssertNoErr
(
t
,
err
)
}
return
rackspace
.
NewIdentityV2
(
provider
)
}
func
TestTokenAuth
(
t
*
testing
.
T
)
{
authedClient
:=
createClient
(
t
,
true
)
token
:=
authedClient
.
TokenID
tenantID
:=
os
.
Getenv
(
"RS_TENANT_ID"
)
if
tenantID
==
""
{
t
.
Skip
(
"You must set RS_TENANT_ID environment variable to run this test"
)
}
authOpts
:=
tokens
.
AuthOptions
{}
authOpts
.
TenantID
=
tenantID
authOpts
.
Token
=
token
_
,
err
:=
tokens
.
Create
(
authedClient
,
authOpts
)
.
ExtractToken
()
th
.
AssertNoErr
(
t
,
err
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go
View file @
45cf5636
...
...
@@ -43,4 +43,8 @@ type AuthOptions struct {
// false, it will not cache these settings, but re-authentication will not be
// possible. This setting defaults to false.
AllowReauth
bool
// TokenID allows users to authenticate (possibly as another user) with an
// authentication token ID.
TokenID
string
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go
View file @
45cf5636
...
...
@@ -171,3 +171,36 @@ func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMet
})
return
res
}
// IDFromName is a convienience function that returns a snapshot's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
snapshotCount
:=
0
snapshotID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A snapshot name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
snapshotList
,
err
:=
ExtractSnapshots
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
s
:=
range
snapshotList
{
if
s
.
Name
==
name
{
snapshotCount
++
snapshotID
=
s
.
ID
}
}
return
true
,
nil
})
switch
snapshotCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find snapshot: %s"
,
name
)
case
1
:
return
snapshotID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d snapshots matching %s"
,
snapshotCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go
View file @
45cf5636
...
...
@@ -201,3 +201,36 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
})
return
res
}
// IDFromName is a convienience function that returns a server's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
volumeCount
:=
0
volumeID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A volume name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
volumeList
,
err
:=
ExtractVolumes
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
s
:=
range
volumeList
{
if
s
.
Name
==
name
{
volumeCount
++
volumeID
=
s
.
ID
}
}
return
true
,
nil
})
switch
volumeCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find volume: %s"
,
name
)
case
1
:
return
volumeID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d volumes matching %s"
,
volumeCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go
View file @
45cf5636
...
...
@@ -3,6 +3,7 @@ package volumes
import
(
"testing"
fixtures
"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing"
"github.com/rackspace/gophercloud/pagination"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
...
...
@@ -12,7 +13,7 @@ func TestList(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockListResponse
(
t
)
fixtures
.
MockListResponse
(
t
)
count
:=
0
...
...
@@ -49,7 +50,7 @@ func TestListAll(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockListResponse
(
t
)
fixtures
.
MockListResponse
(
t
)
allPages
,
err
:=
List
(
client
.
ServiceClient
(),
&
ListOpts
{})
.
AllPages
()
th
.
AssertNoErr
(
t
,
err
)
...
...
@@ -75,7 +76,7 @@ func TestGet(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockGetResponse
(
t
)
fixtures
.
MockGetResponse
(
t
)
v
,
err
:=
Get
(
client
.
ServiceClient
(),
"d32019d3-bc6e-4319-9c1d-6722fc136a22"
)
.
Extract
()
th
.
AssertNoErr
(
t
,
err
)
...
...
@@ -89,7 +90,7 @@ func TestCreate(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockCreateResponse
(
t
)
fixtures
.
MockCreateResponse
(
t
)
options
:=
&
CreateOpts
{
Size
:
75
}
n
,
err
:=
Create
(
client
.
ServiceClient
(),
options
)
.
Extract
()
...
...
@@ -103,7 +104,7 @@ func TestDelete(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockDeleteResponse
(
t
)
fixtures
.
MockDeleteResponse
(
t
)
res
:=
Delete
(
client
.
ServiceClient
(),
"d32019d3-bc6e-4319-9c1d-6722fc136a22"
)
th
.
AssertNoErr
(
t
,
res
.
Err
)
...
...
@@ -113,7 +114,7 @@ func TestUpdate(t *testing.T) {
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
MockUpdateResponse
(
t
)
fixtures
.
MockUpdateResponse
(
t
)
options
:=
UpdateOpts
{
Name
:
"vol-002"
}
v
,
err
:=
Update
(
client
.
ServiceClient
(),
"d32019d3-bc6e-4319-9c1d-6722fc136a22"
,
options
)
.
Extract
()
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/doc.go
0 → 100644
View file @
45cf5636
/*
This is package created is to hold fixtures (which imports testing),
so that importing volumes package does not inadvertently import testing into production code
More information here:
https://github.com/rackspace/gophercloud/issues/473
*/
package
testing
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures.go
→
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/
testing/
fixtures.go
View file @
45cf5636
package
volumes
package
testing
import
(
"fmt"
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
View file @
45cf5636
...
...
@@ -32,6 +32,8 @@ func TestCreateOpts(t *testing.T) {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
"flavorName": "",
"imageName": "",
"block_device_mapping_v2":[
{
"uuid":"123456",
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go
View file @
45cf5636
...
...
@@ -25,6 +25,8 @@ func TestCreateOpts(t *testing.T) {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
"flavorName": "",
"imageName": "",
"OS-DCF:diskConfig": "MANUAL"
}
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/doc.go
0 → 100644
View file @
45cf5636
// Package network provides the ability to manage nova-networks
package
networks
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/fixtures.go
0 → 100644
View file @
45cf5636
// +build fixtures
package
networks
import
(
"fmt"
"net/http"
"testing"
"time"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
// ListOutput is a sample response to a List call.
const
ListOutput
=
`
{
"networks": [
{
"bridge": "br100",
"bridge_interface": "eth0",
"broadcast": "10.0.0.7",
"cidr": "10.0.0.0/29",
"cidr_v6": null,
"created_at": "2011-08-15 06:19:19.387525",
"deleted": false,
"deleted_at": null,
"dhcp_start": "10.0.0.3",
"dns1": null,
"dns2": null,
"gateway": "10.0.0.1",
"gateway_v6": null,
"host": "nsokolov-desktop",
"id": "20c8acc0-f747-4d71-a389-46d078ebf047",
"injected": false,
"label": "mynet_0",
"multi_host": false,
"netmask": "255.255.255.248",
"netmask_v6": null,
"priority": null,
"project_id": "1234",
"rxtx_base": null,
"updated_at": "2011-08-16 09:26:13.048257",
"vlan": 100,
"vpn_private_address": "10.0.0.2",
"vpn_public_address": "127.0.0.1",
"vpn_public_port": 1000
},
{
"bridge": "br101",
"bridge_interface": "eth0",
"broadcast": "10.0.0.15",
"cidr": "10.0.0.10/29",
"cidr_v6": null,
"created_at": "2011-08-15 06:19:19.885495",
"deleted": false,
"deleted_at": null,
"dhcp_start": "10.0.0.11",
"dns1": null,
"dns2": null,
"gateway": "10.0.0.9",
"gateway_v6": null,
"host": null,
"id": "20c8acc0-f747-4d71-a389-46d078ebf000",
"injected": false,
"label": "mynet_1",
"multi_host": false,
"netmask": "255.255.255.248",
"netmask_v6": null,
"priority": null,
"project_id": null,
"rxtx_base": null,
"updated_at": null,
"vlan": 101,
"vpn_private_address": "10.0.0.10",
"vpn_public_address": null,
"vpn_public_port": 1001
}
]
}
`
// GetOutput is a sample response to a Get call.
const
GetOutput
=
`
{
"network": {
"bridge": "br101",
"bridge_interface": "eth0",
"broadcast": "10.0.0.15",
"cidr": "10.0.0.10/29",
"cidr_v6": null,
"created_at": "2011-08-15 06:19:19.885495",
"deleted": false,
"deleted_at": null,
"dhcp_start": "10.0.0.11",
"dns1": null,
"dns2": null,
"gateway": "10.0.0.9",
"gateway_v6": null,
"host": null,
"id": "20c8acc0-f747-4d71-a389-46d078ebf000",
"injected": false,
"label": "mynet_1",
"multi_host": false,
"netmask": "255.255.255.248",
"netmask_v6": null,
"priority": null,
"project_id": null,
"rxtx_base": null,
"updated_at": null,
"vlan": 101,
"vpn_private_address": "10.0.0.10",
"vpn_public_address": null,
"vpn_public_port": 1001
}
}
`
// FirstNetwork is the first result in ListOutput.
var
nilTime
time
.
Time
var
FirstNetwork
=
Network
{
Bridge
:
"br100"
,
BridgeInterface
:
"eth0"
,
Broadcast
:
"10.0.0.7"
,
CIDR
:
"10.0.0.0/29"
,
CIDRv6
:
""
,
CreatedAt
:
time
.
Date
(
2011
,
8
,
15
,
6
,
19
,
19
,
387525000
,
time
.
UTC
),
Deleted
:
false
,
DeletedAt
:
nilTime
,
DHCPStart
:
"10.0.0.3"
,
DNS1
:
""
,
DNS2
:
""
,
Gateway
:
"10.0.0.1"
,
Gatewayv6
:
""
,
Host
:
"nsokolov-desktop"
,
ID
:
"20c8acc0-f747-4d71-a389-46d078ebf047"
,
Injected
:
false
,
Label
:
"mynet_0"
,
MultiHost
:
false
,
Netmask
:
"255.255.255.248"
,
Netmaskv6
:
""
,
Priority
:
0
,
ProjectID
:
"1234"
,
RXTXBase
:
0
,
UpdatedAt
:
time
.
Date
(
2011
,
8
,
16
,
9
,
26
,
13
,
48257000
,
time
.
UTC
),
VLAN
:
100
,
VPNPrivateAddress
:
"10.0.0.2"
,
VPNPublicAddress
:
"127.0.0.1"
,
VPNPublicPort
:
1000
,
}
// SecondNetwork is the second result in ListOutput.
var
SecondNetwork
=
Network
{
Bridge
:
"br101"
,
BridgeInterface
:
"eth0"
,
Broadcast
:
"10.0.0.15"
,
CIDR
:
"10.0.0.10/29"
,
CIDRv6
:
""
,
CreatedAt
:
time
.
Date
(
2011
,
8
,
15
,
6
,
19
,
19
,
885495000
,
time
.
UTC
),
Deleted
:
false
,
DeletedAt
:
nilTime
,
DHCPStart
:
"10.0.0.11"
,
DNS1
:
""
,
DNS2
:
""
,
Gateway
:
"10.0.0.9"
,
Gatewayv6
:
""
,
Host
:
""
,
ID
:
"20c8acc0-f747-4d71-a389-46d078ebf000"
,
Injected
:
false
,
Label
:
"mynet_1"
,
MultiHost
:
false
,
Netmask
:
"255.255.255.248"
,
Netmaskv6
:
""
,
Priority
:
0
,
ProjectID
:
""
,
RXTXBase
:
0
,
UpdatedAt
:
nilTime
,
VLAN
:
101
,
VPNPrivateAddress
:
"10.0.0.10"
,
VPNPublicAddress
:
""
,
VPNPublicPort
:
1001
,
}
// ExpectedNetworkSlice is the slice of results that should be parsed
// from ListOutput, in the expected order.
var
ExpectedNetworkSlice
=
[]
Network
{
FirstNetwork
,
SecondNetwork
}
// HandleListSuccessfully configures the test server to respond to a List request.
func
HandleListSuccessfully
(
t
*
testing
.
T
)
{
th
.
Mux
.
HandleFunc
(
"/os-networks"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"GET"
)
th
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
client
.
TokenID
)
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
fmt
.
Fprintf
(
w
,
ListOutput
)
})
}
// HandleGetSuccessfully configures the test server to respond to a Get request
// for an existing network.
func
HandleGetSuccessfully
(
t
*
testing
.
T
)
{
th
.
Mux
.
HandleFunc
(
"/os-networks/20c8acc0-f747-4d71-a389-46d078ebf000"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"GET"
)
th
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
client
.
TokenID
)
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
fmt
.
Fprintf
(
w
,
GetOutput
)
})
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests.go
0 → 100644
View file @
45cf5636
package
networks
import
(
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager that allows you to iterate over a collection of Network.
func
List
(
client
*
gophercloud
.
ServiceClient
)
pagination
.
Pager
{
url
:=
listURL
(
client
)
createPage
:=
func
(
r
pagination
.
PageResult
)
pagination
.
Page
{
return
NetworkPage
{
pagination
.
SinglePageBase
(
r
)}
}
return
pagination
.
NewPager
(
client
,
url
,
createPage
)
}
// Get returns data about a previously created Network.
func
Get
(
client
*
gophercloud
.
ServiceClient
,
id
string
)
GetResult
{
var
res
GetResult
_
,
res
.
Err
=
client
.
Get
(
getURL
(
client
,
id
),
&
res
.
Body
,
nil
)
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests_test.go
0 → 100644
View file @
45cf5636
package
networks
import
(
"testing"
"github.com/rackspace/gophercloud/pagination"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
func
TestList
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleListSuccessfully
(
t
)
count
:=
0
err
:=
List
(
client
.
ServiceClient
())
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
count
++
actual
,
err
:=
ExtractNetworks
(
page
)
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckDeepEquals
(
t
,
ExpectedNetworkSlice
,
actual
)
return
true
,
nil
})
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckEquals
(
t
,
1
,
count
)
}
func
TestGet
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleGetSuccessfully
(
t
)
actual
,
err
:=
Get
(
client
.
ServiceClient
(),
"20c8acc0-f747-4d71-a389-46d078ebf000"
)
.
Extract
()
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckDeepEquals
(
t
,
&
SecondNetwork
,
actual
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/results.go
0 → 100644
View file @
45cf5636
package
networks
import
(
"fmt"
"time"
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// A Network represents a nova-network that an instance communicates on
type
Network
struct
{
// The Bridge that VIFs on this network are connected to
Bridge
string
`mapstructure:"bridge"`
// BridgeInterface is what interface is connected to the Bridge
BridgeInterface
string
`mapstructure:"bridge_interface"`
// The Broadcast address of the network.
Broadcast
string
`mapstructure:"broadcast"`
// CIDR is the IPv4 subnet.
CIDR
string
`mapstructure:"cidr"`
// CIDRv6 is the IPv6 subnet.
CIDRv6
string
`mapstructure:"cidr_v6"`
// CreatedAt is when the network was created..
CreatedAt
time
.
Time
`mapstructure:"-"`
// Deleted shows if the network has been deleted.
Deleted
bool
`mapstructure:"deleted"`
// DeletedAt is the time when the network was deleted.
DeletedAt
time
.
Time
`mapstructure:"-"`
// DHCPStart is the start of the DHCP address range.
DHCPStart
string
`mapstructure:"dhcp_start"`
// DNS1 is the first DNS server to use through DHCP.
DNS1
string
`mapstructure:"dns_1"`
// DNS2 is the first DNS server to use through DHCP.
DNS2
string
`mapstructure:"dns_2"`
// Gateway is the network gateway.
Gateway
string
`mapstructure:"gateway"`
// Gatewayv6 is the IPv6 network gateway.
Gatewayv6
string
`mapstructure:"gateway_v6"`
// Host is the host that the network service is running on.
Host
string
`mapstructure:"host"`
// ID is the UUID of the network.
ID
string
`mapstructure:"id"`
// Injected determines if network information is injected into the host.
Injected
bool
`mapstructure:"injected"`
// Label is the common name that the network has..
Label
string
`mapstructure:"label"`
// MultiHost is if multi-host networking is enablec..
MultiHost
bool
`mapstructure:"multi_host"`
// Netmask is the network netmask.
Netmask
string
`mapstructure:"netmask"`
// Netmaskv6 is the IPv6 netmask.
Netmaskv6
string
`mapstructure:"netmask_v6"`
// Priority is the network interface priority.
Priority
int
`mapstructure:"priority"`
// ProjectID is the project associated with this network.
ProjectID
string
`mapstructure:"project_id"`
// RXTXBase configures bandwidth entitlement.
RXTXBase
int
`mapstructure:"rxtx_base"`
// UpdatedAt is the time when the network was last updated.
UpdatedAt
time
.
Time
`mapstructure:"-"`
// VLAN is the vlan this network runs on.
VLAN
int
`mapstructure:"vlan"`
// VPNPrivateAddress is the private address of the CloudPipe VPN.
VPNPrivateAddress
string
`mapstructure:"vpn_private_address"`
// VPNPublicAddress is the public address of the CloudPipe VPN.
VPNPublicAddress
string
`mapstructure:"vpn_public_address"`
// VPNPublicPort is the port of the CloudPipe VPN.
VPNPublicPort
int
`mapstructure:"vpn_public_port"`
}
// NetworkPage stores a single, only page of Networks
// results from a List call.
type
NetworkPage
struct
{
pagination
.
SinglePageBase
}
// IsEmpty determines whether or not a NetworkPage is empty.
func
(
page
NetworkPage
)
IsEmpty
()
(
bool
,
error
)
{
va
,
err
:=
ExtractNetworks
(
page
)
return
len
(
va
)
==
0
,
err
}
// ExtractNetworks interprets a page of results as a slice of Networks
func
ExtractNetworks
(
page
pagination
.
Page
)
([]
Network
,
error
)
{
var
res
struct
{
Networks
[]
Network
`mapstructure:"networks"`
}
err
:=
mapstructure
.
Decode
(
page
.
(
NetworkPage
)
.
Body
,
&
res
)
var
rawNetworks
[]
interface
{}
body
:=
page
.
(
NetworkPage
)
.
Body
switch
body
.
(
type
)
{
case
map
[
string
]
interface
{}
:
rawNetworks
=
body
.
(
map
[
string
]
interface
{})[
"networks"
]
.
([]
interface
{})
case
map
[
string
][]
interface
{}
:
rawNetworks
=
body
.
(
map
[
string
][]
interface
{})[
"networks"
]
default
:
return
res
.
Networks
,
fmt
.
Errorf
(
"Unknown type"
)
}
for
i
:=
range
rawNetworks
{
thisNetwork
:=
rawNetworks
[
i
]
.
(
map
[
string
]
interface
{})
if
t
,
ok
:=
thisNetwork
[
"created_at"
]
.
(
string
);
ok
&&
t
!=
""
{
createdAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Networks
,
err
}
res
.
Networks
[
i
]
.
CreatedAt
=
createdAt
}
if
t
,
ok
:=
thisNetwork
[
"updated_at"
]
.
(
string
);
ok
&&
t
!=
""
{
updatedAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Networks
,
err
}
res
.
Networks
[
i
]
.
UpdatedAt
=
updatedAt
}
if
t
,
ok
:=
thisNetwork
[
"deleted_at"
]
.
(
string
);
ok
&&
t
!=
""
{
deletedAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Networks
,
err
}
res
.
Networks
[
i
]
.
DeletedAt
=
deletedAt
}
}
return
res
.
Networks
,
err
}
type
NetworkResult
struct
{
gophercloud
.
Result
}
// Extract is a method that attempts to interpret any Network resource
// response as a Network struct.
func
(
r
NetworkResult
)
Extract
()
(
*
Network
,
error
)
{
if
r
.
Err
!=
nil
{
return
nil
,
r
.
Err
}
var
res
struct
{
Network
*
Network
`json:"network" mapstructure:"network"`
}
config
:=
&
mapstructure
.
DecoderConfig
{
Result
:
&
res
,
WeaklyTypedInput
:
true
,
}
decoder
,
err
:=
mapstructure
.
NewDecoder
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
decoder
.
Decode
(
r
.
Body
);
err
!=
nil
{
return
nil
,
err
}
b
:=
r
.
Body
.
(
map
[
string
]
interface
{})[
"network"
]
.
(
map
[
string
]
interface
{})
if
t
,
ok
:=
b
[
"created_at"
]
.
(
string
);
ok
&&
t
!=
""
{
createdAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Network
,
err
}
res
.
Network
.
CreatedAt
=
createdAt
}
if
t
,
ok
:=
b
[
"updated_at"
]
.
(
string
);
ok
&&
t
!=
""
{
updatedAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Network
,
err
}
res
.
Network
.
UpdatedAt
=
updatedAt
}
if
t
,
ok
:=
b
[
"deleted_at"
]
.
(
string
);
ok
&&
t
!=
""
{
deletedAt
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05.000000"
,
t
)
if
err
!=
nil
{
return
res
.
Network
,
err
}
res
.
Network
.
DeletedAt
=
deletedAt
}
return
res
.
Network
,
err
}
// GetResult is the response from a Get operation. Call its Extract method to interpret it
// as a Network.
type
GetResult
struct
{
NetworkResult
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls.go
0 → 100644
View file @
45cf5636
package
networks
import
"github.com/rackspace/gophercloud"
const
resourcePath
=
"os-networks"
func
resourceURL
(
c
*
gophercloud
.
ServiceClient
)
string
{
return
c
.
ServiceURL
(
resourcePath
)
}
func
listURL
(
c
*
gophercloud
.
ServiceClient
)
string
{
return
resourceURL
(
c
)
}
func
getURL
(
c
*
gophercloud
.
ServiceClient
,
id
string
)
string
{
return
c
.
ServiceURL
(
resourcePath
,
id
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls_test.go
0 → 100644
View file @
45cf5636
package
networks
import
(
"testing"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
func
TestListURL
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
c
:=
client
.
ServiceClient
()
th
.
CheckEquals
(
t
,
c
.
Endpoint
+
"os-networks"
,
listURL
(
c
))
}
func
TestGetURL
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
c
:=
client
.
ServiceClient
()
id
:=
"1"
th
.
CheckEquals
(
t
,
c
.
Endpoint
+
"os-networks/"
+
id
,
getURL
(
c
,
id
))
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/doc.go
0 → 100644
View file @
45cf5636
// Package schedulerhints enables instances to provide the OpenStack scheduler
// hints about where they should be placed in the cloud.
package
schedulerhints
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go
0 → 100644
View file @
45cf5636
package
schedulerhints
import
(
"fmt"
"net"
"regexp"
"strings"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)
// SchedulerHints represents a set of scheduling hints that are passed to the
// OpenStack scheduler
type
SchedulerHints
struct
{
// Group specifies a Server Group to place the instance in.
Group
string
// DifferentHost will place the instance on a compute node that does not
// host the given instances.
DifferentHost
[]
string
// SameHost will place the instance on a compute node that hosts the given
// instances.
SameHost
[]
string
// Query is a conditional statement that results in compute nodes able to
// host the instance.
Query
[]
interface
{}
// TargetCell specifies a cell name where the instance will be placed.
TargetCell
string
// BuildNearHostIP specifies a subnet of compute nodes to host the instance.
BuildNearHostIP
string
}
// SchedulerHintsBuilder builds the scheduler hints into a serializable format.
type
SchedulerHintsBuilder
interface
{
ToServerSchedulerHintsMap
()
(
map
[
string
]
interface
{},
error
)
}
// ToServerSchedulerHintsMap builds the scheduler hints into a serializable format.
func
(
opts
SchedulerHints
)
ToServerSchedulerHintsMap
()
(
map
[
string
]
interface
{},
error
)
{
sh
:=
make
(
map
[
string
]
interface
{})
uuidRegex
,
_
:=
regexp
.
Compile
(
"^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$"
)
if
opts
.
Group
!=
""
{
if
!
uuidRegex
.
MatchString
(
opts
.
Group
)
{
return
nil
,
fmt
.
Errorf
(
"Group must be a UUID"
)
}
sh
[
"group"
]
=
opts
.
Group
}
if
len
(
opts
.
DifferentHost
)
>
0
{
for
_
,
diffHost
:=
range
opts
.
DifferentHost
{
if
!
uuidRegex
.
MatchString
(
diffHost
)
{
return
nil
,
fmt
.
Errorf
(
"The hosts in DifferentHost must be in UUID format."
)
}
}
sh
[
"different_host"
]
=
opts
.
DifferentHost
}
if
len
(
opts
.
SameHost
)
>
0
{
for
_
,
sameHost
:=
range
opts
.
SameHost
{
if
!
uuidRegex
.
MatchString
(
sameHost
)
{
return
nil
,
fmt
.
Errorf
(
"The hosts in SameHost must be in UUID format."
)
}
}
sh
[
"same_host"
]
=
opts
.
SameHost
}
/* Query can be something simple like:
[">=", "$free_ram_mb", 1024]
Or more complex like:
['and',
['>=', '$free_ram_mb', 1024],
['>=', '$free_disk_mb', 200 * 1024]
]
Because of the possible complexity, just make sure the length is a minimum of 3.
*/
if
len
(
opts
.
Query
)
>
0
{
if
len
(
opts
.
Query
)
<
3
{
return
nil
,
fmt
.
Errorf
(
"Query must be a conditional statement in the format of [op,variable,value]"
)
}
sh
[
"query"
]
=
opts
.
Query
}
if
opts
.
TargetCell
!=
""
{
sh
[
"target_cell"
]
=
opts
.
TargetCell
}
if
opts
.
BuildNearHostIP
!=
""
{
if
_
,
_
,
err
:=
net
.
ParseCIDR
(
opts
.
BuildNearHostIP
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"BuildNearHostIP must be a valid subnet in the form 192.168.1.1/24"
)
}
ipParts
:=
strings
.
Split
(
opts
.
BuildNearHostIP
,
"/"
)
sh
[
"build_near_host_ip"
]
=
ipParts
[
0
]
sh
[
"cidr"
]
=
"/"
+
ipParts
[
1
]
}
return
sh
,
nil
}
// CreateOptsExt adds a SchedulerHints option to the base CreateOpts.
type
CreateOptsExt
struct
{
servers
.
CreateOptsBuilder
// SchedulerHints provides a set of hints to the scheduler.
SchedulerHints
SchedulerHintsBuilder
}
// ToServerCreateMap adds the SchedulerHints option to the base server creation options.
func
(
opts
CreateOptsExt
)
ToServerCreateMap
()
(
map
[
string
]
interface
{},
error
)
{
base
,
err
:=
opts
.
CreateOptsBuilder
.
ToServerCreateMap
()
if
err
!=
nil
{
return
nil
,
err
}
schedulerHints
,
err
:=
opts
.
SchedulerHints
.
ToServerSchedulerHintsMap
()
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
schedulerHints
)
==
0
{
return
base
,
nil
}
base
[
"os:scheduler_hints"
]
=
schedulerHints
return
base
,
nil
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests_test.go
0 → 100644
View file @
45cf5636
package
schedulerhints
import
(
"testing"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
th
"github.com/rackspace/gophercloud/testhelper"
)
func
TestCreateOpts
(
t
*
testing
.
T
)
{
base
:=
servers
.
CreateOpts
{
Name
:
"createdserver"
,
ImageRef
:
"asdfasdfasdf"
,
FlavorRef
:
"performance1-1"
,
}
schedulerHints
:=
SchedulerHints
{
Group
:
"101aed42-22d9-4a3e-9ba1-21103b0d1aba"
,
DifferentHost
:
[]
string
{
"a0cf03a5-d921-4877-bb5c-86d26cf818e1"
,
"8c19174f-4220-44f0-824a-cd1eeef10287"
,
},
SameHost
:
[]
string
{
"a0cf03a5-d921-4877-bb5c-86d26cf818e1"
,
"8c19174f-4220-44f0-824a-cd1eeef10287"
,
},
Query
:
[]
interface
{}{
">="
,
"$free_ram_mb"
,
"1024"
},
TargetCell
:
"foobar"
,
BuildNearHostIP
:
"192.168.1.1/24"
,
}
ext
:=
CreateOptsExt
{
CreateOptsBuilder
:
base
,
SchedulerHints
:
schedulerHints
,
}
expected
:=
`
{
"server": {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
"flavorName": "",
"imageName": ""
},
"os:scheduler_hints": {
"group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba",
"different_host": [
"a0cf03a5-d921-4877-bb5c-86d26cf818e1",
"8c19174f-4220-44f0-824a-cd1eeef10287"
],
"same_host": [
"a0cf03a5-d921-4877-bb5c-86d26cf818e1",
"8c19174f-4220-44f0-824a-cd1eeef10287"
],
"query": [
">=", "$free_ram_mb", "1024"
],
"target_cell": "foobar",
"build_near_host_ip": "192.168.1.1",
"cidr": "/24"
}
}
`
actual
,
err
:=
ext
.
ToServerCreateMap
()
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckJSONEquals
(
t
,
expected
,
actual
)
}
func
TestCreateOptsWithComplexQuery
(
t
*
testing
.
T
)
{
base
:=
servers
.
CreateOpts
{
Name
:
"createdserver"
,
ImageRef
:
"asdfasdfasdf"
,
FlavorRef
:
"performance1-1"
,
}
schedulerHints
:=
SchedulerHints
{
Group
:
"101aed42-22d9-4a3e-9ba1-21103b0d1aba"
,
DifferentHost
:
[]
string
{
"a0cf03a5-d921-4877-bb5c-86d26cf818e1"
,
"8c19174f-4220-44f0-824a-cd1eeef10287"
,
},
SameHost
:
[]
string
{
"a0cf03a5-d921-4877-bb5c-86d26cf818e1"
,
"8c19174f-4220-44f0-824a-cd1eeef10287"
,
},
Query
:
[]
interface
{}{
"and"
,
[]
string
{
">="
,
"$free_ram_mb"
,
"1024"
},
[]
string
{
">="
,
"$free_disk_mb"
,
"204800"
}},
TargetCell
:
"foobar"
,
BuildNearHostIP
:
"192.168.1.1/24"
,
}
ext
:=
CreateOptsExt
{
CreateOptsBuilder
:
base
,
SchedulerHints
:
schedulerHints
,
}
expected
:=
`
{
"server": {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
"flavorName": "",
"imageName": ""
},
"os:scheduler_hints": {
"group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba",
"different_host": [
"a0cf03a5-d921-4877-bb5c-86d26cf818e1",
"8c19174f-4220-44f0-824a-cd1eeef10287"
],
"same_host": [
"a0cf03a5-d921-4877-bb5c-86d26cf818e1",
"8c19174f-4220-44f0-824a-cd1eeef10287"
],
"query": [
"and",
[">=", "$free_ram_mb", "1024"],
[">=", "$free_disk_mb", "204800"]
],
"target_cell": "foobar",
"build_near_host_ip": "192.168.1.1",
"cidr": "/24"
}
}
`
actual
,
err
:=
ext
.
ToServerCreateMap
()
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckJSONEquals
(
t
,
expected
,
actual
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go
View file @
45cf5636
...
...
@@ -242,6 +242,7 @@ func mockAddServerToGroupResponse(t *testing.T, serverID string) {
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
w
.
WriteHeader
(
http
.
StatusAccepted
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
}
...
...
@@ -261,5 +262,6 @@ func mockRemoveServerFromGroupResponse(t *testing.T, serverID string) {
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
w
.
WriteHeader
(
http
.
StatusAccepted
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/requests_test.go
View file @
45cf5636
...
...
@@ -3,15 +3,44 @@ package volumeattach
import
(
"testing"
fixtures
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing"
"github.com/rackspace/gophercloud/pagination"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
// FirstVolumeAttachment is the first result in ListOutput.
var
FirstVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdd"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
}
// SecondVolumeAttachment is the first result in ListOutput.
var
SecondVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed
// from ListOutput, in the expected order.
var
ExpectedVolumeAttachmentSlice
=
[]
VolumeAttachment
{
FirstVolumeAttachment
,
SecondVolumeAttachment
}
//CreatedVolumeAttachment is the parsed result from CreatedOutput.
var
CreatedVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
func
TestList
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleListSuccessfully
(
t
)
fixtures
.
HandleListSuccessfully
(
t
)
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
count
:=
0
...
...
@@ -30,7 +59,7 @@ func TestList(t *testing.T) {
func
TestCreate
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleCreateSuccessfully
(
t
)
fixtures
.
HandleCreateSuccessfully
(
t
)
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
actual
,
err
:=
Create
(
client
.
ServiceClient
(),
serverId
,
CreateOpts
{
...
...
@@ -44,7 +73,7 @@ func TestCreate(t *testing.T) {
func
TestGet
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleGetSuccessfully
(
t
)
fixtures
.
HandleGetSuccessfully
(
t
)
aId
:=
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
...
...
@@ -56,7 +85,7 @@ func TestGet(t *testing.T) {
func
TestDelete
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleDeleteSuccessfully
(
t
)
fixtures
.
HandleDeleteSuccessfully
(
t
)
aId
:=
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/doc.go
0 → 100644
View file @
45cf5636
/*
This is package created is to hold fixtures (which imports testing),
so that importing volumeattach package does not inadvertently import testing into production code
More information here:
https://github.com/rackspace/gophercloud/issues/473
*/
package
testing
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/fixtures.go
→
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/
testing/
fixtures.go
View file @
45cf5636
// +build fixtures
package
volumeattach
package
testing
import
(
"fmt"
...
...
@@ -55,34 +55,6 @@ const CreateOutput = `
}
`
// FirstVolumeAttachment is the first result in ListOutput.
var
FirstVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdd"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
}
// SecondVolumeAttachment is the first result in ListOutput.
var
SecondVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed
// from ListOutput, in the expected order.
var
ExpectedVolumeAttachmentSlice
=
[]
VolumeAttachment
{
FirstVolumeAttachment
,
SecondVolumeAttachment
}
// CreatedVolumeAttachment is the parsed result from CreatedOutput.
var
CreatedVolumeAttachment
=
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
// HandleListSuccessfully configures the test server to respond to a List request.
func
HandleListSuccessfully
(
t
*
testing
.
T
)
{
th
.
Mux
.
HandleFunc
(
"/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go
View file @
45cf5636
package
flavors
import
(
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -66,3 +68,36 @@ func Get(client *gophercloud.ServiceClient, id string) GetResult {
_
,
res
.
Err
=
client
.
Get
(
getURL
(
client
,
id
),
&
res
.
Body
,
nil
)
return
res
}
// IDFromName is a convienience function that returns a flavor's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
flavorCount
:=
0
flavorID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A flavor name must be provided."
)
}
pager
:=
ListDetail
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
flavorList
,
err
:=
ExtractFlavors
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
f
:=
range
flavorList
{
if
f
.
Name
==
name
{
flavorCount
++
flavorID
=
f
.
ID
}
}
return
true
,
nil
})
switch
flavorCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find flavor: %s"
,
name
)
case
1
:
return
flavorID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d flavors matching %s"
,
flavorCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go
View file @
45cf5636
package
images
import
(
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -70,3 +72,38 @@ func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
_
,
result
.
Err
=
client
.
Delete
(
deleteURL
(
client
,
id
),
nil
)
return
result
}
// IDFromName is a convienience function that returns an image's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
imageCount
:=
0
imageID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"An image name must be provided."
)
}
pager
:=
ListDetail
(
client
,
&
ListOpts
{
Name
:
name
,
})
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
imageList
,
err
:=
ExtractImages
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
i
:=
range
imageList
{
if
i
.
Name
==
name
{
imageCount
++
imageID
=
i
.
ID
}
}
return
true
,
nil
})
switch
imageCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find image: %s"
,
name
)
case
1
:
return
imageID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d images matching %s"
,
imageCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go
View file @
45cf5636
...
...
@@ -2,10 +2,13 @@ package servers
import
(
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
"github.com/rackspace/gophercloud/openstack/compute/v2/images"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -14,6 +17,7 @@ import (
type
ListOptsBuilder
interface
{
ToServerListQuery
()
(
string
,
error
)
}
// ListOpts allows the filtering and sorting of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the server attributes you want to see returned. Marker and Limit are used
...
...
@@ -45,6 +49,9 @@ type ListOpts struct {
// Integer value for the limit of values to return.
Limit
int
`q:"limit"`
// Bool to show all tenants
AllTenants
bool
`q:"all_tenants"`
}
// ToServerListQuery formats a ListOpts into a query string.
...
...
@@ -95,18 +102,54 @@ type Network struct {
FixedIP
string
}
// Personality is an array of files that are injected into the server at launch.
type
Personality
[]
*
File
// File is used within CreateOpts and RebuildOpts to inject a file into the server at launch.
// File implements the json.Marshaler interface, so when a Create or Rebuild operation is requested,
// json.Marshal will call File's MarshalJSON method.
type
File
struct
{
// Path of the file
Path
string
// Contents of the file. Maximum content size is 255 bytes.
Contents
[]
byte
}
// MarshalJSON marshals the escaped file, base64 encoding the contents.
func
(
f
*
File
)
MarshalJSON
()
([]
byte
,
error
)
{
file
:=
struct
{
Path
string
`json:"path"`
Contents
string
`json:"contents"`
}{
Path
:
f
.
Path
,
Contents
:
base64
.
StdEncoding
.
EncodeToString
(
f
.
Contents
),
}
return
json
.
Marshal
(
file
)
}
// CreateOpts specifies server creation parameters.
type
CreateOpts
struct
{
// Name [required] is the name to assign to the newly launched server.
Name
string
// ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state.
// Optional if using the boot-from-volume extension.
// ImageRef [optional; required if ImageName is not provided] is the ID or full
// URL to the image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageRef
string
// FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs.
// ImageName [optional; required if ImageRef is not provided] is the name of the
// image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageName
string
// FlavorRef [optional; required if FlavorName is not provided] is the ID or
// full URL to the flavor that describes the server's specs.
FlavorRef
string
// FlavorName [optional; required if FlavorRef is not provided] is the name of
// the flavor that describes the server's specs.
FlavorName
string
// SecurityGroups [optional] lists the names of the security groups to which this server should belong.
SecurityGroups
[]
string
...
...
@@ -124,9 +167,9 @@ type CreateOpts struct {
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata
map
[
string
]
string
// Personality [optional] includes
the path and contents of a file
to inject into the server at launch.
//
The maximum size of the file is 255 bytes (decoded)
.
Personality
[]
byte
// Personality [optional] includes
files
to inject into the server at launch.
//
Create will base64-encode file contents for you
.
Personality
Personality
// ConfigDrive [optional] enables metadata injection through a configuration drive.
ConfigDrive
bool
...
...
@@ -148,16 +191,14 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
server
[
"name"
]
=
opts
.
Name
server
[
"imageRef"
]
=
opts
.
ImageRef
server
[
"imageName"
]
=
opts
.
ImageName
server
[
"flavorRef"
]
=
opts
.
FlavorRef
server
[
"flavorName"
]
=
opts
.
FlavorName
if
opts
.
UserData
!=
nil
{
encoded
:=
base64
.
StdEncoding
.
EncodeToString
(
opts
.
UserData
)
server
[
"user_data"
]
=
&
encoded
}
if
opts
.
Personality
!=
nil
{
encoded
:=
base64
.
StdEncoding
.
EncodeToString
(
opts
.
Personality
)
server
[
"personality"
]
=
&
encoded
}
if
opts
.
ConfigDrive
{
server
[
"config_drive"
]
=
"true"
}
...
...
@@ -202,6 +243,10 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
server
[
"networks"
]
=
networks
}
if
len
(
opts
.
Personality
)
>
0
{
server
[
"personality"
]
=
opts
.
Personality
}
return
map
[
string
]
interface
{}{
"server"
:
server
},
nil
}
...
...
@@ -215,6 +260,38 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateRes
return
res
}
// If ImageRef isn't provided, use ImageName to ascertain the image ID.
if
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"imageRef"
]
.
(
string
)
==
""
{
imageName
:=
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"imageName"
]
.
(
string
)
if
imageName
==
""
{
res
.
Err
=
errors
.
New
(
"One and only one of ImageRef and ImageName must be provided."
)
return
res
}
imageID
,
err
:=
images
.
IDFromName
(
client
,
imageName
)
if
err
!=
nil
{
res
.
Err
=
err
return
res
}
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"imageRef"
]
=
imageID
}
delete
(
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{}),
"imageName"
)
// If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID.
if
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"flavorRef"
]
.
(
string
)
==
""
{
flavorName
:=
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"flavorName"
]
.
(
string
)
if
flavorName
==
""
{
res
.
Err
=
errors
.
New
(
"One and only one of FlavorRef and FlavorName must be provided."
)
return
res
}
flavorID
,
err
:=
flavors
.
IDFromName
(
client
,
flavorName
)
if
err
!=
nil
{
res
.
Err
=
err
return
res
}
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{})[
"flavorRef"
]
=
flavorID
}
delete
(
reqBody
[
"server"
]
.
(
map
[
string
]
interface
{}),
"flavorName"
)
_
,
res
.
Err
=
client
.
Post
(
listURL
(
client
),
reqBody
,
&
res
.
Body
,
nil
)
return
res
}
...
...
@@ -391,9 +468,9 @@ type RebuildOpts struct {
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata
map
[
string
]
string
// Personality [optional] includes
the path and contents of a file
to inject into the server at launch.
//
The maximum size of the file is 255 bytes (decoded)
.
Personality
[]
byte
// Personality [optional] includes
files
to inject into the server at launch.
//
Rebuild will base64-encode file contents for you
.
Personality
Personality
}
// ToServerRebuildMap formats a RebuildOpts struct into a map for use in JSON
...
...
@@ -429,9 +506,8 @@ func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) {
server
[
"metadata"
]
=
opts
.
Metadata
}
if
opts
.
Personality
!=
nil
{
encoded
:=
base64
.
StdEncoding
.
EncodeToString
(
opts
.
Personality
)
server
[
"personality"
]
=
&
encoded
if
len
(
opts
.
Personality
)
>
0
{
server
[
"personality"
]
=
opts
.
Personality
}
return
map
[
string
]
interface
{}{
"rebuild"
:
server
},
nil
...
...
@@ -678,9 +754,7 @@ func Metadatum(client *gophercloud.ServiceClient, id, key string) GetMetadatumRe
// DeleteMetadatum will delete the key-value pair with the given key for the given server ID.
func
DeleteMetadatum
(
client
*
gophercloud
.
ServiceClient
,
id
,
key
string
)
DeleteMetadatumResult
{
var
res
DeleteMetadatumResult
_
,
res
.
Err
=
client
.
Delete
(
metadatumURL
(
client
,
id
,
key
),
&
gophercloud
.
RequestOpts
{
JSONResponse
:
&
res
.
Body
,
})
_
,
res
.
Err
=
client
.
Delete
(
metadatumURL
(
client
,
id
,
key
),
nil
)
return
res
}
...
...
@@ -741,5 +815,38 @@ func CreateImage(client *gophercloud.ServiceClient, serverId string, opts Create
})
res
.
Err
=
err
res
.
Header
=
response
.
Header
return
res
return
res
}
// IDFromName is a convienience function that returns a server's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
serverCount
:=
0
serverID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A server name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
serverList
,
err
:=
ExtractServers
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
s
:=
range
serverList
{
if
s
.
Name
==
name
{
serverCount
++
serverID
=
s
.
ID
}
}
return
true
,
nil
})
switch
serverCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find server: %s"
,
name
)
case
1
:
return
serverID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d servers matching %s"
,
serverCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go
View file @
45cf5636
package
servers
import
(
"encoding/base64"
"encoding/json"
"net/http"
"testing"
...
...
@@ -334,3 +336,38 @@ func TestCreateServerImage(t *testing.T) {
_
,
err
:=
CreateImage
(
client
.
ServiceClient
(),
"serverimage"
,
CreateImageOpts
{
Name
:
"test"
})
.
ExtractImageID
()
th
.
AssertNoErr
(
t
,
err
)
}
func
TestMarshalPersonality
(
t
*
testing
.
T
)
{
name
:=
"/etc/test"
contents
:=
[]
byte
(
"asdfasdf"
)
personality
:=
Personality
{
&
File
{
Path
:
name
,
Contents
:
contents
,
},
}
data
,
err
:=
json
.
Marshal
(
personality
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
var
actual
[]
map
[
string
]
string
err
=
json
.
Unmarshal
(
data
,
&
actual
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
actual
)
!=
1
{
t
.
Fatal
(
"expected personality length 1"
)
}
if
actual
[
0
][
"path"
]
!=
name
{
t
.
Fatal
(
"file path incorrect"
)
}
if
actual
[
0
][
"contents"
]
!=
base64
.
StdEncoding
.
EncodeToString
(
contents
)
{
t
.
Fatal
(
"file contents incorrect"
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go
View file @
45cf5636
...
...
@@ -18,7 +18,7 @@ var (
// ErrDomainNameProvided is returned if you attempt to authenticate with a DomainName.
ErrDomainNameProvided
=
unacceptedAttributeErr
(
"DomainName"
)
// ErrUsernameRequired is returned if you attempt
ot
authenticate without a Username.
// ErrUsernameRequired is returned if you attempt
to
authenticate without a Username.
ErrUsernameRequired
=
errors
.
New
(
"You must supply a Username in your AuthOptions."
)
// ErrPasswordRequired is returned if you don't provide a password.
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go
View file @
45cf5636
package
tokens
import
"github.com/rackspace/gophercloud"
import
(
"fmt"
"github.com/rackspace/gophercloud"
)
// AuthOptionsBuilder describes any argument that may be passed to the Create call.
type
AuthOptionsBuilder
interface
{
...
...
@@ -38,20 +42,24 @@ func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) {
return
nil
,
ErrDomainNameProvided
}
// Username and Password are always required.
if
auth
.
Username
==
""
{
return
nil
,
ErrUsernameRequired
}
if
auth
.
Password
==
""
{
return
nil
,
ErrPasswordRequired
}
// Populate the request map.
authMap
:=
make
(
map
[
string
]
interface
{})
authMap
[
"passwordCredentials"
]
=
map
[
string
]
interface
{}{
"username"
:
auth
.
Username
,
"password"
:
auth
.
Password
,
if
auth
.
Username
!=
""
{
if
auth
.
Password
!=
""
{
authMap
[
"passwordCredentials"
]
=
map
[
string
]
interface
{}{
"username"
:
auth
.
Username
,
"password"
:
auth
.
Password
,
}
}
else
{
return
nil
,
ErrPasswordRequired
}
}
else
if
auth
.
TokenID
!=
""
{
authMap
[
"token"
]
=
map
[
string
]
interface
{}{
"id"
:
auth
.
TokenID
,
}
}
else
{
return
nil
,
fmt
.
Errorf
(
"You must provide either username/password or tenantID/token values."
)
}
if
auth
.
TenantID
!=
""
{
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go
View file @
45cf5636
package
tokens
import
(
"fmt"
"testing"
"github.com/rackspace/gophercloud"
...
...
@@ -22,7 +23,7 @@ func tokenPostErr(t *testing.T, options gophercloud.AuthOptions, expectedErr err
HandleTokenPost
(
t
,
""
)
actualErr
:=
Create
(
client
.
ServiceClient
(),
AuthOptions
{
options
})
.
Err
th
.
CheckEquals
(
t
,
expectedErr
,
actualErr
)
th
.
Check
Deep
Equals
(
t
,
expectedErr
,
actualErr
)
}
func
TestCreateWithPassword
(
t
*
testing
.
T
)
{
...
...
@@ -128,7 +129,7 @@ func TestRequireUsername(t *testing.T) {
Password
:
"thing"
,
}
tokenPostErr
(
t
,
options
,
ErrUsernameRequired
)
tokenPostErr
(
t
,
options
,
fmt
.
Errorf
(
"You must provide either username/password or tenantID/token values."
)
)
}
func
TestRequirePassword
(
t
*
testing
.
T
)
{
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go
0 → 100644
View file @
45cf5636
// Package roles provides information and interaction with the roles API
// resource for the OpenStack Identity service.
package
roles
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go
0 → 100644
View file @
45cf5636
package
roles
import
(
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// ListAssignmentsOptsBuilder allows extensions to add additional parameters to
// the ListAssignments request.
type
ListAssignmentsOptsBuilder
interface
{
ToRolesListAssignmentsQuery
()
(
string
,
error
)
}
// ListAssignmentsOpts allows you to query the ListAssignments method.
// Specify one of or a combination of GroupId, RoleId, ScopeDomainId, ScopeProjectId,
// and/or UserId to search for roles assigned to corresponding entities.
// Effective lists effective assignments at the user, project, and domain level,
// allowing for the effects of group membership.
type
ListAssignmentsOpts
struct
{
GroupId
string
`q:"group.id"`
RoleId
string
`q:"role.id"`
ScopeDomainId
string
`q:"scope.domain.id"`
ScopeProjectId
string
`q:"scope.project.id"`
UserId
string
`q:"user.id"`
Effective
bool
`q:"effective"`
}
// ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string.
func
(
opts
ListAssignmentsOpts
)
ToRolesListAssignmentsQuery
()
(
string
,
error
)
{
q
,
err
:=
gophercloud
.
BuildQueryString
(
opts
)
if
err
!=
nil
{
return
""
,
err
}
return
q
.
String
(),
nil
}
// ListAssignments enumerates the roles assigned to a specified resource.
func
ListAssignments
(
client
*
gophercloud
.
ServiceClient
,
opts
ListAssignmentsOptsBuilder
)
pagination
.
Pager
{
url
:=
listAssignmentsURL
(
client
)
query
,
err
:=
opts
.
ToRolesListAssignmentsQuery
()
if
err
!=
nil
{
return
pagination
.
Pager
{
Err
:
err
}
}
url
+=
query
createPage
:=
func
(
r
pagination
.
PageResult
)
pagination
.
Page
{
return
RoleAssignmentsPage
{
pagination
.
LinkedPageBase
{
PageResult
:
r
}}
}
return
pagination
.
NewPager
(
client
,
url
,
createPage
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests_test.go
0 → 100644
View file @
45cf5636
package
roles
import
(
"fmt"
"net/http"
"reflect"
"testing"
"github.com/rackspace/gophercloud/pagination"
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
func
TestListSinglePage
(
t
*
testing
.
T
)
{
testhelper
.
SetupHTTP
()
defer
testhelper
.
TeardownHTTP
()
testhelper
.
Mux
.
HandleFunc
(
"/role_assignments"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
testhelper
.
TestMethod
(
t
,
r
,
"GET"
)
testhelper
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
client
.
TokenID
)
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
fmt
.
Fprintf
(
w
,
`
{
"role_assignments": [
{
"links": {
"assignment": "http://identity:35357/v3/domains/161718/users/313233/roles/123456"
},
"role": {
"id": "123456"
},
"scope": {
"domain": {
"id": "161718"
}
},
"user": {
"id": "313233"
}
},
{
"links": {
"assignment": "http://identity:35357/v3/projects/456789/groups/101112/roles/123456",
"membership": "http://identity:35357/v3/groups/101112/users/313233"
},
"role": {
"id": "123456"
},
"scope": {
"project": {
"id": "456789"
}
},
"user": {
"id": "313233"
}
}
],
"links": {
"self": "http://identity:35357/v3/role_assignments?effective",
"previous": null,
"next": null
}
}
`
)
})
count
:=
0
err
:=
ListAssignments
(
client
.
ServiceClient
(),
ListAssignmentsOpts
{})
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
count
++
actual
,
err
:=
ExtractRoleAssignments
(
page
)
if
err
!=
nil
{
return
false
,
err
}
expected
:=
[]
RoleAssignment
{
RoleAssignment
{
Role
:
Role
{
ID
:
"123456"
},
Scope
:
Scope
{
Domain
:
Domain
{
ID
:
"161718"
}},
User
:
User
{
ID
:
"313233"
},
Group
:
Group
{},
},
RoleAssignment
{
Role
:
Role
{
ID
:
"123456"
},
Scope
:
Scope
{
Project
:
Project
{
ID
:
"456789"
}},
User
:
User
{
ID
:
"313233"
},
Group
:
Group
{},
},
}
if
!
reflect
.
DeepEqual
(
expected
,
actual
)
{
t
.
Errorf
(
"Expected %#v, got %#v"
,
expected
,
actual
)
}
return
true
,
nil
})
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error while paging: %v"
,
err
)
}
if
count
!=
1
{
t
.
Errorf
(
"Expected 1 page, got %d"
,
count
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go
0 → 100644
View file @
45cf5636
package
roles
import
(
"github.com/rackspace/gophercloud/pagination"
"github.com/mitchellh/mapstructure"
)
// RoleAssignment is the result of a role assignments query.
type
RoleAssignment
struct
{
Role
Role
`json:"role,omitempty"`
Scope
Scope
`json:"scope,omitempty"`
User
User
`json:"user,omitempty"`
Group
Group
`json:"group,omitempty"`
}
type
Role
struct
{
ID
string
`json:"id,omitempty"`
}
type
Scope
struct
{
Domain
Domain
`json:"domain,omitempty"`
Project
Project
`json:"domain,omitempty"`
}
type
Domain
struct
{
ID
string
`json:"id,omitempty"`
}
type
Project
struct
{
ID
string
`json:"id,omitempty"`
}
type
User
struct
{
ID
string
`json:"id,omitempty"`
}
type
Group
struct
{
ID
string
`json:"id,omitempty"`
}
// RoleAssignmentsPage is a single page of RoleAssignments results.
type
RoleAssignmentsPage
struct
{
pagination
.
LinkedPageBase
}
// IsEmpty returns true if the page contains no results.
func
(
p
RoleAssignmentsPage
)
IsEmpty
()
(
bool
,
error
)
{
roleAssignments
,
err
:=
ExtractRoleAssignments
(
p
)
if
err
!=
nil
{
return
true
,
err
}
return
len
(
roleAssignments
)
==
0
,
nil
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func
(
page
RoleAssignmentsPage
)
NextPageURL
()
(
string
,
error
)
{
type
resp
struct
{
Links
struct
{
Next
string
`mapstructure:"next"`
}
`mapstructure:"links"`
}
var
r
resp
err
:=
mapstructure
.
Decode
(
page
.
Body
,
&
r
)
if
err
!=
nil
{
return
""
,
err
}
return
r
.
Links
.
Next
,
nil
}
// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
func
ExtractRoleAssignments
(
page
pagination
.
Page
)
([]
RoleAssignment
,
error
)
{
var
response
struct
{
RoleAssignments
[]
RoleAssignment
`mapstructure:"role_assignments"`
}
err
:=
mapstructure
.
Decode
(
page
.
(
RoleAssignmentsPage
)
.
Body
,
&
response
)
return
response
.
RoleAssignments
,
err
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go
0 → 100644
View file @
45cf5636
package
roles
import
"github.com/rackspace/gophercloud"
func
listAssignmentsURL
(
client
*
gophercloud
.
ServiceClient
)
string
{
return
client
.
ServiceURL
(
"role_assignments"
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls_test.go
0 → 100644
View file @
45cf5636
package
roles
import
(
"testing"
"github.com/rackspace/gophercloud"
)
func
TestListAssignmentsURL
(
t
*
testing
.
T
)
{
client
:=
gophercloud
.
ServiceClient
{
Endpoint
:
"http://localhost:5000/v3/"
}
url
:=
listAssignmentsURL
(
&
client
)
if
url
!=
"http://localhost:5000/v3/role_assignments"
{
t
.
Errorf
(
"Unexpected list URL generated: [%s]"
,
url
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls/requests_test.go
View file @
45cf5636
...
...
@@ -212,9 +212,9 @@ func TestUpdate(t *testing.T) {
"name": "fw",
"admin_state_up": false,
"tenant_id": "b4eedccc6fb74fa8a7ad6b08382b852b",
"firewall_policy_id": "19ab8c87-4a32-4e6a-a74e-b77fffb89a0c"
"firewall_policy_id": "19ab8c87-4a32-4e6a-a74e-b77fffb89a0c"
,
"id": "ea5b5315-64f6-4ea3-8e58-981cc37c6576",
"description": "OpenStack firewall"
,
"description": "OpenStack firewall"
}
}
`
)
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go
View file @
45cf5636
...
...
@@ -296,6 +296,7 @@ func TestAssociateHealthMonitor(t *testing.T) {
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
w
.
WriteHeader
(
http
.
StatusCreated
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
_
,
err
:=
AssociateMonitor
(
fake
.
ServiceClient
(),
"332abe93-f488-41ba-870b-2ac66be7f853"
,
"b624decf-d5d3-4c66-9a3d-f047e7786181"
)
.
Extract
()
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go
View file @
45cf5636
...
...
@@ -45,6 +45,9 @@ type CreateOpts struct {
// Required. Human-readable name for the VIP. Does not have to be unique.
Name
string
// Required for admins. Indicates the owner of the VIP.
TenantID
string
// Optional. Describes the security group.
Description
string
}
...
...
@@ -62,6 +65,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
type
secgroup
struct
{
Name
string
`json:"name"`
TenantID
string
`json:"tenant_id,omitempty"`
Description
string
`json:"description,omitempty"`
}
...
...
@@ -71,6 +75,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
reqBody
:=
request
{
SecGroup
:
secgroup
{
Name
:
opts
.
Name
,
TenantID
:
opts
.
TenantID
,
Description
:
opts
.
Description
,
}}
...
...
@@ -91,3 +96,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
_
,
res
.
Err
=
c
.
Delete
(
resourceURL
(
c
,
id
),
nil
)
return
res
}
// IDFromName is a convenience function that returns a security group's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
securityGroupCount
:=
0
securityGroupID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A security group name must be provided."
)
}
pager
:=
List
(
client
,
ListOpts
{})
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
securityGroupList
,
err
:=
ExtractGroups
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
s
:=
range
securityGroupList
{
if
s
.
Name
==
name
{
securityGroupCount
++
securityGroupID
=
s
.
ID
}
}
return
true
,
nil
})
switch
securityGroupCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find security group: %s"
,
name
)
case
1
:
return
securityGroupID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d security groups matching %s"
,
securityGroupCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go
View file @
45cf5636
...
...
@@ -99,6 +99,9 @@ type CreateOpts struct {
// attribute matches the specified IP prefix as the source IP address of the
// IP packet.
RemoteIPPrefix
string
// Required for admins. Indicates the owner of the VIP.
TenantID
string
}
// Create is an operation which provisions a new security group with default
...
...
@@ -133,6 +136,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
Protocol
string
`json:"protocol,omitempty"`
RemoteGroupID
string
`json:"remote_group_id,omitempty"`
RemoteIPPrefix
string
`json:"remote_ip_prefix,omitempty"`
TenantID
string
`json:"tenant_id,omitempty"`
}
type
request
struct
{
...
...
@@ -148,6 +152,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
Protocol
:
opts
.
Protocol
,
RemoteGroupID
:
opts
.
RemoteGroupID
,
RemoteIPPrefix
:
opts
.
RemoteIPPrefix
,
TenantID
:
opts
.
TenantID
,
}}
_
,
res
.
Err
=
c
.
Post
(
rootURL
(
c
),
reqBody
,
&
res
.
Body
,
nil
)
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go
View file @
45cf5636
package
networks
import
(
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -189,3 +191,36 @@ func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult {
_
,
res
.
Err
=
c
.
Delete
(
deleteURL
(
c
,
networkID
),
nil
)
return
res
}
// IDFromName is a convenience function that returns a network's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
networkCount
:=
0
networkID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A network name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
networkList
,
err
:=
ExtractNetworks
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
n
:=
range
networkList
{
if
n
.
Name
==
name
{
networkCount
++
networkID
=
n
.
ID
}
}
return
true
,
nil
})
switch
networkCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find network: %s"
,
name
)
case
1
:
return
networkID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d networks matching %s"
,
networkCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go
View file @
45cf5636
...
...
@@ -204,6 +204,7 @@ func TestCreateWithOptionalFields(t *testing.T) {
`
)
w
.
WriteHeader
(
http
.
StatusCreated
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
iTrue
:=
true
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go
View file @
45cf5636
package
ports
import
(
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -223,3 +225,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
_
,
res
.
Err
=
c
.
Delete
(
deleteURL
(
c
,
id
),
nil
)
return
res
}
// IDFromName is a convenience function that returns a port's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
portCount
:=
0
portID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A port name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
portList
,
err
:=
ExtractPorts
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
p
:=
range
portList
{
if
p
.
Name
==
name
{
portCount
++
portID
=
p
.
ID
}
}
return
true
,
nil
})
switch
portCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find port: %s"
,
name
)
case
1
:
return
portID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d ports matching %s"
,
portCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go
View file @
45cf5636
package
subnets
import
(
"fmt"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
...
...
@@ -200,10 +202,10 @@ func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
if
opts
.
GatewayIP
!=
""
{
s
[
"gateway_ip"
]
=
opts
.
GatewayIP
}
if
len
(
opts
.
DNSNameservers
)
!=
0
{
if
opts
.
DNSNameservers
!=
nil
{
s
[
"dns_nameservers"
]
=
opts
.
DNSNameservers
}
if
len
(
opts
.
HostRoutes
)
!=
0
{
if
opts
.
HostRoutes
!=
nil
{
s
[
"host_routes"
]
=
opts
.
HostRoutes
}
...
...
@@ -234,3 +236,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
_
,
res
.
Err
=
c
.
Delete
(
deleteURL
(
c
,
id
),
nil
)
return
res
}
// IDFromName is a convenience function that returns a subnet's ID given its name.
func
IDFromName
(
client
*
gophercloud
.
ServiceClient
,
name
string
)
(
string
,
error
)
{
subnetCount
:=
0
subnetID
:=
""
if
name
==
""
{
return
""
,
fmt
.
Errorf
(
"A subnet name must be provided."
)
}
pager
:=
List
(
client
,
nil
)
pager
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
subnetList
,
err
:=
ExtractSubnets
(
page
)
if
err
!=
nil
{
return
false
,
err
}
for
_
,
s
:=
range
subnetList
{
if
s
.
Name
==
name
{
subnetCount
++
subnetID
=
s
.
ID
}
}
return
true
,
nil
})
switch
subnetCount
{
case
0
:
return
""
,
fmt
.
Errorf
(
"Unable to find subnet: %s"
,
name
)
case
1
:
return
subnetID
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"Found %d subnets matching %s"
,
subnetCount
,
name
)
}
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go
View file @
45cf5636
...
...
@@ -55,8 +55,8 @@ type AllocationPool struct {
// HostRoute represents a route that should be used by devices with IPs from
// a subnet (not including local subnet route).
type
HostRoute
struct
{
DestinationCIDR
string
`json:"destination"`
NextHop
string
`json:"nexthop"`
DestinationCIDR
string
`
mapstructure:"destination"
json:"destination"`
NextHop
string
`
mapstructure:"nexthop"
json:"nexthop"`
}
// Subnet represents a subnet. See package documentation for a top-level
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results_test.go
0 → 100644
View file @
45cf5636
package
subnets
import
(
"encoding/json"
"github.com/rackspace/gophercloud"
th
"github.com/rackspace/gophercloud/testhelper"
"testing"
)
func
TestHostRoute
(
t
*
testing
.
T
)
{
sejson
:=
[]
byte
(
`
{"subnet": {
"name": "test-subnet",
"enable_dhcp": false,
"network_id": "3e66c41e-cbbd-4019-9aab-740b7e4150a0",
"tenant_id": "f86e123198cf42d19c8854c5f80c2f06",
"dns_nameservers": [],
"gateway_ip": "172.16.0.1",
"ipv6_ra_mode": null,
"allocation_pools": [
{
"start": "172.16.0.2",
"end": "172.16.255.254"
}
],
"host_routes": [
{
"destination": "172.20.1.0/24",
"nexthop": "172.16.0.2"
}
],
"ip_version": 4,
"ipv6_address_mode": null,
"cidr": "172.16.0.0/16",
"id": "6dcaa873-7115-41af-9ef5-915f73636e43",
"subnetpool_id": null
}}
`
)
var
dejson
interface
{}
err
:=
json
.
Unmarshal
(
sejson
,
&
dejson
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s"
,
err
)
}
resp
:=
commonResult
{
gophercloud
.
Result
{
Body
:
dejson
}}
subnet
,
err
:=
resp
.
Extract
()
if
err
!=
nil
{
t
.
Fatalf
(
"%s"
,
err
)
}
route
:=
subnet
.
HostRoutes
[
0
]
th
.
AssertEquals
(
t
,
route
.
NextHop
,
"172.16.0.2"
)
th
.
AssertEquals
(
t
,
route
.
DestinationCIDR
,
"172.20.1.0/24"
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go
View file @
45cf5636
...
...
@@ -43,7 +43,9 @@ func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult {
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -97,7 +99,9 @@ func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult {
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
201
,
202
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go
View file @
45cf5636
...
...
@@ -114,7 +114,9 @@ func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsB
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
201
,
202
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -180,7 +182,9 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
201
,
202
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -193,7 +197,9 @@ func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
resp
,
err
:=
c
.
Request
(
"HEAD"
,
getURL
(
c
,
containerName
),
gophercloud
.
RequestOpts
{
OkCodes
:
[]
int
{
200
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go
View file @
45cf5636
...
...
@@ -3,7 +3,9 @@
package
objects
import
(
"crypto/md5"
"fmt"
"io"
"net/http"
"testing"
...
...
@@ -107,12 +109,18 @@ func HandleListObjectNamesSuccessfully(t *testing.T) {
// HandleCreateTextObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux
// that responds with a `Create` response. A Content-Type of "text/plain" is expected.
func
HandleCreateTextObjectSuccessfully
(
t
*
testing
.
T
)
{
func
HandleCreateTextObjectSuccessfully
(
t
*
testing
.
T
,
content
string
)
{
th
.
Mux
.
HandleFunc
(
"/testContainer/testObject"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"PUT"
)
th
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
fake
.
TokenID
)
th
.
TestHeader
(
t
,
r
,
"Content-Type"
,
"text/plain"
)
th
.
TestHeader
(
t
,
r
,
"Accept"
,
"application/json"
)
hash
:=
md5
.
New
()
io
.
WriteString
(
hash
,
content
)
localChecksum
:=
hash
.
Sum
(
nil
)
w
.
Header
()
.
Set
(
"ETag"
,
fmt
.
Sprintf
(
"%x"
,
localChecksum
))
w
.
WriteHeader
(
http
.
StatusCreated
)
})
}
...
...
@@ -120,7 +128,7 @@ func HandleCreateTextObjectSuccessfully(t *testing.T) {
// HandleCreateTypelessObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler
// mux that responds with a `Create` response. No Content-Type header may be present in the request, so that server-
// side content-type detection will be triggered properly.
func
HandleCreateTypelessObjectSuccessfully
(
t
*
testing
.
T
)
{
func
HandleCreateTypelessObjectSuccessfully
(
t
*
testing
.
T
,
content
string
)
{
th
.
Mux
.
HandleFunc
(
"/testContainer/testObject"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"PUT"
)
th
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
fake
.
TokenID
)
...
...
@@ -130,6 +138,11 @@ func HandleCreateTypelessObjectSuccessfully(t *testing.T) {
t
.
Errorf
(
"Expected Content-Type header to be omitted, but was %#v"
,
contentType
)
}
hash
:=
md5
.
New
()
io
.
WriteString
(
hash
,
content
)
localChecksum
:=
hash
.
Sum
(
nil
)
w
.
Header
()
.
Set
(
"ETag"
,
fmt
.
Sprintf
(
"%x"
,
localChecksum
))
w
.
WriteHeader
(
http
.
StatusCreated
)
})
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go
View file @
45cf5636
package
objects
import
(
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"fmt"
"io"
...
...
@@ -134,10 +136,11 @@ func Download(c *gophercloud.ServiceClient, containerName, objectName string, op
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
200
,
304
},
})
res
.
Body
=
resp
.
Body
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
res
.
Body
=
resp
.
Body
}
res
.
Err
=
err
res
.
Header
=
resp
.
Header
return
res
}
...
...
@@ -187,8 +190,9 @@ func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error)
return
h
,
q
.
String
(),
nil
}
// Create is a function that creates a new object or replaces an existing object.
func
Create
(
c
*
gophercloud
.
ServiceClient
,
containerName
,
objectName
string
,
content
io
.
Reader
,
opts
CreateOptsBuilder
)
CreateResult
{
// Create is a function that creates a new object or replaces an existing object. If the returned response's ETag
// header fails to match the local checksum, the failed request will automatically be retried up to a maximum of 3 times.
func
Create
(
c
*
gophercloud
.
ServiceClient
,
containerName
,
objectName
string
,
content
io
.
ReadSeeker
,
opts
CreateOptsBuilder
)
CreateResult
{
var
res
CreateResult
url
:=
createURL
(
c
,
containerName
,
objectName
)
...
...
@@ -208,14 +212,37 @@ func Create(c *gophercloud.ServiceClient, containerName, objectName string, cont
url
+=
query
}
hash
:=
md5
.
New
()
contentBuffer
:=
bytes
.
NewBuffer
([]
byte
{})
_
,
err
:=
io
.
Copy
(
contentBuffer
,
io
.
TeeReader
(
content
,
hash
))
if
err
!=
nil
{
res
.
Err
=
err
return
res
}
localChecksum
:=
hash
.
Sum
(
nil
)
h
[
"ETag"
]
=
fmt
.
Sprintf
(
"%x"
,
localChecksum
)
ropts
:=
gophercloud
.
RequestOpts
{
RawBody
:
content
,
RawBody
:
strings
.
NewReader
(
contentBuffer
.
String
())
,
MoreHeaders
:
h
,
}
resp
,
err
:=
c
.
Request
(
"PUT"
,
url
,
ropts
)
res
.
Header
=
resp
.
Header
res
.
Err
=
err
if
err
!=
nil
{
res
.
Err
=
err
return
res
}
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
if
resp
.
Header
.
Get
(
"ETag"
)
==
fmt
.
Sprintf
(
"%x"
,
localChecksum
)
{
res
.
Err
=
err
return
res
}
res
.
Err
=
fmt
.
Errorf
(
"Local checksum does not match API ETag header"
)
}
return
res
}
...
...
@@ -270,7 +297,9 @@ func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts C
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
201
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -310,7 +339,9 @@ func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts
}
resp
,
err
:=
c
.
Delete
(
url
,
nil
)
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -354,7 +385,9 @@ func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts Ge
resp
,
err
:=
c
.
Request
(
"HEAD"
,
url
,
gophercloud
.
RequestOpts
{
OkCodes
:
[]
int
{
200
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -410,7 +443,9 @@ func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts
resp
,
err
:=
c
.
Request
(
"POST"
,
url
,
gophercloud
.
RequestOpts
{
MoreHeaders
:
h
,
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go
View file @
45cf5636
...
...
@@ -2,7 +2,10 @@ package objects
import
(
"bytes"
"fmt"
"io"
"net/http"
"strings"
"testing"
"github.com/rackspace/gophercloud/pagination"
...
...
@@ -83,24 +86,44 @@ func TestListObjectNames(t *testing.T) {
func
TestCreateObject
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleCreateTextObjectSuccessfully
(
t
)
content
:=
bytes
.
NewBufferString
(
"Did gyre and gimble in the wabe"
)
content
:=
"Did gyre and gimble in the wabe"
HandleCreateTextObjectSuccessfully
(
t
,
content
)
options
:=
&
CreateOpts
{
ContentType
:
"text/plain"
}
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
content
,
options
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
strings
.
NewReader
(
content
)
,
options
)
th
.
AssertNoErr
(
t
,
res
.
Err
)
}
func
TestCreateObjectWithoutContentType
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
HandleCreateTypelessObjectSuccessfully
(
t
)
content
:=
bytes
.
NewBufferString
(
"The sky was the color of television, tuned to a dead channel."
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
content
,
&
CreateOpts
{})
content
:=
"The sky was the color of television, tuned to a dead channel."
HandleCreateTypelessObjectSuccessfully
(
t
,
content
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
strings
.
NewReader
(
content
),
&
CreateOpts
{})
th
.
AssertNoErr
(
t
,
res
.
Err
)
}
func
TestErrorIsRaisedForChecksumMismatch
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
th
.
Mux
.
HandleFunc
(
"/testContainer/testObject"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Header
()
.
Set
(
"ETag"
,
"acbd18db4cc2f85cedef654fccc4a4d8"
)
w
.
WriteHeader
(
http
.
StatusCreated
)
})
content
:=
strings
.
NewReader
(
"The sky was the color of television, tuned to a dead channel."
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
content
,
&
CreateOpts
{})
err
:=
fmt
.
Errorf
(
"Local checksum does not match API ETag header"
)
th
.
AssertDeepEquals
(
t
,
err
,
res
.
Err
)
}
func
TestCopyObject
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/fixtures.go
View file @
45cf5636
...
...
@@ -67,7 +67,7 @@ const FindOutput = `
"events": [
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:11
Z
",
"event_time": "2015-02-05T21:33:11",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
...
...
@@ -90,7 +90,7 @@ const FindOutput = `
},
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:27
Z
",
"event_time": "2015-02-05T21:33:27",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
...
...
@@ -184,7 +184,7 @@ const ListOutput = `
"events": [
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:11
Z
",
"event_time": "2015-02-05T21:33:11",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
...
...
@@ -207,7 +207,7 @@ const ListOutput = `
},
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:27
Z
",
"event_time": "2015-02-05T21:33:27",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
...
...
@@ -309,7 +309,7 @@ const ListResourceEventsOutput = `
"events": [
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:11
Z
",
"event_time": "2015-02-05T21:33:11",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
...
...
@@ -332,7 +332,7 @@ const ListResourceEventsOutput = `
},
{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:27
Z
",
"event_time": "2015-02-05T21:33:27",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
...
...
@@ -408,7 +408,7 @@ const GetOutput = `
{
"event":{
"resource_name": "hello_world",
"event_time": "2015-02-05T21:33:27
Z
",
"event_time": "2015-02-05T21:33:27",
"links": [
{
"href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/results.go
View file @
45cf5636
...
...
@@ -57,7 +57,7 @@ func (r FindResult) Extract() ([]Event, error) {
for
i
,
eventRaw
:=
range
events
{
event
:=
eventRaw
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
event
[
"event_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -121,7 +121,7 @@ func ExtractEvents(page pagination.Page) ([]Event, error) {
for
i
,
eventRaw
:=
range
events
{
event
:=
eventRaw
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
event
[
"event_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -161,7 +161,7 @@ func (r GetResult) Extract() (*Event, error) {
event
:=
r
.
Body
.
(
map
[
string
]
interface
{})[
"event"
]
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
event
[
"event_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/fixtures.go
View file @
45cf5636
...
...
@@ -53,7 +53,7 @@ const FindOutput = `
],
"logical_resource_id": "hello_world",
"resource_status_reason": "state changed",
"updated_time": "2015-02-05T21:33:11
Z
",
"updated_time": "2015-02-05T21:33:11",
"required_by": [],
"resource_status": "CREATE_IN_PROGRESS",
"physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
...
...
@@ -117,7 +117,7 @@ const ListOutput = `{
],
"logical_resource_id": "hello_world",
"resource_status_reason": "state changed",
"updated_time": "2015-02-05T21:33:11
Z
",
"updated_time": "2015-02-05T21:33:11",
"required_by": [],
"resource_status": "CREATE_IN_PROGRESS",
"physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
...
...
@@ -188,7 +188,7 @@ const GetOutput = `
],
"logical_resource_id": "wordpress_instance",
"resource_status": "CREATE_COMPLETE",
"updated_time": "2014-12-10T18:34:35
Z
",
"updated_time": "2014-12-10T18:34:35",
"required_by": [],
"resource_status_reason": "state changed",
"physical_resource_id": "00e3a2fe-c65d-403c-9483-4db9930dd194",
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/requests.go
View file @
45cf5636
...
...
@@ -25,12 +25,6 @@ type ListOptsBuilder interface {
// ListOpts allows the filtering and sorting of paginated collections through
// the API. Marker and Limit are used for pagination.
type
ListOpts
struct
{
// The stack resource ID with which to start the listing.
Marker
string
`q:"marker"`
// Integer value for the limit of values to return.
Limit
int
`q:"limit"`
// Include resources from nest stacks up to Depth levels of recursion.
Depth
int
`q:"nested_depth"`
}
...
...
@@ -57,9 +51,7 @@ func List(client *gophercloud.ServiceClient, stackName, stackID string, opts Lis
}
createPageFn
:=
func
(
r
pagination
.
PageResult
)
pagination
.
Page
{
p
:=
ResourcePage
{
pagination
.
MarkerPageBase
{
PageResult
:
r
}}
p
.
MarkerPageBase
.
Owner
=
p
return
p
return
ResourcePage
{
pagination
.
SinglePageBase
(
r
)}
}
return
pagination
.
NewPager
(
client
,
url
,
createPageFn
)
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/results.go
View file @
45cf5636
...
...
@@ -48,7 +48,7 @@ func (r FindResult) Extract() ([]Resource, error) {
for
i
,
resourceRaw
:=
range
resources
{
resource
:=
resourceRaw
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
resource
[
"updated_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -63,7 +63,7 @@ func (r FindResult) Extract() ([]Resource, error) {
// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
// data provided through the ExtractResources call.
type
ResourcePage
struct
{
pagination
.
Marker
PageBase
pagination
.
Single
PageBase
}
// IsEmpty returns true if a page contains no Server results.
...
...
@@ -109,7 +109,7 @@ func ExtractResources(page pagination.Page) ([]Resource, error) {
for
i
,
resourceRaw
:=
range
resources
{
resource
:=
resourceRaw
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
resource
[
"updated_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -143,7 +143,7 @@ func (r GetResult) Extract() (*Resource, error) {
resource
:=
r
.
Body
.
(
map
[
string
]
interface
{})[
"resource"
]
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
resource
[
"updated_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/fixtures.go
View file @
45cf5636
...
...
@@ -95,7 +95,7 @@ const FullListOutput = `
],
"stack_status_reason": "Stack CREATE completed successfully",
"stack_name": "postman_stack",
"creation_time": "2015-02-03T20:07:39
Z
",
"creation_time": "2015-02-03T20:07:39",
"updated_time": null,
"stack_status": "CREATE_COMPLETE",
"id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87"
...
...
@@ -110,8 +110,8 @@ const FullListOutput = `
],
"stack_status_reason": "Stack successfully updated",
"stack_name": "gophercloud-test-stack-2",
"creation_time": "2014-12-11T17:39:16
Z
",
"updated_time": "2014-12-11T17:40:37
Z
",
"creation_time": "2014-12-11T17:39:16",
"updated_time": "2014-12-11T17:40:37",
"stack_status": "UPDATE_COMPLETE",
"id": "db6977b2-27aa-4775-9ae7-6213212d4ada"
}
...
...
@@ -181,7 +181,7 @@ const GetOutput = `
"stack_status_reason": "Stack CREATE completed successfully",
"stack_name": "postman_stack",
"outputs": [],
"creation_time": "2015-02-03T20:07:39
Z
",
"creation_time": "2015-02-03T20:07:39",
"links": [
{
"href": "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/results.go
View file @
45cf5636
...
...
@@ -100,7 +100,7 @@ func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
thisStack
:=
(
rawStacks
[
i
])
.
(
map
[
string
]
interface
{})
if
t
,
ok
:=
thisStack
[
"creation_time"
]
.
(
string
);
ok
&&
t
!=
""
{
creationTime
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
t
)
creationTime
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
t
)
if
err
!=
nil
{
return
res
.
Stacks
,
err
}
...
...
@@ -108,7 +108,7 @@ func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
}
if
t
,
ok
:=
thisStack
[
"updated_time"
]
.
(
string
);
ok
&&
t
!=
""
{
updatedTime
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
t
)
updatedTime
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
t
)
if
err
!=
nil
{
return
res
.
Stacks
,
err
}
...
...
@@ -170,7 +170,7 @@ func (r GetResult) Extract() (*RetrievedStack, error) {
b
:=
r
.
Body
.
(
map
[
string
]
interface
{})[
"stack"
]
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
b
[
"creation_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -178,7 +178,7 @@ func (r GetResult) Extract() (*RetrievedStack, error) {
}
if
date
,
ok
:=
b
[
"updated_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -249,7 +249,7 @@ func (r PreviewResult) Extract() (*PreviewedStack, error) {
b
:=
r
.
Body
.
(
map
[
string
]
interface
{})[
"stack"
]
.
(
map
[
string
]
interface
{})
if
date
,
ok
:=
b
[
"creation_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -257,7 +257,7 @@ func (r PreviewResult) Extract() (*PreviewedStack, error) {
}
if
date
,
ok
:=
b
[
"updated_time"
];
ok
&&
date
!=
nil
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
date
.
(
string
))
t
,
err
:=
time
.
Parse
(
gophercloud
.
STACK_TIME_FMT
,
date
.
(
string
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go
View file @
45cf5636
...
...
@@ -36,13 +36,19 @@ func PageResultFrom(resp *http.Response) (PageResult, error) {
parsedBody
=
rawBody
}
return
PageResultFromParsed
(
resp
,
parsedBody
),
err
}
// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its
// body parsed as JSON (and closed).
func
PageResultFromParsed
(
resp
*
http
.
Response
,
body
interface
{})
PageResult
{
return
PageResult
{
Result
:
gophercloud
.
Result
{
Body
:
parsedB
ody
,
Body
:
b
ody
,
Header
:
resp
.
Header
,
},
URL
:
*
resp
.
Request
.
URL
,
}
,
err
}
}
// Request performs an HTTP request and extracts the http.Response from the result.
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go
View file @
45cf5636
...
...
@@ -174,8 +174,10 @@ func (p Pager) AllPages() (Page, error) {
if
err
!=
nil
{
return
nil
,
err
}
// Remove the trailing comma.
pagesSlice
=
pagesSlice
[
:
len
(
pagesSlice
)
-
1
]
if
len
(
pagesSlice
)
>
0
{
// Remove the trailing comma.
pagesSlice
=
pagesSlice
[
:
len
(
pagesSlice
)
-
1
]
}
var
b
[]
byte
// Combine the slice of slices in to a single slice.
for
_
,
slice
:=
range
pagesSlice
{
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go
View file @
45cf5636
...
...
@@ -85,9 +85,9 @@ type RequestOpts struct {
// content type of the request will default to "application/json" unless overridden by MoreHeaders.
// It's an error to specify both a JSONBody and a RawBody.
JSONBody
interface
{}
// RawBody contains an io.Reader that will be consumed by the request directly. No content-type
// RawBody contains an io.Read
Seek
er that will be consumed by the request directly. No content-type
// will be set unless one is provided explicitly by MoreHeaders.
RawBody
io
.
Reader
RawBody
io
.
Read
Seek
er
// JSONResponse, if provided, will be populated with the contents of the response body parsed as
// JSON.
...
...
@@ -124,11 +124,11 @@ var applicationJSON = "application/json"
// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication
// header will automatically be provided.
func
(
client
*
ProviderClient
)
Request
(
method
,
url
string
,
options
RequestOpts
)
(
*
http
.
Response
,
error
)
{
var
body
io
.
Reader
var
body
io
.
Read
Seek
er
var
contentType
*
string
// Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided
// io.Reader as-is. Default the content-type to application/json.
// io.Read
Seek
er as-is. Default the content-type to application/json.
if
options
.
JSONBody
!=
nil
{
if
options
.
RawBody
!=
nil
{
panic
(
"Please provide only one of JSONBody or RawBody to gophercloud.Request()."
)
...
...
@@ -189,6 +189,9 @@ func (client *ProviderClient) Request(method, url string, options RequestOpts) (
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Error trying to re-authenticate: %s"
,
err
)
}
if
options
.
RawBody
!=
nil
{
options
.
RawBody
.
Seek
(
0
,
0
)
}
resp
,
err
=
client
.
Request
(
method
,
url
,
options
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Successfully re-authenticated, but got error executing request: %s"
,
err
)
...
...
@@ -224,7 +227,9 @@ func (client *ProviderClient) Request(method, url string, options RequestOpts) (
// Parse the response body as JSON, if requested to do so.
if
options
.
JSONResponse
!=
nil
{
defer
resp
.
Body
.
Close
()
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
options
.
JSONResponse
)
if
err
:=
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
options
.
JSONResponse
);
err
!=
nil
{
return
nil
,
err
}
}
return
resp
,
nil
...
...
@@ -260,7 +265,7 @@ func (client *ProviderClient) Post(url string, JSONBody interface{}, JSONRespons
opts
=
&
RequestOpts
{}
}
if
v
,
ok
:=
(
JSONBody
)
.
(
io
.
Reader
);
ok
{
if
v
,
ok
:=
(
JSONBody
)
.
(
io
.
Read
Seek
er
);
ok
{
opts
.
RawBody
=
v
}
else
if
JSONBody
!=
nil
{
opts
.
JSONBody
=
JSONBody
...
...
@@ -278,7 +283,7 @@ func (client *ProviderClient) Put(url string, JSONBody interface{}, JSONResponse
opts
=
&
RequestOpts
{}
}
if
v
,
ok
:=
(
JSONBody
)
.
(
io
.
Reader
);
ok
{
if
v
,
ok
:=
(
JSONBody
)
.
(
io
.
Read
Seek
er
);
ok
{
opts
.
RawBody
=
v
}
else
if
JSONBody
!=
nil
{
opts
.
JSONBody
=
JSONBody
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go
View file @
45cf5636
...
...
@@ -3,7 +3,8 @@ package volumes
import
(
"testing"
os
"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
os
"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing"
"github.com/rackspace/gophercloud/pagination"
th
"github.com/rackspace/gophercloud/testhelper"
fake
"github.com/rackspace/gophercloud/testhelper/client"
...
...
@@ -64,7 +65,7 @@ func TestCreate(t *testing.T) {
os
.
MockCreateResponse
(
t
)
n
,
err
:=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
o
s
.
CreateOpts
{
Size
:
75
}})
.
Extract
()
n
,
err
:=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
volume
s
.
CreateOpts
{
Size
:
75
}})
.
Extract
()
th
.
AssertNoErr
(
t
,
err
)
th
.
AssertEquals
(
t
,
n
.
Size
,
4
)
...
...
@@ -72,12 +73,12 @@ func TestCreate(t *testing.T) {
}
func
TestSizeRange
(
t
*
testing
.
T
)
{
_
,
err
:=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
o
s
.
CreateOpts
{
Size
:
1
}})
.
Extract
()
_
,
err
:=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
volume
s
.
CreateOpts
{
Size
:
1
}})
.
Extract
()
if
err
==
nil
{
t
.
Fatalf
(
"Expected error, got none"
)
}
_
,
err
=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
o
s
.
CreateOpts
{
Size
:
2000
}})
.
Extract
()
_
,
err
=
Create
(
fake
.
ServiceClient
(),
CreateOpts
{
volume
s
.
CreateOpts
{
Size
:
2000
}})
.
Extract
()
if
err
==
nil
{
t
.
Fatalf
(
"Expected error, got none"
)
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go
View file @
45cf5636
...
...
@@ -33,6 +33,8 @@ func TestCreateOpts(t *testing.T) {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
"flavorName": "",
"imageName": "",
"block_device_mapping_v2":[
{
"uuid":"123456",
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go
View file @
45cf5636
...
...
@@ -36,11 +36,8 @@ func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagi
}
// Get returns details about a single flavor, identity by ID.
func
Get
(
client
*
gophercloud
.
ServiceClient
,
id
string
)
os
.
GetResult
{
return
os
.
Get
(
client
,
id
)
}
// ExtractFlavors interprets a page of List results as Flavors.
func
ExtractFlavors
(
page
pagination
.
Page
)
([]
os
.
Flavor
,
error
)
{
return
os
.
ExtractFlavors
(
page
)
func
Get
(
client
*
gophercloud
.
ServiceClient
,
id
string
)
GetResult
{
var
res
GetResult
_
,
res
.
Err
=
client
.
Get
(
getURL
(
client
,
id
),
&
res
.
Body
,
nil
)
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go
View file @
45cf5636
...
...
@@ -2,10 +2,6 @@
package
flavors
import
(
os
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
)
// ListOutput is a sample response of a flavor List request.
const
ListOutput
=
`
{
...
...
@@ -103,7 +99,7 @@ const GetOutput = `
// Performance1Flavor is the expected result of parsing GetOutput, or the first element of
// ListOutput.
var
Performance1Flavor
=
os
.
Flavor
{
var
Performance1Flavor
=
Flavor
{
ID
:
"performance1-1"
,
Disk
:
20
,
RAM
:
1024
,
...
...
@@ -111,10 +107,16 @@ var Performance1Flavor = os.Flavor{
RxTxFactor
:
200.0
,
Swap
:
0
,
VCPUs
:
1
,
ExtraSpecs
:
ExtraSpecs
{
NumDataDisks
:
0
,
Class
:
"performance1"
,
DiskIOIndex
:
0
,
PolicyClass
:
"performance_flavor"
,
},
}
// Performance2Flavor is the second result expected from parsing ListOutput.
var
Performance2Flavor
=
os
.
Flavor
{
var
Performance2Flavor
=
Flavor
{
ID
:
"performance1-2"
,
Disk
:
40
,
RAM
:
2048
,
...
...
@@ -122,8 +124,14 @@ var Performance2Flavor = os.Flavor{
RxTxFactor
:
400.0
,
Swap
:
0
,
VCPUs
:
2
,
ExtraSpecs
:
ExtraSpecs
{
NumDataDisks
:
0
,
Class
:
"performance1"
,
DiskIOIndex
:
0
,
PolicyClass
:
"performance_flavor"
,
},
}
// ExpectedFlavorSlice is the slice of Flavor structs that are expected to be parsed from
// ListOutput.
var
ExpectedFlavorSlice
=
[]
os
.
Flavor
{
Performance1Flavor
,
Performance2Flavor
}
var
ExpectedFlavorSlice
=
[]
Flavor
{
Performance1Flavor
,
Performance2Flavor
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/results.go
0 → 100644
View file @
45cf5636
package
flavors
import
(
"reflect"
"github.com/rackspace/gophercloud"
"github.com/mitchellh/mapstructure"
os
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
"github.com/rackspace/gophercloud/pagination"
)
// ExtraSpecs provide additional information about the flavor.
type
ExtraSpecs
struct
{
// The number of data disks
NumDataDisks
int
`mapstructure:"number_of_data_disks"`
// The flavor class
Class
string
`mapstructure:"class"`
// Relative measure of disk I/O performance from 0-99, where higher is faster
DiskIOIndex
int
`mapstructure:"disk_io_index"`
PolicyClass
string
`mapstructure:"policy_class"`
}
// Flavor records represent (virtual) hardware configurations for server resources in a region.
type
Flavor
struct
{
// The Id field contains the flavor's unique identifier.
// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
ID
string
`mapstructure:"id"`
// The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
Disk
int
`mapstructure:"disk"`
RAM
int
`mapstructure:"ram"`
// The Name field provides a human-readable moniker for the flavor.
Name
string
`mapstructure:"name"`
RxTxFactor
float64
`mapstructure:"rxtx_factor"`
// Swap indicates how much space is reserved for swap.
// If not provided, this field will be set to 0.
Swap
int
`mapstructure:"swap"`
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
VCPUs
int
`mapstructure:"vcpus"`
// ExtraSpecs provides extra information about the flavor
ExtraSpecs
ExtraSpecs
`mapstructure:"OS-FLV-WITH-EXT-SPECS:extra_specs"`
}
// GetResult temporarily holds the response from a Get call.
type
GetResult
struct
{
gophercloud
.
Result
}
// Extract provides access to the individual Flavor returned by the Get function.
func
(
gr
GetResult
)
Extract
()
(
*
Flavor
,
error
)
{
if
gr
.
Err
!=
nil
{
return
nil
,
gr
.
Err
}
var
result
struct
{
Flavor
Flavor
`mapstructure:"flavor"`
}
cfg
:=
&
mapstructure
.
DecoderConfig
{
DecodeHook
:
defaulter
,
Result
:
&
result
,
}
decoder
,
err
:=
mapstructure
.
NewDecoder
(
cfg
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
decoder
.
Decode
(
gr
.
Body
)
return
&
result
.
Flavor
,
err
}
func
defaulter
(
from
,
to
reflect
.
Kind
,
v
interface
{})
(
interface
{},
error
)
{
if
(
from
==
reflect
.
String
)
&&
(
to
==
reflect
.
Int
)
{
return
0
,
nil
}
return
v
,
nil
}
// ExtractFlavors provides access to the list of flavors in a page acquired from the List operation.
func
ExtractFlavors
(
page
pagination
.
Page
)
([]
Flavor
,
error
)
{
casted
:=
page
.
(
os
.
FlavorPage
)
.
Body
var
container
struct
{
Flavors
[]
Flavor
`mapstructure:"flavors"`
}
cfg
:=
&
mapstructure
.
DecoderConfig
{
DecodeHook
:
defaulter
,
Result
:
&
container
,
}
decoder
,
err
:=
mapstructure
.
NewDecoder
(
cfg
)
if
err
!=
nil
{
return
container
.
Flavors
,
err
}
err
=
decoder
.
Decode
(
casted
)
if
err
!=
nil
{
return
container
.
Flavors
,
err
}
return
container
.
Flavors
,
nil
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/urls.go
0 → 100644
View file @
45cf5636
package
flavors
import
(
"github.com/rackspace/gophercloud"
)
func
getURL
(
client
*
gophercloud
.
ServiceClient
,
id
string
)
string
{
return
client
.
ServiceURL
(
"flavors"
,
id
)
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go
View file @
45cf5636
...
...
@@ -12,13 +12,24 @@ type CreateOpts struct {
// Name [required] is the name to assign to the newly launched server.
Name
string
// ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state.
// Optional if using the boot-from-volume extension.
// ImageRef [optional; required if ImageName is not provided] is the ID or full
// URL to the image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageRef
string
// FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs.
// ImageName [optional; required if ImageRef is not provided] is the name of the
// image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageName
string
// FlavorRef [optional; required if FlavorName is not provided] is the ID or
// full URL to the flavor that describes the server's specs.
FlavorRef
string
// FlavorName [optional; required if FlavorRef is not provided] is the name of
// the flavor that describes the server's specs.
FlavorName
string
// SecurityGroups [optional] lists the names of the security groups to which this server should belong.
SecurityGroups
[]
string
...
...
@@ -36,9 +47,9 @@ type CreateOpts struct {
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata
map
[
string
]
string
// Personality [optional] includes
the path and contents of a file
to inject into the server at launch.
//
The maximum size of the file is 255 bytes (decoded)
.
Personality
[]
byte
// Personality [optional] includes
files
to inject into the server at launch.
//
Create will base64-encode file contents for you
.
Personality
os
.
Personality
// ConfigDrive [optional] enables metadata injection through a configuration drive.
ConfigDrive
bool
...
...
@@ -58,7 +69,7 @@ type CreateOpts struct {
DiskConfig
diskconfig
.
DiskConfig
// BlockDevice [optional] will create the server from a volume, which is created from an image,
// a snapshot, or an
an
other volume.
// a snapshot, or another volume.
BlockDevice
[]
bootfromvolume
.
BlockDevice
}
...
...
@@ -68,7 +79,9 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
base
:=
os
.
CreateOpts
{
Name
:
opts
.
Name
,
ImageRef
:
opts
.
ImageRef
,
ImageName
:
opts
.
ImageName
,
FlavorRef
:
opts
.
FlavorRef
,
FlavorName
:
opts
.
FlavorName
,
SecurityGroups
:
opts
.
SecurityGroups
,
UserData
:
opts
.
UserData
,
AvailabilityZone
:
opts
.
AvailabilityZone
,
...
...
@@ -104,7 +117,9 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
// key_name doesn't actually come from the extension (or at least isn't documented there) so
// we need to add it manually.
serverMap
:=
res
[
"server"
]
.
(
map
[
string
]
interface
{})
serverMap
[
"key_name"
]
=
opts
.
KeyPair
if
opts
.
KeyPair
!=
""
{
serverMap
[
"key_name"
]
=
opts
.
KeyPair
}
return
res
,
nil
}
...
...
@@ -130,9 +145,9 @@ type RebuildOpts struct {
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata
map
[
string
]
string
// Personality [optional] includes
the path and contents of a file
to inject into the server at launch.
//
The maximum size of the file is 255 bytes (decoded)
.
Personality
[]
byte
// Personality [optional] includes
files
to inject into the server at launch.
//
Rebuild will base64-encode file contents for you
.
Personality
os
.
Personality
// Rackspace-specific stuff begins here.
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go
View file @
45cf5636
...
...
@@ -22,6 +22,8 @@ func TestCreateOpts(t *testing.T) {
"name": "createdserver",
"imageRef": "image-id",
"flavorRef": "flavor-id",
"flavorName": "",
"imageName": "",
"key_name": "mykey",
"OS-DCF:diskConfig": "MANUAL"
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/volumeattach/delegate_test.go
View file @
45cf5636
...
...
@@ -3,24 +3,53 @@ package volumeattach
import
(
"testing"
os
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach"
fixtures
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing"
"github.com/rackspace/gophercloud/pagination"
th
"github.com/rackspace/gophercloud/testhelper"
"github.com/rackspace/gophercloud/testhelper/client"
)
// FirstVolumeAttachment is the first result in ListOutput.
var
FirstVolumeAttachment
=
volumeattach
.
VolumeAttachment
{
Device
:
"/dev/vdd"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f803"
,
}
// SecondVolumeAttachment is the first result in ListOutput.
var
SecondVolumeAttachment
=
volumeattach
.
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed
// from ListOutput, in the expected order.
var
ExpectedVolumeAttachmentSlice
=
[]
volumeattach
.
VolumeAttachment
{
FirstVolumeAttachment
,
SecondVolumeAttachment
}
//CreatedVolumeAttachment is the parsed result from CreatedOutput.
var
CreatedVolumeAttachment
=
volumeattach
.
VolumeAttachment
{
Device
:
"/dev/vdc"
,
ID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
ServerID
:
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
}
func
TestList
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
o
s
.
HandleListSuccessfully
(
t
)
fixture
s
.
HandleListSuccessfully
(
t
)
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
count
:=
0
err
:=
List
(
client
.
ServiceClient
(),
serverId
)
.
EachPage
(
func
(
page
pagination
.
Page
)
(
bool
,
error
)
{
count
++
actual
,
err
:=
os
.
ExtractVolumeAttachments
(
page
)
actual
,
err
:=
volumeattach
.
ExtractVolumeAttachments
(
page
)
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckDeepEquals
(
t
,
os
.
ExpectedVolumeAttachmentSlice
,
actual
)
th
.
CheckDeepEquals
(
t
,
ExpectedVolumeAttachmentSlice
,
actual
)
return
true
,
nil
})
...
...
@@ -31,33 +60,33 @@ func TestList(t *testing.T) {
func
TestCreate
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
o
s
.
HandleCreateSuccessfully
(
t
)
fixture
s
.
HandleCreateSuccessfully
(
t
)
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
actual
,
err
:=
Create
(
client
.
ServiceClient
(),
serverId
,
os
.
CreateOpts
{
actual
,
err
:=
Create
(
client
.
ServiceClient
(),
serverId
,
volumeattach
.
CreateOpts
{
Device
:
"/dev/vdc"
,
VolumeID
:
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
,
})
.
Extract
()
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckDeepEquals
(
t
,
&
os
.
CreatedVolumeAttachment
,
actual
)
th
.
CheckDeepEquals
(
t
,
&
CreatedVolumeAttachment
,
actual
)
}
func
TestGet
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
o
s
.
HandleGetSuccessfully
(
t
)
fixture
s
.
HandleGetSuccessfully
(
t
)
aId
:=
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
actual
,
err
:=
Get
(
client
.
ServiceClient
(),
serverId
,
aId
)
.
Extract
()
th
.
AssertNoErr
(
t
,
err
)
th
.
CheckDeepEquals
(
t
,
&
os
.
SecondVolumeAttachment
,
actual
)
th
.
CheckDeepEquals
(
t
,
&
SecondVolumeAttachment
,
actual
)
}
func
TestDelete
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
o
s
.
HandleDeleteSuccessfully
(
t
)
fixture
s
.
HandleDeleteSuccessfully
(
t
)
aId
:=
"a26887c6-c47b-4654-abb5-dfadf7d3f804"
serverId
:=
"4d8c3732-a248-40ed-bebc-539a6ffd25c0"
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go
View file @
45cf5636
...
...
@@ -107,6 +107,42 @@ func mockCreateResponse(t *testing.T, lbID int) {
})
}
func
mockCreateErrResponse
(
t
*
testing
.
T
,
lbID
int
)
{
th
.
Mux
.
HandleFunc
(
_rootURL
(
lbID
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"POST"
)
th
.
TestHeader
(
t
,
r
,
"X-Auth-Token"
,
fake
.
TokenID
)
th
.
TestJSONRequest
(
t
,
r
,
`
{
"nodes": [
{
"address": "10.2.2.3",
"port": 80,
"condition": "ENABLED",
"type": "PRIMARY"
},
{
"address": "10.2.2.4",
"port": 81,
"condition": "ENABLED",
"type": "SECONDARY"
}
]
}
`
)
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/json"
)
w
.
WriteHeader
(
422
)
// Unprocessable Entity
fmt
.
Fprintf
(
w
,
`
{
"code": 422,
"message": "Load Balancer '%d' has a status of 'PENDING_UPDATE' and is considered immutable."
}
`
,
lbID
)
})
}
func
mockBatchDeleteResponse
(
t
*
testing
.
T
,
lbID
int
,
ids
[]
int
)
{
th
.
Mux
.
HandleFunc
(
_rootURL
(
lbID
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
th
.
TestMethod
(
t
,
r
,
"DELETE"
)
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go
View file @
45cf5636
...
...
@@ -119,12 +119,7 @@ func Create(client *gophercloud.ServiceClient, loadBalancerID int, opts CreateOp
return
res
}
pr
,
err
:=
pagination
.
PageResultFrom
(
resp
)
if
err
!=
nil
{
res
.
Err
=
err
return
res
}
pr
:=
pagination
.
PageResultFromParsed
(
resp
,
res
.
Body
)
return
CreateResult
{
pagination
.
SinglePageBase
(
pr
)}
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go
View file @
45cf5636
...
...
@@ -108,6 +108,38 @@ func TestCreate(t *testing.T) {
th
.
CheckDeepEquals
(
t
,
expected
,
actual
)
}
func
TestCreateErr
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
mockCreateErrResponse
(
t
,
lbID
)
opts
:=
CreateOpts
{
CreateOpt
{
Address
:
"10.2.2.3"
,
Port
:
80
,
Condition
:
ENABLED
,
Type
:
PRIMARY
,
},
CreateOpt
{
Address
:
"10.2.2.4"
,
Port
:
81
,
Condition
:
ENABLED
,
Type
:
SECONDARY
,
},
}
page
:=
Create
(
client
.
ServiceClient
(),
lbID
,
opts
)
actual
,
err
:=
page
.
ExtractNodes
()
if
err
==
nil
{
t
.
Fatal
(
"Did not receive expected error from ExtractNodes"
)
}
if
actual
!=
nil
{
t
.
Fatalf
(
"Received non-nil result from failed ExtractNodes: %#v"
,
actual
)
}
}
func
TestBulkDelete
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go
View file @
45cf5636
...
...
@@ -126,6 +126,9 @@ type CreateResult struct {
// ExtractNodes extracts a slice of Node structs from a CreateResult.
func
(
res
CreateResult
)
ExtractNodes
()
([]
Node
,
error
)
{
if
res
.
Err
!=
nil
{
return
nil
,
res
.
Err
}
return
commonExtractNodes
(
res
.
Body
)
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go
View file @
45cf5636
...
...
@@ -46,6 +46,7 @@ func mockEnableResponse(t *testing.T, lbID int) {
`
)
w
.
WriteHeader
(
http
.
StatusAccepted
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go
View file @
45cf5636
...
...
@@ -63,6 +63,7 @@ func mockUpdateResponse(t *testing.T, lbID int) {
`
)
w
.
WriteHeader
(
http
.
StatusOK
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go
View file @
45cf5636
...
...
@@ -49,6 +49,7 @@ func mockCreateResponse(t *testing.T, lbID int) {
`
)
w
.
WriteHeader
(
http
.
StatusAccepted
)
fmt
.
Fprintf
(
w
,
`{}`
)
})
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go
View file @
45cf5636
...
...
@@ -203,8 +203,17 @@ func TestCreateWithOptionalFields(t *testing.T) {
}
}
`
)
w
.
WriteHeader
(
http
.
StatusCreated
)
fmt
.
Fprintf
(
w
,
`
{
"network": {
"name": "sample_network",
"admin_state_up": true,
"shared": true,
"tenant_id": "12345"
}
}
`
)
})
iTrue
:=
true
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go
View file @
45cf5636
...
...
@@ -43,7 +43,9 @@ func Delete(c *gophercloud.ServiceClient, opts DeleteOptsBuilder) DeleteResult {
JSONBody
:
reqBody
,
JSONResponse
:
&
res
.
Body
,
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go
View file @
45cf5636
...
...
@@ -53,7 +53,9 @@ func Enable(c *gophercloud.ServiceClient, containerName string, opts EnableOptsB
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
201
,
202
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -66,7 +68,9 @@ func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
resp
,
err
:=
c
.
Request
(
"HEAD"
,
getURL
(
c
,
containerName
),
gophercloud
.
RequestOpts
{
OkCodes
:
[]
int
{
200
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
...
...
@@ -149,7 +153,9 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB
MoreHeaders
:
h
,
OkCodes
:
[]
int
{
202
,
204
},
})
res
.
Header
=
resp
.
Header
if
resp
!=
nil
{
res
.
Header
=
resp
.
Header
}
res
.
Err
=
err
return
res
}
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go
View file @
45cf5636
...
...
@@ -33,7 +33,7 @@ func Download(c *gophercloud.ServiceClient, containerName, objectName string, op
}
// Create is a function that creates a new object or replaces an existing object.
func
Create
(
c
*
gophercloud
.
ServiceClient
,
containerName
,
objectName
string
,
content
io
.
Reader
,
opts
os
.
CreateOptsBuilder
)
os
.
CreateResult
{
func
Create
(
c
*
gophercloud
.
ServiceClient
,
containerName
,
objectName
string
,
content
io
.
Read
Seek
er
,
opts
os
.
CreateOptsBuilder
)
os
.
CreateResult
{
return
os
.
Create
(
c
,
containerName
,
objectName
,
content
,
opts
)
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go
View file @
45cf5636
package
objects
import
(
"
byte
s"
"
string
s"
"testing"
os
"github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects"
...
...
@@ -66,21 +66,23 @@ func TestListObjectNames(t *testing.T) {
func
TestCreateObject
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
os
.
HandleCreateTextObjectSuccessfully
(
t
)
content
:=
"Did gyre and gimble in the wabe"
os
.
HandleCreateTextObjectSuccessfully
(
t
,
content
)
content
:=
bytes
.
NewBufferString
(
"Did gyre and gimble in the wabe"
)
options
:=
&
os
.
CreateOpts
{
ContentType
:
"text/plain"
}
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
content
,
options
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
strings
.
NewReader
(
content
)
,
options
)
th
.
AssertNoErr
(
t
,
res
.
Err
)
}
func
TestCreateObjectWithoutContentType
(
t
*
testing
.
T
)
{
th
.
SetupHTTP
()
defer
th
.
TeardownHTTP
()
os
.
HandleCreateTypelessObjectSuccessfully
(
t
)
content
:=
bytes
.
NewBufferString
(
"The sky was the color of television, tuned to a dead channel."
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
content
,
&
os
.
CreateOpts
{})
content
:=
"The sky was the color of television, tuned to a dead channel."
os
.
HandleCreateTypelessObjectSuccessfully
(
t
,
content
)
res
:=
Create
(
fake
.
ServiceClient
(),
"testContainer"
,
"testObject"
,
strings
.
NewReader
(
content
),
&
os
.
CreateOpts
{})
th
.
AssertNoErr
(
t
,
res
.
Err
)
}
...
...
Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go
View file @
45cf5636
...
...
@@ -113,6 +113,9 @@ func DecodeHeader(from, to interface{}) error {
// RFC3339Milli describes a common time format used by some API responses.
const
RFC3339Milli
=
"2006-01-02T15:04:05.999999Z"
// Time format used in cloud orchestration
const
STACK_TIME_FMT
=
"2006-01-02T15:04:05"
/*
Link is an internal type to be used in packages of collection resources that are
paginated in a certain way.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment