Skip to content

Commit 37d08a7

Browse files
authored
Release v1.1.0 (#102)
1 parent 36126af commit 37d08a7

File tree

276 files changed

+11369
-370
lines changed

Some content is hidden

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

276 files changed

+11369
-370
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
.idea/
99
*.swp
1010
.vscode/*
11-
11+
target/
12+
bin/

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66

77

8+
## 1.1.0 - 2018-03-27
9+
### Added
10+
- Support for DNS service
11+
- Support for File Storage service
12+
- Support for PathRouteSets and Listeners in Load Balancing service
13+
- Support for Public IPs in Core Services
14+
- Support for Dynamic Groups in Identity service
15+
- Support for tagging in Core Services and Identity service. Example can be found on [Github](https://github.com/oracle/oci-go-sdk/tree/master/example/example_tagging_test.go)
16+
- Fix ComposingConfigurationProvider to not accept a nil ConfigurationProvider
17+
- Support for passphrase configuration to FileConfiguration provider
18+
819
## 1.0.0 - 2018-02-28 Initial Release
920
### Added
1021
- Support for Audit service

Makefile

+1-1
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
3+
GEN_TARGETS = identity core objectstorage loadbalancer database audit dns filestorage
44
NON_GEN_TARGETS = common common/auth
55
TARGETS = $(NON_GEN_TARGETS) $(GEN_TARGETS)
66

common/auth/certificate_retriever.go

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ func (r *urlBasedX509CertificateRetriever) renewCertificate(url string) (certifi
8282
certificatePemRaw = body.Bytes()
8383
var block *pem.Block
8484
block, _ = pem.Decode(certificatePemRaw)
85+
if block == nil {
86+
return nil, nil, fmt.Errorf("failed to parse the new certificate, not valid pem data")
87+
}
88+
8589
if certificate, err = x509.ParseCertificate(block.Bytes); err != nil {
8690
return nil, nil, fmt.Errorf("failed to parse the new certificate: %s", err.Error())
8791
}

common/auth/certificate_retriever_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ import (
1717
"time"
1818
)
1919

20+
func TestUrlBasedX509CertificateRetriever_BadCertificate(t *testing.T) {
21+
expectedCert := make([]byte, 100)
22+
rand.Read(expectedCert)
23+
certServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24+
fmt.Fprint(w, string(expectedCert))
25+
}))
26+
defer certServer.Close()
27+
28+
retriever := newURLBasedX509CertificateRetriever(certServer.URL, "", "")
29+
err := retriever.Refresh()
30+
31+
assert.Error(t, err)
32+
}
2033
func TestUrlBasedX509CertificateRetriever_RefreshWithoutPrivateKeyUrl(t *testing.T) {
2134
_, expectedCert := generateRandomCertificate()
2235
certServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

common/common.go

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const (
1818
RegionIAD Region = "us-ashburn-1"
1919
//RegionFRA region FRA
2020
RegionFRA Region = "eu-frankfurt-1"
21+
//RegionLHR region LHR
22+
RegionLHR Region = "uk-london-1"
2123
)
2224

2325
//StringToRegion convert a string to Region type
@@ -31,6 +33,8 @@ func StringToRegion(stringRegion string) (r Region) {
3133
r = RegionIAD
3234
case "fra", "eu-frankfurt-1":
3335
r = RegionFRA
36+
case "lhr", "uk-london-1":
37+
r = RegionLHR
3438
default:
3539
r = Region(stringRegion)
3640
Debugf("region named: %s, is not recognized", stringRegion)

common/configuration.go

+21-5
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (p rawConfigurationProvider) Region() (string, error) {
9595
}
9696

9797
// environmentConfigurationProvider reads configuration from environment variables
98-
type environmentConfigurationProvider struct { // TODO: Support Instance Principal
98+
type environmentConfigurationProvider struct {
9999
PrivateKeyPassword string
100100
EnvironmentVariablePrefix string
101101
}
@@ -186,7 +186,7 @@ func (p environmentConfigurationProvider) Region() (value string, err error) {
186186
}
187187

188188
// fileConfigurationProvider. reads configuration information from a file
189-
type fileConfigurationProvider struct { // TODO: Support Instance Principal
189+
type fileConfigurationProvider struct {
190190
//The path to the configuration file
191191
ConfigPath string
192192

@@ -227,8 +227,8 @@ func ConfigurationProviderFromFileWithProfile(configFilePath, profile, privateKe
227227
}
228228

229229
type configFileInfo struct {
230-
UserOcid, Fingerprint, KeyFilePath, TenancyOcid, Region string
231-
PresentConfiguration byte
230+
UserOcid, Fingerprint, KeyFilePath, TenancyOcid, Region, Passphrase string
231+
PresentConfiguration byte
232232
}
233233

234234
const (
@@ -237,6 +237,7 @@ const (
237237
hasFingerprint
238238
hasRegion
239239
hasKeyFile
240+
hasPassphrase
240241
none
241242
)
242243

@@ -277,6 +278,9 @@ func parseConfigAtLine(start int, content []string) (info *configFileInfo, err e
277278

278279
splits := strings.Split(line, "=")
279280
switch key, value := strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1]); strings.ToLower(key) {
281+
case "passphrase":
282+
configurationPresent = configurationPresent | hasPassphrase
283+
info.Passphrase = value
280284
case "user":
281285
configurationPresent = configurationPresent | hasUser
282286
info.UserOcid = value
@@ -397,7 +401,13 @@ func (p fileConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err err
397401
return
398402
}
399403

400-
key, err = PrivateKeyFromBytes(pemFileContent, &p.PrivateKeyPassword)
404+
password := p.PrivateKeyPassword
405+
406+
if password == "" && ((info.PresentConfiguration & hasPassphrase) == hasPassphrase) {
407+
password = info.Passphrase
408+
}
409+
410+
key, err = PrivateKeyFromBytes(pemFileContent, &password)
401411
return
402412
}
403413

@@ -424,6 +434,12 @@ func ComposingConfigurationProvider(providers []ConfigurationProvider) (Configur
424434
if len(providers) == 0 {
425435
return nil, fmt.Errorf("providers can not be an empty slice")
426436
}
437+
438+
for i, p := range providers {
439+
if p == nil {
440+
return nil, fmt.Errorf("provider in position: %d is nil. ComposingConfiurationProvider does not support nil values", i)
441+
}
442+
}
427443
return composingConfigurationProvider{Providers: providers}, nil
428444
}
429445

common/configuration_test.go

+208
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,37 @@ gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
3232
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
3333
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
3434
-----END RSA PRIVATE KEY-----`
35+
testEncryptedPrivateKeyConf = `-----BEGIN RSA PRIVATE KEY-----
36+
Proc-Type: 4,ENCRYPTED
37+
DEK-Info: DES-EDE3-CBC,05B7ACED45203763
38+
39+
bKbv8X2oyfxwp55w3MVKj1bfWnhvQgyqJ/1dER53STao3qRS26epRoBc0BoLtrNj
40+
L+Wfa3NeuEinetDYKRwWGHZqvbs/3PD5OKIXW1y/EAlg1vr6JWX8KxhQ0PzGJOdQ
41+
KPcB2duDtlNJ4awoGEsSp/qYyJLKOKpcz893OWTe3Oi9aQpzuL+kgH6VboCUdwdl
42+
Ub7YyTMFBkGzzjOXV/iSJDaxvVUIZt7CQS/DkBq4IHXX8iFUDzh6L297/BuRp3Q8
43+
hDL4yQacl2F2yCWpUoNNkbPpe6oOmL8JHrxXxo+u0pSJELXx0sjWMn7bSRfgFFIE
44+
k08y4wXZeoxHiQDhHmQI+YTikgqnxEWtDYhHYvWudVQY6Wcf1Fdypa1v4I3gv4S9
45+
QwjDRbRcrnPxMkxWmQEM6xGCwWBj8wmFyIQoEA5MJuQZxWdyptEKVtwwI1TB9etn
46+
SlXPUl125dYYBu2ynmR96nBVEZd6BWl+iFeeZnqxDHABOB0AvpI61vt/6c7tIimC
47+
YciZs74XZH/ERs55p0Ng/G23XNu+UGQQptrr2kyRR5JrS0UGKVjivydIK5Lus4c4
48+
NTaKyEJNMbvSUGY5SLfxyp6HZnlbr4aCDAk62+2ZUotr+sVXplCpuxoSc2Qlw0en
49+
y+plCvd2RdQ/EzIFkpi9V/snIvbMvH3Sp/HqFDG8GehFTRvwpCIVqWC+BZYeaERX
50+
n2P4jODz2M8Ns7txv1nB4CyxWgu19398Zit0K0QmG24kCJtLg9spEOmKtoIuVTnU
51+
9ydxmHQjNNtyH+RceZFn07IkWvPveo2BXpK4K9DXE39Z/g1nQzwTqgN8diXxwRuN
52+
Ge97lBWup4vP1TV8nyHW2AppgFVuPynO+XWfZUuCUzxNseB+XOyeqitoM4uvSNax
53+
DQmokjIf4qXC/46EnJ/fd9Ydz4GVQ4TYyxwNCBJK39RdUOcUtyI+A3IbZ+vt2HIV
54+
eiIN2BhdnwbvNTbPs9nc9McM2NtACqDGQsIzRdXcQ8SFDP2DnTVjGu5E8H9dnVrd
55+
FcuUnA9TIbfBkRHOS7yoDHOo4j28g6xePDV5tK0L5C2yyDh+bwWnO5AIg/gdpnuH
56+
wxIZUxFwkD4GvOVtj5Y4W5L+Uy3c94stMPbHE+zGN75DdQRy5aVbDjWqXRB9AEQN
57+
+NSb526oqhv0JyYlZmCqz2ydBxkT4FsShZv/34pkRr3qL5FSTAQTXQAZdiQQbMTe
58+
H3zKyu4GbEUV9WsyriqSq27ptMwFfIqN1NdsWeVWN1mXf2KZDn61EgleeQXmdSZu
59+
XM4Z1n98xjYDwdCkF738j+oRAlSUThBeU/hYbH6Ysff6ON9MPBAAKy3ZxM5tF86e
60+
l0x20lpND2QLLDZbsg/LrCrE6ZzpWkXn4w4PG4lWMAqph0BebSkFqXvUvuds3c39
61+
yptNH3FsyqeyM9kDwbDpBQAvpsDIQJfwAbQPLAiQJhpbixZyG9lqhkKOhYTZhU3l
62+
ufFtnLEj/5G9a8A//MFrXsXePUeBDEzjtEcjPGNxe0ZkuOgYx11Zc0R4oLI7LoHO
63+
07vtw4qCH4hztCJ5+JOUac6sGcILFRc4vSQQ15Cg5QEdBiSbQ/yo1P0hbNtSvnwO
64+
-----END RSA PRIVATE KEY-----`
65+
testKeyPassphrase = "goisfun"
3566
)
3667

3768
func removeFileFn(filename string) func() {
@@ -443,3 +474,180 @@ func TestComposingConfigurationProvider_MultipleFilesNoConf(t *testing.T) {
443474
assert.Error(t, e)
444475
}
445476
}
477+
478+
func TestComposingConfigurationProvider_FirstConfigWrong(t *testing.T) {
479+
dataTpl0 := ``
480+
dataTpl := `[DEFAULT]
481+
user=someuser
482+
fingerprint=somefingerprint
483+
key_file=%s
484+
tenancy=sometenancy
485+
compartment = somecompartment
486+
region=someregion
487+
`
488+
489+
keyFile := writeTempFile(testPrivateKeyConf)
490+
data := fmt.Sprintf(dataTpl, keyFile)
491+
tmpConfFile0 := writeTempFile(dataTpl0)
492+
tmpConfFile := writeTempFile(data)
493+
494+
defer removeFileFn(tmpConfFile)
495+
defer removeFileFn(tmpConfFile0)
496+
defer removeFileFn(keyFile)
497+
498+
c0, _ := ConfigurationProviderFromFile(tmpConfFile0, "")
499+
c1, _ := ConfigurationProviderFromFile("/dev/nowhere", "")
500+
p0 := ConfigurationProviderEnvironmentVariables("OCI", os.Getenv("BLAH"))
501+
c, _ := ConfigurationProviderFromFile(tmpConfFile, "")
502+
503+
provider, ec := ComposingConfigurationProvider([]ConfigurationProvider{p0, c0, c1, c})
504+
assert.NoError(t, ec)
505+
ok, err := IsConfigurationProviderValid(provider)
506+
assert.NoError(t, err)
507+
assert.True(t, ok)
508+
509+
fns := []func() (string, error){provider.TenancyOCID, provider.UserOCID, provider.KeyFingerprint}
510+
511+
for _, fn := range fns {
512+
val, e := fn()
513+
assert.NoError(t, e)
514+
assert.NotEmpty(t, val)
515+
}
516+
key, _ := provider.PrivateRSAKey()
517+
assert.NotNil(t, key)
518+
}
519+
520+
func TestComposingConfigurationProvider_NilConfiguration(t *testing.T) {
521+
dataTpl := `[DEFAULT]
522+
user=someuser
523+
fingerprint=somefingerprint
524+
key_file=%s
525+
tenancy=sometenancy
526+
compartment = somecompartment
527+
region=someregion
528+
`
529+
530+
keyFile := writeTempFile(testPrivateKeyConf)
531+
data := fmt.Sprintf(dataTpl, keyFile)
532+
tmpConfFile := writeTempFile(data)
533+
534+
defer removeFileFn(tmpConfFile)
535+
defer removeFileFn(keyFile)
536+
537+
c1, _ := ConfigurationProviderFromFile("/dev/nowhere", "")
538+
p0 := ConfigurationProviderEnvironmentVariables("OCI", os.Getenv("BLAH"))
539+
c, _ := ConfigurationProviderFromFile(tmpConfFile, "")
540+
541+
_, ec := ComposingConfigurationProvider([]ConfigurationProvider{p0, nil, c1, c})
542+
assert.Error(t, ec)
543+
}
544+
545+
func TestComposingConfigurationProvider_WithEncryptedKeyPassphraseInConfig(t *testing.T) {
546+
dataTpl := `[DEFAULT]
547+
user=someuser
548+
fingerprint=somefingerprint
549+
key_file=%s
550+
tenancy=sometenancy
551+
compartment = somecompartment
552+
region=someregion
553+
passphrase=%s
554+
`
555+
556+
keyFile := writeTempFile(testEncryptedPrivateKeyConf)
557+
data := fmt.Sprintf(dataTpl, keyFile, testKeyPassphrase)
558+
tmpConfFile := writeTempFile(data)
559+
560+
defer removeFileFn(tmpConfFile)
561+
defer removeFileFn(keyFile)
562+
563+
provider, err := ConfigurationProviderFromFile(tmpConfFile, "")
564+
assert.NoError(t, err)
565+
ok, err := IsConfigurationProviderValid(provider)
566+
assert.NoError(t, err)
567+
assert.True(t, ok)
568+
569+
fns := []func() (string, error){provider.TenancyOCID, provider.UserOCID, provider.KeyFingerprint}
570+
571+
for _, fn := range fns {
572+
val, e := fn()
573+
assert.NoError(t, e)
574+
assert.NotEmpty(t, val)
575+
}
576+
577+
key, err := provider.PrivateRSAKey()
578+
assert.NoError(t, err)
579+
assert.NotNil(t, key)
580+
}
581+
582+
func TestComposingConfigurationProvider_WithEncryptedKeyOverridePassphrase(t *testing.T) {
583+
dataTpl := `[DEFAULT]
584+
user=someuser
585+
fingerprint=somefingerprint
586+
key_file=%s
587+
tenancy=sometenancy
588+
compartment = somecompartment
589+
region=someregion
590+
passphrase=%s
591+
`
592+
593+
keyFile := writeTempFile(testEncryptedPrivateKeyConf)
594+
data := fmt.Sprintf(dataTpl, keyFile, "thewrongpassphrase")
595+
tmpConfFile := writeTempFile(data)
596+
597+
defer removeFileFn(tmpConfFile)
598+
defer removeFileFn(keyFile)
599+
600+
provider, err := ConfigurationProviderFromFile(tmpConfFile, testKeyPassphrase)
601+
assert.NoError(t, err)
602+
ok, err := IsConfigurationProviderValid(provider)
603+
assert.NoError(t, err)
604+
assert.True(t, ok)
605+
606+
fns := []func() (string, error){provider.TenancyOCID, provider.UserOCID, provider.KeyFingerprint}
607+
608+
for _, fn := range fns {
609+
val, e := fn()
610+
assert.NoError(t, e)
611+
assert.NotEmpty(t, val)
612+
}
613+
614+
key, err := provider.PrivateRSAKey()
615+
assert.NoError(t, err)
616+
assert.NotNil(t, key)
617+
}
618+
619+
func TestComposingConfigurationProvider_WithEncryptedKeyNoConfig(t *testing.T) {
620+
dataTpl := `[DEFAULT]
621+
user=someuser
622+
fingerprint=somefingerprint
623+
key_file=%s
624+
tenancy=sometenancy
625+
compartment = somecompartment
626+
region=someregion
627+
`
628+
629+
keyFile := writeTempFile(testEncryptedPrivateKeyConf)
630+
data := fmt.Sprintf(dataTpl, keyFile)
631+
tmpConfFile := writeTempFile(data)
632+
633+
defer removeFileFn(tmpConfFile)
634+
defer removeFileFn(keyFile)
635+
636+
provider, err := ConfigurationProviderFromFile(tmpConfFile, testKeyPassphrase)
637+
assert.NoError(t, err)
638+
ok, err := IsConfigurationProviderValid(provider)
639+
assert.NoError(t, err)
640+
assert.True(t, ok)
641+
642+
fns := []func() (string, error){provider.TenancyOCID, provider.UserOCID, provider.KeyFingerprint}
643+
644+
for _, fn := range fns {
645+
val, e := fn()
646+
assert.NoError(t, e)
647+
assert.NotEmpty(t, val)
648+
}
649+
650+
key, err := provider.PrivateRSAKey()
651+
assert.NoError(t, err)
652+
assert.NotNil(t, key)
653+
}

common/http.go

+5
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ func addToPath(request *http.Request, value reflect.Value, field reflect.StructF
301301
return fmt.Errorf("can not marshal to path in request for field %s. Due to %s", field.Name, e.Error())
302302
}
303303

304+
// path should not be empty for any operations
305+
if len(additionalURLPathPart) == 0 {
306+
return fmt.Errorf("value cannot be empty for field %s in path", field.Name)
307+
}
308+
304309
if request.URL == nil {
305310
request.URL = &url.URL{}
306311
request.URL.Path = ""

0 commit comments

Comments
 (0)