src/jetstream/plugins/desktop/cloudfoundry.go
package desktop
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"os"
"os/user"
"path/filepath"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
)
// CFConfigFile represents the data we need for CF config file
type CFConfigFile struct {
APIEndpoint string `json:"Target"`
AuthorizationEndpoint string `json:"AuthorizationEndpoint"`
TokenEndpoint string `json:"UaaEndpoint"`
DopplerLoggingEndpoint string `json:"DopplerEndPoint"`
SkipSSLValidation bool `json:"SSLDisabled"`
ClientID string `json:"UAAOAuthClient"`
ClientSecret string `json:"UAAOAuthClientSecret"`
AccessToken string `json:"AccessToken"`
RefreshToken string `json:"RefreshToken"`
}
// ListCloudFoundry will list Cloud Foundry endpoints configured locally (can be only one)
func ListCloudFoundry() ([]*interfaces.CNSIRecord, error) {
cfg, apiEndpoint, err := readCFFile()
if err != nil {
return nil, err
}
// Ignore if the api endpoint is empty
if len(cfg.APIEndpoint) == 0 {
return nil, nil
}
eps := make([]*interfaces.CNSIRecord, 1)
eps[0] = &interfaces.CNSIRecord{
GUID: getEndpointGUID(cfg.APIEndpoint),
Name: "CF",
CNSIType: "cf",
APIEndpoint: apiEndpoint,
AuthorizationEndpoint: cfg.AuthorizationEndpoint,
DopplerLoggingEndpoint: cfg.DopplerLoggingEndpoint,
TokenEndpoint: cfg.TokenEndpoint,
SkipSSLValidation: cfg.SkipSSLValidation,
SSOAllowed: false,
ClientId: cfg.ClientID,
ClientSecret: cfg.ClientSecret,
Local: true,
}
return eps, nil
}
// ListConnectedCloudFoundry will list Cloud Foundry endpoints configured locally (can be only one)
func ListConnectedCloudFoundry() ([]*interfaces.ConnectedEndpoint, error) {
cfg, apiEndpoint, err := readCFFile()
if err != nil {
return nil, err
}
// Ignore if the api endpoint is empty
if len(cfg.APIEndpoint) == 0 {
return nil, nil
}
//TODO: Token expiry
eps := make([]*interfaces.ConnectedEndpoint, 1)
eps[0] = &interfaces.ConnectedEndpoint{
GUID: getEndpointGUID(cfg.APIEndpoint),
Name: "CF",
CNSIType: "cf",
APIEndpoint: apiEndpoint,
Account: "local",
TokenExpiry: 20000,
AuthorizationEndpoint: cfg.AuthorizationEndpoint,
DopplerLoggingEndpoint: cfg.DopplerLoggingEndpoint,
SkipSSLValidation: cfg.SkipSSLValidation,
Local: true,
}
return eps, nil
}
func readCFFile() (*CFConfigFile, *url.URL, error) {
var url *url.URL
usr, err := user.Current()
if err != nil {
return nil, url, err
}
cfFile := filepath.Join(usr.HomeDir, ".cf", "config.json")
// Check we can unmarshall the request
data, err := ioutil.ReadFile(cfFile)
if err != nil {
return nil, url, fmt.Errorf("Can not read Cloud Foundry config file: %s", err)
}
config := &CFConfigFile{}
if err = json.Unmarshal(data, config); err != nil {
return nil, url, fmt.Errorf("Can not parse Cloud Foundry config file: %s", err)
}
if len(config.APIEndpoint) > 0 {
url, err = url.Parse(config.APIEndpoint)
if err != nil {
return nil, url, err
}
}
return config, url, nil
}
func updateCFFIle(updates map[string]string) error {
usr, err := user.Current()
if err != nil {
return err
}
cfFile := filepath.Join(usr.HomeDir, ".cf", "config.json")
// Check we can unmarshall the request
data, err := ioutil.ReadFile(cfFile)
if err != nil {
return fmt.Errorf("Can not read Cloud Foundry config file: %s", err)
}
file, err := os.Open(cfFile)
if err != nil {
return err
}
defer file.Close()
stats, err := file.Stat()
if err != nil {
return err
}
var config map[string]interface{}
if err = json.Unmarshal(data, &config); err != nil {
return fmt.Errorf("Can not parse Cloud Foundry config file: %s", err)
}
for k, v := range updates {
config[k] = v
}
data, err = json.Marshal(config)
if err != nil {
return err
}
ioutil.WriteFile(cfFile, data, stats.Mode())
return nil
}
func IsLocalCloudFoundry(cnsiGUID string) bool {
record, _ := FindLocalCloudFoundry(cnsiGUID)
return record != nil
}
func FindLocalCloudFoundry(cnsiGUID string) (*interfaces.CNSIRecord, error) {
local, err := ListCloudFoundry()
if err != nil {
return nil, err
}
if len(local) == 1 && local[0].GUID == cnsiGUID {
return local[0], nil
}
return nil, nil
}