Skip to content

Commit d4adbbb

Browse files
committed
add raw client and noaa helper
1 parent eb0cc34 commit d4adbbb

File tree

4 files changed

+171
-2
lines changed

4 files changed

+171
-2
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package main
1515

1616
import (
1717
"github.com/cloudfoundry-community/go-cf-clients-helper" // package name is clients
18+
"fmt"
1819
)
1920

2021
func main() {
@@ -45,5 +46,20 @@ func main() {
4546

4647
// Get access to logs api and metrics through noaa
4748
session.NOAA()
49+
// you can use helper for retrieving log messages for an app
50+
h := clients.NewNOAAHelper(session.NOAA(), session.ConfigStore())
51+
msgs, err := h.RecentLogs("app-guid", 0) // 0 means no limit of messages to see
52+
if err != nil {
53+
panic(err)
54+
}
55+
fmt.Println(msgs)
56+
57+
// Get an http client which pass authorization header to call api(s) directly
58+
session.Raw()
59+
60+
// Get config store for client which need, for example, current access token (e.g.: NOAA)
61+
session.ConfigStore()
62+
63+
4864
}
4965
```

noaahelper.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package clients
2+
3+
import (
4+
"code.cloudfoundry.org/cli/util/configv3"
5+
"fmt"
6+
noaaconsumer "github.com/cloudfoundry/noaa/consumer"
7+
"github.com/cloudfoundry/sonde-go/events"
8+
"strings"
9+
"time"
10+
)
11+
12+
const LogTimestampFormat = "2006-01-02T15:04:05.00-0700"
13+
14+
type NOAAHelper struct {
15+
consumer *noaaconsumer.Consumer
16+
configStore *configv3.Config
17+
}
18+
19+
func NewNOAAHelper(consumer *noaaconsumer.Consumer, configStore *configv3.Config) *NOAAHelper {
20+
return &NOAAHelper{
21+
consumer: consumer,
22+
configStore: configStore,
23+
}
24+
}
25+
26+
func (c NOAAHelper) RecentLogs(appGUID string, maxMessages int) (string, error) {
27+
logMsgs, err := c.consumer.RecentLogs(appGUID, c.configStore.AccessToken())
28+
if err != nil {
29+
return "", err
30+
}
31+
maxLen := maxMessages
32+
if maxLen < 0 || len(logMsgs) < maxLen {
33+
maxLen = len(logMsgs)
34+
}
35+
if maxLen-1 < 0 {
36+
return "", nil
37+
}
38+
logs := ""
39+
for i := maxLen - 1; i >= 0; i-- {
40+
logMsg := logMsgs[i]
41+
t := time.Unix(0, logMsg.GetTimestamp()).In(time.Local).Format(LogTimestampFormat)
42+
typeMessage := "OUT"
43+
if logMsg.GetMessageType() != events.LogMessage_OUT {
44+
typeMessage = "ERR"
45+
}
46+
header := fmt.Sprintf("%s [%s/%s] %s ",
47+
t,
48+
logMsg.GetSourceType(),
49+
logMsg.GetSourceInstance(),
50+
typeMessage,
51+
)
52+
message := string(logMsg.GetMessage())
53+
for _, line := range strings.Split(message, "\n") {
54+
logs += fmt.Sprintf("\t%s%s\n", header, strings.TrimRight(line, "\r\n"))
55+
}
56+
}
57+
return logs, nil
58+
}

rawclient.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package clients
2+
3+
import (
4+
"code.cloudfoundry.org/cli/api/cloudcontroller"
5+
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
6+
"crypto/tls"
7+
"io"
8+
"net"
9+
"net/http"
10+
"strings"
11+
"time"
12+
)
13+
14+
type rawConnection struct {
15+
httpClient *http.Client
16+
}
17+
18+
func (c rawConnection) Make(request *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error {
19+
response, err := c.httpClient.Do(request.Request)
20+
if err != nil {
21+
return err
22+
}
23+
passedResponse.HTTPResponse = response
24+
return nil
25+
}
26+
27+
// RawClientConfig - configuration for RawClient
28+
type RawClientConfig struct {
29+
DialTimeout time.Duration
30+
SkipSSLValidation bool
31+
ApiEndpoint string
32+
}
33+
34+
// Raw http client has uaa client authentication to make raw request with golang native api.
35+
type RawClient struct {
36+
connection cloudcontroller.Connection
37+
apiEndpoint string
38+
wrappers []ccv3.ConnectionWrapper
39+
}
40+
41+
// NewRawClient -
42+
func NewRawClient(config RawClientConfig, wrappers ...ccv3.ConnectionWrapper) *RawClient {
43+
httpClient := &http.Client{
44+
Transport: &http.Transport{
45+
TLSClientConfig: &tls.Config{
46+
InsecureSkipVerify: config.SkipSSLValidation,
47+
},
48+
Proxy: http.ProxyFromEnvironment,
49+
DialContext: (&net.Dialer{
50+
KeepAlive: 30 * time.Second,
51+
Timeout: config.DialTimeout,
52+
}).DialContext,
53+
},
54+
}
55+
var connection cloudcontroller.Connection = &rawConnection{httpClient}
56+
for _, wrapper := range wrappers {
57+
connection = wrapper.Wrap(connection)
58+
}
59+
return &RawClient{
60+
connection: connection,
61+
apiEndpoint: strings.TrimSuffix(config.ApiEndpoint, "/"),
62+
wrappers: wrappers,
63+
}
64+
}
65+
66+
// Do - Do the request with given http client and wrappers
67+
func (c RawClient) Do(req *http.Request) (*http.Response, error) {
68+
resp := &cloudcontroller.Response{}
69+
err := c.connection.Make(&cloudcontroller.Request{
70+
Request: req,
71+
}, resp)
72+
return resp.HTTPResponse, err
73+
}
74+
75+
// NewRequest - Create a new request with setting api endpoint to the path
76+
func (c RawClient) NewRequest(method, path string, body io.ReadCloser) (*http.Request, error) {
77+
return http.NewRequest(method, c.apiEndpoint+path, body)
78+
}

session.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Session struct {
2525
clientV2 *ccv2.Client
2626
clientV3 *ccv3.Client
2727
clientUAA *uaa.Client
28+
rawClient *RawClient
2829

2930
// To call tcp routing with this router
3031
routerClient *router.Client
@@ -35,7 +36,8 @@ type Session struct {
3536
// netClient permit to access to networking policy api
3637
netClient *cfnetv1.Client
3738

38-
config Config
39+
config Config
40+
configStore *configv3.Config
3941
}
4042

4143
// NewSession -
@@ -68,6 +70,7 @@ func NewSession(c Config) (s *Session, err error) {
6870
BinaryName: "terraform-provider",
6971
},
7072
}
73+
s.configStore = config
7174
uaaClientId := c.UaaClientID
7275
uaaClientSecret := c.UaaClientSecret
7376
if uaaClientId == "" {
@@ -120,6 +123,16 @@ func (s *Session) NOAA() *noaaconsumer.Consumer {
120123
return s.noaaClient
121124
}
122125

126+
// Give an http client which pass authorization header to call api(s) directly
127+
func (s *Session) Raw() *RawClient {
128+
return s.rawClient
129+
}
130+
131+
// Give config store for client which need access token (e.g.: NOAA)
132+
func (s *Session) ConfigStore() *configv3.Config {
133+
return s.configStore
134+
}
135+
123136
func (s *Session) init(config *configv3.Config, configUaa *configv3.Config, configSess Config) error {
124137
// -------------------------
125138
// Create v3 and v2 clients
@@ -299,7 +312,11 @@ func (s *Session) init(config *configv3.Config, configUaa *configv3.Config, conf
299312
if s.IsDebugMode() {
300313
rawWrappers = append(rawWrappers, ccWrapper.NewRequestLogger(NewRequestLogger()))
301314
}
302-
315+
s.rawClient = NewRawClient(RawClientConfig{
316+
ApiEndpoint: config.Target(),
317+
SkipSSLValidation: config.SkipSSLValidation(),
318+
DialTimeout: config.DialTimeout(),
319+
}, rawWrappers...)
303320
// -------------------------
304321

305322
// -------------------------

0 commit comments

Comments
 (0)