Skip to content

CP-47357: Add a Go JSON-RPC client file #5615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

xueqingz
Copy link
Contributor

@xueqingz xueqingz commented May 6, 2024

No description provided.

@duobei duobei requested a review from kc284 May 6, 2024 05:53
@xueqingz xueqingz force-pushed the private/xueqingz/CP-47357 branch from 21c0782 to 69fc086 Compare May 8, 2024 02:43
@duobei duobei requested a review from minglumlu May 8, 2024 03:01
@psafont
Copy link
Member

psafont commented May 8, 2024

Is this the one needed for testing in the CI?

@xueqingz
Copy link
Contributor Author

xueqingz commented May 8, 2024

Is this the one needed for testing in the CI?

Yes, this is the JSON HTTP RPC client for Go SDK, we will add component test in following PRs in CI. Besides we also test the SDK functionalities in XenRT with https://github.com/xenserver/xenserver-samples/tree/master/go.

@gangj
Copy link
Contributor

gangj commented May 11, 2024

Would you please comment the test for this code here, either manual(snapshot) or XenRT(job) is ok, thanks (To indicate the current version of code passed the test).

@xueqingz
Copy link
Contributor Author

xueqingz commented May 11, 2024

For Golang lint checking.

root@3eea0d3e0e5d:/app/go/goSDK# golangci-lint run --config=/app/.golangci.yml
WARN The linter 'gomnd' is deprecated (since v1.58.0) due to: The linter has been renamed. Replaced by mnd. 
WARN The linter 'execinquery' is deprecated (since v1.58.0) due to: The repository of the linter has been archived by the owner.  
0 issues.

XenRT job base on 874f9a6 with this change:
3998847 rt-Next
3998852 Yangtze

}

func convertUnhandledJSONData(jsonBytes []byte) []byte {
jsonString := string(jsonBytes)
Copy link
Member

@minglumlu minglumlu May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converting the bytes to string and then back to bytes may not be clear here.
What I'm concerning is the encoding in the converting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When converting byte slices ([]byte) to strings in Go, encoding is not directly involved. Strings in Go are read-only slices of bytes, we can directly convert a []byte (byte slice) to a string. we can also use:

s := fmt.Sprintf("%s", b)


request.Header.Set("Content-Type", "application/json; charset=utf-8")
request.Header.Set("Accept", "application/json")
request.Header.Set("User-Agent", "XenAPI/" + APIVersionLatest.String())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like XenAPI Go SDK/24.17.0?

Copy link
Contributor Author

@xueqingz xueqingz May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, ming. Here I just follow the code in XC https://code.citrite.net/users/xueqingz/repos/xencenter/browse/XenModel/XenAPI/Session.cs#47.

Access is denied

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, update link.

headers: make(map[string]string),
}

if strings.HasPrefix(opts.URL, "https://") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "https://pkg.go.dev/net/url#Parse" could be used to parse a raw URL.

