Skip to content

Commit

Permalink
add metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
tchinmai7 committed May 16, 2024
1 parent 0b29853 commit 8a1e9bc
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 90 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PROJECT_REPO := github.com/linode/$(PROJECT_NAME)

export TERRAFORM_VERSION := 1.5.5
export TERRAFORM_PROVIDER_SOURCE := linode/linode
export TERRAFORM_PROVIDER_VERSION := 2.20.0
export TERRAFORM_PROVIDER_VERSION := 2.20.1
export TERRAFORM_PROVIDER_DOWNLOAD_NAME := terraform-provider-linode
export TERRAFORM_NATIVE_PROVIDER_BINARY := terraform-provider-linode_v$(TERRAFORM_PROVIDER_VERSION)
export TERRAFORM_PROVIDER_REPO := https://github.com/linode/terraform-provider-linode
Expand Down
37 changes: 1 addition & 36 deletions cluster/images/provider-linode/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.16.2
FROM alpine:3.19.1
RUN apk --no-cache add ca-certificates bash

ARG TARGETOS
Expand All @@ -8,41 +8,6 @@ ADD "bin/${TARGETOS}_${TARGETARCH}/provider" /usr/local/bin/provider

ENV USER_ID=65532

# Setup Terraform environment

## Provider-dependent configuration
ARG TERRAFORM_VERSION
ARG TERRAFORM_PROVIDER_SOURCE
ARG TERRAFORM_PROVIDER_VERSION
ARG TERRAFORM_PROVIDER_DOWNLOAD_NAME
ARG TERRAFORM_NATIVE_PROVIDER_BINARY
## End of - Provider-dependent configuration

ENV PLUGIN_DIR /terraform/provider-mirror/registry.terraform.io/${TERRAFORM_PROVIDER_SOURCE}/${TERRAFORM_PROVIDER_VERSION}/${TARGETOS}_${TARGETARCH}
ENV TF_CLI_CONFIG_FILE /terraform/.terraformrc
ENV TF_FORK 0

RUN mkdir -p ${PLUGIN_DIR}

ADD https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip /tmp
ADD https://releases.hashicorp.com/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}/${TERRAFORM_PROVIDER_VERSION}/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip /tmp
ADD terraformrc.hcl ${TF_CLI_CONFIG_FILE}

