Skip to content

Commit a9e0563

Browse files
authored
Release 2019 08 27 (#185)
Releasing version v8.0.0
1 parent 836866c commit a9e0563

File tree

56 files changed

+2574
-45
lines changed

Some content is hidden

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

56 files changed

+2574
-45
lines changed

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,39 @@ 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+
## 8.0.0 - 2019-08-27
8+
### Added
9+
- Support for the Sao Paulo (GRU) region
10+
- Support for dedicated virtual machine hosts in the Compute service
11+
- Support for resource groups in metrics and alarms in the Monitoring service
12+
- Support for resource principle auth. Example can be found on [Github](https://github.com/oracle/oci-go-sdk/tree/master/example/example_resource_principal_function/README.md)
13+
14+
### Breaking changes
15+
- Breaking changes were made for following enum values
16+
- Before
17+
```golang
18+
autoscaling.ActionTypeEnum.ActionTypeBy
19+
keymanagement.CreateVaultDetailsVaultTypeEnum.CreateVaultDetailsVaultTypePrivate
20+
keymanagement.VaultSummaryVaultTypeEnum.VaultSummaryVaultTypePrivate
21+
keymanagement.VaultVaultTypeEnum.VaultVaultTypePrivate
22+
objectstorage.WorkRequestSummaryOperationTypeEnum.WorkRequestSummaryOperationTypeObject
23+
objectstorage.WorkRequestOperationTypeEnum.WorkRequestOperationTypeObject
24+
resourcemanager.LogEntryTypeEnum.LogEntryTypeConsole
25+
resourcemanager.WorkRequestOperationTypeEnum.WorkRequestOperationTypeCompartment
26+
```
27+
28+
- After
29+
```golang
30+
autoscaling.ActionTypeEnum.ActionTypeChangeCountBy
31+
keymanagement.CreateVaultDetailsVaultTypeEnum.CreateVaultDetailsVaultTypeVirtualPrivate
32+
keymanagement.VaultSummaryVaultTypeEnum.VaultSummaryVaultTypeVirtualPrivate
33+
keymanagement.VaultVaultTypeEnum.VaultVaultTypeVirtualPrivate
34+
objectstorage.WorkRequestSummaryOperationTypeEnum.WorkRequestSummaryOperationTypeCopyObject
35+
objectstorage.WorkRequestOperationTypeEnum.WorkRequestOperationTypeCopyObject
36+
resourcemanager.LogEntryTypeEnum.LogEntryTypeTerraformConsole
37+
resourcemanager.WorkRequestOperationTypeEnum.WorkRequestOperationTypeChangeStackCompartment
38+
```
39+
740
## 7.1.0 - 2019-08-20
841
### Added
942
- Support for the Limits service

autoscaling/action.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ type ActionTypeEnum string
3333

3434
// Set of constants representing the allowable values for ActionTypeEnum
3535
const (
36-
ActionTypeBy ActionTypeEnum = "CHANGE_COUNT_BY"
36+
ActionTypeChangeCountBy ActionTypeEnum = "CHANGE_COUNT_BY"
3737
)
3838

3939
var mappingActionType = map[string]ActionTypeEnum{
40-
"CHANGE_COUNT_BY": ActionTypeBy,
40+
"CHANGE_COUNT_BY": ActionTypeChangeCountBy,
4141
}
4242

4343
// GetActionTypeEnumValues Enumerates the set of values for ActionTypeEnum

common/auth/federation_client.go

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99
"crypto/rsa"
1010
"crypto/x509"
1111
"encoding/pem"
12+
"errors"
1213
"fmt"
1314
"github.com/oracle/oci-go-sdk/common"
15+
"io/ioutil"
1416
"net/http"
1517
"os"
1618
"strings"
@@ -21,10 +23,113 @@ import (
2123
// federationClient is a client to retrieve the security token for an instance principal necessary to sign a request.
2224
// It also provides the private key whose corresponding public key is used to retrieve the security token.
2325
type federationClient interface {
26+
ClaimHolder
2427
PrivateKey() (*rsa.PrivateKey, error)
2528
SecurityToken() (string, error)
2629
}
2730

31+
// ClaimHolder is implemented by any token interface that provides access to the security claims embedded in the token.
32+
type ClaimHolder interface {
33+
GetClaim(key string) (interface{}, error)
34+
}
35+
36+
type genericFederationClient struct {
37+
SessionKeySupplier sessionKeySupplier
38+
RefreshSecurityToken func() (securityToken, error)
39+
40+
securityToken securityToken
41+
mux sync.Mutex
42+
}
43+
44+
var _ federationClient = &genericFederationClient{}
45+
46+
func (c *genericFederationClient) PrivateKey() (*rsa.PrivateKey, error) {
47+
c.mux.Lock()
48+
defer c.mux.Unlock()
49+
50+
if err := c.renewKeyAndSecurityTokenIfNotValid(); err != nil {
51+
return nil, err
52+
}
53+
return c.SessionKeySupplier.PrivateKey(), nil
54+
}
55+
56+
func (c *genericFederationClient) SecurityToken() (token string, err error) {
57+
c.mux.Lock()
58+
defer c.mux.Unlock()
59+
60+
if err = c.renewKeyAndSecurityTokenIfNotValid(); err != nil {
61+
return "", err
62+
}
63+
return c.securityToken.String(), nil
64+
}
65+
66+
func (c *genericFederationClient) renewKeyAndSecurityTokenIfNotValid() (err error) {
67+
if c.securityToken == nil || !c.securityToken.Valid() {
68+
if err = c.renewKeyAndSecurityToken(); err != nil {
69+
return fmt.Errorf("failed to renew security token: %s", err.Error())
70+
}
71+
}
72+
return nil
73+
}
74+
75+
func (c *genericFederationClient) renewKeyAndSecurityToken() (err error) {
76+
common.Logf("Renewing keys for file based security token at: %v\n", time.Now().Format("15:04:05.000"))
77+
if err = c.SessionKeySupplier.Refresh(); err != nil {
78+
return fmt.Errorf("failed to refresh session key: %s", err.Error())
79+
}
80+
81+
common.Logf("Renewing security token at: %v\n", time.Now().Format("15:04:05.000"))
82+
if c.securityToken, err = c.RefreshSecurityToken(); err != nil {
83+
return fmt.Errorf("failed to refresh security token key: %s", err.Error())
84+
}
85+
common.Logf("Security token renewed at: %v\n", time.Now().Format("15:04:05.000"))
86+
return nil
87+
}
88+
89+
func (c *genericFederationClient) GetClaim(key string) (interface{}, error) {
90+
c.mux.Lock()
91+
defer c.mux.Unlock()
92+
93+
if err := c.renewKeyAndSecurityTokenIfNotValid(); err != nil {
94+
return nil, err
95+
}
96+
return c.securityToken.GetClaim(key)
97+
}
98+
99+
func newFileBasedFederationClient(securityTokenPath string, supplier sessionKeySupplier) (*genericFederationClient, error) {
100+
return &genericFederationClient{
101+
SessionKeySupplier: supplier,
102+
RefreshSecurityToken: func() (token securityToken, err error) {
103+
var content []byte
104+
if content, err = ioutil.ReadFile(securityTokenPath); err != nil {
105+
return nil, fmt.Errorf("failed to read security token from :%s. Due to: %s", securityTokenPath, err.Error())
106+
}
107+
108+
var newToken securityToken
109+
if newToken, err = newInstancePrincipalToken(string(content)); err != nil {
110+
return nil, fmt.Errorf("failed to read security token from :%s. Due to: %s", securityTokenPath, err.Error())
111+
}
112+
113+
return newToken, nil
114+
},
115+
}, nil
116+
}
117+
118+
func newStaticFederationClient(sessionToken string, supplier sessionKeySupplier) (*genericFederationClient, error) {
119+
var newToken securityToken
120+
var err error
121+
if newToken, err = newInstancePrincipalToken(string(sessionToken)); err != nil {
122+
return nil, fmt.Errorf("failed to read security token. Due to: %s", err.Error())
123+
}
124+
125+
return &genericFederationClient{
126+
SessionKeySupplier: supplier,
127+
RefreshSecurityToken: func() (token securityToken, err error) {
128+
return newToken, nil
129+
},
130+
}, nil
131+
}
132+
28133
// x509FederationClient retrieves a security token from Auth service.
29134
type x509FederationClient struct {
30135
tenancyID string
@@ -197,6 +302,16 @@ func (c *x509FederationClient) getSecurityToken() (securityToken, error) {
197302
return newInstancePrincipalToken(response.Token.Token)
198303
}
199304

305+
func (c *x509FederationClient) GetClaim(key string) (interface{}, error) {
306+
c.mux.Lock()
307+
defer c.mux.Unlock()
308+
309+
if err := c.renewSecurityTokenIfNotValid(); err != nil {
310+
return nil, err
311+
}
312+
return c.securityToken.GetClaim(key)
313+
}
314+
200315
type x509FederationRequest struct {
201316
X509FederationDetails `contributesTo:"body"`
202317
}
@@ -249,6 +364,103 @@ type sessionKeySupplier interface {
249364
PublicKeyPemRaw() []byte
250365
}
251366

367+
//genericKeySupplier implements sessionKeySupplier and provides an arbitrary refresh mechanism
368+
type genericKeySupplier struct {
369+
RefreshFn func() (*rsa.PrivateKey, []byte, error)
370+
371+
privateKey *rsa.PrivateKey
372+
publicKeyPemRaw []byte
373+
}
374+
375+
func (s genericKeySupplier) PrivateKey() *rsa.PrivateKey {
376+
if s.privateKey == nil {
377+
return nil
378+
}
379+
380+
c := *s.privateKey
381+
return &c
382+
}
383+
384+
func (s genericKeySupplier) PublicKeyPemRaw() []byte {
385+
if s.publicKeyPemRaw == nil {
386+
return nil
387+
}
388+
389+
c := make([]byte, len(s.publicKeyPemRaw))
390+
copy(c, s.publicKeyPemRaw)
391+
return c
392+
}
393+
394+
func (s *genericKeySupplier) Refresh() (err error) {
395+
privateKey, publicPem, err := s.RefreshFn()
396+
if err != nil {
397+
return err
398+
}
399+
400+
s.privateKey = privateKey
401+
s.publicKeyPemRaw = publicPem
402+
return nil
403+
}
404+
405+
// create a sessionKeySupplier that reads keys from file every time it refreshes
406+
func newFileBasedKeySessionSupplier(privateKeyPemPath string, passphrasePath *string) (*genericKeySupplier, error) {
407+
return &genericKeySupplier{
408+
RefreshFn: func() (*rsa.PrivateKey, []byte, error) {
409+
var err error
410+
var passContent []byte
411+
if passphrasePath != nil {
412+
if passContent, err = ioutil.ReadFile(*passphrasePath); err != nil {
413+
return nil, nil, fmt.Errorf("can not read passphrase from file: %s, due to %s", *passphrasePath, err.Error())
414+
}
415+
}
416+
417+
var keyPemContent []byte
418+
if keyPemContent, err = ioutil.ReadFile(privateKeyPemPath); err != nil {
419+
return nil, nil, fmt.Errorf("can not read private privateKey pem from file: %s, due to %s", privateKeyPemPath, err.Error())
420+
}
421+
422+
var privateKey *rsa.PrivateKey
423+
if privateKey, err = common.PrivateKeyFromBytesWithPassword(keyPemContent, passContent); err != nil {
424+
return nil, nil, fmt.Errorf("can not create private privateKey from contents of: %s, due to: %s", privateKeyPemPath, err.Error())
425+
}
426+
427+
var publicKeyAsnBytes []byte
428+
if publicKeyAsnBytes, err = x509.MarshalPKIXPublicKey(privateKey.Public()); err != nil {
429+
return nil, nil, fmt.Errorf("failed to marshal the public part of the new keypair: %s", err.Error())
430+
}
431+
publicKeyPemRaw := pem.EncodeToMemory(&pem.Block{
432+
Type: "PUBLIC KEY",
433+
Bytes: publicKeyAsnBytes,
434+
})
435+
return privateKey, publicKeyPemRaw, nil
436+
},
437+
}, nil
438+
}
439+
440+
func newStaticKeySessionSupplier(privateKeyPemContent, passphrase []byte) (*genericKeySupplier, error) {
441+
var err error
442+
var privateKey *rsa.PrivateKey
443+
444+
if privateKey, err = common.PrivateKeyFromBytesWithPassword(privateKeyPemContent, passphrase); err != nil {
445+
return nil, fmt.Errorf("can not create private privateKey, due to: %s", err.Error())
446+
}
447+
448+
var publicKeyAsnBytes []byte
449+
if publicKeyAsnBytes, err = x509.MarshalPKIXPublicKey(privateKey.Public()); err != nil {
450+
return nil, fmt.Errorf("failed to marshal the public part of the new keypair: %s", err.Error())
451+
}
452+
publicKeyPemRaw := pem.EncodeToMemory(&pem.Block{
453+
Type: "PUBLIC KEY",
454+
Bytes: publicKeyAsnBytes,
455+
})
456+
457+
return &genericKeySupplier{
458+
RefreshFn: func() (key *rsa.PrivateKey, bytes []byte, err error) {
459+
return privateKey, publicKeyPemRaw, nil
460+
},
461+
}, nil
462+
}
463+
252464
// inMemorySessionKeySupplier implements sessionKeySupplier to vend an RSA keypair.
253465
// Refresh() generates a new RSA keypair with a random source, and keeps it in memory.
254466
//
@@ -311,6 +523,8 @@ func (s *inMemorySessionKeySupplier) PublicKeyPemRaw() []byte {
311523
type securityToken interface {
312524
fmt.Stringer
313525
Valid() bool
526+
527+
ClaimHolder
314528
}
315529

316530
type instancePrincipalToken struct {
@@ -333,3 +547,15 @@ func (t *instancePrincipalToken) String() string {
333547
func (t *instancePrincipalToken) Valid() bool {
334548
return !t.jwtToken.expired()
335549
}
550+
551+
var (
552+
// ErrNoSuchClaim is returned when a token does not hold the claim sought
553+
ErrNoSuchClaim = errors.New("no such claim")
554+
)
555+
556+
func (t *instancePrincipalToken) GetClaim(key string) (interface{}, error) {
557+
if value, ok := t.jwtToken.payload[key]; ok {
558+
return value, nil
559+
}
560+
return nil, ErrNoSuchClaim
561+
}

common/auth/federation_client_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,8 @@ func (m *mockSecurityToken) Valid() bool {
559559
args := m.Called()
560560
return args.Bool(0)
561561
}
562+
563+
func (m *mockSecurityToken) GetClaim(key string) (interface{}, error) {
564+
args := m.Called(key)
565+
return args.Get(0), args.Error(1)
566+
}

common/auth/instance_principal_key_provider_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,8 @@ func (m *mockFederationClient) SecurityToken() (string, error) {
118118
args := m.Called()
119119
return args.String(0), args.Error(1)
120120
}
121+
122+
func (m *mockFederationClient) GetClaim(key string) (interface{}, error) {
123+
args := m.Called(key)
124+
return args.Get(0), args.Error(1)
125+
}

0 commit comments

Comments
 (0)