removes vendor make target

documents how to correctly add deps

removes unused dependencies

installs govendor as part of deps make target
This commit is contained in:
Matthew Hooker 2016-10-05 14:15:57 -07:00
parent 9ff9539d72
commit fb8ced982a
400 changed files with 8 additions and 215112 deletions

View File

@ -106,6 +106,11 @@ If you are submitting a change that requires new or updated dependencies, please
Note that you will need to use [govendor](https://github.com/kardianos/govendor) to do this. This step is recommended but not required; if you don't use govendor please indicate in your PR which dependencies have changed and to what versions.
Use `govendor fetch <project>` to add dependencies to the project. See
[govendor quick
start(https://github.com/kardianos/govendor#quick-start-also-see-the-faq) for
examples.
Please only apply the minimal vendor changes to get your PR to work. Packer does not attempt to track the latest version for each dependency.
#### Running Unit Tests

View File

@ -29,6 +29,8 @@ package:
deps:
go get github.com/mitchellh/gox
go get golang.org/x/tools/cmd/stringer
go get -u github.com/kardianos/govendor
govendor sync
dev: deps ## Build and install a development build
@grep 'const VersionPrerelease = ""' version/version.go > /dev/null ; if [ $$? -eq 0 ]; then \
@ -73,8 +75,7 @@ updatedeps:
# This is used to add new dependencies to packer. If you are submitting a PR
# that includes new dependencies you will need to run this.
vendor: ## Add new dependencies.
govendor add +external
govendor sync
@echo "INFO: Packer deps are managed by govendor. See CONTRIBUTING.md"
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

View File

@ -1,47 +0,0 @@
package util
import (
"fmt"
"time"
"github.com/digitalocean/godo"
)
const (
// activeFailure is the amount of times we can fail before deciding
// the check for active is a total failure. This can help account
// for servers randomly not answering.
activeFailure = 3
)
// WaitForActive waits for a droplet to become active
func WaitForActive(client *godo.Client, monitorURI string) error {
if len(monitorURI) == 0 {
return fmt.Errorf("create had no monitor uri")
}
completed := false
failCount := 0
for !completed {
action, _, err := client.DropletActions.GetByURI(monitorURI)
if err != nil {
if failCount <= activeFailure {
failCount++
continue
}
return err
}
switch action.Status {
case godo.ActionInProgress:
time.Sleep(5 * time.Second)
case godo.ActionCompleted:
completed = true
default:
return fmt.Errorf("unknown status: [%s]", action.Status)
}
}
return nil
}

View File

@ -1,122 +0,0 @@
// Code generated by protoc-gen-go.
// source: proto3_proto/proto3.proto
// DO NOT EDIT!
/*
Package proto3_proto is a generated protocol buffer package.
It is generated from these files:
proto3_proto/proto3.proto
It has these top-level messages:
Message
Nested
MessageWithMap
*/
package proto3_proto
import proto "github.com/golang/protobuf/proto"
import testdata "github.com/golang/protobuf/proto/testdata"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
type Message_Humour int32
const (
Message_UNKNOWN Message_Humour = 0
Message_PUNS Message_Humour = 1
Message_SLAPSTICK Message_Humour = 2
Message_BILL_BAILEY Message_Humour = 3
)
var Message_Humour_name = map[int32]string{
0: "UNKNOWN",
1: "PUNS",
2: "SLAPSTICK",
3: "BILL_BAILEY",
}
var Message_Humour_value = map[string]int32{
"UNKNOWN": 0,
"PUNS": 1,
"SLAPSTICK": 2,
"BILL_BAILEY": 3,
}
func (x Message_Humour) String() string {
return proto.EnumName(Message_Humour_name, int32(x))
}
type Message struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"`
TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"`
Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"`
Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"`
Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *Message) Reset() { *m = Message{} }
func (m *Message) String() string { return proto.CompactTextString(m) }
func (*Message) ProtoMessage() {}
func (m *Message) GetNested() *Nested {
if m != nil {
return m.Nested
}
return nil
}
func (m *Message) GetTerrain() map[string]*Nested {
if m != nil {
return m.Terrain
}
return nil
}
func (m *Message) GetProto2Field() *testdata.SubDefaults {
if m != nil {
return m.Proto2Field
}
return nil
}
func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
if m != nil {
return m.Proto2Value
}
return nil
}
type Nested struct {
Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
}
func (m *Nested) Reset() { *m = Nested{} }
func (m *Nested) String() string { return proto.CompactTextString(m) }
func (*Nested) ProtoMessage() {}
type MessageWithMap struct {
ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
func (*MessageWithMap) ProtoMessage() {}
func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
if m != nil {
return m.ByteMapping
}
return nil
}
func init() {
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
}

View File

@ -1,68 +0,0 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2014 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
import "testdata/test.proto";
package proto3_proto;
message Message {
enum Humour {
UNKNOWN = 0;
PUNS = 1;
SLAPSTICK = 2;
BILL_BAILEY = 3;
}
string name = 1;
Humour hilarity = 2;
uint32 height_in_cm = 3;
bytes data = 4;
int64 result_count = 7;
bool true_scotsman = 8;
float score = 9;
repeated uint64 key = 5;
Nested nested = 6;
map<string, Nested> terrain = 10;
testdata.SubDefaults proto2_field = 11;
map<string, testdata.SubDefaults> proto2_value = 13;
}
message Nested {
string bunny = 1;
}
message MessageWithMap {
map<bool, bytes> byte_mapping = 1;
}

View File

@ -1,13 +0,0 @@
package jmespath
import "github.com/jmespath/go-jmespath"
// Fuzz will fuzz test the JMESPath parser.
func Fuzz(data []byte) int {
p := jmespath.NewParser()
_, err := p.Parse(string(data))
if err != nil {
return 1
}
return 0
}

View File

@ -1,6 +0,0 @@
# cpuid private
This is a specially converted of the cpuid package, so it can be included in
a package without exporting anything.
Package home: https://github.com/klauspost/cpuid

View File

@ -1,987 +0,0 @@
// Generated, DO NOT EDIT,
// but copy it to your own project and rename the package.
// See more at http://github.com/klauspost/cpuid
package cpuid
import (
"strings"
)
// Vendor is a representation of a CPU vendor.
type vendor int
const (
other vendor = iota
intel
amd
via
transmeta
nsc
kvm // Kernel-based Virtual Machine
msvm // Microsoft Hyper-V or Windows Virtual PC
vmware
xenhvm
)
const (
cmov = 1 << iota // i686 CMOV
nx // NX (No-Execute) bit
amd3dnow // AMD 3DNOW
amd3dnowext // AMD 3DNowExt
mmx // standard MMX
mmxext // SSE integer functions or AMD MMX ext
sse // SSE functions
sse2 // P4 SSE functions
sse3 // Prescott SSE3 functions
ssse3 // Conroe SSSE3 functions
sse4 // Penryn SSE4.1 functions
sse4a // AMD Barcelona microarchitecture SSE4a instructions
sse42 // Nehalem SSE4.2 functions
avx // AVX functions
avx2 // AVX2 functions
fma3 // Intel FMA 3
fma4 // Bulldozer FMA4 functions
xop // Bulldozer XOP functions
f16c // Half-precision floating-point conversion
bmi1 // Bit Manipulation Instruction Set 1
bmi2 // Bit Manipulation Instruction Set 2
tbm // AMD Trailing Bit Manipulation
lzcnt // LZCNT instruction
popcnt // POPCNT instruction
aesni // Advanced Encryption Standard New Instructions
clmul // Carry-less Multiplication
htt // Hyperthreading (enabled)
hle // Hardware Lock Elision
rtm // Restricted Transactional Memory
rdrand // RDRAND instruction is available
rdseed // RDSEED instruction is available
adx // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
sha // Intel SHA Extensions
avx512f // AVX-512 Foundation
avx512dq // AVX-512 Doubleword and Quadword Instructions
avx512ifma // AVX-512 Integer Fused Multiply-Add Instructions
avx512pf // AVX-512 Prefetch Instructions
avx512er // AVX-512 Exponential and Reciprocal Instructions
avx512cd // AVX-512 Conflict Detection Instructions
avx512bw // AVX-512 Byte and Word Instructions
avx512vl // AVX-512 Vector Length Extensions
avx512vbmi // AVX-512 Vector Bit Manipulation Instructions
mpx // Intel MPX (Memory Protection Extensions)
erms // Enhanced REP MOVSB/STOSB
rdtscp // RDTSCP Instruction
cx16 // CMPXCHG16B Instruction
// Performance indicators
sse2slow // SSE2 is supported, but usually not faster
sse3slow // SSE3 is supported, but usually not faster
atom // Atom processor, some SSSE3 instructions are slower
)
var flagNames = map[flags]string{
cmov: "CMOV", // i686 CMOV
nx: "NX", // NX (No-Execute) bit
amd3dnow: "AMD3DNOW", // AMD 3DNOW
amd3dnowext: "AMD3DNOWEXT", // AMD 3DNowExt
mmx: "MMX", // Standard MMX
mmxext: "MMXEXT", // SSE integer functions or AMD MMX ext
sse: "SSE", // SSE functions
sse2: "SSE2", // P4 SSE2 functions
sse3: "SSE3", // Prescott SSE3 functions
ssse3: "SSSE3", // Conroe SSSE3 functions
sse4: "SSE4.1", // Penryn SSE4.1 functions
sse4a: "SSE4A", // AMD Barcelona microarchitecture SSE4a instructions
sse42: "SSE4.2", // Nehalem SSE4.2 functions
avx: "AVX", // AVX functions
avx2: "AVX2", // AVX functions
fma3: "FMA3", // Intel FMA 3
fma4: "FMA4", // Bulldozer FMA4 functions
xop: "XOP", // Bulldozer XOP functions
f16c: "F16C", // Half-precision floating-point conversion
bmi1: "BMI1", // Bit Manipulation Instruction Set 1
bmi2: "BMI2", // Bit Manipulation Instruction Set 2
tbm: "TBM", // AMD Trailing Bit Manipulation
lzcnt: "LZCNT", // LZCNT instruction
popcnt: "POPCNT", // POPCNT instruction
aesni: "AESNI", // Advanced Encryption Standard New Instructions
clmul: "CLMUL", // Carry-less Multiplication
htt: "HTT", // Hyperthreading (enabled)
hle: "HLE", // Hardware Lock Elision
rtm: "RTM", // Restricted Transactional Memory
rdrand: "RDRAND", // RDRAND instruction is available
rdseed: "RDSEED", // RDSEED instruction is available
adx: "ADX", // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
sha: "SHA", // Intel SHA Extensions
avx512f: "AVX512F", // AVX-512 Foundation
avx512dq: "AVX512DQ", // AVX-512 Doubleword and Quadword Instructions
avx512ifma: "AVX512IFMA", // AVX-512 Integer Fused Multiply-Add Instructions
avx512pf: "AVX512PF", // AVX-512 Prefetch Instructions
avx512er: "AVX512ER", // AVX-512 Exponential and Reciprocal Instructions
avx512cd: "AVX512CD", // AVX-512 Conflict Detection Instructions
avx512bw: "AVX512BW", // AVX-512 Byte and Word Instructions
avx512vl: "AVX512VL", // AVX-512 Vector Length Extensions
avx512vbmi: "AVX512VBMI", // AVX-512 Vector Bit Manipulation Instructions
mpx: "MPX", // Intel MPX (Memory Protection Extensions)
erms: "ERMS", // Enhanced REP MOVSB/STOSB
rdtscp: "RDTSCP", // RDTSCP Instruction
cx16: "CX16", // CMPXCHG16B Instruction
// Performance indicators
sse2slow: "SSE2SLOW", // SSE2 supported, but usually not faster
sse3slow: "SSE3SLOW", // SSE3 supported, but usually not faster
atom: "ATOM", // Atom processor, some SSSE3 instructions are slower
}
// CPUInfo contains information about the detected system CPU.
type cpuInfo struct {
brandname string // Brand name reported by the CPU
vendorid vendor // Comparable CPU vendor ID
features flags // Features of the CPU
physicalcores int // Number of physical processor cores in your CPU. Will be 0 if undetectable.
threadspercore int // Number of threads per physical core. Will be 1 if undetectable.
logicalcores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable.
family int // CPU family number
model int // CPU model number
cacheline int // Cache line size in bytes. Will be 0 if undetectable.
cache struct {
l1i int // L1 Instruction Cache (per core or shared). Will be -1 if undetected
l1d int // L1 Data Cache (per core or shared). Will be -1 if undetected
l2 int // L2 Cache (per core or shared). Will be -1 if undetected
l3 int // L3 Instruction Cache (per core or shared). Will be -1 if undetected
}
maxFunc uint32
maxExFunc uint32
}
var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
var cpuidex func(op, op2 uint32) (eax, ebx, ecx, edx uint32)
var xgetbv func(index uint32) (eax, edx uint32)
var rdtscpAsm func() (eax, ebx, ecx, edx uint32)
// CPU contains information about the CPU as detected on startup,
// or when Detect last was called.
//
// Use this as the primary entry point to you data,
// this way queries are
var cpu cpuInfo
func init() {
initCPU()
detect()
}
// Detect will re-detect current CPU info.
// This will replace the content of the exported CPU variable.
//
// Unless you expect the CPU to change while you are running your program
// you should not need to call this function.
// If you call this, you must ensure that no other goroutine is accessing the
// exported CPU variable.
func detect() {
cpu.maxFunc = maxFunctionID()
cpu.maxExFunc = maxExtendedFunction()
cpu.brandname = brandName()
cpu.cacheline = cacheLine()
cpu.family, cpu.model = familyModel()
cpu.features = support()
cpu.threadspercore = threadsPerCore()
cpu.logicalcores = logicalCores()
cpu.physicalcores = physicalCores()
cpu.vendorid = vendorID()
cpu.cacheSize()
}
// Generated here: http://play.golang.org/p/BxFH2Gdc0G
// Cmov indicates support of CMOV instructions
func (c cpuInfo) cmov() bool {
return c.features&cmov != 0
}
// Amd3dnow indicates support of AMD 3DNOW! instructions
func (c cpuInfo) amd3dnow() bool {
return c.features&amd3dnow != 0
}
// Amd3dnowExt indicates support of AMD 3DNOW! Extended instructions
func (c cpuInfo) amd3dnowext() bool {
return c.features&amd3dnowext != 0
}
// MMX indicates support of MMX instructions
func (c cpuInfo) mmx() bool {
return c.features&mmx != 0
}
// MMXExt indicates support of MMXEXT instructions
// (SSE integer functions or AMD MMX ext)
func (c cpuInfo) mmxext() bool {
return c.features&mmxext != 0
}
// SSE indicates support of SSE instructions
func (c cpuInfo) sse() bool {
return c.features&sse != 0
}
// SSE2 indicates support of SSE 2 instructions
func (c cpuInfo) sse2() bool {
return c.features&sse2 != 0
}
// SSE3 indicates support of SSE 3 instructions
func (c cpuInfo) sse3() bool {
return c.features&sse3 != 0
}
// SSSE3 indicates support of SSSE 3 instructions
func (c cpuInfo) ssse3() bool {
return c.features&ssse3 != 0
}
// SSE4 indicates support of SSE 4 (also called SSE 4.1) instructions
func (c cpuInfo) sse4() bool {
return c.features&sse4 != 0
}
// SSE42 indicates support of SSE4.2 instructions
func (c cpuInfo) sse42() bool {
return c.features&sse42 != 0
}
// AVX indicates support of AVX instructions
// and operating system support of AVX instructions
func (c cpuInfo) avx() bool {
return c.features&avx != 0
}
// AVX2 indicates support of AVX2 instructions
func (c cpuInfo) avx2() bool {
return c.features&avx2 != 0
}
// FMA3 indicates support of FMA3 instructions
func (c cpuInfo) fma3() bool {
return c.features&fma3 != 0
}
// FMA4 indicates support of FMA4 instructions
func (c cpuInfo) fma4() bool {
return c.features&fma4 != 0
}
// XOP indicates support of XOP instructions
func (c cpuInfo) xop() bool {
return c.features&xop != 0
}
// F16C indicates support of F16C instructions
func (c cpuInfo) f16c() bool {
return c.features&f16c != 0
}
// BMI1 indicates support of BMI1 instructions
func (c cpuInfo) bmi1() bool {
return c.features&bmi1 != 0
}
// BMI2 indicates support of BMI2 instructions
func (c cpuInfo) bmi2() bool {
return c.features&bmi2 != 0
}
// TBM indicates support of TBM instructions
// (AMD Trailing Bit Manipulation)
func (c cpuInfo) tbm() bool {
return c.features&tbm != 0
}
// Lzcnt indicates support of LZCNT instruction
func (c cpuInfo) lzcnt() bool {
return c.features&lzcnt != 0
}
// Popcnt indicates support of POPCNT instruction
func (c cpuInfo) popcnt() bool {
return c.features&popcnt != 0
}
// HTT indicates the processor has Hyperthreading enabled
func (c cpuInfo) htt() bool {
return c.features&htt != 0
}
// SSE2Slow indicates that SSE2 may be slow on this processor
func (c cpuInfo) sse2slow() bool {
return c.features&sse2slow != 0
}
// SSE3Slow indicates that SSE3 may be slow on this processor
func (c cpuInfo) sse3slow() bool {
return c.features&sse3slow != 0
}
// AesNi indicates support of AES-NI instructions
// (Advanced Encryption Standard New Instructions)
func (c cpuInfo) aesni() bool {
return c.features&aesni != 0
}
// Clmul indicates support of CLMUL instructions
// (Carry-less Multiplication)
func (c cpuInfo) clmul() bool {
return c.features&clmul != 0
}
// NX indicates support of NX (No-Execute) bit
func (c cpuInfo) nx() bool {
return c.features&nx != 0
}
// SSE4A indicates support of AMD Barcelona microarchitecture SSE4a instructions
func (c cpuInfo) sse4a() bool {
return c.features&sse4a != 0
}
// HLE indicates support of Hardware Lock Elision
func (c cpuInfo) hle() bool {
return c.features&hle != 0
}
// RTM indicates support of Restricted Transactional Memory
func (c cpuInfo) rtm() bool {
return c.features&rtm != 0
}
// Rdrand indicates support of RDRAND instruction is available
func (c cpuInfo) rdrand() bool {
return c.features&rdrand != 0
}
// Rdseed indicates support of RDSEED instruction is available
func (c cpuInfo) rdseed() bool {
return c.features&rdseed != 0
}
// ADX indicates support of Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
func (c cpuInfo) adx() bool {
return c.features&adx != 0
}
// SHA indicates support of Intel SHA Extensions
func (c cpuInfo) sha() bool {
return c.features&sha != 0
}
// AVX512F indicates support of AVX-512 Foundation
func (c cpuInfo) avx512f() bool {
return c.features&avx512f != 0
}
// AVX512DQ indicates support of AVX-512 Doubleword and Quadword Instructions
func (c cpuInfo) avx512dq() bool {
return c.features&avx512dq != 0
}
// AVX512IFMA indicates support of AVX-512 Integer Fused Multiply-Add Instructions
func (c cpuInfo) avx512ifma() bool {
return c.features&avx512ifma != 0
}
// AVX512PF indicates support of AVX-512 Prefetch Instructions
func (c cpuInfo) avx512pf() bool {
return c.features&avx512pf != 0
}
// AVX512ER indicates support of AVX-512 Exponential and Reciprocal Instructions
func (c cpuInfo) avx512er() bool {
return c.features&avx512er != 0
}
// AVX512CD indicates support of AVX-512 Conflict Detection Instructions
func (c cpuInfo) avx512cd() bool {
return c.features&avx512cd != 0
}
// AVX512BW indicates support of AVX-512 Byte and Word Instructions
func (c cpuInfo) avx512bw() bool {
return c.features&avx512bw != 0
}
// AVX512VL indicates support of AVX-512 Vector Length Extensions
func (c cpuInfo) avx512vl() bool {
return c.features&avx512vl != 0
}
// AVX512VBMI indicates support of AVX-512 Vector Bit Manipulation Instructions
func (c cpuInfo) avx512vbmi() bool {
return c.features&avx512vbmi != 0
}
// MPX indicates support of Intel MPX (Memory Protection Extensions)
func (c cpuInfo) mpx() bool {
return c.features&mpx != 0
}
// ERMS indicates support of Enhanced REP MOVSB/STOSB
func (c cpuInfo) erms() bool {
return c.features&erms != 0
}
func (c cpuInfo) rdtscp() bool {
return c.features&rdtscp != 0
}
func (c cpuInfo) cx16() bool {
return c.features&cx16 != 0
}
// Atom indicates an Atom processor
func (c cpuInfo) atom() bool {
return c.features&atom != 0
}
// Intel returns true if vendor is recognized as Intel
func (c cpuInfo) intel() bool {
return c.vendorid == intel
}
// AMD returns true if vendor is recognized as AMD
func (c cpuInfo) amd() bool {
return c.vendorid == amd
}
// Transmeta returns true if vendor is recognized as Transmeta
func (c cpuInfo) transmeta() bool {
return c.vendorid == transmeta
}
// NSC returns true if vendor is recognized as National Semiconductor
func (c cpuInfo) nsc() bool {
return c.vendorid == nsc
}
// VIA returns true if vendor is recognized as VIA
func (c cpuInfo) via() bool {
return c.vendorid == via
}
// RTCounter returns the 64-bit time-stamp counter
// Uses the RDTSCP instruction. The value 0 is returned
// if the CPU does not support the instruction.
func (c cpuInfo) rtcounter() uint64 {
if !c.rdtscp() {
return 0
}
a, _, _, d := rdtscpAsm()
return uint64(a) | (uint64(d) << 32)
}
// Ia32TscAux returns the IA32_TSC_AUX part of the RDTSCP.
// This variable is OS dependent, but on Linux contains information
// about the current cpu/core the code is running on.
// If the RDTSCP instruction isn't supported on the CPU, the value 0 is returned.
func (c cpuInfo) ia32tscaux() uint32 {
if !c.rdtscp() {
return 0
}
_, _, ecx, _ := rdtscpAsm()
return ecx
}
// LogicalCPU will return the Logical CPU the code is currently executing on.
// This is likely to change when the OS re-schedules the running thread
// to another CPU.
// If the current core cannot be detected, -1 will be returned.
func (c cpuInfo) logicalcpu() int {
if c.maxFunc < 1 {
return -1
}
_, ebx, _, _ := cpuid(1)
return int(ebx >> 24)
}
// VM Will return true if the cpu id indicates we are in
// a virtual machine. This is only a hint, and will very likely
// have many false negatives.
func (c cpuInfo) vm() bool {
switch c.vendorid {
case msvm, kvm, vmware, xenhvm:
return true
}
return false
}
// Flags contains detected cpu features and caracteristics
type flags uint64
// String returns a string representation of the detected
// CPU features.
func (f flags) String() string {
return strings.Join(f.strings(), ",")
}
// Strings returns and array of the detected features.
func (f flags) strings() []string {
s := support()
r := make([]string, 0, 20)
for i := uint(0); i < 64; i++ {
key := flags(1 << i)
val := flagNames[key]
if s&key != 0 {
r = append(r, val)
}
}
return r
}
func maxExtendedFunction() uint32 {
eax, _, _, _ := cpuid(0x80000000)
return eax
}
func maxFunctionID() uint32 {
a, _, _, _ := cpuid(0)
return a
}
func brandName() string {
if maxExtendedFunction() >= 0x80000004 {
v := make([]uint32, 0, 48)
for i := uint32(0); i < 3; i++ {
a, b, c, d := cpuid(0x80000002 + i)
v = append(v, a, b, c, d)
}
return strings.Trim(string(valAsString(v...)), " ")
}
return "unknown"
}
func threadsPerCore() int {
mfi := maxFunctionID()
if mfi < 0x4 || vendorID() != intel {
return 1
}
if mfi < 0xb {
_, b, _, d := cpuid(1)
if (d & (1 << 28)) != 0 {
// v will contain logical core count
v := (b >> 16) & 255
if v > 1 {
a4, _, _, _ := cpuid(4)
// physical cores
v2 := (a4 >> 26) + 1
if v2 > 0 {
return int(v) / int(v2)
}
}
}
return 1
}
_, b, _, _ := cpuidex(0xb, 0)
if b&0xffff == 0 {
return 1
}
return int(b & 0xffff)
}
func logicalCores() int {
mfi := maxFunctionID()
switch vendorID() {
case intel:
// Use this on old Intel processors
if mfi < 0xb {
if mfi < 1 {
return 0
}
// CPUID.1:EBX[23:16] represents the maximum number of addressable IDs (initial APIC ID)
// that can be assigned to logical processors in a physical package.
// The value may not be the same as the number of logical processors that are present in the hardware of a physical package.
_, ebx, _, _ := cpuid(1)
logical := (ebx >> 16) & 0xff
return int(logical)
}
_, b, _, _ := cpuidex(0xb, 1)
return int(b & 0xffff)
case amd:
_, b, _, _ := cpuid(1)
return int((b >> 16) & 0xff)
default:
return 0
}
}
func familyModel() (int, int) {
if maxFunctionID() < 0x1 {
return 0, 0
}
eax, _, _, _ := cpuid(1)
family := ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff)
model := ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0)
return int(family), int(model)
}
func physicalCores() int {
switch vendorID() {
case intel:
return logicalCores() / threadsPerCore()
case amd:
if maxExtendedFunction() >= 0x80000008 {
_, _, c, _ := cpuid(0x80000008)
return int(c&0xff) + 1
}
}
return 0
}
// Except from http://en.wikipedia.org/wiki/CPUID#EAX.3D0:_Get_vendor_ID
var vendorMapping = map[string]vendor{
"AMDisbetter!": amd,
"AuthenticAMD": amd,
"CentaurHauls": via,
"GenuineIntel": intel,
"TransmetaCPU": transmeta,
"GenuineTMx86": transmeta,
"Geode by NSC": nsc,
"VIA VIA VIA ": via,
"KVMKVMKVMKVM": kvm,
"Microsoft Hv": msvm,
"VMwareVMware": vmware,
"XenVMMXenVMM": xenhvm,
}
func vendorID() vendor {
_, b, c, d := cpuid(0)
v := valAsString(b, d, c)
vend, ok := vendorMapping[string(v)]
if !ok {
return other
}
return vend
}
func cacheLine() int {
if maxFunctionID() < 0x1 {
return 0
}
_, ebx, _, _ := cpuid(1)
cache := (ebx & 0xff00) >> 5 // cflush size
if cache == 0 && maxExtendedFunction() >= 0x80000006 {
_, _, ecx, _ := cpuid(0x80000006)
cache = ecx & 0xff // cacheline size
}
// TODO: Read from Cache and TLB Information
return int(cache)
}
func (c *cpuInfo) cacheSize() {
c.cache.l1d = -1
c.cache.l1i = -1
c.cache.l2 = -1
c.cache.l3 = -1
vendor := vendorID()
switch vendor {
case intel:
if maxFunctionID() < 4 {
return
}
for i := uint32(0); ; i++ {
eax, ebx, ecx, _ := cpuidex(4, i)
cacheType := eax & 15
if cacheType == 0 {
break
}
cacheLevel := (eax >> 5) & 7
coherency := int(ebx&0xfff) + 1
partitions := int((ebx>>12)&0x3ff) + 1
associativity := int((ebx>>22)&0x3ff) + 1
sets := int(ecx) + 1
size := associativity * partitions * coherency * sets
switch cacheLevel {
case 1:
if cacheType == 1 {
// 1 = Data Cache
c.cache.l1d = size
} else if cacheType == 2 {
// 2 = Instruction Cache
c.cache.l1i = size
} else {
if c.cache.l1d < 0 {
c.cache.l1i = size
}
if c.cache.l1i < 0 {
c.cache.l1i = size
}
}
case 2:
c.cache.l2 = size
case 3:
c.cache.l3 = size
}
}
case amd:
// Untested.
if maxExtendedFunction() < 0x80000005 {
return
}
_, _, ecx, edx := cpuid(0x80000005)
c.cache.l1d = int(((ecx >> 24) & 0xFF) * 1024)
c.cache.l1i = int(((edx >> 24) & 0xFF) * 1024)
if maxExtendedFunction() < 0x80000006 {
return
}
_, _, ecx, _ = cpuid(0x80000006)
c.cache.l2 = int(((ecx >> 16) & 0xFFFF) * 1024)
}
return
}
func support() flags {
mfi := maxFunctionID()
vend := vendorID()
if mfi < 0x1 {
return 0
}
rval := uint64(0)
_, _, c, d := cpuid(1)
if (d & (1 << 15)) != 0 {
rval |= cmov
}
if (d & (1 << 23)) != 0 {
rval |= mmx
}
if (d & (1 << 25)) != 0 {
rval |= mmxext
}
if (d & (1 << 25)) != 0 {
rval |= sse
}
if (d & (1 << 26)) != 0 {
rval |= sse2
}
if (c & 1) != 0 {
rval |= sse3
}
if (c & 0x00000200) != 0 {
rval |= ssse3
}
if (c & 0x00080000) != 0 {
rval |= sse4
}
if (c & 0x00100000) != 0 {
rval |= sse42
}
if (c & (1 << 25)) != 0 {
rval |= aesni
}
if (c & (1 << 1)) != 0 {
rval |= clmul
}
if c&(1<<23) != 0 {
rval |= popcnt
}
if c&(1<<30) != 0 {
rval |= rdrand
}
if c&(1<<29) != 0 {
rval |= f16c
}
if c&(1<<13) != 0 {
rval |= cx16
}
if vend == intel && (d&(1<<28)) != 0 && mfi >= 4 {
if threadsPerCore() > 1 {
rval |= htt
}
}
// Check XGETBV, OXSAVE and AVX bits
if c&(1<<26) != 0 && c&(1<<27) != 0 && c&(1<<28) != 0 {
// Check for OS support
eax, _ := xgetbv(0)
if (eax & 0x6) == 0x6 {
rval |= avx
if (c & 0x00001000) != 0 {
rval |= fma3
}
}
}
// Check AVX2, AVX2 requires OS support, but BMI1/2 don't.
if mfi >= 7 {
_, ebx, ecx, _ := cpuidex(7, 0)
if (rval&avx) != 0 && (ebx&0x00000020) != 0 {
rval |= avx2
}
if (ebx & 0x00000008) != 0 {
rval |= bmi1
if (ebx & 0x00000100) != 0 {
rval |= bmi2
}
}
if ebx&(1<<4) != 0 {
rval |= hle
}
if ebx&(1<<9) != 0 {
rval |= erms
}
if ebx&(1<<11) != 0 {
rval |= rtm
}
if ebx&(1<<14) != 0 {
rval |= mpx
}
if ebx&(1<<18) != 0 {
rval |= rdseed
}
if ebx&(1<<19) != 0 {
rval |= adx
}
if ebx&(1<<29) != 0 {
rval |= sha
}
// Only detect AVX-512 features if XGETBV is supported
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
// Check for OS support
eax, _ := xgetbv(0)
// Verify that XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 and
// ZMM16-ZMM31 state are enabled by OS)
/// and that XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS).
if (eax>>5)&7 == 7 && (eax>>1)&3 == 3 {
if ebx&(1<<16) != 0 {
rval |= avx512f
}
if ebx&(1<<17) != 0 {
rval |= avx512dq
}
if ebx&(1<<21) != 0 {
rval |= avx512ifma
}
if ebx&(1<<26) != 0 {
rval |= avx512pf
}
if ebx&(1<<27) != 0 {
rval |= avx512er
}
if ebx&(1<<28) != 0 {
rval |= avx512cd
}
if ebx&(1<<30) != 0 {
rval |= avx512bw
}
if ebx&(1<<31) != 0 {
rval |= avx512vl
}
// ecx
if ecx&(1<<1) != 0 {
rval |= avx512vbmi
}
}
}
}
if maxExtendedFunction() >= 0x80000001 {
_, _, c, d := cpuid(0x80000001)
if (c & (1 << 5)) != 0 {
rval |= lzcnt
rval |= popcnt
}
if (d & (1 << 31)) != 0 {
rval |= amd3dnow
}
if (d & (1 << 30)) != 0 {
rval |= amd3dnowext
}
if (d & (1 << 23)) != 0 {
rval |= mmx
}
if (d & (1 << 22)) != 0 {
rval |= mmxext
}
if (c & (1 << 6)) != 0 {
rval |= sse4a
}
if d&(1<<20) != 0 {
rval |= nx
}
if d&(1<<27) != 0 {
rval |= rdtscp
}
/* Allow for selectively disabling SSE2 functions on AMD processors
with SSE2 support but not SSE4a. This includes Athlon64, some
Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster
than SSE2 often enough to utilize this special-case flag.
AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case
so that SSE2 is used unless explicitly disabled by checking
AV_CPU_FLAG_SSE2SLOW. */
if vendorID() != intel &&
rval&sse2 != 0 && (c&0x00000040) == 0 {
rval |= sse2slow
}
/* XOP and FMA4 use the AVX instruction coding scheme, so they can't be
* used unless the OS has AVX support. */
if (rval & avx) != 0 {
if (c & 0x00000800) != 0 {
rval |= xop
}
if (c & 0x00010000) != 0 {
rval |= fma4
}
}
if vendorID() == intel {
family, model := familyModel()
if family == 6 && (model == 9 || model == 13 || model == 14) {
/* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and
* 6/14 (core1 "yonah") theoretically support sse2, but it's
* usually slower than mmx. */
if (rval & sse2) != 0 {
rval |= sse2slow
}
if (rval & sse3) != 0 {
rval |= sse3slow
}
}
/* The Atom processor has SSSE3 support, which is useful in many cases,
* but sometimes the SSSE3 version is slower than the SSE2 equivalent
* on the Atom, but is generally faster on other processors supporting
* SSSE3. This flag allows for selectively disabling certain SSSE3
* functions on the Atom. */
if family == 6 && model == 28 {
rval |= atom
}
}
}
return flags(rval)
}
func valAsString(values ...uint32) []byte {
r := make([]byte, 4*len(values))
for i, v := range values {
dst := r[i*4:]
dst[0] = byte(v & 0xff)
dst[1] = byte((v >> 8) & 0xff)
dst[2] = byte((v >> 16) & 0xff)
dst[3] = byte((v >> 24) & 0xff)
switch {
case dst[0] == 0:
return r[:i*4]
case dst[1] == 0:
return r[:i*4+1]
case dst[2] == 0:
return r[:i*4+2]
case dst[3] == 0:
return r[:i*4+3]
}
}
return r
}

