GithubHelp home page GithubHelp logo

go-cfclient's Introduction

go-cfclient

build workflow GoDoc Report card

Overview

go-cfclient is a go module library to assist you in writing apps that need to interact the Cloud Foundry Cloud Controller v3 API. The v2 API is no longer supported, however if you really need to use the older API you may use the go-cfclient v2 branch and releases.

NOTE - The v3 version in the main branch is currently under development and may have breaking changes until a v3.0.0 release is cut. Until then, you may want to pin to a specific v3.0.0-alpha.x release.

Installation

go-cfclient is compatible with modern Go releases in module mode, with Go installed:

go get github.com/cloudfoundry/go-cfclient/v3

Will resolve and add the package to the current development module, along with its dependencies. Eventually this library will cut releases that will be tagged with v3.0.0, v3.0.1 etc, see the Versioning section below.

Usage

Using go modules import the client, config and resource packages:

import (
    "github.com/cloudfoundry/go-cfclient/v3/client"
    "github.com/cloudfoundry/go-cfclient/v3/config"
    "github.com/cloudfoundry/go-cfclient/v3/resource"
)

Authentication

Construct a new CF client configuration object. The configuration object configures how the client will authenticate to the CF API. There are various supported auth mechanisms.

The simplest being - use the existing CF CLI configuration and auth token:

cfg, _ := config.NewFromCFHome()
cf, _ := client.New(cfg)

Username and password:

cfg, _ := config.New("https://api.example.org", config.UserPassword("user", "pass"))
cf, _ := client.New(cfg)

Client and client secret:

cfg, _ := config.New("https://api.example.org", config.ClientCredentials("cf", "secret"))
cf, _ := client.New(cfg)

Static OAuth token, which requires both an access and refresh token:

cfg, _ := config.New("https://api.example.org", config.Token(accessToken, refreshToken))
cf, _ := client.New(cfg)

For more detailed examples of using the various authentication and configuration options, see the auth example.

Resources

The services of a client divide the API into logical chunks and correspond to the structure of the CF API documentation at https://v3-apidocs.cloudfoundry.org. In other words each major resource type has its own service client that is accessible via the main client instance.

apps, _ := cf.Applications.ListAll(context.Background(), nil)
for _, app := range apps {
    fmt.Printf("Application %s is %s\n", app.Name, app.State)
}

All clients and their functions that interact with the CF API live in the client package. The client package is responsible for making HTTP requests using the resources defined in the resource package. All generic serializable resource definitions live in the resource package and could be reused with other client's outside this library.

NOTE - Using the context package you can easily pass cancellation signals and deadlines to various client calls for handling a request. In case there is no context available, then context.Background() can be used as a starting point.

Pagination

All requests for resource collections (apps, orgs, spaces etc) support pagination. Pagination options are described in the client.ListOptions struct and passed to the list methods directly or as an embedded type of a more specific list options struct (for example client.AppListOptions).

Example iterating through all apps one page at a time:

opts := client.NewAppListOptions()
for {
    apps, pager, _ := cf.Applications.List(context.Background(), opts)
    for _, app := range apps {
        fmt.Printf("Application %s is %s\n", app.Name, app.State)
    }  
    if !pager.HasNextPage() {
        break
    }
    pager.NextPage(opts)
}

If you'd rather get all of the resources in one go and not worry about paging, every collection has a corresponding All method that gathers all the resources from every page before returning. While this may be convenient, this could have negative performance consequences on larger foundations/collections.

opts := client.NewAppListOptions()
apps, _ := cf.Applications.ListAll(context.Background(), opts)
for _, app := range apps {
    fmt.Printf("Application %s is %s\n", app.Name, app.State)
}

Asynchronous Jobs

Some API calls are long-running so immediately return a JobID (GUID) instead of waiting and returning a resource. In those cases you only know if the job was accepted. You will need to poll the Job API to find out when the job finishes. There's a PollComplete utility function that you can use to block until the job finishes:

jobGUID, err := cf.Manifests.ApplyManifest(context.Background(), spaceGUID, manifest))
if err != nil {
    return err
}
opts := client.NewPollingOptions()
err = cf.Jobs.PollComplete(context.Background(), jobGUID, opts)
if err != nil {
    return err
}

The timeout and polling interval can be configured using the PollingOptions struct.