caCertPool := x509.NewCertPool()
certs := []tls.Certificate{}
if opts.SecureOpts != nil {
skipVerify = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this should be false iif when the CA is presented. Otherwise, the CA is not required.
So it should be moved into if opts.SecureOpts.ServerCert != "" {

certs = []tls.Certificate{cert}
}
}
tlsConfig := &tls.Config{
Copy link
Member

@minglumlu minglumlu May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the tls.Config, the CipherSuites needs to be set explicitly for the sake of security.
It would be better to set the TLS version explicitly as well.

if err != nil {
log.Fatal(err)
}
caCertPool.AppendCertsFromPEM(caCert)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return needs to be cared. An invalid cert can't be ignored.

func paramsParse(params ...interface{}) interface{} {
var finalParams interface{}
finalParams = params
if len(params) == 1 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could some comments be added to explain why this is required when there is only one parameter?
And why is a finalParams required here, as it gets a copy of a slice, which means it actually refers to the same memory location of params? This is because I understand the params is a slice rather than an array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The paramParse is to handle different types of parameter support way in method. eg.
Examples:

Examples:
	1.Nil:                                      sendCall(ctx, "method_name") -> {"method": "method_name"}
	2.Single value (simple type):  sendCall(ctx, "method_name", 1) -> {"method": "method_name", "params": [1]}
	3.Single value (slice/array):    sendCall(ctx, "method_name", []int{1, 2, 3}) -> {"method": "method_name", "params": [1, 2, 3]}
        4.Single value (struct):          sendCall(ctx, "method_name", &Person{Name: "Alex", Age: 35}) -> {"method": "method_name", "params": {"name": "Alex", "age": 35}}
	5.Multiple values:                  sendCall(ctx, "method_name", 1, 2, 3) -> {"method": "method_name", "params": [1, 2, 3]}

For case 3,4 ,we need to set finalParams = params[0].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll add some comments on code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion about details , we think it's actually not needed, we only need to support 1, 2,5. remove this function.

xueqingz added 2 commits May 14, 2024 10:19
Signed-off-by: xueqingz <xueqing.zhang@citrix.com>
Signed-off-by: xueqingz <xueqing.zhang@citrix.com>
@xueqingz xueqingz force-pushed the private/xueqingz/CP-47357 branch from 69fc086 to 890ae8d Compare May 14, 2024 10:20
@xueqingz
Copy link
Contributor Author

checking golang lint on new commit:

root@28dd5689a02b:/app/go/goSDK# golangci-lint run --config=/app/.golangci.yml
WARN The linter 'execinquery' is deprecated (since v1.58.0) due to: The repository of the linter has been archived by the owner.  
WARN The linter 'gomnd' is deprecated (since v1.58.0) due to: The linter has been renamed. Replaced by mnd. 
0 issues.

Test for review changes:

  1. bad http/https url
ubuntu@ubuntu-server:~/code/xenserver-samples/go$ go test base_test.go -ip="10.70.40.100" -username="root" -password="BOfpcNyZ5cMe" -ca_cert_path="/home/ubuntu/xapi-ssl.pem" -v
=== RUN   TestLogin
    base_test.go:35: call session.login_with_password() on htt://10.70.40.100/jsonrpc. Error making http request: Post "htt://10.70.40.100/jsonrpc": unsupported protocol scheme "htt"
--- FAIL: TestLogin (0.00s)
FAIL
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6c05c2]

goroutine 1 [running]:
command-line-arguments.TestMain(0xc000110960)
        /home/ubuntu/code/xenserver-samples/go/base_test.go:49 +0xa2
main.main()
        _testmain.go:49 +0x195
FAIL    command-line-arguments  0.005s
FAIL
  1. https with valid CA certificate/ https with opts.SecureOpts.ServerCert = "" :
ubuntu@ubuntu-server:~/code/xenserver-samples/go$ go test base_test.go -ip="10.70.40.100" -username="root" -password="BOfpcNyZ5cMe" -ca_cert_path="/home/ubuntu/xapi-ssl.pem" -v
=== RUN   TestLogin
/home/ubuntu/xapi-ssl.pem
    base_test.go:39: api version:  2.21
    base_test.go:40: xapi rpm version:  24.14
--- PASS: TestLogin (0.05s)
PASS
ok      command-line-arguments  0.052s
  1. https with invalid CA certificate:
ubuntu@ubuntu-server:~/code/xenserver-samples/go$ go test base_test.go -ip="10.70.40.100" -username="root" -password="BOfpcNyZ5cMe" -ca_cert_path="/home/ubuntu/xapi-ssl-bad.pem" -v
=== RUN   TestLogin
2024/05/14 09:12:29 failed to parse CA certificate
FAIL    command-line-arguments  0.003s
FAIL

Try run xenserver-samples test manually, no special error found.

@xueqingz xueqingz merged commit a20df67 into xapi-project:feature/go_sdk May 14, 2024
13 checks passed
Copy link

pytype_reporter extracted 50 problem reports from pytype output

.

You can check the results of the job here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants