Skip to content

Commit

Permalink
Releasing version 1 5 0 (#110)
Browse files Browse the repository at this point in the history
thanks for review
  • Loading branch information
jasonyin authored May 17, 2018
1 parent da23606 commit bc848a8
Show file tree
Hide file tree
Showing 36 changed files with 415 additions and 61 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.

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

## 1.5.0 - 2018-05-17
### Added
- Support for backup or clone of multiple volumes at once using volume groups in the Block Storage service
- Support for the ability to optionally specify a compartment filter when listing exports in the File Storage service
- Support for tagging virtual cloud network resources in the Networking service
- Support for specifying the PARAVIRTUALIZED remote volume type when creating a virtual image or launching a new instance in the Compute service
- Support for tilde in private key path in configuration files

## 1.4.0 - 2018-05-03
### Added
- Support for ``event_name`` in Audit Service
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ $(TARGETS_CLEAN): clean-%:%
@echo "cleaning $<"
@-rm -rf $<

# clean all generated code under GEN_TARGETS folder
clean-generate:
for target in ${GEN_TARGETS}; do \
echo "cleaning $$target"; \
rm -rf $$target; \
done

pre-doc:
@echo "Rendering doc server to ${DOC_SERVER_URL}"
find . -name \*.go |xargs sed -i '' 's/{{DOC_SERVER_URL}}/${DOC_SERVER_URL}/g'
Expand Down
6 changes: 5 additions & 1 deletion common/auth/federation_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ var (
func newAuthClient(region common.Region, provider common.KeyProvider) *common.BaseClient {
signer := common.RequestSigner(provider, genericHeaders, bodyHeaders)
client := common.DefaultBaseClientWithSigner(signer)
client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "auth", string(region))
if region == common.RegionSEA {
client.Host = "https://auth.r1.oracleiaas.com"
} else {
client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "auth", string(region))
}
client.BasePath = "v1/x509"
return &client
}
Expand Down
23 changes: 20 additions & 3 deletions common/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"os"
"path"
"regexp"
"strings"
)
Expand Down Expand Up @@ -120,7 +121,8 @@ func (p environmentConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey,
return nil, fmt.Errorf("can not read PrivateKey from env variable: %s", environmentVariable)
}

