Skip to content

Commit f97cb21

Browse files
authored
Releasing version v2.5.0 (#130)
Releasing version v2.5.0
1 parent 761df5a commit f97cb21

File tree

92 files changed

+4834
-78
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+4834
-78
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66

7+
## 2.5.0 - 2018-09-27
8+
### Added
9+
- Support for paravirtualized launch mode when importing images in the Compute service
10+
- Support for Key Management service
11+
- Support for encrypting the contents of an Object Storage bucket using a Key Management service key
12+
- Support for specifying a Key Management service key when launching a compute instance in the Compute service
13+
- Support for specifying a Key Management service key when backing up or restoring a block storage volume in the Block Volume service
14+
715
## 2.4.0 - 2018-09-06
816
### Added
917
- Added support for updating metadata fields on an instance in the Compute service

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
DOC_SERVER_URL=https:\/\/docs.us-phoenix-1.oraclecloud.com
22

3-
GEN_TARGETS = identity core objectstorage loadbalancer database audit dns filestorage email containerengine resourcesearch ##SPECNAME##
3+
GEN_TARGETS = identity core objectstorage loadbalancer database audit dns filestorage email containerengine resourcesearch keymanagement ##SPECNAME##
44
NON_GEN_TARGETS = common common/auth
55
TARGETS = $(NON_GEN_TARGETS) $(GEN_TARGETS)
66

common/client.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,6 @@ func (client *BaseClient) prepareRequest(request *http.Request) (err error) {
197197
request.Header.Set(requestHeaderUserAgent, client.UserAgent)
198198
request.Header.Set(requestHeaderDate, time.Now().UTC().Format(http.TimeFormat))
199199

200-
if request.Header.Get(requestHeaderOpcRetryToken) == "" {
201-
request.Header.Set(requestHeaderOpcRetryToken, generateRetryToken())
202-
}
203-
204200
if !strings.Contains(client.Host, "http") &&
205201
!strings.Contains(client.Host, "https") {
206202
client.Host = fmt.Sprintf("%s://%s", defaultScheme, client.Host)

common/client_test.go

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -104,26 +104,6 @@ func TestClient_prepareRequestUpdatesDateHeader(t *testing.T) {
104104
assert.NotEqual(t, d1, d2)
105105
}
106106

107-
func TestClient_prepareRequestOnlySetsRetryTokenOnce(t *testing.T) {
108-
host := "somehost:9000"
109-
basePath := "basePath"
110-
restPath := "somepath"
111-
112-
c := BaseClient{UserAgent: "asdf"}
113-
c.Host = host
114-
c.BasePath = basePath
115-
116-
request := http.Request{}
117-
request.URL = &url.URL{Path: restPath}
118-
c.prepareRequest(&request)
119-
token1 := request.Header.Get(requestHeaderOpcRetryToken)
120-
assert.NotEmpty(t, token1)
121-
c.prepareRequest(&request)
122-
token2 := request.Header.Get(requestHeaderOpcRetryToken)
123-
assert.NotEmpty(t, token2)
124-
assert.Equal(t, token1, token2)
125-
}
126-
127107
func TestDefaultHTTPDispatcher_transportNotSet(t *testing.T) {
128108
client := defaultHTTPDispatcher()
129109

@@ -473,8 +453,8 @@ func TestRetry_GetsSuccessfulResponseAfterMultipleAttempts(t *testing.T) {
473453
}
474454

475455
func TestRetryToken_GenerateMultipleTimes(t *testing.T) {
476-
token1 := generateRetryToken()
477-
token2 := generateRetryToken()
456+
token1 := RetryToken()
457+
token2 := RetryToken()
478458
assert.NotEqual(t, token1, token2)
479459
}
480460

common/common.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package common
44

55
import (
6+
"fmt"
67
"strings"
78
)
89

@@ -41,3 +42,12 @@ func StringToRegion(stringRegion string) (r Region) {
4142
}
4243
return
4344
}
45+
46+
// canStringBeRegion test if the string can be a region, if it can, returns the string as is, otherwise it
47+
// returns an error
48+
func canStringBeRegion(stringRegion string) (region string, err error) {
49+
if strings.Contains(stringRegion, " ") || stringRegion == "" {
50+
return "", fmt.Errorf("region can not be empty or have spaces")
51+
}
52+
return stringRegion, nil
53+
}

common/configuration.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (p rawConfigurationProvider) KeyFingerprint() (string, error) {
9292
}
9393

9494
func (p rawConfigurationProvider) Region() (string, error) {
95-
return p.region, nil
95+
return canStringBeRegion(p.region)
9696
}
9797

9898
// environmentConfigurationProvider reads configuration from environment variables
@@ -183,8 +183,10 @@ func (p environmentConfigurationProvider) Region() (value string, err error) {
183183
var ok bool
184184
if value, ok = os.LookupEnv(environmentVariable); !ok {
185185
err = fmt.Errorf("can not read region from environment variable %s", environmentVariable)
186+
return value, err
186187
}
187-
return
188+
189+
return canStringBeRegion(value)
188190
}
189191

190192
// fileConfigurationProvider. reads configuration information from a file
@@ -436,7 +438,11 @@ func (p fileConfigurationProvider) Region() (value string, err error) {
436438
}
437439

438440
value, err = presentOrError(info.Region, hasRegion, info.PresentConfiguration, "region")
439-
return
441+
if err != nil {
442+
return
443+
}
444+
445+
return canStringBeRegion(value)
440446
}
441447

442448
// A configuration provider that look for information in multiple configuration providers

common/configuration_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,72 @@ func TestRawConfigurationProvider(t *testing.T) {
112112

113113
}
114114

115+
func TestRawConfigurationProvider_BadRegion(t *testing.T) {
116+
var (
117+
testTenancy = "ocid1.tenancy.oc1..aaaaaaaaxf3fuazos"
118+
testUser = "ocid1.user.oc1..aaaaaaaa3p67n2kmpxnbcnff"
119+
testRegion = "us-ashburn-1 "
120+
testFingerprint = "af:81:71:8e:d2"
121+
)
122+
123+
c := NewRawConfigurationProvider(testTenancy, testUser, testRegion, testFingerprint, testPrivateKeyConf, nil)
124+
125+
user, err := c.UserOCID()
126+
assert.NoError(t, err)
127+
assert.Equal(t, user, testUser)
128+
129+
fingerprint, err := c.KeyFingerprint()
130+
assert.NoError(t, err)
131+
assert.Equal(t, fingerprint, testFingerprint)
132+
133+
_, err = c.Region()
134+
assert.Error(t, err)
135+
136+
rsaKey, err := c.PrivateRSAKey()
137+
assert.NoError(t, err)
138+
assert.NotEmpty(t, rsaKey)
139+
140+
keyID, err := c.KeyID()
141+
assert.NoError(t, err)
142+
assert.NotEmpty(t, keyID)
143+
144+
assert.Equal(t, keyID, "ocid1.tenancy.oc1..aaaaaaaaxf3fuazos/ocid1.user.oc1..aaaaaaaa3p67n2kmpxnbcnff/af:81:71:8e:d2")
145+
146+
}
147+
148+
func TestEnvironmentConfigurationProvider(t *testing.T) {
149+
envVars := []string{"region", "fingerprint", "user_ocid", "tenancy_ocid"}
150+
keyFile := writeTempFile(testPrivateKeyConf)
151+
defer removeFileFn(keyFile)
152+
153+
for _, v := range envVars {
154+
os.Setenv(fmt.Sprintf("OCI_TEST_%s", v), "someval")
155+
}
156+
os.Setenv("OCI_TEST_private_key_path", keyFile)
157+
158+
conf := ConfigurationProviderEnvironmentVariables("OCI_TEST", "")
159+
b, _ := IsConfigurationProviderValid(conf)
160+
assert.True(t, b)
161+
}
162+
163+
func TestEnvironmentConfigurationProvider_BadRegion(t *testing.T) {
164+
envVars := []string{"fingerprint", "user_ocid", "tenancy_ocid"}
165+
keyFile := writeTempFile(testPrivateKeyConf)
166+
defer removeFileFn(keyFile)
167+
168+
for _, v := range envVars {
169+
os.Setenv(fmt.Sprintf("OCI_TEST_%s", v), "someval")
170+
}
171+
os.Setenv("OCI_TEST_private_key_path", keyFile)
172+
os.Setenv("OCI_TEST_region", "asdfas ")
173+
174+
conf := ConfigurationProviderEnvironmentVariables("OCI_TEST", "")
175+
b, _ := IsConfigurationProviderValid(conf)
176+
assert.False(t, b)
177+
_, e := conf.Region()
178+
assert.Error(t, e)
179+
}
180+
115181
func TestFileConfigurationProvider_parseConfigFileData(t *testing.T) {
116182
data := `[DEFAULT]
117183
user=someuser
@@ -160,6 +226,27 @@ region=someregion
160226
}
161227
}
162228

229+
func TestFileConfigurationProvider_FromFileBadRegion(t *testing.T) {
230+
data := `[DEFAULT]
231+
user=someuser
232+
fingerprint=somefingerprint
233+
key_file=somelocation
234+
tenancy=sometenancy
235+
compartment = somecompartment
236+
region= asdf asdf
237+
`
238+
filename := writeTempFile(data)
239+
defer removeFileFn(filename)
240+
241+
c := fileConfigurationProvider{ConfigPath: filename, Profile: "DEFAULT"}
242+
fns := []func() (string, error){c.Region}
243+
244+
for _, fn := range fns {
245+
_, e := fn()
246+
assert.Error(t, e)
247+
}
248+
}
249+
163250
func TestFileConfigurationProvider_FromFileEmptyProfile(t *testing.T) {
164251
expected := []string{ttenancy, tuser, tfingerprint, tkeyfile}
165252
data := `
@@ -722,3 +809,32 @@ func TestExpandPath(t *testing.T) {
722809
})
723810
}
724811
}
812+
813+
func TestIsRegionValid(t *testing.T) {
814+
testIO := []struct {
815+
name string
816+
input string
817+
expected bool
818+
}{
819+
{"valid", "aasb asdf", true},
820+
{"valid", "aasb-asdf", false},
821+
{"empty", "", true},
822+
{"leading strings", " aasb", true},
823+
{"single leading string", " aasb", true},
824+
{"single trailing string", "aasb ", true},
825+
{"trailing string", "aasb ", true},
826+
{"single trailing and leading", " aasb ", true},
827+
{"trailing and leading", " aasb ", true},
828+
}
829+
830+
for _, tIO := range testIO {
831+
t.Run(tIO.name, func(t *testing.T) {
832+
_, err := canStringBeRegion(tIO.input)
833+
if tIO.expected {
834+
assert.Error(t, err)
835+
} else {
836+
assert.NoError(t, err)
837+
}
838+
})
839+
}
840+
}