View File

@ -1,40 +0,0 @@
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
// func asmCpuid(op uint32) (eax, ebx, ecx, edx uint32)
TEXT ·asmCpuid(SB), 7, $0
XORL CX, CX
MOVL op+0(FP), AX
CPUID
MOVL AX, eax+4(FP)
MOVL BX, ebx+8(FP)
MOVL CX, ecx+12(FP)
MOVL DX, edx+16(FP)
RET
// func asmCpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
TEXT ·asmCpuidex(SB), 7, $0
MOVL op+0(FP), AX
MOVL op2+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func xgetbv(index uint32) (eax, edx uint32)
TEXT ·asmXgetbv(SB), 7, $0
MOVL index+0(FP), CX
BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV
MOVL AX, eax+4(FP)
MOVL DX, edx+8(FP)
RET
// func asmRdtscpAsm() (eax, ebx, ecx, edx uint32)
TEXT ·asmRdtscpAsm(SB), 7, $0
BYTE $0x0F; BYTE $0x01; BYTE $0xF9 // RDTSCP
MOVL AX, eax+0(FP)
MOVL BX, ebx+4(FP)
MOVL CX, ecx+8(FP)
MOVL DX, edx+12(FP)
RET

View File

@ -1,40 +0,0 @@
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
// func asmCpuid(op uint32) (eax, ebx, ecx, edx uint32)
TEXT ·asmCpuid(SB), 7, $0
XORQ CX, CX
MOVL op+0(FP), AX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func asmCpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
TEXT ·asmCpuidex(SB), 7, $0
MOVL op+0(FP), AX
MOVL op2+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func asmXgetbv(index uint32) (eax, edx uint32)
TEXT ·asmXgetbv(SB), 7, $0
MOVL index+0(FP), CX
BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV
MOVL AX, eax+8(FP)
MOVL DX, edx+12(FP)
RET
// func asmRdtscpAsm() (eax, ebx, ecx, edx uint32)
TEXT ·asmRdtscpAsm(SB), 7, $0
BYTE $0x0F; BYTE $0x01; BYTE $0xF9 // RDTSCP
MOVL AX, eax+0(FP)
MOVL BX, ebx+4(FP)
MOVL CX, ecx+8(FP)
MOVL DX, edx+12(FP)
RET

