Skip to content

Commit

Permalink
Detect CF-on-K8s in cf api
Browse files Browse the repository at this point in the history
This makes `cf api` able to detect the `cf-on-k8s` flag in the root
endpoint response and persist this information in the config. This will
allow us to enable CF-on-K8s-specific behaviour for every following
command.

We have introduced a new `selfcontained` integration suite which
contains tests that do not need to be run against a cf deployment.

Issue: cloudfoundry/cf-k8s-api#10
Co-authored-by: Danail Branekov <danailster@gmail.com>
Co-authored-by: Giuseppe Capizzi <gcapizzi@pivotal.io>
Co-authored-by: Georgi Sabev <georgethebeatle@gmail.com>
  • Loading branch information
3 people committed Sep 30, 2021
1 parent e8d41cf commit 42a8473
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 15 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,15 @@ ip: integration-push
integration-push: build integration-cleanup ## Run all push-related integration tests
$(ginkgo_int) -nodes $(NODES) integration/$(TARGET)/push

integration-tests: build integration-cleanup integration-isolated integration-push integration-global ## Run all isolated, push, and global integration tests
integration-selfcontained:
$(ginkgo_int) -nodes $(NODES) integration/v7/selfcontained

integration-tests: build integration-cleanup integration-isolated integration-push integration-global integration-selfcontained ## Run all isolated, push, selfcontained, and global integration tests


i: integration-tests-full
integration-full-tests: integration-tests-full
integration-tests-full: build integration-cleanup integration-isolated integration-push integration-experimental integration-plugin integration-global ## Run all isolated, push, experimental, plugin, and global integration tests
integration-tests-full: build integration-cleanup integration-isolated integration-push integration-experimental integration-plugin integration-global integration-selfcontained # ## Run all isolated, push, experimental, plugin, selfcontained, and global integration tests

integration-tests-full-ci: integration-cleanup
$(ginkgo_int) -nodes $(NODES) -flakeAttempts $(FLAKE_ATTEMPTS) \
Expand Down
1 change: 1 addition & 0 deletions actor/v7action/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (actor Actor) SetTarget(settings TargetSettings) (Warnings, error) {
Routing: rootInfo.Routing(),
SkipSSLValidation: settings.SkipSSLValidation,
UAA: rootInfo.UAA(),
CFOnK8s: rootInfo.CFOnK8s,
})

