harness / harness-go-sdk Goto Github PK
View Code? Open in Web Editor NEWAn SDK written in Go for interacting with the Harness API's
License: Apache License 2.0
An SDK written in Go for interacting with the Harness API's
License: Apache License 2.0
I am testing harness terraform module in Jenkins. I am able to perform the terraform execution part, but while reaching out to client sdk to validate few properties I am facing the following error:
**panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xcef4c1]**
goroutine 19 [running]:
testing.tRunner.func1.2(0xdb4ee0, 0x1565770)
/usr/share/go/src/testing/testing.go:1144 +0x332
testing.tRunner.func1(0xc000102d80)
/usr/share/go/src/testing/testing.go:1147 +0x4b6
panic(0xdb4ee0, 0x1565770)
/usr/share/go/src/runtime/panic.go:965 +0x1b9
test/unit.TestHarnessK8sCloudProvider(0xc000102d80)
**/tmp/workspace/xxxx/provider_test.go:72** +0x661
testing.tRunner(0xc000102d80, 0xf00748)
/usr/share/go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
/usr/share/go/src/testing/testing.go:1239 +0x2b3
Line# 72 in the code is the following one:
require.Equal(t, client.Configuration.AccountId, "AbcxYz1234", "FAILED: AccountID does NOT match")
The code for client config is the following. I have set env vars HARNESSS_ACCOUNT_ID and HARNESS_API_KEY:
client, _ := cd.NewClient(&cd.Config{
AccountId: helpers.EnvVars.AccountId.Get(),
APIKey: helpers.EnvVars.ApiKey.Get(),
DebugLogging: true,
})
I would like to know if there is additional instruction to set network config to reach out to the harness sdk. Kindly help us to get the way forward here.
Thank you.
@abrahamkoshy
I see the SecretTextSpec struct which I believe is what I need to create an inline text secret. However, the secret APIs only accepts the SecretRequestWrapper -> Secret -> SecretSpec.
Do the clients just need to be rebuilt from the swagger definitions?
The GraphQL Service has ArtifactorySources attribute however it is not populated on get. Also, there is no method to get the list of artifacts collected for a source.
Hi Team, hopefully this is right place to ask, if not, I'd appreciate if you can direct me.
I'm the founder of cloudquery.io, a high performance open source ELT framework.
Our users are interested in a Harness plugin, but as we cannot maintain all the plugins ourselves, I was curious if this would be an interesting collaboration, where we would help implement an initial source plugin, and you will help maintain it (Similar to terraform provider but much easier as it's just the extract part).
This will give your users the ability to sync Harness APIs to any of their datalakes/data-warehouses/databases easily using any of the growing list of CQ destination plugins.
Best,
Yevgeny
Please add GetServiceByName to ConfigAsCodeClient
The ConfigAsCodeClient is missing ListServices to list services for an application.
Request to add config variables to the GraphQL service model @ https://github.com/harness/harness-go-sdk/blob/main/harness/cd/graphql/model_service.go#L5. We look up service by name and so we have to call GetServiceByName and then use ConfigAsCode GetServiceById to be able to get the list of ConfigVariables.
Also, there are multiple API calls behind the scene here. 1) GetServiceByName has to list services by application and then loop thru to find the service by name. 2) ConfigAsCode GetServiceById has to get the directory tree, recursive calls to find object, and then make another API call to get service. Will there be performance issue once we have many services under an app?
Trying to debug some issues with Terraform module for Harness, and found that after trying to use the underlying SDK for Go directly myself that it suffers from the same problem I was seeing: 401 unauthorized.
Looking into the various underlying operations, such as GetClusterList
we see the auth code is trying to read from the context:
if ctx != nil {
// API Key Authentication
if auth, ok := ctx.Value(ContextAPIKey).(APIKey); ok {
var key string
if auth.Prefix != "" {
key = auth.Prefix + " " + auth.Key
} else {
key = auth.Key
}
localVarHeaderParams["x-api-key"] = key
}
}
However, I'm not sure - but don't these need to also check the c.client.cfg.ApiKey? I'm passing the API key as a setup parameter to the nextgen API client, and it's being propagated into the struct for the clusters APIs etc. If I hack the code to manually set my API key from the structs API key, then it seems to work fine though. It seems like this is a pattern throughout the whole SDK.
Cross reference at: harness/terraform-provider-harness#260
I want to create a new settings api so that I can use it in the terraform, but I am struggling on how to move forward with this. I did try to figure out the usage of the swagger-generator and tried related configs but I had some issues like
The incoming YAML document exceeds the limit
then I tried converting the yaml to json and run it based on the issue and it ran with the swagger generator, but then it generated files and doc but with the package as swagger, but then I tried adding the api-package and model-package variable in the command, but still that did not worked as expected.
The expectation here is that can someone please provide some guideline on how to refer the harness APIs, what command to use and what are the pre-requisites to be able to contribute to this repo and use it in diff use cases.
Looking at the following list functions, there are some inconsistencies in the input args. Some have filters while others not. Some filter use specific struct while another uses separate args. Most of the args start with limit and offset but then ListServicesByApplicationId starts with appId.
Like to propose the following changes.
Hi,
We are integrating with feature-flags service in go SDK and have found following issues:
json:"permanent,omitempty"
property has issue due to extra whitespace, so the field is not getting set in request (and the API returns Bad Request error - "request body has an error: doesn't match the schema: Error at "/permanent": property "permanent" is missing").Please address these issues, and if any clarifications are needed please do reach out.
Thank you
In order to pass in a yaml pipeline content this has to have a content-type: application/yaml
header. There's no way to actually select it in the autogenerated code.
harness-go-sdk/harness/nextgen/api_pipelines.go
Lines 1644 to 1650 in fc0a3f3
harness-go-sdk/harness/nextgen/client.go
Lines 308 to 316 in fc0a3f3
Currently if a user is just using next gen, and only has a next gen api key, they are still required to set a fake API key during sdk.NewSession(). This is because the current-gen client explicitly looks for an API key and returns an error if one is not set.
https://github.com/harness-io/harness-go-sdk/blob/main/harness/cd/client.go#L54
Ideally, I should be able to use a current-gen key, a next-gen key, or both without any errors being thrown.
Related to:
harness/terraform-provider-harness#75 (comment)
Can type used for timestamps be consistent and a type that doesn't cause error with json.Marshal?
Here are two examples that I'm working with. The Delegate LastHeartBeat is in string but the value is actual int64 which I have to convert to int64 first and then to time.Time manually. The CloudProvider CreatedAt is in *time.Time that returns pointer error on json.Marshal.
It is unclear in the SDK how the deserializers are to be used or which one to use. Although the
GraphQL responses do seem to have the responses, none are revealed from the SDK exported structures.
Please see the following as a small example for the issue.
Issue: GraphQL queries returned with the "data" tags are not processed
Here is a simple query .... for Application Id.
As you can see from the session below the GraphQL is returning the query
but the desrializer in the code is not handling it properly.
func HarnessAppId(name string) (string, error) {
var buf string = ""
var err error
client := getClient()
query := &cd.GraphQLQuery{
Query: fmt.Sprintf(`query($name: String!) {
applicationByName(name: $name) {
id
name
}
}`),
Variables: map[string]interface{}{
"name": name,
},
}
res := &struct {
App graphql.Application
}{}
err = client.ExecuteGraphQLQuery(query, &res)
if err != nil {
log.Fatalln(err)
return buf, err
}
fmt.Println("==>", res)
fmt.Println("==>", res.App)
fmt.Println("> ", res.App.CommonMetadata.Id)
fmt.Println("> ", res.App.Name)
fmt.Println("> ", res.App.Id)
buf = res.App.Id
return buf, nil
}
And here is a simple session for that code with Debug turned on.
2022-02-21 22:18:28 [DEBUG] harness-go-sdk performing request%!(EXTRA string=method, string=POST, string=url, *url.URL=https://app.harness.io/gateway/api/graphql?accountId=vrst0PgwRnOIeii0a2inKg)
2022-02-21 22:18:28 [DEBUG] harness-go-sdk harness-go-sdk API Request Details:
---[ REQUEST ]---------------------------------------
POST /gateway/api/graphql?accountId=vrst0PgwRnOIeii0a2inKg HTTP/1.1
Host: app.harness.io
Content-Length: 152
Accept: application/json; charset=utf-8
Content-Type: application/json; charset=utf-8
X-Api-Key: xxx
Accept-Encoding: gzip
{
"query": "query($name: String!) {\n\t\t\tapplicationByName(name: $name) {\n\t\t\t\tid\n\t\t\t\tname\n\t\t\t}\n\t\t}",
"variables": {
"name": "raider-poc"
}
}
-----------------------------------------------------
2022-02-21 22:18:28 [DEBUG] harness-go-sdk harness-go-sdk API Response Details:
---[ RESPONSE ]--------------------------------------
HTTP/2.0 200 OK
Content-Length: 82
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Content-Type: application/json;charset=utf-8
Date: Mon, 21 Feb 2022 22:18:28 GMT
Strict-Transport-Security: max-age=15724800; includeSubDomains
Via: 1.1 google
{
"data": {
"applicationByName": {
"id": "QwhnkOO9QKS6ZCxnFkLPnw",
"name": "raider-poc"
}
}
}
-----------------------------------------------------
==> &{{{<nil> <nil> []} [] <nil> false <nil> <nil> <nil>}}
==> {{<nil> <nil> []} [] <nil> false <nil> <nil> <nil>}
>
>
>
In harness\time\time.go, the UnmarshalJSON function assumes that the incoming int64 value does not have the nanosecond portion, and creates the Time type as:
*(*time.Time)(t) = time.Unix(parsedInt, 0)
We observe that this assumption is not true, at least for the executions query, as in
query {
executions(limit:10) {
nodes {
id
startedAt
endedAt
status
}
}
The startedAt and endedAt fields return values greater than "seconds from Unix epoch", causing the function to return an invalid Time object.
Documentation is incorrect for the example
We state in the example that we can use NewClient() , but this is incorrect it is missing a config parameter
harness-go-sdk/harness/cd/client.go
Line 71 in dd21cbe
When using the SaaS version the graphql endpoint is /gateway/api/grahpql
but on-prem it is /api/graphql
. We need the ability to override this.
"HTTPClient" should be passed instead of "Endpoint" to NewInvalidConfigError:
harness-go-sdk/harness/cd/client.go
Lines 88 to 90 in cf5bd4f
Can create, update, and delete functions be added to the new ServiceClient @ https://github.com/harness/harness-go-sdk/blob/main/harness/cd/service.go? There is upsert and delete in the ConfigAsCode client. Seems inconsistent to switch between the Service client and CAC client.
This is a missing field needed for the terraform provider to support setting execute_on_delegate flag.
Related issue: harness/terraform-provider-harness#949
Hi,
I'm passing existing applicationId and environmentId to:
env, err := client.ConfigAsCodeClient.GetEnvironmentById(applicationId, environmentId)
and getting below error:
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x2c pc=0x6b9366]
goroutine 6 [running]:
testing.tRunner.func1.1(0x754ec0, 0xa6ab70)
/usr/local/go/src/testing/testing.go:988 +0x30d
testing.tRunner.func1(0xc00009c900)
/usr/local/go/src/testing/testing.go:991 +0x3f9
panic(0x754ec0, 0xa6ab70)
/usr/local/go/src/runtime/panic.go:969 +0x166
github.com/sirupsen/logrus.(*Logger).level(...)
/home/lf/go/pkg/mod/github.com/sirupsen/[email protected]/logger.go:352
github.com/sirupsen/logrus.(*Logger).IsLevelEnabled(...)
/home/lf/go/pkg/mod/github.com/sirupsen/[email protected]/logger.go:374
github.com/sirupsen/logrus.(*Logger).Logf(0x0, 0x5, 0x7c1ce4, 0x14, 0xc0001abcd8, 0x1, 0x1)
/home/lf/go/pkg/mod/github.com/sirupsen/[email protected]/logger.go:149 +0x26
github.com/sirupsen/logrus.(*Logger).Debugf(...)
/home/lf/go/pkg/mod/github.com/sirupsen/[email protected]/logger.go:161
github.com/harness/harness-go-sdk/harness/cd.(*ConfigAsCodeClient).FindObjectById(0xc0000c2400, 0x7c29a5, 0x16, 0x7c29fd, 0x16, 0x757060, 0xc00014eb40, 0x73a400, 0x530000c0001d80f0)
/home/lf/go/pkg/mod/github.com/harness/[email protected]/harness/cd/cac.go:371 +0xd2
github.com/harness/harness-go-sdk/harness/cd.(*ConfigAsCodeClient).GetEnvironmentById(0xc0000c2400, 0x7c29a5, 0x16, 0x7c29fd, 0x16, 0xc0001d8100, 0xc0001abe00, 0x1)
/home/lf/go/pkg/mod/github.com/harness/[email protected]/harness/cd/cac_environment.go:75 +0x115
Client is able to connect to Harness.io (checked with a different method and I can retrieve ApplicationId for example.
Hi Team,
I am trying to update my harness-go-sdk version from 0.1.11 to 0.3.9 and in one of our terraform module its failing on the terratest.
Below are the details . Please check the details and suggest the fix/resolution for doing the backward compatibility while upgrading the harness-go-sdk version.
I have checked the arguments passed to FindYamlByPath which are 'id' and 'path' and they are getting valid values. Please let me know if you need any further information from the code to reproduce the error.
# The line which gives error
workflowYamlItem err := client.ConfigAsCodeClient.FindYamlByPath(fmt.Sprint(applicationAttributes["id"]), cac.YamlPath(path)
# Error message :
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: nvalid memory address or nil pointer dereference
# Client Configuration for Harness
client, err := cd.NewClient(&cd.Config{
AccoundId: helpers.EnvVars.AccountId.Get(),
APIKey: helpers.EnvVars.ApiKey.Get(),
Endpoint: "https://app.harness.io/gateway",
DefaultHeader: make(map[string]string),
HTTPClient: &retryablehttp.Client{
RetryMax: 10,
RetryWaitMin: 5 * time.Second,
RetryWaitMax: 10 * time.Second,
HTTPClient: &http.client{
Timeout: 10 * time.Second,
},
Backoff: retryablehttp.DefaultBackoff,
CheckRetry: retryablehttp.DefaultRetryPolicy,
}
DebugLogging: true,
})
# imports in go.mod ( go version 1.16 )
github.com/gruntwork-io/terratest v0.40.2
github.com/harness/harness-go-sdk v0.3.9
github.com/hashicorp/go-retryablehttp v0.7.1
github.com/stretchr/testify v.1.7.1
gopkg.in/yaml.v3 v3.0.1
# Terratest imports :
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/harness/harness-go-sdk/harness/cd"
"github.com/harness/harness-go-sdk/harness/helpers"
"github.com/hashicorp/go-retryablehttp"
"github.com/harness/harness-go-sdk/harness/cd/cac"
"github.com/stretchr/testify/require"
"testing"
"os"
"encoding/json"
"fmt"
"gopkg.in/yaml.v3"
"time"
"net/http"
Looking for a good way to do pipeline and workflow executions using the golang APIs,
and retrieve the status on each of them, including failure status and current state of the
environment it failed on.
The code in the README.md doesn't specify the namespaces/packages to import Client or other objects from with illustrative import statements.
Given the very strange way this package has gone to lengths to make it pull all the sub-packages in the initial go get (the root package is essentially empty with nothing more than a bunch of underscored references to other sub-packages...), it's even stranger that there's no examples folder, or a hint as to what package Client refers to.
Would suggest:
Add imports statements to the README.md examples
Add an /examples folder showing a few basic scenarios.
Remove the underscored imports. Go will automatically lock in the sub-packages, however this approach will mean that go get / go mod vendor will always include all the subtrees for components you might not even be using (i.e. if you're not using legacy/firstgen).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.