View File

@ -1,17 +0,0 @@
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
// +build 386 amd64
package cpuid
func asmCpuid(op uint32) (eax, ebx, ecx, edx uint32)
func asmCpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
func asmXgetbv(index uint32) (eax, edx uint32)
func asmRdtscpAsm() (eax, ebx, ecx, edx uint32)
func initCPU() {
cpuid = asmCpuid
cpuidex = asmCpuidex
xgetbv = asmXgetbv
rdtscpAsm = asmRdtscpAsm
}

View File

@ -1,23 +0,0 @@
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
// +build !amd64,!386
package cpuid
func initCPU() {
cpuid = func(op uint32) (eax, ebx, ecx, edx uint32) {
return 0, 0, 0, 0
}
cpuidex = func(op, op2 uint32) (eax, ebx, ecx, edx uint32) {
return 0, 0, 0, 0
}
xgetbv = func(index uint32) (eax, edx uint32) {
return 0, 0
}
rdtscpAsm = func() (eax, ebx, ecx, edx uint32) {
return 0, 0, 0, 0
}
}

Binary file not shown.

View File

@ -1,45 +0,0 @@
package lz4
import (
"bytes"
"io/ioutil"
"github.com/pierrec/lz4"
)
// lz4.Reader fuzz function
func Fuzz(data []byte) int {
// uncompress some data
d, err := ioutil.ReadAll(lz4.NewReader(bytes.NewReader(data)))
if err != nil {
return 0
}
// got valid compressed data
// compress the uncompressed data
// and compare with the original input
buf := bytes.NewBuffer(nil)
zw := lz4.NewWriter(buf)
n, err := zw.Write(d)
if err != nil {
panic(err)
}
if n != len(d) {
panic("short write")
}
err = zw.Close()
if err != nil {
panic(err)
}
// uncompress the newly compressed data
ud, err := ioutil.ReadAll(lz4.NewReader(buf))
if err != nil {
panic(err)
}
if bytes.Compare(d, ud) != 0 {
panic("not equal")
}
return 1
}

View File

@ -1,3 +0,0 @@
// The v2 package contains acceptance tests for the Openstack Compute V2 service.
package v2

View File

@ -1,70 +0,0 @@
// +build acceptance db
package v1
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack"
"github.com/rackspace/gophercloud/openstack/db/v1/instances"
th "github.com/rackspace/gophercloud/testhelper"
)
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := openstack.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := openstack.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := openstack.NewDBV1(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
th.AssertNoErr(t, err)
return c
}
type context struct {
test *testing.T
client *gophercloud.ServiceClient
instanceID string
DBIDs []string
users []string
}
func newContext(t *testing.T) context {
return context{
test: t,
client: newClient(t),
}
}
func (c context) Logf(msg string, args ...interface{}) {
if len(args) > 0 {
c.test.Logf(msg, args...)
} else {
c.test.Log(msg)
}
}
func (c context) AssertNoErr(err error) {
th.AssertNoErr(c.test, err)
}
func (c context) WaitUntilActive(id string) {
err := gophercloud.WaitFor(60, func() (bool, error) {
inst, err := instances.Get(c.client, id).Extract()
if err != nil {
return false, err
}
if inst.Status == "ACTIVE" {
return true, nil
}
return false, nil
})
c.AssertNoErr(err)
}

View File

@ -1 +0,0 @@
package v1

View File

@ -1 +0,0 @@
package v2

View File

@ -1 +0,0 @@
package v3

View File

@ -1,39 +0,0 @@
package v2
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack"
th "github.com/rackspace/gophercloud/testhelper"
)
var Client *gophercloud.ServiceClient
func NewClient() (*gophercloud.ServiceClient, error) {
opts, err := openstack.AuthOptionsFromEnv()
if err != nil {
return nil, err
}
provider, err := openstack.AuthenticatedClient(opts)
if err != nil {
return nil, err
}
return openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
Name: "neutron",
Region: os.Getenv("OS_REGION_NAME"),
})
}
func Setup(t *testing.T) {
client, err := NewClient()
th.AssertNoErr(t, err)
Client = client
}
func Teardown() {
Client = nil
}

View File

@ -1,78 +0,0 @@
package lbaas
import (
"testing"
base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2"
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors"
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools"
"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
"github.com/rackspace/gophercloud/openstack/networking/v2/subnets"
th "github.com/rackspace/gophercloud/testhelper"
)
func SetupTopology(t *testing.T) (string, string) {
// create network
n, err := networks.Create(base.Client, networks.CreateOpts{Name: "tmp_network"}).Extract()
th.AssertNoErr(t, err)
t.Logf("Created network %s", n.ID)
// create subnet
s, err := subnets.Create(base.Client, subnets.CreateOpts{
NetworkID: n.ID,
CIDR: "192.168.199.0/24",
IPVersion: subnets.IPv4,
Name: "tmp_subnet",
}).Extract()
th.AssertNoErr(t, err)
t.Logf("Created subnet %s", s.ID)
return n.ID, s.ID
}
func DeleteTopology(t *testing.T, networkID string) {
res := networks.Delete(base.Client, networkID)
th.AssertNoErr(t, res.Err)
t.Logf("Deleted network %s", networkID)
}
func CreatePool(t *testing.T, subnetID string) string {
p, err := pools.Create(base.Client, pools.CreateOpts{
LBMethod: pools.LBMethodRoundRobin,
Protocol: "HTTP",
Name: "tmp_pool",
SubnetID: subnetID,
}).Extract()
th.AssertNoErr(t, err)
t.Logf("Created pool %s", p.ID)
return p.ID
}
func DeletePool(t *testing.T, poolID string) {
res := pools.Delete(base.Client, poolID)
th.AssertNoErr(t, res.Err)
t.Logf("Deleted pool %s", poolID)
}
func CreateMonitor(t *testing.T) string {
m, err := monitors.Create(base.Client, monitors.CreateOpts{
Delay: 10,
Timeout: 10,
MaxRetries: 3,
Type: monitors.TypeHTTP,
ExpectedCodes: "200",
URLPath: "/login",
HTTPMethod: "GET",
}).Extract()
th.AssertNoErr(t, err)
t.Logf("Created monitor ID [%s]", m.ID)
return m.ID
}

View File

@ -1 +0,0 @@
package extensions

View File

@ -1 +0,0 @@
package v2

View File

@ -1,28 +0,0 @@
// +build acceptance
package v1
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack"
th "github.com/rackspace/gophercloud/testhelper"
)
var metadata = map[string]string{"gopher": "cloud"}
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := openstack.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := openstack.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
th.AssertNoErr(t, err)
return c
}

View File

@ -1,44 +0,0 @@
// +build acceptance
package v1
import (
"fmt"
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack"
th "github.com/rackspace/gophercloud/testhelper"
)
var template = fmt.Sprintf(`
{
"heat_template_version": "2013-05-23",
"description": "Simple template to test heat commands",
"parameters": {},
"resources": {
"hello_world": {
"type":"OS::Nova::Server",
"properties": {
"flavor": "%s",
"image": "%s",
"user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
}
}
}
}`, os.Getenv("OS_FLAVOR_ID"), os.Getenv("OS_IMAGE_ID"))
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := openstack.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := openstack.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := openstack.NewOrchestrationV1(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
th.AssertNoErr(t, err)
return c
}

View File

@ -1,13 +0,0 @@
{
"heat_template_version": "2013-05-23",
"resources": {
"compute_instance": {
"type": "OS::Nova::Server",
"properties": {
"flavor": "m1.small",
"image": "cirros-0.3.2-x86_64-disk",
"name": "Single Compute Instance"
}
}
}
}

View File

@ -1,4 +0,0 @@
// +build acceptance
package openstack

View File

@ -1,38 +0,0 @@
// +build acceptance
package v1
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
func newClient() (*gophercloud.ServiceClient, error) {
opts, err := rackspace.AuthOptionsFromEnv()
if err != nil {
return nil, err
}
opts = tools.OnlyRS(opts)
region := os.Getenv("RS_REGION")
provider, err := rackspace.AuthenticatedClient(opts)
if err != nil {
return nil, err
}
return rackspace.NewBlockStorageV1(provider, gophercloud.EndpointOpts{
Region: region,
})
}
func setup(t *testing.T) *gophercloud.ServiceClient {
client, err := newClient()
th.AssertNoErr(t, err)
return client
}

View File

@ -1,23 +0,0 @@
// +build acceptance
package v1
import (
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := rackspace.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := rackspace.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := rackspace.NewCDNV1(client, gophercloud.EndpointOpts{})
th.AssertNoErr(t, err)
return c
}

View File

@ -1 +0,0 @@
package v2

View File

@ -1,73 +0,0 @@
// +build acceptance db rackspace
package v1
import (
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/rackspace"
"github.com/rackspace/gophercloud/rackspace/db/v1/instances"
th "github.com/rackspace/gophercloud/testhelper"
)
func newClient(t *testing.T) *gophercloud.ServiceClient {
opts, err := rackspace.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
opts = tools.OnlyRS(opts)
client, err := rackspace.AuthenticatedClient(opts)
th.AssertNoErr(t, err)
c, err := rackspace.NewDBV1(client, gophercloud.EndpointOpts{
Region: "IAD",
})
th.AssertNoErr(t, err)
return c
}
type context struct {
test *testing.T
client *gophercloud.ServiceClient
instanceID string
DBIDs []string
replicaID string
backupID string
configGroupID string
users []string
}
func newContext(t *testing.T) context {
return context{
test: t,
client: newClient(t),
}
}
func (c context) Logf(msg string, args ...interface{}) {
if len(args) > 0 {
c.test.Logf(msg, args...)
} else {
c.test.Log(msg)
}
}
func (c context) AssertNoErr(err error) {
th.AssertNoErr(c.test, err)
}
func (c context) WaitUntilActive(id string) {
err := gophercloud.WaitFor(60, func() (bool, error) {
inst, err := instances.Get(c.client, id).Extract()
if err != nil {
return false, err
}
if inst.Status == "ACTIVE" {
return true, nil
}
return false, nil
})
c.AssertNoErr(err)
}

View File

@ -1 +0,0 @@
package v1

View File

@ -1 +0,0 @@
package v2

View File

@ -1,62 +0,0 @@
// +build acceptance lbs
package v1
import (
"os"
"strconv"
"strings"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
func newProvider() (*gophercloud.ProviderClient, error) {
opts, err := rackspace.AuthOptionsFromEnv()
if err != nil {
return nil, err
}
opts = tools.OnlyRS(opts)
return rackspace.AuthenticatedClient(opts)
}
func newClient() (*gophercloud.ServiceClient, error) {
provider, err := newProvider()
if err != nil {
return nil, err
}
return rackspace.NewLBV1(provider, gophercloud.EndpointOpts{
Region: os.Getenv("RS_REGION"),
})
}
func newComputeClient() (*gophercloud.ServiceClient, error) {
provider, err := newProvider()
if err != nil {
return nil, err
}
return rackspace.NewComputeV2(provider, gophercloud.EndpointOpts{
Region: os.Getenv("RS_REGION"),
})
}
func setup(t *testing.T) *gophercloud.ServiceClient {
client, err := newClient()
th.AssertNoErr(t, err)
return client
}
func intsToStr(ids []int) string {
strIDs := []string{}
for _, id := range ids {
strIDs = append(strIDs, strconv.Itoa(id))
}
return strings.Join(strIDs, ", ")
}

View File

@ -1,39 +0,0 @@
package v2
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
var Client *gophercloud.ServiceClient
func NewClient() (*gophercloud.ServiceClient, error) {
opts, err := rackspace.AuthOptionsFromEnv()
if err != nil {
return nil, err
}
provider, err := rackspace.AuthenticatedClient(opts)
if err != nil {
return nil, err
}
return rackspace.NewNetworkV2(provider, gophercloud.EndpointOpts{
Name: "cloudNetworks",
Region: os.Getenv("RS_REGION"),
})
}
func Setup(t *testing.T) {
client, err := NewClient()
th.AssertNoErr(t, err)
Client = client
}
func Teardown() {
Client = nil
}

View File

@ -1,54 +0,0 @@
// +build acceptance rackspace objectstorage v1
package v1
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
"github.com/rackspace/gophercloud/rackspace"
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, cdn bool) (*gophercloud.ServiceClient, error) {
region := os.Getenv("RS_REGION")
if region == "" {
t.Fatal("Please provide a Rackspace region as RS_REGION")
}
ao := rackspaceAuthOptions(t)
provider, err := rackspace.NewClient(ao.IdentityEndpoint)
th.AssertNoErr(t, err)
err = rackspace.Authenticate(provider, ao)
th.AssertNoErr(t, err)
if cdn {
return rackspace.NewObjectCDNV1(provider, gophercloud.EndpointOpts{
Region: region,
})
}
return rackspace.NewObjectStorageV1(provider, gophercloud.EndpointOpts{
Region: region,
})
}