The PollComplete function will return a nil error if the job completes successfully. If PollComplete times out waiting for the job to complete a client.AsyncProcessTimeoutError is returned. If the job itself failed then the job API is queried for the job error which is then returned as a resource.CloudFoundryError which can be inspected to find the failure cause.

Error Handling

All client methods will return a resource.CloudFoundryError or sub-type for any response that isn't a 200 level status code. All CF errors have a corresponding error code and the client uses those codes to construct a specific client side error type. This allows you to easily branch your logic based off specific API error codes using one of the many resource.IsSomeTypeOfError(err error) functions, for example:

params, err := cf.ServiceCredentialBindings.GetParameters(guid)
if resource.IsServiceFetchBindingParametersNotSupportedError(err) {
    fmt.Println(err.(resource.CloudFoundryError).Detail)
} else if err != nil {
    return err // all other errors
} else {
    fmt.Printf("Parameters: %v\n", params)
}

Migrating v2 to v3

A very basic example using the v2 client:

c := &cfclient.Config{
    ApiAddress: "https://api.sys.example.com",
    Username:   "user",
    Password:   "password",
}
client, _ := cfclient.NewClient(c)
apps, _ := client.ListApps()
for _, a := range apps {
	fmt.Println(a.Name)
}

Converted to do the same in the v3 client:

cfg, _ := config.New("https://api.sys.example.org", config.UserPassword("user", "pass"))
client, _ := client.New(cfg)
apps, _ := client.Applications.ListAll(context.Background(), nil)
for _, app := range apps {
    fmt.Println(app.Name)
}

If you need to migrate over to the new client iteratively you can do that by referencing both the old and new modules simultaneously and creating two separate client instances - one for each module version.

Some of the main differences between the old client and the new v3 client include:

  • The old v2 client supported most v2 resources and few a v3 resources. The new v3 client supports all v3 resources and no v2 resources. While most v2 resources are similar to their v3 counterparts, some code changes will need to be made.
  • The v2 client had a single type that contained resource functions disambiguated by function name. The v3 client has a separate client nested under the main client for each resource. For example: client.ListApps() vs client.Applications.ListAll()
  • All v3 client functions take a cancellable context object as their first parameter.
  • All v3 client list functions take a type specific options struct that support type safe filtering.
  • All v3 client list functions support paging natively in the client for ease of use.
  • The v3 client supports shared access across goroutines.

Versioning

In general, go-cfclient follows semver as closely as we can for tagging releases of the package. We've adopted the following versioning policy:

  • We increment the major version with any incompatible change to non-preview functionality, including changes to the exported Go API surface or behavior of the API.
  • We increment the minor version with any backwards-compatible changes to functionality
  • We increment the patch version with any backwards-compatible bug fixes.

Development

All development takes place on feature branches and is merged to the main branch. Therefore the main branch is considered a potentially unstable branch until a new release (see below) is cut.

make all

Please attempt to use standard go naming conventions for all structs, for example use GUID over Guid. All client functions should have at least once basic unit test.

Errors

If the Cloud Foundry error definitions change at https://github.com/cloudfoundry/cloud_controller_ng/blob/master/vendor/errors/v2.yml then the error predicate functions in this package need to be regenerated.

To do this, simply use Go to regenerate the code:

make generate

Contributing

Pull requests welcome. Please ensure you run all the unit tests, go fmt the code, and golangci-lint via make all

go-cfclient's People

Contributors

asehra avatar calebwashburn avatar ckganesan avatar davidchua avatar debtheray avatar dependabot[bot] avatar dray56 avatar drnic avatar folksgl avatar frodenas avatar geofffranks avatar gourab1998 avatar iandelahorne avatar jmcarp avatar joefitzgerald avatar johnlonganecker avatar jonathaningram avatar liorokman avatar lnguyen avatar mb175 avatar peterellisjones avatar rkoster avatar sambryant4 avatar shinji62 avatar simonjohansson avatar sneal avatar srbry avatar stuwill avatar thepanz avatar zmb3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-cfclient's Issues

Way to Distinguish Between Communication and Not Found errors in Get calls

Get(Org/Space/App/etc) gives an error if nothing was found with the expected input (name or GUID). There's not a good way (other than looking at the code and error string regex matching) to determine if the error was the result of an HTTP/TCP error or because nothing exists with the parameters the caller provided.