common/helpers.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ func tryParsing(data []byte, layouts ...string) (tm time.Time, err error) {
149149
return
150150
}
151151

152+
// String returns string representation of SDKDate
153+
func (t *SDKDate) String() string {
154+
return t.Date.Format(sdkDateFormat)
155+
}
156+
157+
// NewSDKDateFromString parses the dateString into SDKDate
158+
func NewSDKDateFromString(dateString string) (*SDKDate, error) {
159+
parsedTime, err := time.Parse(sdkDateFormat, dateString)
160+
if err != nil {
161+
return nil, err
162+
}
163+
164+
return &SDKDate{Date: parsedTime}, nil
165+
}
166+
152167
// UnmarshalJSON unmarshals from json
153168
func (t *SDKTime) UnmarshalJSON(data []byte) (e error) {
154169
s := string(data)
@@ -222,3 +237,9 @@ func generateRandUUID() (string, error) {
222237

223238
return uuid, nil
224239
}
240+
241+
func makeACopy(original []string) []string {
242+
tmp := make([]string, len(original))
243+
copy(tmp, original)
244+
return tmp
245+
}

common/helpers_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,22 @@ func TestFormattedTimeUnMarshaling(t *testing.T) {
159159
}
160160

161161
}
162+
163+
func TestSDKDateToAndFromString(t *testing.T) {
164+
_, err := NewSDKDateFromString("InvalidFormat")
165+
s, _ := NewSDKDateFromString("2018-09-13")
166+
str := fmt.Sprintf("%s", s)
167+
168+
assert.Equal(t, "2018-09-13", str)
169+
assert.IsType(t, &time.ParseError{}, err)
170+
}
171+
172+
func TestMakeACopy(t *testing.T) {
173+
original := []string{"a", "b", "c"}
174+
175+
copy := makeACopy(original)
176+
177+
assert.Equal(t, original, copy)
178+
copy[0] = "mutate"
179+
assert.NotEqual(t, original, copy)
180+
}