View File

@ -1,45 +0,0 @@
// +build acceptance
package v1
import (
"fmt"
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
var template = fmt.Sprintf(`
{
"heat_template_version": "2013-05-23",
"description": "Simple template to test heat commands",
"parameters": {},
"resources": {
"hello_world": {
"type":"OS::Nova::Server",
"properties": {
"flavor": "%s",
"image": "%s",
"user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
}
}
}
}
`, os.Getenv("RS_FLAVOR_ID"), os.Getenv("RS_IMAGE_ID"))
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := rackspace.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := rackspace.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := rackspace.NewOrchestrationV1(client, gophercloud.EndpointOpts{
Region: os.Getenv("RS_REGION_NAME"),
})
th.AssertNoErr(t, err)
return c
}

View File

@ -1 +0,0 @@
package rackspace

View File

@ -1,26 +0,0 @@
// +build acceptance
package v3
import (
"os"
"testing"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/rackspace"
th "github.com/rackspace/gophercloud/testhelper"
)
func newClient(t *testing.T) *gophercloud.ServiceClient {
ao, err := rackspace.AuthOptionsFromEnv()
th.AssertNoErr(t, err)
client, err := rackspace.AuthenticatedClient(ao)
th.AssertNoErr(t, err)
c, err := rackspace.NewRackConnectV3(client, gophercloud.EndpointOpts{
Region: os.Getenv("RS_REGION_NAME"),
})
th.AssertNoErr(t, err)
return c
}

View File

@ -1 +0,0 @@
package tools

View File

@ -1,89 +0,0 @@
// +build acceptance common
package tools
import (
"crypto/rand"
"errors"
mrand "math/rand"
"os"
"time"
"github.com/rackspace/gophercloud"
)
// ErrTimeout is returned if WaitFor takes longer than 300 second to happen.
var ErrTimeout = errors.New("Timed out")
// OnlyRS overrides the default Gophercloud behavior of using OS_-prefixed environment variables
// if RS_ variables aren't present. Otherwise, they'll stomp over each other here in the acceptance
// tests, where you need to have both defined.
func OnlyRS(original gophercloud.AuthOptions) gophercloud.AuthOptions {
if os.Getenv("RS_AUTH_URL") == "" {
original.IdentityEndpoint = ""
}
if os.Getenv("RS_USERNAME") == "" {
original.Username = ""
}
if os.Getenv("RS_PASSWORD") == "" {
original.Password = ""
}
if os.Getenv("RS_API_KEY") == "" {
original.APIKey = ""
}
return original
}
// WaitFor polls a predicate function once per second to wait for a certain state to arrive.
func WaitFor(predicate func() (bool, error)) error {
for i := 0; i < 300; i++ {
time.Sleep(1 * time.Second)
satisfied, err := predicate()
if err != nil {
return err
}
if satisfied {
return nil
}
}
return ErrTimeout
}
// MakeNewPassword generates a new string that's guaranteed to be different than the given one.
func MakeNewPassword(oldPass string) string {
randomPassword := RandomString("", 16)
for randomPassword == oldPass {
randomPassword = RandomString("", 16)
}
return randomPassword
}
// RandomString generates a string of given length, but random content.
// All content will be within the ASCII graphic character set.
// (Implementation from Even Shaw's contribution on
// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
func RandomString(prefix string, n int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return prefix + string(bytes)
}
// RandomInt will return a random integer between a specified range.
func RandomInt(min, max int) int {
mrand.Seed(time.Now().Unix())
return mrand.Intn(max-min) + min
}
// Elide returns the first bit of its input string with a suffix of "..." if it's longer than
// a comfortable 40 characters.
func Elide(value string) string {
if len(value) > 40 {
return value[0:37] + "..."
}
return value
}

View File

@ -1,57 +0,0 @@
package rackspace
import (
"fmt"
"os"
"github.com/rackspace/gophercloud"
)
var nilOptions = gophercloud.AuthOptions{}
// ErrNoAuthUrl, ErrNoUsername, and ErrNoPassword errors indicate of the
// required RS_AUTH_URL, RS_USERNAME, or RS_PASSWORD environment variables,
// respectively, remain undefined. See the AuthOptions() function for more details.
var (
ErrNoAuthURL = fmt.Errorf("Environment variable RS_AUTH_URL or OS_AUTH_URL need to be set.")
ErrNoUsername = fmt.Errorf("Environment variable RS_USERNAME or OS_USERNAME need to be set.")
ErrNoPassword = fmt.Errorf("Environment variable RS_API_KEY or RS_PASSWORD needs to be set.")
)
func prefixedEnv(base string) string {
value := os.Getenv("RS_" + base)
if value == "" {
value = os.Getenv("OS_" + base)
}
return value
}
// AuthOptionsFromEnv fills out an identity.AuthOptions structure with the
// settings found on the various Rackspace RS_* environment variables.
func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
authURL := prefixedEnv("AUTH_URL")
username := prefixedEnv("USERNAME")
password := prefixedEnv("PASSWORD")
apiKey := prefixedEnv("API_KEY")
if authURL == "" {
return nilOptions, ErrNoAuthURL
}
if username == "" {
return nilOptions, ErrNoUsername
}
if password == "" && apiKey == "" {
return nilOptions, ErrNoPassword
}
ao := gophercloud.AuthOptions{
IdentityEndpoint: authURL,
Username: username,
Password: password,
APIKey: apiKey,
}
return ao, nil
}

View File

@ -1,131 +0,0 @@
package snapshots
import (
"errors"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
)
func updateURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("snapshots", id)
}
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToSnapshotCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains options for creating a Snapshot. This object is passed to
// the snapshots.Create function. For more information about these parameters,
// see the Snapshot object.
type CreateOpts struct {
// REQUIRED
VolumeID string
// OPTIONAL
Description string
// OPTIONAL
Force bool
// OPTIONAL
Name string
}
// ToSnapshotCreateMap assembles a request body based on the contents of a
// CreateOpts.
func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) {
s := make(map[string]interface{})
if opts.VolumeID == "" {
return nil, errors.New("Required CreateOpts field 'VolumeID' not set.")
}
s["volume_id"] = opts.VolumeID
if opts.Description != "" {
s["display_description"] = opts.Description
}
if opts.Name != "" {
s["display_name"] = opts.Name
}
if opts.Force {
s["force"] = opts.Force
}
return map[string]interface{}{"snapshot": s}, nil
}
// Create will create a new Snapshot based on the values in CreateOpts. To
// extract the Snapshot object from the response, call the Extract method on the
// CreateResult.
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
return CreateResult{os.Create(client, opts)}
}
// Delete will delete the existing Snapshot with the provided ID.
func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult {
return os.Delete(client, id)
}
// Get retrieves the Snapshot with the provided ID. To extract the Snapshot
// object from the response, call the Extract method on the GetResult.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
return GetResult{os.Get(client, id)}
}
// List returns Snapshots.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client, os.ListOpts{})
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
type UpdateOptsBuilder interface {
ToSnapshotUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts is the common options struct used in this package's Update
// operation.
type UpdateOpts struct {
Name string
Description string
}
// ToSnapshotUpdateMap casts a UpdateOpts struct to a map.
func (opts UpdateOpts) ToSnapshotUpdateMap() (map[string]interface{}, error) {
s := make(map[string]interface{})
if opts.Name != "" {
s["display_name"] = opts.Name
}
if opts.Description != "" {
s["display_description"] = opts.Description
}
return map[string]interface{}{"snapshot": s}, nil
}
// Update accepts a UpdateOpts struct and updates an existing snapshot using the
// values provided.
func Update(c *gophercloud.ServiceClient, snapshotID string, opts UpdateOptsBuilder) UpdateResult {
var res UpdateResult
reqBody, err := opts.ToSnapshotUpdateMap()
if err != nil {
res.Err = err
return res
}
// Send request to API
_, res.Err = c.Request("PUT", updateURL(c, snapshotID), gophercloud.RequestOpts{
JSONBody: &reqBody,
JSONResponse: &res.Body,
OkCodes: []int{200, 201},
})
return res
}

View File

@ -1,3 +0,0 @@
// Package snapshots provides information and interaction with the snapshot
// API resource for the Rackspace Block Storage service.
package snapshots

View File

@ -1,147 +0,0 @@
package snapshots
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
"github.com/rackspace/gophercloud/pagination"
"github.com/mitchellh/mapstructure"
)
// Status is the type used to represent a snapshot's status
type Status string
// Constants to use for supported statuses
const (
Creating Status = "CREATING"
Available Status = "AVAILABLE"
Deleting Status = "DELETING"
Error Status = "ERROR"
DeleteError Status = "ERROR_DELETING"
)
// Snapshot is the Rackspace representation of an external block storage device.
type Snapshot struct {
// The timestamp when this snapshot was created.
CreatedAt string `mapstructure:"created_at"`
// The human-readable description for this snapshot.
Description string `mapstructure:"display_description"`
// The human-readable name for this snapshot.
Name string `mapstructure:"display_name"`
// The UUID for this snapshot.
ID string `mapstructure:"id"`
// The random metadata associated with this snapshot. Note: unlike standard
// OpenStack snapshots, this cannot actually be set.
Metadata map[string]string `mapstructure:"metadata"`
// Indicates the current progress of the snapshot's backup procedure.
Progress string `mapstructure:"os-extended-snapshot-attributes:progress"`
// The project ID.
ProjectID string `mapstructure:"os-extended-snapshot-attributes:project_id"`
// The size of the volume which this snapshot backs up.
Size int `mapstructure:"size"`
// The status of the snapshot.
Status Status `mapstructure:"status"`
// The ID of the volume which this snapshot seeks to back up.
VolumeID string `mapstructure:"volume_id"`
}
// CreateResult represents the result of a create operation
type CreateResult struct {
os.CreateResult
}
// GetResult represents the result of a get operation
type GetResult struct {
os.GetResult
}
// UpdateResult represents the result of an update operation
type UpdateResult struct {
gophercloud.Result
}
func commonExtract(resp interface{}, err error) (*Snapshot, error) {
if err != nil {
return nil, err
}
var respStruct struct {
Snapshot *Snapshot `json:"snapshot"`
}
err = mapstructure.Decode(resp, &respStruct)
return respStruct.Snapshot, err
}
// Extract will get the Snapshot object out of the GetResult object.
func (r GetResult) Extract() (*Snapshot, error) {
return commonExtract(r.Body, r.Err)
}
// Extract will get the Snapshot object out of the CreateResult object.
func (r CreateResult) Extract() (*Snapshot, error) {
return commonExtract(r.Body, r.Err)
}
// Extract will get the Snapshot object out of the UpdateResult object.
func (r UpdateResult) Extract() (*Snapshot, error) {
return commonExtract(r.Body, r.Err)
}
// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call.
func ExtractSnapshots(page pagination.Page) ([]Snapshot, error) {
var response struct {
Snapshots []Snapshot `json:"snapshots"`
}
err := mapstructure.Decode(page.(os.ListResult).Body, &response)
return response.Snapshots, err
}
// WaitUntilComplete will continually poll a snapshot until it successfully
// transitions to a specified state. It will do this for at most the number of
// seconds specified.
func (snapshot Snapshot) WaitUntilComplete(c *gophercloud.ServiceClient, timeout int) error {
return gophercloud.WaitFor(timeout, func() (bool, error) {
// Poll resource
current, err := Get(c, snapshot.ID).Extract()
if err != nil {
return false, err
}
// Has it been built yet?
if current.Progress == "100%" {
return true, nil
}
return false, nil
})
}
// WaitUntilDeleted will continually poll a snapshot until it has been
// successfully deleted, i.e. returns a 404 status.
func (snapshot Snapshot) WaitUntilDeleted(c *gophercloud.ServiceClient, timeout int) error {
return gophercloud.WaitFor(timeout, func() (bool, error) {
// Poll resource
_, err := Get(c, snapshot.ID).Extract()
// Check for a 404
if casted, ok := err.(*gophercloud.UnexpectedResponseCodeError); ok && casted.Actual == 404 {
return true, nil
} else if err != nil {
return false, err
}
return false, nil
})
}

View File

@ -1,75 +0,0 @@
package volumes
import (
"fmt"
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
"github.com/rackspace/gophercloud/pagination"
)
type CreateOpts struct {
os.CreateOpts
}
func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
if opts.Size < 75 || opts.Size > 1024 {
return nil, fmt.Errorf("Size field must be between 75 and 1024")
}
return opts.CreateOpts.ToVolumeCreateMap()
}
// Create will create a new Volume based on the values in CreateOpts. To extract
// the Volume object from the response, call the Extract method on the
// CreateResult.
func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) CreateResult {
return CreateResult{os.Create(client, opts)}
}
// Delete will delete the existing Volume with the provided ID.
func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult {
return os.Delete(client, id)
}
// Get retrieves the Volume with the provided ID. To extract the Volume object
// from the response, call the Extract method on the GetResult.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
return GetResult{os.Get(client, id)}
}
// List returns volumes optionally limited by the conditions provided in ListOpts.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client, os.ListOpts{})
}
// UpdateOpts contain options for updating an existing Volume. This object is passed
// to the volumes.Update function. For more information about the parameters, see
// the Volume object.
type UpdateOpts struct {
// OPTIONAL
Name string
// OPTIONAL
Description string
}
// ToVolumeUpdateMap assembles a request body based on the contents of an
// UpdateOpts.
func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
v := make(map[string]interface{})
if opts.Description != "" {
v["display_description"] = opts.Description
}
if opts.Name != "" {
v["display_name"] = opts.Name
}
return map[string]interface{}{"volume": v}, nil
}
// Update will update the Volume with provided information. To extract the updated
// Volume from the response, call the Extract method on the UpdateResult.
func Update(client *gophercloud.ServiceClient, id string, opts os.UpdateOptsBuilder) UpdateResult {
return UpdateResult{os.Update(client, id, opts)}
}

View File

@ -1,3 +0,0 @@
// Package volumes provides information and interaction with the volume
// API resource for the Rackspace Block Storage service.
package volumes

View File

@ -1,66 +0,0 @@
package volumes
import (
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
"github.com/rackspace/gophercloud/pagination"
"github.com/mitchellh/mapstructure"
)
// Volume wraps an Openstack volume
type Volume os.Volume
// CreateResult represents the result of a create operation
type CreateResult struct {
os.CreateResult
}
// GetResult represents the result of a get operation
type GetResult struct {
os.GetResult
}
// UpdateResult represents the result of an update operation
type UpdateResult struct {
os.UpdateResult
}
func commonExtract(resp interface{}, err error) (*Volume, error) {
if err != nil {
return nil, err
}
var respStruct struct {
Volume *Volume `json:"volume"`
}
err = mapstructure.Decode(resp, &respStruct)
return respStruct.Volume, err
}
// Extract will get the Volume object out of the GetResult object.
func (r GetResult) Extract() (*Volume, error) {
return commonExtract(r.Body, r.Err)
}
// Extract will get the Volume object out of the CreateResult object.
func (r CreateResult) Extract() (*Volume, error) {
return commonExtract(r.Body, r.Err)
}
// Extract will get the Volume object out of the UpdateResult object.
func (r UpdateResult) Extract() (*Volume, error) {
return commonExtract(r.Body, r.Err)
}
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
func ExtractVolumes(page pagination.Page) ([]Volume, error) {
var response struct {
Volumes []Volume `json:"volumes"`
}
err := mapstructure.Decode(page.(os.ListResult).Body, &response)
return response.Volumes, err
}

View File

@ -1,18 +0,0 @@
package volumetypes
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes"
"github.com/rackspace/gophercloud/pagination"
)
// List returns all volume types.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client)
}
// Get will retrieve the volume type with the provided ID. To extract the volume
// type from the result, call the Extract method on the GetResult.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
return GetResult{os.Get(client, id)}
}

View File

@ -1,3 +0,0 @@
// Package volumetypes provides information and interaction with the volume type
// API resource for the Rackspace Block Storage service.
package volumetypes

View File