Usage of the library could be made more robust if we created public error types for these and returned the proper type of error depending on the cause of the problem.

ListApps() method is redirecting the http post

I have created a Slackbot Application in GO and Deployed in CloudFoundry. It was working until i started using this ListApps() method from go-cfclient. Whenever I call this method, its looping for 10 times and calling the main post method and the whole application is looping for 10 times because of the usual redirect policy to stop after 10 redirects.

c := &cfclient.Config{
ApiAddress: apiURL,
Username: uname,
Password: upwd,
}
client, _ := cfclient.NewClient(c)

apps, _ := client.ListApps()

Can someone help me resolve this issue

Allow setting a specific Useragent

Hey

This is a feature request.

I have opened a feature request at the cf_exporter project to set a specific useragent value that the calls on the receiving end can be identified as cf_exporter. @frodenas mentioned, that cf_exporter uses this client to make the calls and that go-cfclient atm does not support setting a custom useragent.

Therefore: Can you please add the feature to set a custom useragent?

cheers

Check for mocks being called

I introduced a check for seeing whether mocks are really called (see https://github.com/elgohr/go-cfclient/tree/mockCalled).
I needed this for TDD. Otherwise no implementation (simply return nil) would be a valid and the most easy implementation to fit the tests.
Nevertheless there are some tests failing after this.

I'm not sure if it would be a good idea to create a pull request for this, as Github mixes this with the other functionallity I requested for pull, which shouldn't be that controversial to discuss. In this way I would like to discuss this first.

Getting a large number of processes causes the library to hang

When calling the ListAllProcessesByQuery or ListAllProcesses methods, the methods will enter an infinite loop if there is more than one page of results. After reviewing the code, there is a shadow variable that does not pick up the url for the next page of data.

Add support for V3 apps using GUID and 'Include'

Hi folks,

I have the case where I'd like to query the following endpoint (see API):
/v3/apps?guids=guid0,guid1,...,guidN&include=space,space.organization

So far, the client has no support for the include-primitive and no method for multiple apps via GUID.
Would you be open to PR(s) to implement this change, e.g. via a ListV3AppsByGUIDsAndQuery function?
Thanks!

xsuaa broker launch via go-cfclient

Hi,

I want to launch a xsuaa broker via the go-cfclient. What calls do i need to launch via the goclient? I am newbie to the cloudfoundry world. Could you point me to some sample code which i can refer ?

Regards,
Kevin

service-keys missing GUID

func (c *Client) mergeServiceKey(serviceKey ServiceKeyResource) ServiceKey {
serviceKey.Entity.Guid = serviceKey.Meta.Guid
serviceKey.Entity.CreatedAt = serviceKey.Meta.CreatedAt
serviceKey.Entity.UpdatedAt = serviceKey.Meta.UpdatedAt
serviceKey.Entity.c = c
return serviceKey.Entity
}

should be added to service_keys.go and used in CreateServiceKey(). Withouth this, serviceKey.Entity.Guid is empty.

Add option for making API requests through CLI

Hello! I'm interested in using this package as part of a Cloud Foundry CLI plugin, where it's preferable to make requests through cf curl, rather than passing credentials explicitly. Thoughts about exposing that as an option?

Querying multiple/individual pages doesn't work for several functions

I noticed this error while working on this PR to support result sets that span multiple pages.

It seems that a number of functions also don't support this functionality still, and at the same time, some of those that do have flawed implementations such that, if the query parameter ?page=X is passed, the function will return all pages from X onwards. This is true for the ListServiceKeysByQuery function from the above PR.

In total, it looks like the following functions may need to be modified:

ListOrgsByQuery
ListOrgUsersByQuery
listOrgRolesByQuery
ListOrgManagersByQuery
ListOrgAuditorsByQuery
ListOrgBillingManagersByQuery
ListAllProcessesByQuery
ListRouteMappingsByQuery
ListRoutesByQuery
ListServiceBindingsByQuery
ListServiceBrokersByQuery
ListServiceInstancesByQuery
ListServiceKeysByQuery
ListServicePlanVisibilitiesByQuery
ListServicePlansByQuery
ListServiceUsageEventsByQuery
ListServicesByQuery
ListSpaceQuotasByQuery
ListSpaceManagersByQuery
ListSpaceAuditorsByQuery
ListSpaceDevelopersByQuery
ListSpacesByQuery
ListStacksByQuery
ListTasksByQuery
TasksByAppByQuery
ListUserProvidedServiceInstancesByQuery
ListUsersByQuery

I've been slowly going through each of these to confirm whether the behavior needs to change, and will try to submit a PR soon to fix this. Just wanted to solicit thoughts from the community and see if this issue was on anybody else's radar!

CloudFoundryError is not correct

https://github.com/cloudfoundry-community/go-cfclient/blob/master/error.go#L19 defines the JSON of a Cloud Foundry error to contain code, title and detail. Actually, the errors are of the format (I'm using CF API 2.65.0):

{
  "code": 1002,
  "description": "Invalid relation: 1b346d07-c710-47f5-ag52-0e6d34a5a4b2",
  "error_code": "CF-InvalidRelation"
}

I think CloudFoundryError should rather be:

type CloudFoundryError struct {
	Code        int    `json:"code"`
	ErrorCode   string `json:"error_code"`
	Description string `json:"description"`
}

Do you guys agree or am I missing something?

V3 errors are different than V2 errors

The tasks code uses v3 endpoints but handles the errors returned as if they were v2 errors. Since the error responses are different between v2 and v3 (as shown below) this doesn't unmarshal into the CloudFoundryError object in errors.go. This makes handling certain errors (like app not found) impossible using the tasks helpers.

cf curl /v2/apps/sdaglk
{
   "description": "The app could not be found: sdaglk",
   "error_code": "CF-AppNotFound",
   "code": 100004
}
cf curl /v3/apps/sdaglk
{
   "errors": [
      {
         "detail": "App not found",
         "title": "CF-ResourceNotFound",
         "code": 10010
      }
   ]
}

Doesn't appear to work on non-PWS?

panic: Error getting token: oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"unauthorized","error_description":"Bad credentials"}

