From b4dd445f23f3707ef6c6534d296e8848b847b03d Mon Sep 17 00:00:00 2001 From: Stuart McLaren Date: Tue, 20 Aug 2024 19:08:30 +0100 Subject: [PATCH] Add basic client and auth code These clients will be used to access various APIs. For example the virt client will be used for creating Virtual Machines. --- go.mod | 3 +- go.sum | 2 + internal/auth/auth.go | 31 +++++++++ internal/client/client.go | 117 ++++++++++++++++++++++++++++++++++ internal/defaults/defaults.go | 12 ++++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 internal/auth/auth.go create mode 100644 internal/client/client.go create mode 100644 internal/defaults/defaults.go diff --git a/go.mod b/go.mod index c2e954e..bd6e455 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,9 @@ go 1.22.3 require ( github.com/google/uuid v1.6.0 github.com/hashicorp/terraform-plugin-framework v1.11.0 + github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/microsoft/kiota-abstractions-go v1.6.1 + github.com/microsoft/kiota-http-go v1.4.4 github.com/microsoft/kiota-serialization-form-go v1.0.0 github.com/microsoft/kiota-serialization-json-go v1.0.8 github.com/microsoft/kiota-serialization-multipart-go v1.0.0 @@ -23,7 +25,6 @@ require ( github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/terraform-plugin-go v0.23.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect diff --git a/go.sum b/go.sum index 2578598..0dfed89 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,8 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/microsoft/kiota-abstractions-go v1.6.1 h1:NXK50S3BwJn9Wj6bO0YFuAig7y2WVgdQ/ie1ktMl2J4= github.com/microsoft/kiota-abstractions-go v1.6.1/go.mod h1:FI1I2OHg0E7bK5t8DPnw+9C/CHVyLP6XeqDBT+95pTE= +github.com/microsoft/kiota-http-go v1.4.4 h1:HM0KT/Q7o+JsGatFkkbTIqJL24Jzo5eMI5NNe9N4TQ4= +github.com/microsoft/kiota-http-go v1.4.4/go.mod h1:Kup5nMDD3a9sjdgRKHCqZWqtrv3FbprjcPaGjLR6FzM= github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= github.com/microsoft/kiota-serialization-json-go v1.0.8 h1:+aViv9k6wqaw1Fx6P49fl5GIB1hN3b6CG0McNTcUYBc= diff --git a/internal/auth/auth.go b/internal/auth/auth.go new file mode 100644 index 0000000..98e756d --- /dev/null +++ b/internal/auth/auth.go @@ -0,0 +1,31 @@ +package auth + +import ( + "context" + "net/url" + + "github.com/microsoft/kiota-abstractions-go/authentication" +) + +type PcbeAccessTokenProvider struct { + token string +} + +func (p *PcbeAccessTokenProvider) GetAuthorizationToken( + ctx context.Context, url *url.URL, + additionalAuthenticationContext map[string]interface{}, +) (string, error) { + return p.token, nil +} + +func (p *PcbeAccessTokenProvider) GetAllowedHostsValidator() *authentication.AllowedHostsValidator { + return nil +} + +func NewPcbeAccessTokenProvider(token string) *PcbeAccessTokenProvider { + p := PcbeAccessTokenProvider{ + token: token, + } + + return &p +} diff --git a/internal/client/client.go b/internal/client/client.go new file mode 100644 index 0000000..07a2305 --- /dev/null +++ b/internal/client/client.go @@ -0,0 +1,117 @@ +package client + +import ( + "context" + "time" + + "github.com/HewlettPackard/hpegl-pcbe-terraform-resources/internal/auth" + "github.com/HewlettPackard/hpegl-pcbe-terraform-resources/internal/defaults" + "github.com/HewlettPackard/hpegl-pcbe-terraform-resources/internal/sdk/async" + "github.com/HewlettPackard/hpegl-pcbe-terraform-resources/internal/sdk/systems" + "github.com/HewlettPackard/hpegl-pcbe-terraform-resources/internal/sdk/virt" + "github.com/microsoft/kiota-abstractions-go/authentication" + "github.com/microsoft/kiota-http-go" +) + +type PCBeClient struct { + Config Config +} + +type Config struct { + Host string + Token string + HTTPDump bool + MaxPolls int32 + PollInterval float32 + HTTPTimeout time.Duration +} + +func (c *PCBeClient) NewAsyncClient(ctx context.Context) (*async.ApiClient, error) { + var middlewares []nethttplibrary.Middleware + + tp := auth.NewPcbeAccessTokenProvider(c.Config.Token) + authProvider := authentication.NewBaseBearerTokenAuthenticationProvider(tp) + observeOpts := nethttplibrary.ObservabilityOptions{} + headerOpts := nethttplibrary.NewHeadersInspectionOptions() + headerOpts.InspectResponseHeaders = true + headerOptsHandler := nethttplibrary.NewHeadersInspectionHandlerWithOptions(*headerOpts) + middlewares = append(middlewares, headerOptsHandler) + httpclient := nethttplibrary.GetDefaultClient(middlewares...) + httpclient.Timeout = c.Config.HTTPTimeout + + adapter, err := nethttplibrary.NewNetHttpRequestAdapterWithParseNodeFactoryAndSerializationWriterFactoryAndHttpClientAndObservabilityOptions(authProvider, nil, nil, httpclient, observeOpts) // nolint: lll + if err != nil { + return nil, err + } + + adapter.SetBaseUrl(c.Config.Host) + asyncClient := async.NewApiClient(adapter) + + return asyncClient, nil +} + +func (c *PCBeClient) NewVirtClient( + ctx context.Context, +) (*virt.ApiClient, *nethttplibrary.HeadersInspectionOptions, error) { + var middlewares []nethttplibrary.Middleware + + tp := auth.NewPcbeAccessTokenProvider(c.Config.Token) + authProvider := authentication.NewBaseBearerTokenAuthenticationProvider(tp) + observeOpts := nethttplibrary.ObservabilityOptions{} + headerOpts := nethttplibrary.NewHeadersInspectionOptions() + headerOpts.InspectResponseHeaders = true + headerOptsHandler := nethttplibrary.NewHeadersInspectionHandlerWithOptions(*headerOpts) + middlewares = append(middlewares, headerOptsHandler) + httpclient := nethttplibrary.GetDefaultClient(middlewares...) + httpclient.Timeout = c.Config.HTTPTimeout + + adapter, err := nethttplibrary.NewNetHttpRequestAdapterWithParseNodeFactoryAndSerializationWriterFactoryAndHttpClientAndObservabilityOptions(authProvider, nil, nil, httpclient, observeOpts) // nolint: lll + if err != nil { + return nil, nil, err + } + + adapter.SetBaseUrl(c.Config.Host) + virtClient := virt.NewApiClient(adapter) + + return virtClient, headerOpts, nil +} + +func (c *PCBeClient) NewSysClient( + ctx context.Context, +) (*systems.ApiClient, *nethttplibrary.HeadersInspectionOptions, error) { + var middlewares []nethttplibrary.Middleware + + tp := auth.NewPcbeAccessTokenProvider(c.Config.Token) + authProvider := authentication.NewBaseBearerTokenAuthenticationProvider(tp) + observeOpts := nethttplibrary.ObservabilityOptions{} + headerOpts := nethttplibrary.NewHeadersInspectionOptions() + headerOpts.InspectResponseHeaders = true + headerOptsHandler := nethttplibrary.NewHeadersInspectionHandlerWithOptions(*headerOpts) + middlewares = append(middlewares, headerOptsHandler) + httpclient := nethttplibrary.GetDefaultClient(middlewares...) + httpclient.Timeout = c.Config.HTTPTimeout + + adapter, err := nethttplibrary.NewNetHttpRequestAdapterWithParseNodeFactoryAndSerializationWriterFactoryAndHttpClientAndObservabilityOptions(authProvider, nil, nil, httpclient, observeOpts) // nolint: lll + if err != nil { + return nil, nil, err + } + + adapter.SetBaseUrl(c.Config.Host) + sysClient := systems.NewApiClient(adapter) + + return sysClient, headerOpts, nil +} + +func NewPCBeClient(ctx context.Context, cfg Config) (*PCBeClient, error) { + if cfg.MaxPolls == 0 { + cfg.MaxPolls = defaults.MaxPolls + } + if cfg.PollInterval == 0.0 { + cfg.PollInterval = defaults.PollInterval + } + client := &PCBeClient{ + Config: cfg, + } + + return client, nil +} diff --git a/internal/defaults/defaults.go b/internal/defaults/defaults.go new file mode 100644 index 0000000..a2c63ac --- /dev/null +++ b/internal/defaults/defaults.go @@ -0,0 +1,12 @@ +package defaults + +import "time" + +const ( + // Time in seconds between polling for updates of resources + PollInterval = float32(5.0) + // Limit on number of polls for a resource + MaxPolls = int32(100) + // http client timeout + HTTPTimeout = 60 * time.Second +)