@ -1,37 +0,0 @@
package volumetypes
import (
"github.com/mitchellh/mapstructure"
os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes"
"github.com/rackspace/gophercloud/pagination"
)
type VolumeType os.VolumeType
type GetResult struct {
os.GetResult
}
// Extract will get the Volume Type struct out of the response.
func (r GetResult) Extract() (*VolumeType, error) {
if r.Err != nil {
return nil, r.Err
}
var res struct {
VolumeType *VolumeType `json:"volume_type" mapstructure:"volume_type"`
}
err := mapstructure.Decode(r.Body, &res)
return res.VolumeType, err
}
func ExtractVolumeTypes(page pagination.Page) ([]VolumeType, error) {
var response struct {
VolumeTypes []VolumeType `mapstructure:"volume_types"`
}
err := mapstructure.Decode(page.(os.ListResult).Body, &response)
return response.VolumeTypes, err
}

View File

@ -1,18 +0,0 @@
package base
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/cdn/v1/base"
)
// Get retrieves the home document, allowing the user to discover the
// entire API.
func Get(c *gophercloud.ServiceClient) os.GetResult {
return os.Get(c)
}
// Ping retrieves a ping to the server.
func Ping(c *gophercloud.ServiceClient) os.PingResult {
return os.Ping(c)
}

View File

@ -1,4 +0,0 @@
// Package base provides information and interaction with the base API
// resource in the Rackspace CDN service. This API resource allows for
// retrieving the Home Document and pinging the root URL.
package base

View File

@ -1,18 +0,0 @@
package flavors
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/cdn/v1/flavors"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a single page of CDN flavors.
func List(c *gophercloud.ServiceClient) pagination.Pager {
return os.List(c)
}
// Get retrieves a specific flavor based on its unique ID.
func Get(c *gophercloud.ServiceClient, id string) os.GetResult {
return os.Get(c, id)
}

View File

@ -1,6 +0,0 @@
// Package flavors provides information and interaction with the flavors API
// resource in the Rackspace CDN service. This API resource allows for
// listing flavors and retrieving a specific flavor.
//
// A flavor is a mapping configuration to a CDN provider.
package flavors

View File

@ -1,13 +0,0 @@
package serviceassets
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/cdn/v1/serviceassets"
)
// Delete accepts a unique ID and deletes the CDN service asset associated with
// it.
func Delete(c *gophercloud.ServiceClient, id string, opts os.DeleteOptsBuilder) os.DeleteResult {
return os.Delete(c, id, opts)
}

View File

@ -1,7 +0,0 @@
// Package serviceassets provides information and interaction with the
// serviceassets API resource in the Rackspace CDN service. This API resource
// allows for deleting cached assets.
//
// A service distributes assets across the network. Service assets let you
// interrogate properties about these assets and perform certain actions on them.
package serviceassets

View File

@ -1,37 +0,0 @@
package services
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/cdn/v1/services"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager which allows you to iterate over a collection of
// CDN services. It accepts a ListOpts struct, which allows for pagination via
// marker and limit.
func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager {
return os.List(c, opts)
}
// Create accepts a CreateOpts struct and creates a new CDN service using the
// values provided.
func Create(c *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(c, opts)
}
// Get retrieves a specific service based on its unique ID.
func Get(c *gophercloud.ServiceClient, id string) os.GetResult {
return os.Get(c, id)
}
// Update accepts a UpdateOpts struct and updates an existing CDN service using
// the values provided.
func Update(c *gophercloud.ServiceClient, id string, patches []os.Patch) os.UpdateResult {
return os.Update(c, id, patches)
}
// Delete accepts a unique ID and deletes the CDN service associated with it.
func Delete(c *gophercloud.ServiceClient, id string) os.DeleteResult {
return os.Delete(c, id)
}

View File

@ -1,7 +0,0 @@
// Package services provides information and interaction with the services API
// resource in the Rackspace CDN service. This API resource allows for
// listing, creating, updating, retrieving, and deleting services.
//
// A service represents an application that has its content cached to the edge
// nodes.
package services

View File

@ -1,224 +0,0 @@
package rackspace
import (
"fmt"
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack"
"github.com/rackspace/gophercloud/openstack/utils"
tokens2 "github.com/rackspace/gophercloud/rackspace/identity/v2/tokens"
)
const (
// RackspaceUSIdentity is an identity endpoint located in the United States.
RackspaceUSIdentity = "https://identity.api.rackspacecloud.com/v2.0/"
// RackspaceUKIdentity is an identity endpoint located in the UK.
RackspaceUKIdentity = "https://lon.identity.api.rackspacecloud.com/v2.0/"
)
const (
v20 = "v2.0"
)
// NewClient creates a client that's prepared to communicate with the Rackspace API, but is not
// yet authenticated. Most users will probably prefer using the AuthenticatedClient function
// instead.
//
// Provide the base URL of the identity endpoint you wish to authenticate against as "endpoint".
// Often, this will be either RackspaceUSIdentity or RackspaceUKIdentity.
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
if endpoint == "" {
return os.NewClient(RackspaceUSIdentity)
}
return os.NewClient(endpoint)
}
// AuthenticatedClient logs in to Rackspace with the provided credentials and constructs a
// ProviderClient that's ready to operate.
//
// If the provided AuthOptions does not specify an explicit IdentityEndpoint, it will default to
// the canonical, production Rackspace US identity endpoint.
func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
client, err := NewClient(options.IdentityEndpoint)
if err != nil {
return nil, err
}
err = Authenticate(client, options)
if err != nil {
return nil, err
}
return client, nil
}
// Authenticate or re-authenticate against the most recent identity service supported at the
// provided endpoint.
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
versions := []*utils.Version{
&utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"},
}
chosen, endpoint, err := utils.ChooseVersion(client, versions)
if err != nil {
return err
}
switch chosen.ID {
case v20:
return v2auth(client, endpoint, options)
default:
// The switch statement must be out of date from the versions list.
return fmt.Errorf("Unrecognized identity version: %s", chosen.ID)
}
}
// AuthenticateV2 explicitly authenticates with v2 of the identity service.
func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
return v2auth(client, "", options)
}
func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions) error {
v2Client := NewIdentityV2(client)
if endpoint != "" {
v2Client.Endpoint = endpoint
}
result := tokens2.Create(v2Client, tokens2.WrapOptions(options))
token, err := result.ExtractToken()
if err != nil {
return err
}
catalog, err := result.ExtractServiceCatalog()
if err != nil {
return err
}
if options.AllowReauth {
client.ReauthFunc = func() error {
return AuthenticateV2(client, options)
}
}
client.TokenID = token.ID
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
return os.V2EndpointURL(catalog, opts)
}
return nil
}
// NewIdentityV2 creates a ServiceClient that may be used to access the v2 identity service.
func NewIdentityV2(client *gophercloud.ProviderClient) *gophercloud.ServiceClient {
v2Endpoint := client.IdentityBase + "v2.0/"
return &gophercloud.ServiceClient{
ProviderClient: client,
Endpoint: v2Endpoint,
}
}
// NewComputeV2 creates a ServiceClient that may be used to access the v2 compute service.
func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("compute")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{
ProviderClient: client,
Endpoint: url,
}, nil
}
// NewObjectCDNV1 creates a ServiceClient that may be used with the Rackspace v1 CDN.
func NewObjectCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("rax:object-cdn")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewObjectStorageV1 creates a ServiceClient that may be used with the Rackspace v1 object storage package.
func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return os.NewObjectStorageV1(client, eo)
}
// NewBlockStorageV1 creates a ServiceClient that can be used to access the
// Rackspace Cloud Block Storage v1 API.
func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("volume")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewLBV1 creates a ServiceClient that can be used to access the Rackspace
// Cloud Load Balancer v1 API.
func NewLBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("rax:load-balancer")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewNetworkV2 creates a ServiceClient that can be used to access the Rackspace
// Networking v2 API.
func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("network")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewCDNV1 creates a ServiceClient that may be used to access the Rackspace v1
// CDN service.
func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("rax:cdn")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 orchestration service.
func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("orchestration")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewRackConnectV3 creates a ServiceClient that may be used to access the v3 RackConnect service.
func NewRackConnectV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("rax:rackconnect")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
// NewDBV1 creates a ServiceClient that may be used to access the v1 DB service.
func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
eo.ApplyDefaults("rax:database")
url, err := client.EndpointLocator(eo)
if err != nil {
return nil, err
}
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}

View File

@ -1,12 +0,0 @@
package bootfromvolume
import (
"github.com/rackspace/gophercloud"
osBFV "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume"
osServers "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)
// Create requests the creation of a server from the given block device mapping.
func Create(client *gophercloud.ServiceClient, opts osServers.CreateOptsBuilder) osServers.CreateResult {
return osBFV.Create(client, opts)
}

View File

@ -1,43 +0,0 @@
package flavors
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
"github.com/rackspace/gophercloud/pagination"
)
// ListOpts helps control the results returned by the List() function. For example, a flavor with a
// minDisk field of 10 will not be returned if you specify MinDisk set to 20.
type ListOpts struct {
// MinDisk and MinRAM, if provided, elide flavors that do not meet your criteria.
MinDisk int `q:"minDisk"`
MinRAM int `q:"minRam"`
// Marker specifies the ID of the last flavor in the previous page.
Marker string `q:"marker"`
// Limit instructs List to refrain from sending excessively large lists of flavors.
Limit int `q:"limit"`
}
// ToFlavorListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToFlavorListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
if err != nil {
return "", err
}
return q.String(), nil
}
// ListDetail enumerates the server images available to your account.
func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager {
return os.ListDetail(client, opts)
}
// Get returns details about a single flavor, identity by ID.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
var res GetResult
_, res.Err = client.Get(getURL(client, id), &res.Body, nil)
return res
}

View File

@ -1,3 +0,0 @@
// Package flavors provides information and interaction with the flavor
// API resource for the Rackspace Cloud Servers service.
package flavors

View File

@ -1,137 +0,0 @@
// +build fixtures
package flavors
// ListOutput is a sample response of a flavor List request.
const ListOutput = `
{
"flavors": [
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"OS-FLV-WITH-EXT-SPECS:extra_specs": {
"class": "performance1",
"disk_io_index": "40",
"number_of_data_disks": "0",
"policy_class": "performance_flavor",
"resize_policy_class": "performance_flavor"
},
"disk": 20,
"id": "performance1-1",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-1",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-1",
"rel": "bookmark"
}
],
"name": "1 GB Performance",
"ram": 1024,
"rxtx_factor": 200,
"swap": "",
"vcpus": 1
},
{
"OS-FLV-EXT-DATA:ephemeral": 20,
"OS-FLV-WITH-EXT-SPECS:extra_specs": {
"class": "performance1",
"disk_io_index": "40",
"number_of_data_disks": "1",
"policy_class": "performance_flavor",
"resize_policy_class": "performance_flavor"
},
"disk": 40,
"id": "performance1-2",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-2",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-2",
"rel": "bookmark"
}
],
"name": "2 GB Performance",
"ram": 2048,
"rxtx_factor": 400,
"swap": "",
"vcpus": 2
}
]
}`
// GetOutput is a sample response from a flavor Get request. Its contents correspond to the
// Performance1Flavor struct.
const GetOutput = `
{
"flavor": {
"OS-FLV-EXT-DATA:ephemeral": 0,
"OS-FLV-WITH-EXT-SPECS:extra_specs": {
"class": "performance1",
"disk_io_index": "40",
"number_of_data_disks": "0",
"policy_class": "performance_flavor",
"resize_policy_class": "performance_flavor"
},
"disk": 20,
"id": "performance1-1",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/864477/flavors/performance1-1",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/864477/flavors/performance1-1",
"rel": "bookmark"
}
],
"name": "1 GB Performance",
"ram": 1024,
"rxtx_factor": 200,
"swap": "",
"vcpus": 1
}
}
`
// Performance1Flavor is the expected result of parsing GetOutput, or the first element of
// ListOutput.
var Performance1Flavor = Flavor{
ID: "performance1-1",
Disk: 20,
RAM: 1024,
Name: "1 GB Performance",
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 = Flavor{
ID: "performance1-2",
Disk: 40,
RAM: 2048,
Name: "2 GB Performance",
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 = []Flavor{Performance1Flavor, Performance2Flavor}

View File

@ -1,104 +0,0 @@
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
}

View File

@ -1,9 +0,0 @@
package flavors
import (
"github.com/rackspace/gophercloud"
)
func getURL(client *gophercloud.ServiceClient, id string) string {
return client.ServiceURL("flavors", id)
}

View File

@ -1,22 +0,0 @@
package images
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/compute/v2/images"
"github.com/rackspace/gophercloud/pagination"
)
// ListDetail enumerates the available server images.
func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager {
return os.ListDetail(client, opts)
}
// Get acquires additional detail about a specific image by ID.
func Get(client *gophercloud.ServiceClient, id string) os.GetResult {
return os.Get(client, id)
}
// ExtractImages interprets a page as a collection of server images.
func ExtractImages(page pagination.Page) ([]os.Image, error) {
return os.ExtractImages(page)
}

View File

@ -1,3 +0,0 @@
// Package images provides information and interaction with the image
// API resource for the Rackspace Cloud Servers service.
package images

View File

@ -1,200 +0,0 @@
// +build fixtures
package images
import (
os "github.com/rackspace/gophercloud/openstack/compute/v2/images"
)
// ListOutput is an example response from an /images/detail request.
const ListOutput = `
{
"images": [
{
"OS-DCF:diskConfig": "MANUAL",
"OS-EXT-IMG-SIZE:size": 1.017415075e+09,
"created": "2014-10-01T15:49:02Z",
"id": "30aa010e-080e-4d4b-a7f9-09fc55b07d69",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69",
"rel": "bookmark"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/30aa010e-080e-4d4b-a7f9-09fc55b07d69",
"rel": "alternate",
"type": "application/vnd.openstack.image"
}
],
"metadata": {
"auto_disk_config": "disabled",
"cache_in_nova": "True",
"com.rackspace__1__build_core": "1",
"com.rackspace__1__build_managed": "1",
"com.rackspace__1__build_rackconnect": "1",
"com.rackspace__1__options": "0",
"com.rackspace__1__platform_target": "PublicCloud",
"com.rackspace__1__release_build_date": "2014-10-01_15-46-08",
"com.rackspace__1__release_id": "100",
"com.rackspace__1__release_version": "10",
"com.rackspace__1__source": "kickstart",
"com.rackspace__1__visible_core": "1",
"com.rackspace__1__visible_managed": "0",
"com.rackspace__1__visible_rackconnect": "0",
"image_type": "base",
"org.openstack__1__architecture": "x64",
"org.openstack__1__os_distro": "org.archlinux",
"org.openstack__1__os_version": "2014.8",
"os_distro": "arch",
"os_type": "linux",
"vm_mode": "hvm"
},
"minDisk": 20,
"minRam": 512,
"name": "Arch 2014.10 (PVHVM)",
"progress": 100,
"status": "ACTIVE",
"updated": "2014-10-01T19:37:58Z"
},
{
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-IMG-SIZE:size": 1.060306463e+09,
"created": "2014-10-01T12:58:11Z",
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "alternate",
"type": "application/vnd.openstack.image"
}
],
"metadata": {
"auto_disk_config": "True",
"cache_in_nova": "True",
"com.rackspace__1__build_core": "1",
"com.rackspace__1__build_managed": "1",
"com.rackspace__1__build_rackconnect": "1",
"com.rackspace__1__options": "0",
"com.rackspace__1__platform_target": "PublicCloud",
"com.rackspace__1__release_build_date": "2014-10-01_12-31-03",
"com.rackspace__1__release_id": "1007",
"com.rackspace__1__release_version": "6",
"com.rackspace__1__source": "kickstart",
"com.rackspace__1__visible_core": "1",
"com.rackspace__1__visible_managed": "1",
"com.rackspace__1__visible_rackconnect": "1",
"image_type": "base",
"org.openstack__1__architecture": "x64",
"org.openstack__1__os_distro": "com.ubuntu",
"org.openstack__1__os_version": "14.04",
"os_distro": "ubuntu",
"os_type": "linux",
"vm_mode": "xen"
},
"minDisk": 20,
"minRam": 512,
"name": "Ubuntu 14.04 LTS (Trusty Tahr)",
"progress": 100,
"status": "ACTIVE",
"updated": "2014-10-01T15:51:44Z"
}
]
}
`
// GetOutput is an example response from an /images request.
const GetOutput = `
{
"image": {
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-IMG-SIZE:size": 1060306463,
"created": "2014-10-01T12:58:11Z",
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": [
{
"href": "https://iad.servers.api.rackspacecloud.com/v2/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "self"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark"
},
{
"href": "https://iad.servers.api.rackspacecloud.com/111222/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "alternate",
"type": "application/vnd.openstack.image"
}
],
"metadata": {
"auto_disk_config": "True",
"cache_in_nova": "True",
"com.rackspace__1__build_core": "1",
"com.rackspace__1__build_managed": "1",
"com.rackspace__1__build_rackconnect": "1",
"com.rackspace__1__options": "0",
"com.rackspace__1__platform_target": "PublicCloud",
"com.rackspace__1__release_build_date": "2014-10-01_12-31-03",
"com.rackspace__1__release_id": "1007",
"com.rackspace__1__release_version": "6",
"com.rackspace__1__source": "kickstart",
"com.rackspace__1__visible_core": "1",
"com.rackspace__1__visible_managed": "1",
"com.rackspace__1__visible_rackconnect": "1",
"image_type": "base",
"org.openstack__1__architecture": "x64",
"org.openstack__1__os_distro": "com.ubuntu",
"org.openstack__1__os_version": "14.04",
"os_distro": "ubuntu",
"os_type": "linux",
"vm_mode": "xen"
},
"minDisk": 20,
"minRam": 512,
"name": "Ubuntu 14.04 LTS (Trusty Tahr)",
"progress": 100,
"status": "ACTIVE",
"updated": "2014-10-01T15:51:44Z"
}
}
`
// ArchImage is the first Image structure that should be parsed from ListOutput.
var ArchImage = os.Image{
ID: "30aa010e-080e-4d4b-a7f9-09fc55b07d69",
Name: "Arch 2014.10 (PVHVM)",
Created: "2014-10-01T15:49:02Z",
Updated: "2014-10-01T19:37:58Z",
MinDisk: 20,
MinRAM: 512,
Progress: 100,
Status: "ACTIVE",
}
// UbuntuImage is the second Image structure that should be parsed from ListOutput and
// the only image that should be extracted from GetOutput.
var UbuntuImage = os.Image{
ID: "e19a734c-c7e6-443a-830c-242209c4d65d",
Name: "Ubuntu 14.04 LTS (Trusty Tahr)",
Created: "2014-10-01T12:58:11Z",
Updated: "2014-10-01T15:51:44Z",
MinDisk: 20,
MinRAM: 512,
Progress: 100,
Status: "ACTIVE",
}
// ExpectedImageSlice is the collection of images that should be parsed from ListOutput,
// in order.
var ExpectedImageSlice = []os.Image{ArchImage, UbuntuImage}