It works fine for me on PWS, but fails on Swisscom and Bluemix. I'm reasonably
sure I've not fat-fingered the credentials.

    config = &cfclient.Config{
            ApiAddress: info.API,
            Username:   info.Username,
            Password:   info.Password}

    var (
        client *cfclient.Client
        err    error
    )

    if client, err = cfclient.NewClient(config); err != nil {
        panic(err)
    }

Unrecognized import path "golang.org/x/..."

Hello,
When trying o import the go-cfclient library, I get the following error messages:
package golang.org/x/net/context: unrecognized import path "golang.org/x/net/context"
package golang.org/x/oauth2: unrecognized import path "golang.org/x/oauth2"

I don't know if this caused by some closure around googlecode.com but it means the library is not usable.
I have searched for alternate path to try to submit a pull request but my knowledge of golang is pretty limited and I did not find the answer.

Number of app instances

Hi,
Is there a way to get/set number of app instances and get app cpu_usage?

I was able to list all apps, but that's all...

Speed test

Not an issue really, just seeing that enumerating apps using this client takes longer than anticipated and would like a sanity check.

Running on a local enterprise network, it takes right at 3 minutes to do a listApps on an CF with 816 applications. I can't see anything glaring as far as CC connections queue, CC DB metrics, etc that would point to an issue there.

Is this time frame representative of what others are seeing with the client?

Consider removing `vendor` directory

It's my understanding that including a vendor directory in a library (as opposed to a binary) is generally bad practice, at least according to this 2016 tip.

I've encountered a similar issue today, where I'm trying to write code like this:

import (
	"github.com/cloudfoundry-community/go-cfclient"
	"golang.org/x/oauth2"
)

...

		cfclient.NewClient(&cfclient.Config{
			ApiAddress:  api,
			TokenSource: oauth2.StaticTokenSource(&oauth2.Token{AccessToken: at}),
		})

gives unhelpful errors like:

cannot use "golang.org/x/oauth2".StaticTokenSource(&"golang.org/x/oauth2".Token literal) (type "golang.org/x/oauth2".TokenSource) as type "github.com/cloudfoundry-community/go-cfclient/vendor/golang.org/x/oauth2".TokenSource in field value:
        "golang.org/x/oauth2".TokenSource does not implement "github.com/cloudfoundry-community/go-cfclient/vendor/golang.org/x/oauth2".TokenSource (wrong type for Token method)
                have Token() (*"golang.org/x/oauth2".Token, error)
                want Token() (*"github.com/cloudfoundry-community/go-cfclient/vendor/golang.org/x/oauth2".Token, error)