RUN unzip /tmp/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip -d /usr/local/bin \
&& chmod +x /usr/local/bin/terraform \
&& rm /tmp/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip \
&& unzip /tmp/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip -d ${PLUGIN_DIR} \
&& chmod +x ${PLUGIN_DIR}/* \
&& rm /tmp/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip \
&& chown -R ${USER_ID}:${USER_ID} /terraform
# End of - Setup Terraform environment

# Provider controller needs these environment variable at runtime
ENV TERRAFORM_VERSION ${TERRAFORM_VERSION}
ENV TERRAFORM_PROVIDER_SOURCE ${TERRAFORM_PROVIDER_SOURCE}
ENV TERRAFORM_PROVIDER_VERSION ${TERRAFORM_PROVIDER_VERSION}
ENV TERRAFORM_NATIVE_PROVIDER_PATH ${PLUGIN_DIR}/${TERRAFORM_NATIVE_PROVIDER_BINARY}

USER ${USER_ID}
EXPOSE 8080

Expand Down
6 changes: 0 additions & 6 deletions cluster/images/provider-linode/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,9 @@ img.publish:

img.build.shared:
@cp Dockerfile $(IMAGE_TEMP_DIR) || $(FAIL)
@cp terraformrc.hcl $(IMAGE_TEMP_DIR) || $(FAIL)
@cp -r $(OUTPUT_DIR)/bin/ $(IMAGE_TEMP_DIR)/bin || $(FAIL)
@docker buildx build $(BUILD_ARGS) \
--platform $(IMAGE_PLATFORMS) \
--build-arg TERRAFORM_VERSION=$(TERRAFORM_VERSION) \
--build-arg TERRAFORM_PROVIDER_SOURCE=$(TERRAFORM_PROVIDER_SOURCE) \
--build-arg TERRAFORM_PROVIDER_VERSION=$(TERRAFORM_PROVIDER_VERSION) \
--build-arg TERRAFORM_PROVIDER_DOWNLOAD_NAME=$(TERRAFORM_PROVIDER_DOWNLOAD_NAME) \
--build-arg TERRAFORM_NATIVE_PROVIDER_BINARY=$(TERRAFORM_NATIVE_PROVIDER_BINARY) \
-t $(IMAGE) \
$(IMAGE_TEMP_DIR) || $(FAIL)

Expand Down
9 changes: 0 additions & 9 deletions cluster/images/provider-linode/terraformrc.hcl

This file was deleted.

57 changes: 28 additions & 29 deletions cmd/provider/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/feature"
"github.com/crossplane/crossplane-runtime/pkg/logging"
"github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
"github.com/crossplane/crossplane-runtime/pkg/resource"
"github.com/crossplane/crossplane-runtime/pkg/statemetrics"

tjcontroller "github.com/crossplane/upjet/pkg/controller"
"github.com/crossplane/upjet/pkg/terraform"
"gopkg.in/alecthomas/kingpin.v2"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/leaderelection/resourcelock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics"

"github.com/linode/provider-linode/apis"
"github.com/linode/provider-linode/apis/v1alpha1"
Expand All @@ -37,24 +40,23 @@ import (

func main() {
var (
app = kingpin.New(filepath.Base(os.Args[0]), "Linode support for Crossplane.").DefaultEnvars()
debug = app.Flag("debug", "Run with debug logging.").Short('d').Bool()
syncInterval = app.Flag("sync", "Sync interval controls how often all resources will be double checked for drift.").Short('s').Default("1h").Duration()
pollInterval = app.Flag("poll", "Poll interval controls how often an individual resource should be checked for drift.").Default("10m").Duration()
leaderElection = app.Flag("leader-election", "Use leader election for the controller manager.").Short('l').Default("false").OverrideDefaultFromEnvar("LEADER_ELECTION").Bool()
maxReconcileRate = app.Flag("max-reconcile-rate", "The global maximum rate per second at which resources may be checked for drift from the desired state.").Default("100").Int()
pluginProcessTTL = app.Flag("provider-ttl", "TTL for the native plugin processes before they are replaced. Changing the default may increase memory consumption.").Default("100").Int()

app = kingpin.New(filepath.Base(os.Args[0]), "Linode support for Crossplane.").DefaultEnvars()
debug = app.Flag("debug", "Run with debug logging.").Short('d').Bool()
syncInterval = app.Flag("sync", "Sync interval controls how often all resources will be double checked for drift.").Short('s').Default("1h").Duration()
pollInterval = app.Flag("poll", "Poll interval controls how often an individual resource should be checked for drift.").Default("10m").Duration()
leaderElection = app.Flag("leader-election", "Use leader election for the controller manager.").Short('l').Default("false").OverrideDefaultFromEnvar("LEADER_ELECTION").Bool()
maxReconcileRate = app.Flag("max-reconcile-rate", "The global maximum rate per second at which resources may be checked for drift from the desired state.").Default("100").Int()
_ = app.Flag("provider-ttl", "DEPRECATED: TTL for the native plugin processes before they are replaced. Changing the default may increase memory consumption.").Default("100").Int()
pollStateMetricInterval = app.Flag("poll-state-metric", "State metric recording interval").Default("5s").Duration()
namespace = app.Flag("namespace", "Namespace used to set as default scope in default secret store config.").Default("crossplane-system").Envar("POD_NAMESPACE").String()
enableExternalSecretStores = app.Flag("enable-external-secret-stores", "Enable support for ExternalSecretStores.").Default("false").Envar("ENABLE_EXTERNAL_SECRET_STORES").Bool()
essTLSCertsPath = app.Flag("ess-tls-cert-dir", "Path of ESS TLS certificates.").Envar("ESS_TLS_CERTS_DIR").String()
enableManagementPolicies = app.Flag("enable-management-policies", "Enable support for Management Policies.").Default("true").Envar("ENABLE_MANAGEMENT_POLICIES").Bool()
)
setupConfig := &clients.SetupConfig{}
setupConfig.TerraformVersion = app.Flag("terraform-version", "Terraform version.").Required().Envar("TERRAFORM_VERSION").String()
setupConfig.NativeProviderSource = app.Flag("terraform-provider-source", "Terraform provider source.").Required().Envar("TERRAFORM_PROVIDER_SOURCE").String()
setupConfig.NativeProviderVersion = app.Flag("terraform-provider-version", "Terraform provider version.").Required().Envar("TERRAFORM_PROVIDER_VERSION").String()
setupConfig.NativeProviderPath = app.Flag("terraform-native-provider-path", "Terraform native provider path for shared execution.").Default("").Envar("TERRAFORM_NATIVE_PROVIDER_PATH").String()
_ = app.Flag("terraform-version", "DEPRECATED: Terraform version.").Envar("TERRAFORM_VERSION").String()
_ = app.Flag("terraform-provider-source", "DEPRECATED: Terraform provider source.").Envar("TERRAFORM_PROVIDER_SOURCE").String()
_ = app.Flag("terraform-provider-version", "DEPRECATED: Terraform provider version.").Envar("TERRAFORM_PROVIDER_VERSION").String()
_ = app.Flag("terraform-native-provider-path", "DEPRECATED: Terraform native provider path for shared execution.").Default("").Envar("TERRAFORM_NATIVE_PROVIDER_PATH").String()

kingpin.MustParse(app.Parse(os.Args[1:]))

Expand Down Expand Up @@ -84,32 +86,31 @@ func main() {
kingpin.FatalIfError(err, "Cannot create controller manager")
kingpin.FatalIfError(apis.AddToScheme(mgr.GetScheme()), "Cannot add Linode APIs to scheme")

// if the native Terraform provider plugin's path is not configured via
// the env. variable TERRAFORM_NATIVE_PROVIDER_PATH or
// the `--terraform-native-provider-path` command-line option,
// we do not use the shared gRPC server and default to the regular
// Terraform CLI behaviour (of forking a plugin process per invocation).
// This removes some complexity for setting up development environments.
setupConfig.DefaultScheduler = terraform.NewNoOpProviderScheduler()
if len(*setupConfig.NativeProviderPath) != 0 {
setupConfig.DefaultScheduler = terraform.NewSharedProviderScheduler(log, *pluginProcessTTL,
terraform.WithSharedProviderOptions(terraform.WithNativeProviderPath(*setupConfig.NativeProviderPath), terraform.WithNativeProviderName("registry.terraform.io/"+*setupConfig.NativeProviderSource)))
}
mm := managed.NewMRMetricRecorder()
sm := statemetrics.NewMRStateMetrics()

metrics.Registry.MustRegister(mm)
metrics.Registry.MustRegister(sm)

mo := xpcontroller.MetricOptions{
PollStateMetricInterval: *pollStateMetricInterval,
MRMetrics: mm,
MRStateMetrics: sm,
}
ctx := context.Background()
provider, err := config.GetProvider(ctx, false)
kingpin.FatalIfError(err, "Cannot initialize the provider configuration")
setupConfig.TerraformProvider = provider.TerraformProvider
o := tjcontroller.Options{
Options: xpcontroller.Options{
Logger: log,
GlobalRateLimiter: ratelimiter.NewGlobal(*maxReconcileRate),
PollInterval: *pollInterval,
MaxConcurrentReconciles: *maxReconcileRate,
Features: &feature.Flags{},
MetricOptions: &mo,
},
Provider: provider,
SetupFn: clients.TerraformSetupBuilder(*setupConfig.TerraformVersion, *setupConfig.NativeProviderSource, *setupConfig.NativeProviderVersion, provider.TerraformProvider, setupConfig.DefaultScheduler),
SetupFn: clients.TerraformSetupBuilder(provider.TerraformProvider),
PollJitter: pollJitter,
OperationTrackerStore: tjcontroller.NewOperationStore(log),
}
Expand All @@ -119,8 +120,6 @@ func main() {
log.Info("Beta feature enabled", "flag", features.EnableBetaManagementPolicies)
}

o.WorkspaceStore = terraform.NewWorkspaceStore(log, terraform.WithDisableInit(len(*setupConfig.NativeProviderPath) != 0), terraform.WithProcessReportInterval(*pollInterval), terraform.WithFeatures(o.Features))

if *enableExternalSecretStores {
o.SecretStoreConfigGVK = &v1alpha1.StoreConfigGroupVersionKind
log.Info("Alpha feature enabled", "flag", features.EnableAlphaExternalSecretStores)
Expand Down
11 changes: 2 additions & 9 deletions internal/clients/linode.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,9 @@ type SetupConfig struct {

// TerraformSetupBuilder builds Terraform a terraform.SetupFn function which
// returns Terraform provider setup configuration
func TerraformSetupBuilder(version, providerSource, providerVersion string, tfProvider *schema.Provider, scheduler terraform.ProviderScheduler) terraform.SetupFn {
func TerraformSetupBuilder(tfProvider *schema.Provider) terraform.SetupFn {
return func(ctx context.Context, client client.Client, mg resource.Managed) (terraform.Setup, error) {
ps := terraform.Setup{
Version: version,
Requirement: terraform.ProviderRequirement{
Source: providerSource,
Version: providerVersion,
},
Scheduler: scheduler,
}
ps := terraform.Setup{}

configRef := mg.GetProviderConfigReference()
if configRef == nil {
Expand Down

0 comments on commit 8a1e9bc

Please sign in to comment.