View File

@ -1,33 +0,0 @@
package keypairs
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager that allows you to iterate over a collection of KeyPairs.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client)
}
// Create requests the creation of a new keypair on the server, or to import a pre-existing
// keypair.
func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(client, opts)
}
// Get returns public data about a previously uploaded KeyPair.
func Get(client *gophercloud.ServiceClient, name string) os.GetResult {
return os.Get(client, name)
}
// Delete requests the deletion of a previous stored KeyPair from the server.
func Delete(client *gophercloud.ServiceClient, name string) os.DeleteResult {
return os.Delete(client, name)
}
// ExtractKeyPairs interprets a page of results as a slice of KeyPairs.
func ExtractKeyPairs(page pagination.Page) ([]os.KeyPair, error) {
return os.ExtractKeyPairs(page)
}

View File

@ -1,3 +0,0 @@
// Package keypairs provides information and interaction with the keypair
// API resource for the Rackspace Cloud Servers service.
package keypairs

View File

@ -1,3 +0,0 @@
// Package networks provides information and interaction with the network
// API resource for the Rackspace Cloud Servers service.
package networks

View File

@ -1,89 +0,0 @@
package networks
import (
"errors"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager which allows you to iterate over a collection of
// networks. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
func List(c *gophercloud.ServiceClient) pagination.Pager {
createPage := func(r pagination.PageResult) pagination.Page {
return NetworkPage{pagination.SinglePageBase(r)}
}
return pagination.NewPager(c, listURL(c), createPage)
}
// Get retrieves a specific network based on its unique ID.
func Get(c *gophercloud.ServiceClient, id string) GetResult {
var res GetResult
_, res.Err = c.Get(getURL(c, id), &res.Body, nil)
return res
}
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
type CreateOptsBuilder interface {
ToNetworkCreateMap() (map[string]interface{}, error)
}
// CreateOpts is the common options struct used in this package's Create
// operation.
type CreateOpts struct {
// REQUIRED. See Network object for more info.
CIDR string
// REQUIRED. See Network object for more info.
Label string
}
// ToNetworkCreateMap casts a CreateOpts struct to a map.
func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) {
n := make(map[string]interface{})
if opts.CIDR == "" {
return nil, errors.New("Required field CIDR not set.")
}
if opts.Label == "" {
return nil, errors.New("Required field Label not set.")
}
n["label"] = opts.Label
n["cidr"] = opts.CIDR
return map[string]interface{}{"network": n}, nil
}
// Create accepts a CreateOpts struct and creates a new network using the values
// provided. This operation does not actually require a request body, i.e. the
// CreateOpts struct argument can be empty.
//
// The tenant ID that is contained in the URI is the tenant that creates the
// network. An admin user, however, has the option of specifying another tenant
// ID in the CreateOpts struct.
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
var res CreateResult
reqBody, err := opts.ToNetworkCreateMap()
if err != nil {
res.Err = err
return res
}
// Send request to API
_, res.Err = c.Post(createURL(c), reqBody, &res.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 201, 202},
})
return res
}
// Delete accepts a unique ID and deletes the network associated with it.
func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult {
var res DeleteResult
_, res.Err = c.Delete(deleteURL(c, networkID), nil)
return res
}

View File

@ -1,81 +0,0 @@
package networks
import (
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a network resource.
func (r commonResult) Extract() (*Network, error) {
if r.Err != nil {
return nil, r.Err
}
var res struct {
Network *Network `json:"network"`
}
err := mapstructure.Decode(r.Body, &res)
return res.Network, err
}
// CreateResult represents the result of a create operation.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
type GetResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
type DeleteResult struct {
gophercloud.ErrResult
}
// Network represents, well, a network.
type Network struct {
// UUID for the network
ID string `mapstructure:"id" json:"id"`
// Human-readable name for the network. Might not be unique.
Label string `mapstructure:"label" json:"label"`
// Classless Inter-Domain Routing
CIDR string `mapstructure:"cidr" json:"cidr"`
}
// NetworkPage is the page returned by a pager when traversing over a
// collection of networks.
type NetworkPage struct {
pagination.SinglePageBase
}
// IsEmpty returns true if the NetworkPage contains no Networks.
func (r NetworkPage) IsEmpty() (bool, error) {
networks, err := ExtractNetworks(r)
if err != nil {
return true, err
}
return len(networks) == 0, nil
}
// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct,
// and extracts the elements into a slice of Network structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractNetworks(page pagination.Page) ([]Network, error) {
var resp struct {
Networks []Network `mapstructure:"networks" json:"networks"`
}
err := mapstructure.Decode(page.(NetworkPage).Body, &resp)
return resp.Networks, err
}

View File

@ -1,27 +0,0 @@
package networks
import "github.com/rackspace/gophercloud"
func resourceURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("os-networksv2", id)
}
func rootURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("os-networksv2")
}
func getURL(c *gophercloud.ServiceClient, id string) string {
return resourceURL(c, id)
}
func listURL(c *gophercloud.ServiceClient) string {
return rootURL(c)
}
func createURL(c *gophercloud.ServiceClient) string {
return rootURL(c)
}
func deleteURL(c *gophercloud.ServiceClient, id string) string {
return resourceURL(c, id)
}

View File

@ -1,116 +0,0 @@
package servers
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
"github.com/rackspace/gophercloud/pagination"
)
// List makes a request against the API to list servers accessible to you.
func List(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager {
return os.List(client, opts)
}
// Create requests a server to be provisioned to the user in the current tenant.
func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(client, opts)
}
// Update requests an existing server to be updated with the supplied options.
func Update(client *gophercloud.ServiceClient, id string, opts os.UpdateOptsBuilder) os.UpdateResult {
return os.Update(client, id, opts)
}
// Delete requests that a server previously provisioned be removed from your account.
func Delete(client *gophercloud.ServiceClient, id string) os.DeleteResult {
return os.Delete(client, id)
}
// Get requests details on a single server, by ID.
func Get(client *gophercloud.ServiceClient, id string) os.GetResult {
return os.Get(client, id)
}
// ChangeAdminPassword alters the administrator or root password for a specified server.
func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) os.ActionResult {
return os.ChangeAdminPassword(client, id, newPassword)
}
// Reboot requests that a given server reboot. Two methods exist for rebooting a server:
//
// os.HardReboot (aka PowerCycle) restarts the server instance by physically cutting power to the
// machine, or if a VM, terminating it at the hypervisor level. It's done. Caput. Full stop. Then,
// after a brief wait, power is restored or the VM instance restarted.
//
// os.SoftReboot (aka OSReboot) simply tells the OS to restart under its own procedures. E.g., in
// Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to restart the machine.
func Reboot(client *gophercloud.ServiceClient, id string, how os.RebootMethod) os.ActionResult {
return os.Reboot(client, id, how)
}
// Rebuild will reprovision the server according to the configuration options provided in the
// RebuildOpts struct.
func Rebuild(client *gophercloud.ServiceClient, id string, opts os.RebuildOptsBuilder) os.RebuildResult {
return os.Rebuild(client, id, opts)
}
// Resize instructs the provider to change the flavor of the server.
// Note that this implies rebuilding it.
// Unfortunately, one cannot pass rebuild parameters to the resize function.
// When the resize completes, the server will be in RESIZE_VERIFY state.
// While in this state, you can explore the use of the new server's configuration.
// If you like it, call ConfirmResize() to commit the resize permanently.
// Otherwise, call RevertResize() to restore the old configuration.
func Resize(client *gophercloud.ServiceClient, id string, opts os.ResizeOptsBuilder) os.ActionResult {
return os.Resize(client, id, opts)
}
// ConfirmResize confirms a previous resize operation on a server.
// See Resize() for more details.
func ConfirmResize(client *gophercloud.ServiceClient, id string) os.ActionResult {
return os.ConfirmResize(client, id)
}
// WaitForStatus will continually poll a server until it successfully transitions to a specified
// status. It will do this for at most the number of seconds specified.
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
return os.WaitForStatus(c, id, status, secs)
}
// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
func ExtractServers(page pagination.Page) ([]os.Server, error) {
return os.ExtractServers(page)
}
// ListAddresses makes a request against the API to list the servers IP addresses.
func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
return os.ListAddresses(client, id)
}
// ExtractAddresses interprets the results of a single page from a ListAddresses() call, producing a map of Address slices.
func ExtractAddresses(page pagination.Page) (map[string][]os.Address, error) {
return os.ExtractAddresses(page)
}
// ListAddressesByNetwork makes a request against the API to list the servers IP addresses
// for the given network.
func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager {
return os.ListAddressesByNetwork(client, id, network)
}
// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call, producing a map of Address slices.
func ExtractNetworkAddresses(page pagination.Page) ([]os.Address, error) {
return os.ExtractNetworkAddresses(page)
}
// Metadata requests all the metadata for the given server ID.
func Metadata(client *gophercloud.ServiceClient, id string) os.GetMetadataResult {
return os.Metadata(client, id)
}
// UpdateMetadata updates (or creates) all the metadata specified by opts for the given server ID.
// This operation does not affect already-existing metadata that is not specified
// by opts.
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts os.UpdateMetadataOptsBuilder) os.UpdateMetadataResult {
return os.UpdateMetadata(client, id, opts)
}

View File

@ -1,3 +0,0 @@
// Package servers provides information and interaction with the server
// API resource for the Rackspace Cloud Servers service.
package servers

View File