I can workaround by simply deleting the vendor dir from the cf-client library.

Fetch for List of service instances fails

I am getting below error while fetching list of service instances.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x679650]

goroutine 1 [running]:
github.com/cloudfoundry-community/go-cfclient.(*Client).NewRequest(...)
        /<$GOPATH>/src/github.com/cloudfoundry-community/go-cfclient/client.go:236
github.com/cloudfoundry-community/go-cfclient.(*Client).ListServiceInstancesByQuery(0x0, 0x0, 0x7782c0, 0xc000298220, 0xc000080de0, 0xc000080e70, 0x2)
        /<$GOPATH>/src/github.com/cloudfoundry-community/go-cfclient/service_instances.go:71 +0x2f0
main.main()

I am using code

package main

import (
        "github.com/cloudfoundry-community/go-cfclient"
        "fmt"
)

func main() {
        c := &cfclient.Config{
                ApiAddress:   "https://api.<redacted>",
                Username:     "<redacted>",
                Password:     "<redacted>",
                SkipSslValidation: true,
        }

        client, _ := cfclient.NewClient(c)
        instances, err := client.ListServiceInstanes(nil)
        if err != nil {
                fmt.Println(err)
        }
        fmt.Println(instances)

}

We have around 75k instances in total.

Support GA v3 APIs (organization of the overlapping struct names)

I have a use case that requires the current droplet information:
http://v3-apidocs.cloudfoundry.org/version/3.34.0/index.html#get-current-droplet
GET /v3/apps/:guid/droplets/current

As a result of the path, it would make sense to support the V3 App struct too but as we all know there's already a V2 App struct in this library.

And now that a bunch of the V3 APIs (not all) were marked GA in August, I'm wondering how we want to go about supporting the V3 APIs and objects in this library especially ones with overlapping struct names.

As a note: this library currently already has some v3 calls but none of them had pre-existing v2 equivalents.
https://github.com/cloudfoundry-community/go-cfclient/search?utf8=%E2%9C%93&q=v3&type=

A couple of ideas:

  1. Break the package into two sub packages v2 and v3 like it does in the java client.
  • Pros: it will make transitioning easier as more v3 apis go GA
  • Cons: huge refactor for people now
  1. Prefix overlapping structs with v3 (e.g. V3App)
  • Pros: not a huge refactor for library users
  • Cons: it feels way too dirty

I like the first one better but would love to know the thoughts of others / what would get accepted.

cc: @thomasmmitchell @lnguyen

Create/Push app feature support

Hi Team,

We are looking for Create/Push app feature support in the cfclient. Any plans of supporting it with an ETA. Does anyone has picked this up to proceed with. If not we are interested to contribute on this and use for our project.

How should we handle token expiration? Not sure if go-cfclient handles this for us.

I am fairly new to programming in Golang, so I am sorry if I am doing something wrong myself here, and I will try to describe this as concise as possible:

I have a Golang web app with an endpoint that uses a method to retrieve information from CF, this is the snippet in pseude-code (no imports):

// main.go
func GetCfClient() (client *cfclient.Client, err error) {
	new_client, err := cfclient.NewClient(&cfclient.Config{
		ApiAddress: cfAPI,
		Username:   cfUser,
		Password:   cfPassword,
		HttpClient: myHttpClient,
	})

	if err != nil {
		return client, errors.New(fmt.Sprintf("Failed to create CfClient:", err))
	}
	return new_client, nil
}

var client, client_err = GetCfClient()

func AppByGuid(cfAppGuid string) (app cfclient.App, err error) {
	if client_err != nil {
                return cfclient.App{}, client_err
        }

        cfApp, err := AppByGuid(cfAppGuid)
        if err != nil {
                return cfclient.App{}, err
        }
        return cfApp, nil
}

As you can see, I am putting the var client in the file blocks scope, according to http://www.tapirgames.com/blog/golang-block-and-scope. I am doing this because it feels more sensible to have a "global" client available, instead of creating a new one for every request (the request gets handled by the AppByGuid function, but that code is irrelevant for here). What I am seeing is that I sometimes get this:

oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"invalid_token","error_description":"The token expired, was revoked, or the token ID is incorrect: XXX"})