pemFileContent, err := ioutil.ReadFile(value)
expandedPath := expandPath(value)
pemFileContent, err := ioutil.ReadFile(expandedPath)
if err != nil {
Debugln("Can not read PrivateKey location from environment variable: " + environmentVariable)
return
Expand Down Expand Up @@ -303,8 +305,21 @@ func parseConfigAtLine(start int, content []string) (info *configFileInfo, err e

}

// cleans and expands the path if it contains a tilde , returns the expanded path or the input path as is if not expansion
// was performed
func expandPath(filepath string) (expandedPath string) {
cleanedPath := path.Clean(filepath)
expandedPath = cleanedPath
if strings.HasPrefix(cleanedPath, "~/") {
rest := cleanedPath[2:]
expandedPath = path.Join(getHomeFolder(), rest)
}
return
}

func openConfigFile(configFilePath string) (data []byte, err error) {
data, err = ioutil.ReadFile(configFilePath)
expandedPath := expandPath(configFilePath)
data, err = ioutil.ReadFile(expandedPath)
if err != nil {
err = fmt.Errorf("can not read config file: %s due to: %s", configFilePath, err.Error())
}
Expand Down Expand Up @@ -395,7 +410,9 @@ func (p fileConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err err
if err != nil {
return
}
pemFileContent, err := ioutil.ReadFile(filePath)

expandedPath := expandPath(filePath)
pemFileContent, err := ioutil.ReadFile(expandedPath)
if err != nil {
err = fmt.Errorf("can not read PrivateKey from configuration file due to: %s", err.Error())
return
Expand Down
79 changes: 75 additions & 4 deletions common/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"path"
"strings"
)

var (
Expand Down Expand Up @@ -65,10 +67,8 @@ ufFtnLEj/5G9a8A//MFrXsXePUeBDEzjtEcjPGNxe0ZkuOgYx11Zc0R4oLI7LoHO
testKeyPassphrase = "goisfun"
)

func removeFileFn(filename string) func() {
return func() {
os.Remove(filename)
}
func removeFileFn(filename string) {
os.Remove(filename)
}

func writeTempFile(data string) (filename string) {
Expand Down Expand Up @@ -651,3 +651,74 @@ region=someregion
assert.NoError(t, err)
assert.NotNil(t, key)
}

func TestConfigurationWithTilde(t *testing.T) {
dataTpl := `[DEFAULT]
user=someuser
fingerprint=somefingerprint
key_file=%s
tenancy=sometenancy
compartment = somecompartment
region=someregion
`

tmpKeyLocation := path.Join(getHomeFolder(), "testKey")
e := ioutil.WriteFile(tmpKeyLocation, []byte(testEncryptedPrivateKeyConf), 777)
if e != nil {
assert.FailNow(t, e.Error())
}

newlocation := strings.Replace(tmpKeyLocation, getHomeFolder(), "~/", 1)
data := fmt.Sprintf(dataTpl, newlocation)
tmpConfFile := writeTempFile(data)

defer removeFileFn(tmpConfFile)
defer removeFileFn(tmpKeyLocation)

provider, err := ConfigurationProviderFromFile(tmpConfFile, testKeyPassphrase)
assert.NoError(t, err)
ok, err := IsConfigurationProviderValid(provider)
assert.NoError(t, err)
assert.True(t, ok)

fns := []func() (string, error){provider.TenancyOCID, provider.UserOCID, provider.KeyFingerprint}

for _, fn := range fns {
val, e := fn()
assert.NoError(t, e)
assert.NotEmpty(t, val)
}

key, err := provider.PrivateRSAKey()
assert.NoError(t, err)
assert.NotNil(t, key)
}

func TestExpandPath(t *testing.T) {
home := getHomeFolder()
testIO := []struct {
name, inPath, expectedPath string
}{
{
name: "should expand tilde and return appended home dir",
inPath: "~/somepath",
expectedPath: path.Join(home, "somepath"),
},
{
name: "should not do anything",
inPath: "/somepath/some/dir/~/file",
expectedPath: "/somepath/some/dir/~/file",
},
{
name: "should replace one tilde only",
inPath: "~/~/some/path",
expectedPath: path.Join(home, "~/some/path"),
},
}
for _, tio := range testIO {
t.Run(tio.name, func(t *testing.T) {
p := expandPath(tio.inPath)
assert.Equal(t, tio.expectedPath, p)
})
}
}
25 changes: 18 additions & 7 deletions common/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,22 +274,23 @@ func addToQuery(request *http.Request, value reflect.Value, field reflect.Struct
}

encoding := strings.ToLower(field.Tag.Get("collectionFormat"))
var collectionFormatStringValues []string
switch encoding {
case "csv":
case "csv", "multi":
if value.Kind() != reflect.Slice && value.Kind() != reflect.Array {
e = fmt.Errorf("query paramater is tagged as csv yet its type is neither an Array nor a Slice: %s", field.Name)
e = fmt.Errorf("query parameter is tagged as csv or multi yet its type is neither an Array nor a Slice: %s", field.Name)
break
}

numOfElements := value.Len()
stringValues := make([]string, numOfElements)
collectionFormatStringValues = make([]string, numOfElements)
for i := 0; i < numOfElements; i++ {
stringValues[i], e = toStringValue(value.Index(i), field)
collectionFormatStringValues[i], e = toStringValue(value.Index(i), field)
if e != nil {
break
}
}
queryParameterValue = strings.Join(stringValues, ",")
queryParameterValue = strings.Join(collectionFormatStringValues, ",")
case "":
queryParameterValue, e = toStringValue(value, field)
default:
Expand All @@ -305,18 +306,28 @@ func addToQuery(request *http.Request, value reflect.Value, field reflect.Struct
if omitEmpty, present := field.Tag.Lookup("omitEmpty"); present {
omitEmptyBool, _ := strconv.ParseBool(strings.ToLower(omitEmpty))
if queryParameterValue != "" || !omitEmptyBool {
query.Set(queryParameterName, queryParameterValue)
addToQueryForEncoding(&query, encoding, queryParameterName, queryParameterValue, collectionFormatStringValues)
} else {
Debugf("Omitting %s, is empty and omitEmpty tag is set", field.Name)
}
} else {
query.Set(queryParameterName, queryParameterValue)
addToQueryForEncoding(&query, encoding, queryParameterName, queryParameterValue, collectionFormatStringValues)
}

request.URL.RawQuery = query.Encode()
return
}

func addToQueryForEncoding(query *url.Values, encoding string, queryParameterName string, queryParameterValue string, collectionFormatStringValues []string) {
if encoding == "multi" {
for _, stringValue := range collectionFormatStringValues {
query.Add(queryParameterName, stringValue)
}
} else {
query.Set(queryParameterName, queryParameterValue)
}
}

// Adds to the path of the url in the order they appear in the structure
func addToPath(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
var additionalURLPathPart string
Expand Down
18 changes: 10 additions & 8 deletions common/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,16 @@ func TestHttpMarshalerAll(t *testing.T) {
includes := []inc{inc("One"), inc("Two")}

s := struct {
ID string `contributesTo:"path"`
Name string `contributesTo:"query" name:"name"`
When *SDKTime `contributesTo:"query" name:"when"`
Income float32 `contributesTo:"query" name:"income"`
Include []inc `contributesTo:"query" name:"includes" collectionFormat:"csv"`
Male bool `contributesTo:"header" name:"male"`
Details TestupdateUserDetails `contributesTo:"body"`
ID string `contributesTo:"path"`
Name string `contributesTo:"query" name:"name"`
When *SDKTime `contributesTo:"query" name:"when"`
Income float32 `contributesTo:"query" name:"income"`
Include []inc `contributesTo:"query" name:"includes" collectionFormat:"csv"`
IncludeMulti []inc `contributesTo:"query" name:"includesMulti" collectionFormat:"multi"`
Male bool `contributesTo:"header" name:"male"`
Details TestupdateUserDetails `contributesTo:"body"`
}{
"101", "tapir", now(), 3.23, includes, true, TestupdateUserDetails{Description: desc},
"101", "tapir", now(), 3.23, includes, includes, true, TestupdateUserDetails{Description: desc},
}
request := MakeDefaultHTTPRequest(http.MethodPost, "/")
e := HTTPRequestMarshaller(s, &request)
Expand All @@ -198,6 +199,7 @@ func TestHttpMarshalerAll(t *testing.T) {
assert.True(t, request.URL.Query().Get("income") == strconv.FormatFloat(float64(s.Income), 'f', 6, 32))
assert.True(t, request.URL.Query().Get("when") == when)
assert.True(t, request.URL.Query().Get("includes") == "One,Two")
assert.True(t, reflect.DeepEqual(request.URL.Query()["includesMulti"], []string{"One", "Two"}))
assert.Contains(t, content, "description")
assert.Equal(t, request.Header.Get(requestHeaderContentType), "application/json")
if val, ok := content["description"]; !ok || val != desc {
Expand Down
2 changes: 1 addition & 1 deletion common/version.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions core/core_compute_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,11 +980,7 @@ func (client ComputeClient) getWindowsInstanceInitialCredentials(ctx context.Con
// **stop** - power off
// **softreset** - ACPI shutdown and power on
// **reset** - power off and power on
// Note that the **stop** state has no effect on the resources you consume.
// Billing continues for instances that you stop, and related resources continue
// to apply against any relevant quotas. You must terminate an instance
// (TerminateInstance)
// to remove its resources from billing and quotas.
// For more information see Stopping and Starting an Instance (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/restartinginstance.htm).
func (client ComputeClient) InstanceAction(ctx context.Context, request InstanceActionRequest) (response InstanceActionResponse, err error) {
var ociResponse common.OCIResponse
policy := common.NoRetryPolicy()
Expand Down
12 changes: 6 additions & 6 deletions core/core_virtualnetwork_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3774,7 +3774,7 @@ func (client VirtualNetworkClient) listVirtualCircuits(ctx context.Context, requ
return response, err
}

// UpdateCpe Updates the specified CPE's display name.
// UpdateCpe Updates the specified CPE's display name or tags.
// Avoid entering confidential information.
func (client VirtualNetworkClient) UpdateCpe(ctx context.Context, request UpdateCpeRequest) (response UpdateCpeResponse, err error) {
var ociResponse common.OCIResponse
Expand Down Expand Up @@ -3934,7 +3934,7 @@ func (client VirtualNetworkClient) updateDhcpOptions(ctx context.Context, reques
return response, err
}

// UpdateDrg Updates the specified DRG's display name. Avoid entering confidential information.
// UpdateDrg Updates the specified DRG's display name or tags. Avoid entering confidential information.
func (client VirtualNetworkClient) UpdateDrg(ctx context.Context, request UpdateDrgRequest) (response UpdateDrgResponse, err error) {
var ociResponse common.OCIResponse
policy := common.NoRetryPolicy()
Expand Down Expand Up @@ -4013,7 +4013,7 @@ func (client VirtualNetworkClient) updateDrgAttachment(ctx context.Context, requ
return response, err
}

// UpdateIPSecConnection Updates the display name for the specified IPSec connection.
// UpdateIPSecConnection Updates the display name or tags for the specified IPSec connection.
// Avoid entering confidential information.
func (client VirtualNetworkClient) UpdateIPSecConnection(ctx context.Context, request UpdateIPSecConnectionRequest) (response UpdateIPSecConnectionResponse, err error) {
var ociResponse common.OCIResponse
Expand Down Expand Up @@ -4053,8 +4053,8 @@ func (client VirtualNetworkClient) updateIPSecConnection(ctx context.Context, re
return response, err
}

// UpdateInternetGateway Updates the specified Internet Gateway. You can disable/enable it, or change its display name.
// Avoid entering confidential information.
// UpdateInternetGateway Updates the specified Internet Gateway. You can disable/enable it, or change its display name
// or tags. Avoid entering confidential information.
// If the gateway is disabled, that means no traffic will flow to/from the internet even if there's
// a route rule that enables that traffic.
func (client VirtualNetworkClient) UpdateInternetGateway(ctx context.Context, request UpdateInternetGatewayRequest) (response UpdateInternetGatewayResponse, err error) {
Expand Down Expand Up @@ -4185,7 +4185,7 @@ func (client VirtualNetworkClient) updatePrivateIp(ctx context.Context, request
// * Move a reserved public IP to a different private IP.
// * Unassign a reserved public IP from a private IP (which returns it to your pool
// of reserved public IPs).
// * Change the display name for a public IP.
// * Change the display name or tags for a public IP.
// Assigning, moving, and unassigning a reserved public IP are asynchronous
// operations. Poll the public IP's `lifecycleState` to determine if the operation
// succeeded.
Expand Down
11 changes: 11 additions & 0 deletions core/cpe.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,21 @@ type Cpe struct {
// The public IP address of the on-premises router.
IpAddress *string `mandatory:"true" json:"ipAddress"`

// Defined tags for this resource. Each key is predefined and scoped to a namespace.
// For more information, see Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
// Example: `{"Operations": {"CostCenter": "42"}}`
DefinedTags map[string]map[string]interface{} `mandatory:"false" json:"definedTags"`

// A user-friendly name. Does not have to be unique, and it's changeable.
// Avoid entering confidential information.
DisplayName *string `mandatory:"false" json:"displayName"`

// Free-form tags for this resource. Each tag is a simple key-value pair with no
// predefined name, type, or namespace. For more information, see
// Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
// Example: `{"Department": "Finance"}`
FreeformTags map[string]string `mandatory:"false" json:"freeformTags"`

// The date and time the CPE was created, in the format defined by RFC3339.
// Example: `2016-08-25T21:10:29.600Z`
TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"`
Expand Down
11 changes: 11 additions & 0 deletions core/create_cpe_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,19 @@ type CreateCpeDetails struct {
// Example: `143.19.23.16`
IpAddress *string `mandatory:"true" json:"ipAddress"`

// Defined tags for this resource. Each key is predefined and scoped to a namespace.
// For more information, see Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
// Example: `{"Operations": {"CostCenter": "42"}}`
DefinedTags map[string]map[string]interface{} `mandatory:"false" json:"definedTags"`

// A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.
DisplayName *string `mandatory:"false" json:"displayName"`

// Free-form tags for this resource. Each tag is a simple key-value pair with no
// predefined name, type, or namespace. For more information, see
// Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
// Example: `{"Department": "Finance"}`
FreeformTags map[string]string `mandatory:"false" json:"freeformTags"`
}

func (m CreateCpeDetails) String() string {
Expand Down
Loading

0 comments on commit bc848a8

Please sign in to comment.