@ -1,574 +0,0 @@
// +build fixtures
package servers
import (
os "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)
// ListOutput is the recorded output of a Rackspace servers.List request.
const ListOutput = `
{
"servers": [
{
"OS-DCF:diskConfig": "MANUAL",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"accessIPv4": "1.2.3.4",
"accessIPv6": "1111:4822:7818:121:2000:9b5e:7438:a2d0",
"addresses": {
"private": [
{
"addr": "10.208.230.113",
"version": 4
}
],
"public": [
{
"addr": "2001:4800:7818:101:2000:9b5e:7428:a2d0",
"version": 6
},
{
"addr": "104.130.131.164",
"version": 4
}
]
},
"created": "2014-09-23T12:34:58Z",
"flavor": {
"id": "performance1-8",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-8",
"rel": "bookmark"
}
]
},
"hostId": "e8951a524bc465b0898aeac7674da6fe1495e253ae1ea17ddb2c2475",
"id": "59818cee-bc8c-44eb-8073-673ee65105f7",
"image": {
"id": "255df5fb-e3d4-45a3-9a07-c976debf7c14",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/255df5fb-e3d4-45a3-9a07-c976debf7c14",
"rel": "bookmark"
}
]
},
"key_name": "mykey",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7",
"rel": "self"
},
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7",
"rel": "bookmark"
}
],
"metadata": {},
"name": "devstack",
"progress": 100,
"status": "ACTIVE",
"tenant_id": "111111",
"updated": "2014-09-23T12:38:19Z",
"user_id": "14ae7bb21d81422694655f3cc30f2930"
},
{
"OS-DCF:diskConfig": "MANUAL",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"accessIPv4": "1.1.2.3",
"accessIPv6": "2222:4444:7817:101:be76:4eff:f0e5:9e02",
"addresses": {
"private": [
{
"addr": "10.10.20.30",
"version": 4
}
],
"public": [
{
"addr": "1.1.2.3",
"version": 4
},
{
"addr": "2222:4444:7817:101:be76:4eff:f0e5:9e02",
"version": 6
}
]
},
"created": "2014-07-21T19:32:55Z",
"flavor": {
"id": "performance1-2",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-2",
"rel": "bookmark"
}
]
},
"hostId": "f859679906d6b1a38c1bd516b78f4dcc7d5fcf012578fa3ce460716c",
"id": "25f1c7f5-e00a-4715-b354-16e24b2f4630",
"image": {
"id": "bb02b1a3-bc77-4d17-ab5b-421d89850fca",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/bb02b1a3-bc77-4d17-ab5b-421d89850fca",
"rel": "bookmark"
}
]
},
"key_name": "otherkey",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630",
"rel": "self"
},
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630",
"rel": "bookmark"
}
],
"metadata": {},
"name": "peril-dfw",
"progress": 100,
"status": "ACTIVE",
"tenant_id": "111111",
"updated": "2014-07-21T19:34:24Z",
"user_id": "14ae7bb21d81422694655f3cc30f2930"
}
]
}
`
// GetOutput is the recorded output of a Rackspace servers.Get request.
const GetOutput = `
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"accessIPv4": "1.2.4.8",
"accessIPv6": "2001:4800:6666:105:2a0f:c056:f594:7777",
"addresses": {
"private": [
{
"addr": "10.20.40.80",
"version": 4
}
],
"public": [
{
"addr": "1.2.4.8",
"version": 4
},
{
"addr": "2001:4800:6666:105:2a0f:c056:f594:7777",
"version": 6
}
]
},
"created": "2014-10-21T14:42:16Z",
"flavor": {
"id": "performance1-1",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1",
"rel": "bookmark"
}
]
},
"hostId": "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7",
"id": "8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"image": {
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark"
}
]
},
"key_name": null,
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "self"
},
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "bookmark"
}
],
"metadata": {},
"name": "Gophercloud-pxpGGuey",
"progress": 100,
"status": "ACTIVE",
"tenant_id": "111111",
"updated": "2014-10-21T14:42:57Z",
"user_id": "14ae7bb21d81423694655f4dd30f2930"
}
}
`
// UpdateOutput is the recorded output of a Rackspace servers.Update request.
const UpdateOutput = `
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"accessIPv4": "1.2.4.8",
"accessIPv6": "2001:4800:6666:105:2a0f:c056:f594:7777",
"addresses": {
"private": [
{
"addr": "10.20.40.80",
"version": 4
}
],
"public": [
{
"addr": "1.2.4.8",
"version": 4
},
{
"addr": "2001:4800:6666:105:2a0f:c056:f594:7777",
"version": 6
}
]
},
"created": "2014-10-21T14:42:16Z",
"flavor": {
"id": "performance1-1",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1",
"rel": "bookmark"
}
]
},
"hostId": "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7",
"id": "8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"image": {
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark"
}
]
},
"key_name": null,
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "self"
},
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "bookmark"
}
],
"metadata": {},
"name": "test-server-updated",
"progress": 100,
"status": "ACTIVE",
"tenant_id": "111111",
"updated": "2014-10-21T14:42:57Z",
"user_id": "14ae7bb21d81423694655f4dd30f2930"
}
}
`
// CreateOutput contains a sample of Rackspace's response to a Create call.
const CreateOutput = `
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"adminPass": "v7tADqbE5pr9",
"id": "bb63327b-6a2f-34bc-b0ef-4b6d97ea637e",
"links": [
{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/bb63327b-6a2f-34bc-b0ef-4b6d97ea637e",
"rel": "self"
},
{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/bb63327b-6a2f-34bc-b0ef-4b6d97ea637e",
"rel": "bookmark"
}
]
}
}
`
// DevstackServer is the expected first result from parsing ListOutput.
var DevstackServer = os.Server{
ID: "59818cee-bc8c-44eb-8073-673ee65105f7",
Name: "devstack",
TenantID: "111111",
UserID: "14ae7bb21d81422694655f3cc30f2930",
HostID: "e8951a524bc465b0898aeac7674da6fe1495e253ae1ea17ddb2c2475",
Updated: "2014-09-23T12:38:19Z",
Created: "2014-09-23T12:34:58Z",
AccessIPv4: "1.2.3.4",
AccessIPv6: "1111:4822:7818:121:2000:9b5e:7438:a2d0",
Progress: 100,
Status: "ACTIVE",
Image: map[string]interface{}{
"id": "255df5fb-e3d4-45a3-9a07-c976debf7c14",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/255df5fb-e3d4-45a3-9a07-c976debf7c14",
"rel": "bookmark",
},
},
},
Flavor: map[string]interface{}{
"id": "performance1-8",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-8",
"rel": "bookmark",
},
},
},
Addresses: map[string]interface{}{
"private": []interface{}{
map[string]interface{}{
"addr": "10.20.30.40",
"version": float64(4.0),
},
},
"public": []interface{}{
map[string]interface{}{
"addr": "1111:4822:7818:121:2000:9b5e:7438:a2d0",
"version": float64(6.0),
},
map[string]interface{}{
"addr": "1.2.3.4",
"version": float64(4.0),
},
},
},
Metadata: map[string]interface{}{},
Links: []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59918cee-bd9d-44eb-8173-673ee75105f7",
"rel": "self",
},
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/59818cee-bc8c-44eb-8073-673ee65105f7",
"rel": "bookmark",
},
},
KeyName: "mykey",
AdminPass: "",
}
// PerilServer is the expected second result from parsing ListOutput.
var PerilServer = os.Server{
ID: "25f1c7f5-e00a-4715-b354-16e24b2f4630",
Name: "peril-dfw",
TenantID: "111111",
UserID: "14ae7bb21d81422694655f3cc30f2930",
HostID: "f859679906d6b1a38c1bd516b78f4dcc7d5fcf012578fa3ce460716c",
Updated: "2014-07-21T19:34:24Z",
Created: "2014-07-21T19:32:55Z",
AccessIPv4: "1.1.2.3",
AccessIPv6: "2222:4444:7817:101:be76:4eff:f0e5:9e02",
Progress: 100,
Status: "ACTIVE",
Image: map[string]interface{}{
"id": "bb02b1a3-bc77-4d17-ab5b-421d89850fca",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/bb02b1a3-bc77-4d17-ab5b-421d89850fca",
"rel": "bookmark",
},
},
},
Flavor: map[string]interface{}{
"id": "performance1-2",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-2",
"rel": "bookmark",
},
},
},
Addresses: map[string]interface{}{
"private": []interface{}{
map[string]interface{}{
"addr": "10.10.20.30",
"version": float64(4.0),
},
},
"public": []interface{}{
map[string]interface{}{
"addr": "2222:4444:7817:101:be76:4eff:f0e5:9e02",
"version": float64(6.0),
},
map[string]interface{}{
"addr": "1.1.2.3",
"version": float64(4.0),
},
},
},
Metadata: map[string]interface{}{},
Links: []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630",
"rel": "self",
},
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/25f1c7f5-e00a-4715-b355-16e24b2f4630",
"rel": "bookmark",
},
},
KeyName: "otherkey",
AdminPass: "",
}
// GophercloudServer is the expected result from parsing GetOutput.
var GophercloudServer = os.Server{
ID: "8c65cb68-0681-4c30-bc88-6b83a8a26aee",
Name: "Gophercloud-pxpGGuey",
TenantID: "111111",
UserID: "14ae7bb21d81423694655f4dd30f2930",
HostID: "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7",
Updated: "2014-10-21T14:42:57Z",
Created: "2014-10-21T14:42:16Z",
AccessIPv4: "1.2.4.8",
AccessIPv6: "2001:4800:6666:105:2a0f:c056:f594:7777",
Progress: 100,
Status: "ACTIVE",
Image: map[string]interface{}{
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark",
},
},
},
Flavor: map[string]interface{}{
"id": "performance1-1",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1",
"rel": "bookmark",
},
},
},
Addresses: map[string]interface{}{
"private": []interface{}{
map[string]interface{}{
"addr": "10.20.40.80",
"version": float64(4.0),
},
},
"public": []interface{}{
map[string]interface{}{
"addr": "2001:4800:6666:105:2a0f:c056:f594:7777",
"version": float64(6.0),
},
map[string]interface{}{
"addr": "1.2.4.8",
"version": float64(4.0),
},
},
},
Metadata: map[string]interface{}{},
Links: []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "self",
},
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "bookmark",
},
},
KeyName: "",
AdminPass: "",
}
// GophercloudUpdatedServer is the expected result from parsing UpdateOutput.
var GophercloudUpdatedServer = os.Server{
ID: "8c65cb68-0681-4c30-bc88-6b83a8a26aee",
Name: "test-server-updated",
TenantID: "111111",
UserID: "14ae7bb21d81423694655f4dd30f2930",
HostID: "430d2ae02de0a7af77012c94778145eccf67e75b1fac0528aa10d4a7",
Updated: "2014-10-21T14:42:57Z",
Created: "2014-10-21T14:42:16Z",
AccessIPv4: "1.2.4.8",
AccessIPv6: "2001:4800:6666:105:2a0f:c056:f594:7777",
Progress: 100,
Status: "ACTIVE",
Image: map[string]interface{}{
"id": "e19a734c-c7e6-443a-830c-242209c4d65d",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/images/e19a734c-c7e6-443a-830c-242209c4d65d",
"rel": "bookmark",
},
},
},
Flavor: map[string]interface{}{
"id": "performance1-1",
"links": []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/flavors/performance1-1",
"rel": "bookmark",
},
},
},
Addresses: map[string]interface{}{
"private": []interface{}{
map[string]interface{}{
"addr": "10.20.40.80",
"version": float64(4.0),
},
},
"public": []interface{}{
map[string]interface{}{
"addr": "2001:4800:6666:105:2a0f:c056:f594:7777",
"version": float64(6.0),
},
map[string]interface{}{
"addr": "1.2.4.8",
"version": float64(4.0),
},
},
},
Metadata: map[string]interface{}{},
Links: []interface{}{
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/v2/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "self",
},
map[string]interface{}{
"href": "https://dfw.servers.api.rackspacecloud.com/111111/servers/8c65cb68-0681-4c30-bc88-6b83a8a26aee",
"rel": "bookmark",
},
},
KeyName: "",
AdminPass: "",
}
// CreatedServer is the partial Server struct that can be parsed from CreateOutput.
var CreatedServer = os.Server{
ID: "bb63327b-6a2f-34bc-b0ef-4b6d97ea637e",
AdminPass: "v7tADqbE5pr9",
Links: []interface{}{},
}
// ExpectedServerSlice is the collection of servers, in order, that should be parsed from ListOutput.
var ExpectedServerSlice = []os.Server{DevstackServer, PerilServer}

View File

@ -1,178 +0,0 @@
package servers
import (
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig"
os "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)
// CreateOpts specifies all of the options that Rackspace accepts in its Create request, including
// the union of all extensions that Rackspace supports.
type CreateOpts struct {
// Name [required] is the name to assign to the newly launched server.
Name string
// 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
// 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
// UserData [optional] contains configuration information or scripts to use upon launch.
// Create will base64-encode it for you.
UserData []byte
// AvailabilityZone [optional] in which to launch the server.
AvailabilityZone string
// Networks [optional] dictates how this server will be attached to available networks.
// By default, the server will be attached to all isolated networks for the tenant.
Networks []os.Network
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata map[string]string
// 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
// AdminPass [optional] sets the root user password. If not set, a randomly-generated
// password will be created and returned in the response.
AdminPass string
// Rackspace-specific extensions begin here.
// KeyPair [optional] specifies the name of the SSH KeyPair to be injected into the newly launched
// server. See the "keypairs" extension in OpenStack compute v2.
KeyPair string
// DiskConfig [optional] controls how the created server's disk is partitioned. See the "diskconfig"
// extension in OpenStack compute v2.
DiskConfig diskconfig.DiskConfig
// BlockDevice [optional] will create the server from a volume, which is created from an image,
// a snapshot, or another volume.
BlockDevice []bootfromvolume.BlockDevice
}
// ToServerCreateMap constructs a request body using all of the OpenStack extensions that are
// active on Rackspace.
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,
Networks: opts.Networks,
Metadata: opts.Metadata,
Personality: opts.Personality,
ConfigDrive: opts.ConfigDrive,
AdminPass: opts.AdminPass,
}
drive := diskconfig.CreateOptsExt{
CreateOptsBuilder: base,
DiskConfig: opts.DiskConfig,
}
res, err := drive.ToServerCreateMap()
if err != nil {
return nil, err
}
if len(opts.BlockDevice) != 0 {
bfv := bootfromvolume.CreateOptsExt{
CreateOptsBuilder: drive,
BlockDevice: opts.BlockDevice,
}
res, err = bfv.ToServerCreateMap()
if err != nil {
return nil, err
}
}
// 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{})
if opts.KeyPair != "" {
serverMap["key_name"] = opts.KeyPair
}
return res, nil
}
// RebuildOpts represents all of the configuration options used in a server rebuild operation that
// are supported by Rackspace.
type RebuildOpts struct {
// Required. The ID of the image you want your server to be provisioned on
ImageID string
// Name to set the server to
Name string
// Required. The server's admin password
AdminPass string
// AccessIPv4 [optional] provides a new IPv4 address for the instance.
AccessIPv4 string
// AccessIPv6 [optional] provides a new IPv6 address for the instance.
AccessIPv6 string
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
Metadata map[string]string
// 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.
// DiskConfig [optional] controls how the created server's disk is partitioned. See the "diskconfig"
// extension in OpenStack compute v2.
DiskConfig diskconfig.DiskConfig
}
// ToServerRebuildMap constructs a request body using all of the OpenStack extensions that are
// active on Rackspace.
func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) {
base := os.RebuildOpts{
ImageID: opts.ImageID,
Name: opts.Name,
AdminPass: opts.AdminPass,
AccessIPv4: opts.AccessIPv4,
AccessIPv6: opts.AccessIPv6,
Metadata: opts.Metadata,
Personality: opts.Personality,
}
drive := diskconfig.RebuildOptsExt{
RebuildOptsBuilder: base,
DiskConfig: opts.DiskConfig,
}
return drive.ToServerRebuildMap()
}

View File

@ -1,45 +0,0 @@
package virtualinterfaces
import (
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager which allows you to iterate over a collection of
// networks. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
func List(c *gophercloud.ServiceClient, instanceID string) pagination.Pager {
createPage := func(r pagination.PageResult) pagination.Page {
return VirtualInterfacePage{pagination.SinglePageBase(r)}
}
return pagination.NewPager(c, listURL(c, instanceID), createPage)
}
// Create creates a new virtual interface for a network and attaches the network
// to the server instance.
func Create(c *gophercloud.ServiceClient, instanceID, networkID string) CreateResult {
var res CreateResult
reqBody := map[string]map[string]string{
"virtual_interface": {
"network_id": networkID,
},
}
// Send request to API
_, res.Err = c.Post(createURL(c, instanceID), reqBody, &res.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 201, 202},
})
return res
}
// Delete deletes the interface with interfaceID attached to the instance with
// instanceID.
func Delete(c *gophercloud.ServiceClient, instanceID, interfaceID string) DeleteResult {
var res DeleteResult
_, res.Err = c.Delete(deleteURL(c, instanceID, interfaceID), &gophercloud.RequestOpts{
OkCodes: []int{200, 204},
})
return res
}

View File

@ -1,81 +0,0 @@
package virtualinterfaces
import (
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a network resource.
func (r commonResult) Extract() (*VirtualInterface, error) {
if r.Err != nil {
return nil, r.Err
}
var res struct {
VirtualInterfaces []VirtualInterface `mapstructure:"virtual_interfaces" json:"virtual_interfaces"`
}
err := mapstructure.Decode(r.Body, &res)
return &res.VirtualInterfaces[0], err
}
// CreateResult represents the result of a create operation.
type CreateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
type DeleteResult struct {
gophercloud.ErrResult
}
// IPAddress represents a vitual address attached to a VirtualInterface.
type IPAddress struct {
Address string `mapstructure:"address" json:"address"`
NetworkID string `mapstructure:"network_id" json:"network_id"`
NetworkLabel string `mapstructure:"network_label" json:"network_label"`
}
// VirtualInterface represents a virtual interface.
type VirtualInterface struct {
// UUID for the virtual interface
ID string `mapstructure:"id" json:"id"`
MACAddress string `mapstructure:"mac_address" json:"mac_address"`
IPAddresses []IPAddress `mapstructure:"ip_addresses" json:"ip_addresses"`
}
// VirtualInterfacePage is the page returned by a pager when traversing over a
// collection of virtual interfaces.
type VirtualInterfacePage struct {
pagination.SinglePageBase
}
// IsEmpty returns true if the NetworkPage contains no Networks.
func (r VirtualInterfacePage) IsEmpty() (bool, error) {
networks, err := ExtractVirtualInterfaces(r)
if err != nil {
return true, err
}
return len(networks) == 0, nil
}
// ExtractVirtualInterfaces accepts a Page struct, specifically a VirtualInterfacePage struct,
// and extracts the elements into a slice of VirtualInterface structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractVirtualInterfaces(page pagination.Page) ([]VirtualInterface, error) {
var resp struct {
VirtualInterfaces []VirtualInterface `mapstructure:"virtual_interfaces" json:"virtual_interfaces"`
}
err := mapstructure.Decode(page.(VirtualInterfacePage).Body, &resp)
return resp.VirtualInterfaces, err
}

View File

@ -1,15 +0,0 @@
package virtualinterfaces
import "github.com/rackspace/gophercloud"
func listURL(c *gophercloud.ServiceClient, instanceID string) string {
return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2")
}
func createURL(c *gophercloud.ServiceClient, instanceID string) string {
return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2")
}
func deleteURL(c *gophercloud.ServiceClient, instanceID, interfaceID string) string {
return c.ServiceURL("servers", instanceID, "os-virtual-interfacesv2", interfaceID)
}

View File

@ -1,27 +0,0 @@
package volumeattach
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach"
"github.com/rackspace/gophercloud/pagination"
)
// List returns a Pager that allows you to iterate over a collection of VolumeAttachments.
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
return os.List(client, serverID)
}
// Create requests the creation of a new volume attachment on the server
func Create(client *gophercloud.ServiceClient, serverID string, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(client, serverID, opts)
}
// Get returns public data about a previously created VolumeAttachment.
func Get(client *gophercloud.ServiceClient, serverID, aID string) os.GetResult {
return os.Get(client, serverID, aID)
}
// Delete requests the deletion of a previous stored VolumeAttachment from the server.
func Delete(client *gophercloud.ServiceClient, serverID, aID string) os.DeleteResult {
return os.Delete(client, serverID, aID)
}

View File

@ -1,3 +0,0 @@
// Package volumeattach provides the ability to attach and detach volume
// to instances to Rackspace servers
package volumeattach

View File

@ -1,6 +0,0 @@
// Package backups provides information and interaction with the backup API
// resource in the Rackspace Database service.
//
// A backup is a copy of a database instance that can be used to restore it to
// some defined point in history.
package backups

View File