Which I think happens when my CF authorization is expired. How should I handle this instead?

Login with sso or origin

Hi,

Is it possible to use the go-cfclient to login with --sso or --origin?

Kind regards,
Adriana

Login broke after '--origin uaa' introduced in CF

Hi,

Recently started noticing login issues with the library after auth mechanisms were modified in our CF deployment to use OIDC

Previously, the following code snippet used to work fine:

	CFConfig = &cfclient.Config{
		ApiAddress:        os.Getenv(constants.ENV_CF_API_URL),
		Username:          os.Getenv(constants.ENV_CF_USERNAME),
		Password:          os.Getenv(constants.ENV_CF_PASSWORD),
		SkipSslValidation: true,
	}

which has now started failing with the below error:

Error getting token: oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"unauthorized","error_description":"Bad credentials"}

After OIDC was introduced, our CF CLI auth had to be appended by --origin uaa to function correctly.

Is there an equivalent feature in library as well ?

Thanks.

NewRequestWithBody fails at DoRequest

The reasons seems to be that content-type for JSON is not set in the header of the request.
There is no way to inject headers from the outside.

A possible solution would be injecting the header in DoRequest():

req.Header.Set("Content-type", "application/json")

...but only if a body is set? I think that would fit to all POST with body requests?

Service creation using CreateServiceInstance fails for brokers which are not async.

The CloudFoundry controller returns HTTP StatusCreated for services created by brokers which do not provision instances asynchronously. The go-cfclient implementation returns an error, since it expects a StatusAccepted return code.

As a result, it is currently not possible to create instances using this library from service brokers where the service broker itself doesn't support async. provisioning.

Please merge PR #209 for fixing this.

Bad credentials when using ClientID and ClientSecret

When I use ClientID and ClientSecret to authenticate against CF i get this error {"error":"unauthorized","error_description":"Bad credentials"}

This actually worked fine when I was using an older version of the golang.org/x/oauth2 package (commit: ad516a2) but when I updated to commit 876b1c6 it stopped working.

Here is the code I used to test:

func main() {
	c := &cfclient.Config{
		ApiAddress:   "https://api.<redacted>",
		ClientID:     "<redacted>",
		ClientSecret: "<redacted>",
	}
	client, _ := cfclient.NewClient(c)
	svs, err := client.ListServices()
	if err != nil {
		fmt.Println(err)
	}
	for _, sv := range svs {
		fmt.Println(sv.Label)
	}
}

And here is the stdout:

go run main.go
Error requesting services: Get https://api.cf-prod.intranet.rws.nl/v2/services?: oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"unauthorized","error_description":"Bad credentials"}

Again: this worked when golang/x/oauth2 package was at commit ad516a2

No license specified

There doesn't seem to be any license specified for this repo.

This is a big problem if want to use it in a product, because right now cf-client can be seen as some random code from the Internet that I can't use legally.

Could you add a LICENSE file? MIT license would be ok.

Security Group Create/Update Omitting code/type fields

We are running into a problem when using security groups and the security group has a code or type of 0.

Example

{
  "protocol": "icmp",
  "destination": "10.50.0.0/20",
  "type": 0,
  "code": 0,
  "log": true,
  "description": "Allow icmp echo to operations stack"
}

Since 0 is equal to the empty value in go, it omits the type/code fields in the request to the CF API

Relevant Lines
https://github.com/cloudfoundry-community/go-cfclient/blob/master/secgroups.go#L39-L40

We could define type/code to not be omitted on empty. From my understanding the type/code fields get ignored by the other protocols so should not cause any problems if they are set to 0 for udp and tcp

What do you guys think?

UpdateDetails look different to API definition

I was about to use the new #218 and initially noticed a) the method UpdateServiceInstance does not consume the UpdateDetails struct, rather an unstructured Reader; b) the UpdateDetails struct does not look to match the API definition.

I might try to come back and investigate if UpdateDetails needs to be changed (b), and if UpdateServiceInstance can be upgraded to consume it rather than Reader (a); but will create this issue in the meantime in case I'm missing something.

API definition - https://apidocs.cloudfoundry.org/7.9.0/service_instances/update_a_service_instance.html

Screen Shot 2019-03-31 at 8 10 59 am

UpdateDetails struct has some different fields:

image

Best way to get route information from the client?

