From cdee11f9a5fdd709f78b58ac69ab762dcf6c380b Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Tue, 18 Jun 2024 18:10:05 +0000 Subject: [PATCH 1/2] add timeout for linodego http client --- README.md | 13 +++++++++++-- cloud/linode/client/client.go | 22 +++++++++++++++++++--- cloud/linode/cloud.go | 12 +++++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index de3381da..5c2987f9 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,15 @@ sessionAffinityConfig: timeoutSeconds: 100 ``` +## Additional environment variables +To tweak CCM based on needs, one can overwrite the default values set for caches and requests by setting appropriate environment variables when applying the manifest or helm chart. + +Environment Variable | Default | Description +---|---|--- +`LINODE_INSTANCE_CACHE_TTL` | `15` | Default timeout of instance cache in seconds +`LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds +`LINODE_REQUEST_TIMEOUT_SECONDS` | `120` | Default timeout in seconds for http requests to linode API + ## Generating a Manifest for Deployment Use the script located at `./deploy/generate-manifest.sh` to generate a self-contained deployment manifest for the Linode CCM. Two arguments are required. @@ -320,7 +329,7 @@ helm repo update ccm-linode ### To deploy ccm-linode. Run the following command: ```sh -export VERSION=v0.3.22 +export VERSION=v0.4.8 export LINODE_API_TOKEN= export REGION= helm install ccm-linode --set apiToken=$LINODE_API_TOKEN,region=$REGION ccm-linode/ccm-linode @@ -335,7 +344,7 @@ _See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command doc ### To upgrade when new changes are made to the helm chart. Run the following command: ```sh -export VERSION=v0.3.22 +export VERSION=v0.4.8 export LINODE_API_TOKEN= export REGION= diff --git a/cloud/linode/client/client.go b/cloud/linode/client/client.go index ce7ff307..a02e43f9 100644 --- a/cloud/linode/client/client.go +++ b/cloud/linode/client/client.go @@ -4,8 +4,17 @@ package client import ( "context" + "net/http" + "time" "github.com/linode/linodego" + "golang.org/x/oauth2" + "k8s.io/klog/v2" +) + +const ( + // DefaultClientTimeout is the default timeout for a client Linode API call + DefaultClientTimeout = 120 * time.Second ) type Client interface { @@ -48,14 +57,21 @@ type Client interface { var _ Client = (*linodego.Client)(nil) // New creates a new linode client with a given token, userAgent, and API URL -func New(token, userAgent, apiURL string) (*linodego.Client, error) { - linodeClient := linodego.NewClient(nil) +func New(token, userAgent, apiURL string, timeout time.Duration) (*linodego.Client, error) { + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) + oauth2Client := &http.Client{ + Transport: &oauth2.Transport{ + Source: tokenSource, + }, + Timeout: timeout, + } + linodeClient := linodego.NewClient(oauth2Client) client, err := linodeClient.UseURL(apiURL) if err != nil { return nil, err } client.SetUserAgent(userAgent) - client.SetToken(token) + klog.V(3).Infof("Linode client created with default timeout of %v seconds", timeout) return client, nil } diff --git a/cloud/linode/cloud.go b/cloud/linode/cloud.go index a7d5fc54..a2e9a04c 100644 --- a/cloud/linode/cloud.go +++ b/cloud/linode/cloud.go @@ -4,7 +4,9 @@ import ( "fmt" "io" "os" + "strconv" "sync" + "time" "github.com/linode/linodego" "github.com/spf13/pflag" @@ -98,7 +100,15 @@ func newCloud() (cloudprovider.Interface, error) { url := os.Getenv(urlEnv) ua := fmt.Sprintf("linode-cloud-controller-manager %s", linodego.DefaultUserAgent) - linodeClient, err := client.New(apiToken, ua, url) + // set timeout used by linodeclient for API calls + timeout := client.DefaultClientTimeout + if raw, ok := os.LookupEnv("LINODE_REQUEST_TIMEOUT_SECONDS"); ok { + if t, _ := strconv.Atoi(raw); t > 0 { + timeout = time.Duration(t) * time.Second + } + } + + linodeClient, err := client.New(apiToken, ua, url, timeout) if err != nil { return nil, fmt.Errorf("client was not created succesfully: %w", err) } From 92239924f4644324e1d8d86c883f895531995a43 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Tue, 18 Jun 2024 22:15:14 +0000 Subject: [PATCH 2/2] address review comments --- cloud/linode/client/client.go | 11 ++++++++--- cloud/linode/cloud.go | 9 ++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cloud/linode/client/client.go b/cloud/linode/client/client.go index a02e43f9..abf5bee7 100644 --- a/cloud/linode/client/client.go +++ b/cloud/linode/client/client.go @@ -4,7 +4,9 @@ package client import ( "context" + "fmt" "net/http" + "os" "time" "github.com/linode/linodego" @@ -56,8 +58,11 @@ type Client interface { // linodego.Client implements Client var _ Client = (*linodego.Client)(nil) -// New creates a new linode client with a given token, userAgent, and API URL -func New(token, userAgent, apiURL string, timeout time.Duration) (*linodego.Client, error) { +// New creates a new linode client with a given token and default timeout +func New(token string, timeout time.Duration) (*linodego.Client, error) { + userAgent := fmt.Sprintf("linode-cloud-controller-manager %s", linodego.DefaultUserAgent) + apiURL := os.Getenv("LINODE_URL") + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) oauth2Client := &http.Client{ Transport: &oauth2.Transport{ @@ -72,6 +77,6 @@ func New(token, userAgent, apiURL string, timeout time.Duration) (*linodego.Clie } client.SetUserAgent(userAgent) - klog.V(3).Infof("Linode client created with default timeout of %v seconds", timeout) + klog.V(3).Infof("Linode client created with default timeout of %v", timeout) return client, nil } diff --git a/cloud/linode/cloud.go b/cloud/linode/cloud.go index a2e9a04c..f1138988 100644 --- a/cloud/linode/cloud.go +++ b/cloud/linode/cloud.go @@ -8,7 +8,6 @@ import ( "sync" "time" - "github.com/linode/linodego" "github.com/spf13/pflag" "golang.org/x/exp/slices" "k8s.io/client-go/informers" @@ -22,7 +21,6 @@ const ( ProviderName = "linode" accessTokenEnv = "LINODE_API_TOKEN" regionEnv = "LINODE_REGION" - urlEnv = "LINODE_URL" ciliumLBType = "cilium-bgp" nodeBalancerLBType = "nodebalancer" ) @@ -97,18 +95,15 @@ func newCloud() (cloudprovider.Interface, error) { return nil, fmt.Errorf("%s must be set in the environment (use a k8s secret)", regionEnv) } - url := os.Getenv(urlEnv) - ua := fmt.Sprintf("linode-cloud-controller-manager %s", linodego.DefaultUserAgent) - // set timeout used by linodeclient for API calls timeout := client.DefaultClientTimeout if raw, ok := os.LookupEnv("LINODE_REQUEST_TIMEOUT_SECONDS"); ok { - if t, _ := strconv.Atoi(raw); t > 0 { + if t, err := strconv.Atoi(raw); err == nil && t > 0 { timeout = time.Duration(t) * time.Second } } - linodeClient, err := client.New(apiToken, ua, url, timeout) + linodeClient, err := client.New(apiToken, timeout) if err != nil { return nil, fmt.Errorf("client was not created succesfully: %w", err) }