@ -1,66 +0,0 @@
package backups
import "time"
var (
timestamp = "2015-11-12T14:22:42Z"
timeVal, _ = time.Parse(time.RFC3339, timestamp)
)
var getResp = `
{
"backup": {
"created": "` + timestamp + `",
"description": "My Backup",
"id": "61f12fef-edb1-4561-8122-e7c00ef26a82",
"instance_id": "d4603f69-ec7e-4e9b-803f-600b9205576f",
"locationRef": null,
"name": "snapshot",
"parent_id": null,
"size": 100,
"status": "NEW",
"datastore": {
"version": "5.1",
"type": "MySQL",
"version_id": "20000000-0000-0000-0000-000000000002"
},
"updated": "` + timestamp + `"
}
}
`
var createReq = `
{
"backup": {
"description": "My Backup",
"instance": "d4603f69-ec7e-4e9b-803f-600b9205576f",
"name": "snapshot"
}
}
`
var createResp = getResp
var listResp = `
{
"backups": [
{
"status": "COMPLETED",
"updated": "` + timestamp + `",
"description": "Backup from Restored Instance",
"datastore": {
"version": "5.1",
"type": "MySQL",
"version_id": "20000000-0000-0000-0000-000000000002"
},
"id": "87972694-4be2-40f5-83f8-501656e0032a",
"size": 0.141026,
"name": "restored_backup",
"created": "` + timestamp + `",
"instance_id": "29af2cd9-0674-48ab-b87a-b160f00208e6",
"parent_id": null,
"locationRef": "http://localhost/path/to/backup"
}
]
}
`

View File

@ -1,138 +0,0 @@
package backups
import (
"errors"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// CreateOptsBuilder is the top-level interface for creating JSON maps.
type CreateOptsBuilder interface {
ToBackupCreateMap() (map[string]interface{}, error)
}
// CreateOpts is responsible for configuring newly provisioned backups.
type CreateOpts struct {
// [REQUIRED] The name of the backup. The only restriction is the name must
// be less than 64 characters long.
Name string
// [REQUIRED] The ID of the instance being backed up.
InstanceID string
// [OPTIONAL] A human-readable explanation of the backup.
Description string
}
// ToBackupCreateMap will create a JSON map for the Create operation.
func (opts CreateOpts) ToBackupCreateMap() (map[string]interface{}, error) {
if opts.Name == "" {
return nil, errors.New("Name is a required field")
}
if opts.InstanceID == "" {
return nil, errors.New("InstanceID is a required field")
}
backup := map[string]interface{}{
"name": opts.Name,
"instance": opts.InstanceID,
}
if opts.Description != "" {
backup["description"] = opts.Description
}
return map[string]interface{}{"backup": backup}, nil
}
// Create asynchronously creates a new backup for a specified database instance.
// During the backup process, write access on MyISAM databases will be
// temporarily disabled; innoDB databases will be unaffected. During this time,
// you will not be able to add or delete databases or users; nor delete, stop
// or reboot the instance itself. Only one backup is permitted at once.
//
// Backups are not deleted when database instances are deleted; you must
// manually delete any backups created using Delete(). Backups are saved to your
// Cloud Files account in a new container called z_CLOUDDB_BACKUPS. It is
// strongly recommended you do not alter this container or its contents; usual
// storage costs apply.
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
var res CreateResult
reqBody, err := opts.ToBackupCreateMap()
if err != nil {
res.Err = err
return res
}
_, res.Err = client.Request("POST", baseURL(client), gophercloud.RequestOpts{
JSONBody: &reqBody,
JSONResponse: &res.Body,
OkCodes: []int{202},
})
return res
}
// ListOptsBuilder is the top-level interface for creating query strings.
type ListOptsBuilder interface {
ToBackupListQuery() (string, error)
}
// ListOpts allows you to refine a list search by certain parameters.
type ListOpts struct {
// The type of datastore by which to filter.
Datastore string `q:"datastore"`
}
// ToBackupListQuery converts a ListOpts struct into a query string.
func (opts ListOpts) ToBackupListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
if err != nil {
return "", err
}
return q.String(), nil
}
// List will list all the saved backups for all database instances.
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := baseURL(client)
if opts != nil {
query, err := opts.ToBackupListQuery()
if err != nil {
return pagination.Pager{Err: err}
}
url += query
}
pageFn := func(r pagination.PageResult) pagination.Page {
return BackupPage{pagination.SinglePageBase(r)}
}
return pagination.NewPager(client, url, pageFn)
}
// Get will retrieve details for a particular backup based on its unique ID.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
var res GetResult
_, res.Err = client.Request("GET", resourceURL(client, id), gophercloud.RequestOpts{
JSONResponse: &res.Body,
OkCodes: []int{200},
})
return res
}
// Delete will permanently delete a backup.
func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
var res DeleteResult
_, res.Err = client.Request("DELETE", resourceURL(client, id), gophercloud.RequestOpts{
OkCodes: []int{202},
})
return res
}

View File

@ -1,149 +0,0 @@
package backups
import (
"fmt"
"reflect"
"time"
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/db/v1/datastores"
"github.com/rackspace/gophercloud/pagination"
)
// Status represents the various states a Backup can be in.
type Status string
// Enum types for the status.
const (
StatusNew Status = "NEW"
StatusBuilding Status = "BUILDING"
StatusCompleted Status = "COMPLETED"
StatusFailed Status = "FAILED"
StatusDeleteFailed Status = "DELETE_FAILED"
)
// Backup represents a Backup API resource.
type Backup struct {
Description string
ID string
InstanceID string `json:"instance_id" mapstructure:"instance_id"`
LocationRef string
Name string
ParentID string `json:"parent_id" mapstructure:"parent_id"`
Size float64
Status Status
Created time.Time `mapstructure:"-"`
Updated time.Time `mapstructure:"-"`
Datastore datastores.DatastorePartial
}
// CreateResult represents the result of a create operation.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
type GetResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
type DeleteResult struct {
gophercloud.ErrResult
}
type commonResult struct {
gophercloud.Result
}
// Extract will retrieve a Backup struct from an operation's result.
func (r commonResult) Extract() (*Backup, error) {
if r.Err != nil {
return nil, r.Err
}
var response struct {
Backup Backup `mapstructure:"backup"`
}
err := mapstructure.Decode(r.Body, &response)
val := r.Body.(map[string]interface{})["backup"].(map[string]interface{})
if t, ok := val["created"].(string); ok && t != "" {
creationTime, err := time.Parse(time.RFC3339, t)
if err != nil {
return &response.Backup, err
}
response.Backup.Created = creationTime
}
if t, ok := val["updated"].(string); ok && t != "" {
updatedTime, err := time.Parse(time.RFC3339, t)
if err != nil {
return &response.Backup, err
}
response.Backup.Updated = updatedTime
}
return &response.Backup, err
}
// BackupPage represents a page of backups.
type BackupPage struct {
pagination.SinglePageBase
}
// IsEmpty checks whether an BackupPage struct is empty.
func (r BackupPage) IsEmpty() (bool, error) {
is, err := ExtractBackups(r)
if err != nil {
return true, err
}
return len(is) == 0, nil
}
// ExtractBackups will retrieve a slice of Backup structs from a paginated collection.
func ExtractBackups(page pagination.Page) ([]Backup, error) {
casted := page.(BackupPage).Body
var resp struct {
Backups []Backup `mapstructure:"backups" json:"backups"`
}
if err := mapstructure.Decode(casted, &resp); err != nil {
return nil, err
}
var vals []interface{}
switch casted.(type) {
case map[string]interface{}:
vals = casted.(map[string]interface{})["backups"].([]interface{})
case map[string][]interface{}:
vals = casted.(map[string][]interface{})["backups"]
default:
return resp.Backups, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
}
for i, v := range vals {
val := v.(map[string]interface{})
if t, ok := val["created"].(string); ok && t != "" {
creationTime, err := time.Parse(time.RFC3339, t)
if err != nil {
return resp.Backups, err
}
resp.Backups[i].Created = creationTime
}
if t, ok := val["updated"].(string); ok && t != "" {
updatedTime, err := time.Parse(time.RFC3339, t)
if err != nil {
return resp.Backups, err
}
resp.Backups[i].Updated = updatedTime
}
}
return resp.Backups, nil
}

View File

@ -1,11 +0,0 @@
package backups
import "github.com/rackspace/gophercloud"
func baseURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("backups")
}
func resourceURL(c *gophercloud.ServiceClient, backupID string) string {
return c.ServiceURL("backups", backupID)
}

View File

@ -1,79 +0,0 @@
package configurations
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/db/v1/configurations"
"github.com/rackspace/gophercloud/pagination"
)
// List will list all of the available configurations.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client)
}
// Create will create a new configuration group.
func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(client, opts)
}
// Get will retrieve the details for a specified configuration group.
func Get(client *gophercloud.ServiceClient, configID string) os.GetResult {
return os.Get(client, configID)
}
// Update will modify an existing configuration group by performing a merge
// between new and existing values. If the key already exists, the new value
// will overwrite. All other keys will remain unaffected.
func Update(client *gophercloud.ServiceClient, configID string, opts os.UpdateOptsBuilder) os.UpdateResult {
return os.Update(client, configID, opts)
}
// Replace will modify an existing configuration group by overwriting the
// entire parameter group with the new values provided. Any existing keys not
// included in UpdateOptsBuilder will be deleted.
func Replace(client *gophercloud.ServiceClient, configID string, opts os.UpdateOptsBuilder) os.ReplaceResult {
return os.Replace(client, configID, opts)
}
// Delete will permanently delete a configuration group. Please note that
// config groups cannot be deleted whilst still attached to running instances -
// you must detach and then delete them.
func Delete(client *gophercloud.ServiceClient, configID string) os.DeleteResult {
return os.Delete(client, configID)
}
// ListInstances will list all the instances associated with a particular
// configuration group.
func ListInstances(client *gophercloud.ServiceClient, configID string) pagination.Pager {
return os.ListInstances(client, configID)
}
// ListDatastoreParams will list all the available and supported parameters
// that can be used for a particular datastore ID and a particular version.
// For example, if you are wondering how you can configure a MySQL 5.6 instance,
// you can use this operation (you will need to retrieve the MySQL datastore ID
// by using the datastores API).
func ListDatastoreParams(client *gophercloud.ServiceClient, datastoreID, versionID string) pagination.Pager {
return os.ListDatastoreParams(client, datastoreID, versionID)
}
// GetDatastoreParam will retrieve information about a specific configuration
// parameter. For example, you can use this operation to understand more about
// "innodb_file_per_table" configuration param for MySQL datastores. You will
// need the param's ID first, which can be attained by using the ListDatastoreParams
// operation.
func GetDatastoreParam(client *gophercloud.ServiceClient, datastoreID, versionID, paramID string) os.ParamResult {
return os.GetDatastoreParam(client, datastoreID, versionID, paramID)
}
// ListGlobalParams is similar to ListDatastoreParams but does not require a
// DatastoreID.
func ListGlobalParams(client *gophercloud.ServiceClient, versionID string) pagination.Pager {
return os.ListGlobalParams(client, versionID)
}
// GetGlobalParam is similar to GetDatastoreParam but does not require a
// DatastoreID.
func GetGlobalParam(client *gophercloud.ServiceClient, versionID, paramID string) os.ParamResult {
return os.GetGlobalParam(client, versionID, paramID)
}

View File

@ -1 +0,0 @@
package configurations

View File

@ -1,159 +0,0 @@
package configurations
import (
"fmt"
"time"
os "github.com/rackspace/gophercloud/openstack/db/v1/configurations"
)
var (
timestamp = "2015-11-12T14:22:42Z"
timeVal, _ = time.Parse(time.RFC3339, timestamp)
)
var singleConfigJSON = `
{
"created": "` + timestamp + `",
"datastore_name": "mysql",
"datastore_version_id": "b00000b0-00b0-0b00-00b0-000b000000bb",
"datastore_version_name": "5.6",
"description": "example_description",
"id": "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
"name": "example-configuration-name",
"updated": "` + timestamp + `"
}
`
var singleConfigWithValuesJSON = `
{
"created": "` + timestamp + `",
"datastore_name": "mysql",
"datastore_version_id": "b00000b0-00b0-0b00-00b0-000b000000bb",
"datastore_version_name": "5.6",
"description": "example description",
"id": "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
"instance_count": 0,
"name": "example-configuration-name",
"updated": "` + timestamp + `",
"values": {
"collation_server": "latin1_swedish_ci",
"connect_timeout": 120
}
}
`
var (
listConfigsJSON = fmt.Sprintf(`{"configurations": [%s]}`, singleConfigJSON)
getConfigJSON = fmt.Sprintf(`{"configuration": %s}`, singleConfigJSON)
createConfigJSON = fmt.Sprintf(`{"configuration": %s}`, singleConfigWithValuesJSON)
)
var createReq = `
{
"configuration": {
"datastore": {
"type": "a00000a0-00a0-0a00-00a0-000a000000aa",
"version": "b00000b0-00b0-0b00-00b0-000b000000bb"
},
"description": "example description",
"name": "example-configuration-name",
"values": {
"collation_server": "latin1_swedish_ci",
"connect_timeout": 120
}
}
}
`
var updateReq = `
{
"configuration": {
"values": {
"connect_timeout": 300
}
}
}
`
var listInstancesJSON = `
{
"instances": [
{
"id": "d4603f69-ec7e-4e9b-803f-600b9205576f",
"name": "json_rack_instance"
}
]
}
`
var listParamsJSON = `
{
"configuration-parameters": [
{
"max": 1,
"min": 0,
"name": "innodb_file_per_table",
"restart_required": true,
"type": "integer"
},
{
"max": 4294967296,
"min": 0,
"name": "key_buffer_size",
"restart_required": false,
"type": "integer"
},
{
"max": 65535,
"min": 2,
"name": "connect_timeout",
"restart_required": false,
"type": "integer"
},
{
"max": 4294967296,
"min": 0,
"name": "join_buffer_size",
"restart_required": false,
"type": "integer"
}
]
}
`
var getParamJSON = `
{
"max": 1,
"min": 0,
"name": "innodb_file_per_table",
"restart_required": true,
"type": "integer"
}
`
var exampleConfig = os.Config{
Created: timeVal,
DatastoreName: "mysql",
DatastoreVersionID: "b00000b0-00b0-0b00-00b0-000b000000bb",
DatastoreVersionName: "5.6",
Description: "example_description",
ID: "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
Name: "example-configuration-name",
Updated: timeVal,
}
var exampleConfigWithValues = os.Config{
Created: timeVal,
DatastoreName: "mysql",
DatastoreVersionID: "b00000b0-00b0-0b00-00b0-000b000000bb",
DatastoreVersionName: "5.6",
Description: "example description",
ID: "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
Name: "example-configuration-name",
Updated: timeVal,
Values: map[string]interface{}{
"collation_server": "latin1_swedish_ci",
"connect_timeout": 120,
},
}

View File

@ -1,19 +0,0 @@
package databases
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/db/v1/databases"
"github.com/rackspace/gophercloud/pagination"
)
func Create(client *gophercloud.ServiceClient, instanceID string, opts os.CreateOptsBuilder) os.CreateResult {
return os.Create(client, instanceID, opts)
}
func List(client *gophercloud.ServiceClient, instanceID string) pagination.Pager {
return os.List(client, instanceID)
}
func Delete(client *gophercloud.ServiceClient, instanceID, dbName string) os.DeleteResult {
return os.Delete(client, instanceID, dbName)
}

View File

@ -1,3 +0,0 @@
// Package databases provides information and interaction with the database API
// resource in the Rackspace Database service.
package databases

View File

@ -1 +0,0 @@
package databases

View File

@ -1,28 +0,0 @@
package datastores
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/db/v1/datastores"
"github.com/rackspace/gophercloud/pagination"
)
// List will list all available flavors.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client)
}
// Get retrieves the details for a particular flavor.
func Get(client *gophercloud.ServiceClient, flavorID string) os.GetResult {
return os.Get(client, flavorID)
}
// ListVersions will list all of the available versions for a specified
// datastore type.
func ListVersions(client *gophercloud.ServiceClient, datastoreID string) pagination.Pager {
return os.ListVersions(client, datastoreID)
}
// GetVersion will retrieve the details of a specified datastore version.
func GetVersion(client *gophercloud.ServiceClient, datastoreID, versionID string) os.GetVersionResult {
return os.GetVersion(client, datastoreID, versionID)
}

View File

@ -1 +0,0 @@
package datastores

View File

@ -1,17 +0,0 @@
package flavors
import (
"github.com/rackspace/gophercloud"
os "github.com/rackspace/gophercloud/openstack/db/v1/flavors"
"github.com/rackspace/gophercloud/pagination"
)
// List will list all available flavors.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return os.List(client)
}
// Get retrieves the details for a particular flavor.
func Get(client *gophercloud.ServiceClient, flavorID string) os.GetResult {
return os.Get(client, flavorID)
}

Some files were not shown because too many files have changed in this diff Show More