common/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ func addToHeader(request *http.Request, value reflect.Value, field reflect.Struc
433433
return
434434
}
435435

436-
request.Header.Set(headerName, headerValue)
436+
request.Header.Add(headerName, headerValue)
437437
return
438438
}
439439

common/http_signer.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ var (
5050
}
5151
)
5252

53+
// DefaultGenericHeaders list of default generic headers that is used in signing
54+
func DefaultGenericHeaders() []string {
55+
return makeACopy(defaultGenericHeaders)
56+
}
57+
58+
// DefaultBodyHeaders list of default body headers that is used in signing
59+
func DefaultBodyHeaders() []string {
60+
return makeACopy(defaultBodyHeaders)
61+
}
62+
5363
// DefaultRequestSigner creates a signer with default parameters.
5464
func DefaultRequestSigner(provider KeyProvider) HTTPRequestSigner {
5565
return RequestSigner(provider, defaultGenericHeaders, defaultBodyHeaders)

common/http_signer_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,17 @@ func TestOCIRequestSigner_SignEmptyBody(t *testing.T) {
285285
assert.NotEmpty(t, r.Header.Get(requestHeaderAuthorization))
286286
assert.NotEmpty(t, r.Header.Get(requestHeaderXContentSHA256))
287287
}
288+
289+
func TestDefaultHeadersReturnsCopy(t *testing.T) {
290+
genericHeaders := DefaultGenericHeaders()
291+
bodyHeaders := DefaultBodyHeaders()
292+
293+
assert.Equal(t, defaultGenericHeaders, genericHeaders)
294+
assert.Equal(t, defaultBodyHeaders, bodyHeaders)
295+
296+
genericHeaders[0] = "mutate"
297+
bodyHeaders[0] = "mutate"
298+
299+
assert.NotEqual(t, defaultGenericHeaders, genericHeaders)
300+
assert.NotEqual(t, defaultBodyHeaders, bodyHeaders)
301+
}

common/http_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type updateUserRequest struct {
3838
UserID string `mandatory:"true" contributesTo:"path" name:"userId"`
3939
TestupdateUserDetails `contributesTo:"body"`
4040
IfMatch string `mandatory:"false" contributesTo:"header" name:"if-match"`
41+
HeaderValueOne string `mandatory:"false" contributesTo:"header" name:"listInHeader"`
42+
HeaderValueTwo string `mandatory:"false" contributesTo:"header" name:"listInHeader"`
4143
}
4244

4345
type TestcreateAPIKeyDetails struct {
@@ -101,11 +103,21 @@ func TestMakeDefault(t *testing.T) {
101103
}
102104

103105
func TestHttpMarshallerSimpleHeader(t *testing.T) {
104-
s := updateUserRequest{UserID: "id1", IfMatch: "n=as", TestupdateUserDetails: TestupdateUserDetails{Description: "name of"}}
106+
s := updateUserRequest{
107+
UserID: "id1",
108+
IfMatch: "n=as",
109+
TestupdateUserDetails: TestupdateUserDetails{Description: "name of"},
110+
HeaderValueOne: "1",
111+
HeaderValueTwo: "2",
112+
}
105113
request := MakeDefaultHTTPRequest(http.MethodPost, "/random")
106114
HTTPRequestMarshaller(s, &request)
107115
header := request.Header
108116
assert.True(t, header.Get(requestHeaderIfMatch) == "n=as")
117+
listInHeader := header["Listinheader"]
118+
assert.True(t, len(listInHeader) == 2)
119+
hone, htwo := listInHeader[0], listInHeader[1]
120+
assert.True(t, hone == "1" && htwo == "2")
109121
}
110122

111123
func TestHttpMarshallerSimpleStruct(t *testing.T) {

0 commit comments

Comments
 (0)