@mrdavidlaing and I are looking at fetching routes for an app through the client, and are wondering what would be the best way to implementing this? We have come up with two solutions that would work.

Create a routes struct and either

  1. From the big get from /v2/apps?inline-relations-depth=2 we get routes ands domains in the response; but the data is split over two arrays that we'd need to join manually.
    Specifically we would have to filter the domains list with the routes.1.entity.domain_guid to get the full route "blablabla.asdasdasd.com"
                  "routes": [
                     {
                        "metadata": {
                           "guid": "068fd8e4-eec5-4600-9316-2e923b700f13",
                           "url": "/v2/routes/068fd8e4-eec5-4600-9316-2e923b700f13",
                           "created_at": "2015-07-10T14:10:43Z",
                           "updated_at": null
                        },
                        "entity": {
                           "host": "blablabla",
                           "domain_guid": "cdeefcc6-5fd6-4eb5-be82-c3e98ea1baf5",
                           "space_guid": "3281654f-73e8-4bab-b4fe-7c9fd973e473",
                           "path": "",
                           "domain_url": "/v2/domains/cdeefcc6-5fd6-4eb5-be82-c3e98ea1baf5",
                           "space_url": "/v2/spaces/3281654f-73e8-4bab-b4fe-7c9fd973e473",
                           "apps_url": "/v2/routes/068fd8e4-eec5-4600-9316-2e923b700f13/apps"
                        }
                     },

with

                  "domains": [
                     {
                        "metadata": {
                           "guid": "cdeefcc6-5fd6-4eb5-be82-c3e98ea1baf5",
                           "url": "/v2/domains/cdeefcc6-5fd6-4eb5-be82-c3e98ea1baf5",
                           "created_at": "2015-07-07T06:39:52Z",
                           "updated_at": null
                        },
                        "entity": {
                           "name": "asdasdasd.com"
                        }
                     },
                     {
                        "metadata": {
                           "guid": "d136df7b-d1c5-46b9-b1f4-817cdbc476c2",
                           "url": "/v2/domains/d136df7b-d1c5-46b9-b1f4-817cdbc476c2",
                           "created_at": "2015-07-09T14:27:42Z",
                           "updated_at": null
                        },
                        "entity": {
                           "name": "fjhjkfsdjkadsjkh.com",
                           "owning_organization_guid": "45c800ab-8f19-4e69-9e02-c64e08c7eaec",
                           "owning_organization_url": "/v2/organizations/45c800ab-8f19-4e69-9e02-c64e08c7eaec",
                           "spaces_url": "/v2/domains/d136df7b-d1c5-46b9-b1f4-817cdbc476c2/spaces"
                        }
                     }
                  ],

OR Make a subsequent api call to http://apidocs.cloudfoundry.org/205/apps/get_app_summary.html where we have the (combined) route information for free.

Downside with the second way is ofc that we need to make a subsequent API call, but the implementation will be simpler, also inline-relations-depth[1] is deprecated so it looks like going forward we might have to make more calls anyways installing of relying of the "auto"-relations as we do now.

Thoughts?

[1] http://apidocs.cloudfoundry.org/release-candidate/apps/list_all_apps.html

Inline relations depth

Query parameter is deprecated and we've noticed it causes significant CPU load on cloud controller. Using the GraphQL model, I've noticed better efficiency with calling the specific URLs individually and aggregating the results. This also puts less load on each CC instance by avoiding unnecessary fetches

Goroutine leakage happening in create_service_instance,create_service_key,update_service_instance,delete_service_instance.

I see there is goroutine leakage. I was performing some operations like create service instance,create service key ,udpate service key , delete service key,delete service instance.
I observe following when I did some goroutine profiling -
**goroutine profile: total 8
2 @ 0x1032760 0x10420bb 0x1308069 0x105fc71

0x1308068 net/http.(*persistConn).readLoop+0x998 /usr/local/go/src/net/http/transport.go:2032

2 @ 0x1032760 0x10420bb 0x1309343 0x105fc71

0x1309342 net/http.(persistConn).writeLoop+0x122 /usr/local/go/src/net/http/transport.go:2210*

This readLoop and writeLoop goroutines are pilling up.

vendoring

I'm just wondering about the plans to change to /vendor directory to have all dependencies in-place. Speaks anything against removing godep dependency management?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.