actor.Config.SetTokenInformation("", "", "")
Expand Down
14 changes: 13 additions & 1 deletion actor/v7action/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ var _ = Describe("Targeting", func() {

BeforeEach(func() {
actor, fakeCloudControllerClient, fakeConfig, _, _, _, _ = NewTestActor()

})

Describe("SetTarget", func() {
Expand Down Expand Up @@ -120,6 +119,7 @@ var _ = Describe("Targeting", func() {
Expect(targetInfoArgs.LogCache).To(Equal(expectedLogCache))
Expect(targetInfoArgs.Routing).To(Equal(expectedRouting))
Expect(targetInfoArgs.SkipSSLValidation).To(Equal(skipSSLValidation))
Expect(targetInfoArgs.CFOnK8s).To(BeFalse())
})

It("clears all the token information", func() {
Expand All @@ -135,6 +135,18 @@ var _ = Describe("Targeting", func() {
Expect(err).ToNot(HaveOccurred())
Expect(warnings).To(ConsistOf(Warnings{"info-warning"}))
})

When("deployed on Kubernetes", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetInfoReturns(ccv3.Info{CFOnK8s: true}, nil, nil)
})

It("sets the CFOnK8s target information", func() {
Expect(fakeConfig.SetTargetInformationCallCount()).To(Equal(1))
targetInfoArgs := fakeConfig.SetTargetInformationArgsForCall(0)
Expect(targetInfoArgs.CFOnK8s).To(BeTrue())
})
})
})

Describe("ClearTarget", func() {
Expand Down
3 changes: 2 additions & 1 deletion api/cloudcontroller/ccv3/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ type InfoLinks struct {
// controller API.
type Info struct {
// Links is a list of top level Cloud Controller APIs.
Links InfoLinks `json:"links"`
Links InfoLinks `json:"links"`
CFOnK8s bool `json:"cf_on_k8s"`
}

// AppSSHEndpoint returns the HREF for SSHing into an app container.
Expand Down
27 changes: 19 additions & 8 deletions api/cloudcontroller/ccv3/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var _ = Describe("Info", func() {
client *Client
rootRespondWith http.HandlerFunc

apis Info
info Info
warnings Warnings
executeErr error
)
Expand All @@ -37,7 +37,7 @@ var _ = Describe("Info", func() {
),
)

apis, warnings, executeErr = client.GetInfo()
info, warnings, executeErr = client.GetInfo()
})

Describe("when all requests are successful", func() {
Expand Down Expand Up @@ -86,18 +86,29 @@ var _ = Describe("Info", func() {

It("returns the CC Information", func() {
Expect(executeErr).NotTo(HaveOccurred())
Expect(apis.UAA()).To(Equal("https://uaa.bosh-lite.com"))
Expect(apis.Logging()).To(Equal("wss://doppler.bosh-lite.com:443"))
Expect(apis.NetworkPolicyV1()).To(Equal(fmt.Sprintf("%s/networking/v1/external", server.URL())))
Expect(apis.AppSSHHostKeyFingerprint()).To(Equal("some-fingerprint"))
Expect(apis.AppSSHEndpoint()).To(Equal("ssh.bosh-lite.com:2222"))
Expect(apis.OAuthClient()).To(Equal("some-client"))
Expect(info.UAA()).To(Equal("https://uaa.bosh-lite.com"))
Expect(info.Logging()).To(Equal("wss://doppler.bosh-lite.com:443"))
Expect(info.NetworkPolicyV1()).To(Equal(fmt.Sprintf("%s/networking/v1/external", server.URL())))
Expect(info.AppSSHHostKeyFingerprint()).To(Equal("some-fingerprint"))
Expect(info.AppSSHEndpoint()).To(Equal("ssh.bosh-lite.com:2222"))
Expect(info.OAuthClient()).To(Equal("some-client"))
Expect(info.CFOnK8s).To(BeFalse())
})

It("returns all warnings", func() {
Expect(executeErr).NotTo(HaveOccurred())
Expect(warnings).To(ConsistOf("warning 1"))
})

When("CF-on-K8s", func() {
BeforeEach(func() {
rootRespondWith = RespondWith(http.StatusOK, `{ "cf_on_k8s": true }`)
})

It("sets the CFOnK8s", func() {
Expect(info.CFOnK8s).To(BeTrue())
})
})
})

When("the cloud controller encounters an error", func() {
Expand Down
3 changes: 2 additions & 1 deletion integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Running `make integration-tests` can be time-consuming, because it includes the
- `isolated` suite is for tests that are stand alone and do not affect each other. They are meant to run in their own organization and space, and will not affect system state. This is the most common type of integration tests.
- `push` suite is for tests related to the `cf push` command only.
- `experimental` suite is for tests that require the cf experimental flag to be set and/or an experimental feature for the CF CLI.
- `plugin` suite is for tests that surround the CF CLI plugin framework. *These tests do not run in parallel.*
- `plugin` suite is for tests that surround the CF CLI plugin framework. _These tests do not run in parallel._
- `selfcontained` suite is for tests that talk to a fake CF API, hence they do not require a cf deployment

## How to run
These tests rely on [ginkgo](https://github.com/onsi/ginkgo) to be installed.
Expand Down
2 changes: 1 addition & 1 deletion integration/v7/isolated/api_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ var _ = Describe("api command", func() {

Context("--unset is passed", func() {
BeforeEach(func() {

userConfig := configv3.Config{
ConfigFile: configv3.JSONConfig{
ConfigVersion: configv3.CurrentConfigVersion,
Expand Down Expand Up @@ -338,6 +337,7 @@ var _ = Describe("api command", func() {
Expect(configFile.TargetedSpace.GUID).To(BeEmpty())
Expect(configFile.TargetedSpace.Name).To(BeEmpty())
Expect(configFile.TargetedSpace.AllowSSH).To(BeFalse())
Expect(configFile.CFOnK8s).To(Equal(configv3.CFOnK8s{}))
})

It("handles API endpoints with trailing slash", func() {
Expand Down
66 changes: 66 additions & 0 deletions integration/v7/selfcontained/api_command_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package selfcontained_test

import (
"encoding/json"
"io/ioutil"
"net/http"
"path/filepath"

"code.cloudfoundry.org/cli/integration/helpers"
"code.cloudfoundry.org/cli/util/configv3"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
"github.com/onsi/gomega/ghttp"
)

var _ = Describe("cf api", func() {
var (
server *ghttp.Server
responseBody string
)

BeforeEach(func() {
responseBody = "{}"
})

JustBeforeEach(func() {
server = ghttp.NewServer()
server.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/"),
ghttp.RespondWith(http.StatusOK, responseBody),
),
)

Eventually(helpers.CF("api", server.URL())).Should(gexec.Exit(0))
})

AfterEach(func() {
server.Close()
})

It("disables cf-on-k8s in config", func() {
Expect(loadConfig().CFOnK8s.Enabled).To(BeFalse())
})

When("pointed to cf-on-k8s", func() {
BeforeEach(func() {
responseBody = `{ "cf_on_k8s": true }`
})

It("enables cf-on-k8s in config", func() {
Expect(loadConfig().CFOnK8s.Enabled).To(BeTrue())
})
})
})

func loadConfig() configv3.JSONConfig {
rawConfig, err := ioutil.ReadFile(filepath.Join(homeDir, ".cf", "config.json"))
Expect(err).NotTo(HaveOccurred())

var configFile configv3.JSONConfig
Expect(json.Unmarshal(rawConfig, &configFile)).To(Succeed())

return configFile
}
24 changes: 24 additions & 0 deletions integration/v7/selfcontained/selfcontained_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package selfcontained_test

import (
"testing"

"code.cloudfoundry.org/cli/integration/helpers"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var homeDir string

func TestSelfcontained(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Selfcontained Suite")
}

var _ = BeforeEach(func() {
homeDir = helpers.SetHomeDir()
})

var _ = AfterEach(func() {
helpers.DestroyHomeDir(homeDir)
})
9 changes: 8 additions & 1 deletion util/configv3/json_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type JSONConfig struct {
APIVersion string `json:"APIVersion"`
AsyncTimeout int `json:"AsyncTimeout"`
AuthorizationEndpoint string `json:"AuthorizationEndpoint"`
CFOnK8s CFOnK8s `json:"CFOnK8s"`
ColorEnabled string `json:"ColorEnabled"`
ConfigVersion int `json:"ConfigVersion"`
DopplerEndpoint string `json:"DopplerEndPoint"`
Expand Down Expand Up @@ -48,6 +49,10 @@ type Space struct {
AllowSSH bool `json:"AllowSSH"`
}

type CFOnK8s struct {
Enabled bool `json:"Enabled"`
}

// User represents the user information provided by the JWT access token.
type User struct {
Name string
Expand Down Expand Up @@ -192,6 +197,7 @@ type TargetInformationArgs struct {
Routing string
SkipSSLValidation bool
UAA string
CFOnK8s bool
}

// SetTargetInformation sets the currently targeted CC API and related other
Expand All @@ -213,6 +219,8 @@ func (config *Config) SetTargetInformation(args TargetInformationArgs) {
// ever read from there.
config.ConfigFile.AuthorizationEndpoint = args.Auth

config.ConfigFile.CFOnK8s.Enabled = args.CFOnK8s

config.UnsetOrganizationAndSpaceInformation()
}

Expand Down Expand Up @@ -319,7 +327,6 @@ func (config *Config) UnsetUserInformation() {
config.SetUAAClientCredentials(DefaultUAAOAuthClient, DefaultUAAOAuthClientSecret)

config.UnsetOrganizationAndSpaceInformation()

}

// V7SetSpaceInformation sets the currently targeted space.
Expand Down
3 changes: 3 additions & 0 deletions util/configv3/json_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ var _ = Describe("JSONConfig", func() {
LogCache: "https://log-cache.foo.com",
Routing: "https://api.foo.com/routing",
SkipSSLValidation: true,
CFOnK8s: true,
})

Expect(config.ConfigFile.Target).To(Equal("https://api.foo.com"))
Expand All @@ -323,6 +324,8 @@ var _ = Describe("JSONConfig", func() {
Expect(config.ConfigFile.TargetedSpace.GUID).To(BeEmpty())
Expect(config.ConfigFile.TargetedSpace.Name).To(BeEmpty())
Expect(config.ConfigFile.TargetedSpace.AllowSSH).To(BeFalse())

Expect(config.ConfigFile.CFOnK8s.Enabled).To(BeTrue())
})
})

Expand Down

0 comments on commit 42a8473

Please sign in to comment.