Skip to content
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

Break provider-gcp up by service #288

Merged
merged 4 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
47 changes: 29 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export TERRAFORM_DOCS_PATH ?= website/docs/r

PLATFORMS ?= linux_amd64 linux_arm64

export PROJECT_NAME := $(PROJECT_NAME)

# -include will silently skip missing files, which allows us
# to load those files with a target in the Makefile. If only
# "include" was used, the make command would fail and refuse
Expand Down Expand Up @@ -43,19 +45,42 @@ export GOPRIVATE = github.com/upbound/*

GO_REQUIRED_VERSION ?= 1.19
GOLANGCILINT_VERSION ?= 1.50.0
GO_STATIC_PACKAGES = $(GO_PROJECT)/cmd/provider $(GO_PROJECT)/cmd/generator
# SUBPACKAGES ?= $(shell find cmd/provider -type d -maxdepth 1 -mindepth 1 | cut -d/ -f3)
SUBPACKAGES ?= monolith
GO_STATIC_PACKAGES ?= $(GO_PROJECT)/cmd/generator ${SUBPACKAGES:%=$(GO_PROJECT)/cmd/provider/%}
GO_LDFLAGS += -X $(GO_PROJECT)/internal/version.Version=$(VERSION)
GO_SUBDIRS += cmd internal apis
GO111MODULE = on

export SUBPACKAGES := $(SUBPACKAGES)

-include build/makelib/golang.mk

# ====================================================================================
# Setup XPKG

XPKG_REG_ORGS ?= xpkg.upbound.io/upbound
# NOTE(hasheddan): skip promoting on xpkg.upbound.io as channel tags are
# inferred.
XPKG_REG_ORGS_NO_PROMOTE ?= xpkg.upbound.io/upbound

export XPKG_REG_ORGS := $(XPKG_REG_ORGS)
export XPKG_REG_ORGS_NO_PROMOTE := $(XPKG_REG_ORGS_NO_PROMOTE)

-include build/makelib/xpkg.mk

# ====================================================================================
# Setup Kubernetes tools

KIND_VERSION = v0.15.0
UPTEST_VERSION = v0.5.0
# dependency for up
UP_VERSION = v0.16.1
UP_CHANNEL = stable
UPTEST_VERSION = v0.5.0

export UP_VERSION := $(UP_VERSION)
export UP_CHANNEL := $(UP_CHANNEL)

-include build/makelib/k8s_tools.mk

# ====================================================================================
Expand All @@ -65,20 +90,6 @@ REGISTRY_ORGS ?= xpkg.upbound.io/upbound
IMAGES = provider-gcp
-include build/makelib/imagelight.mk

# ====================================================================================
# Setup XPKG

XPKG_REG_ORGS ?= xpkg.upbound.io/upbound
# NOTE(hasheddan): skip promoting on xpkg.upbound.io as channel tags are
# inferred.
XPKG_REG_ORGS_NO_PROMOTE ?= xpkg.upbound.io/upbound
XPKGS = provider-gcp
-include build/makelib/xpkg.mk

# NOTE(hasheddan): we force image building to happen prior to xpkg build so that
# we ensure image is present in daemon.
xpkg.build.provider-gcp: do.build.images

# ====================================================================================
# Targets

Expand Down Expand Up @@ -169,9 +180,9 @@ uptest: $(UPTEST) $(KUBECTL) $(KUTTL)
uptest-local:
@$(WARN) "this target is deprecated, please use 'make uptest' instead"

local-deploy: build controlplane.up local.xpkg.deploy.provider.$(PROJECT_NAME)
local-deploy: build controlplane.up local.xpkg.deploy.provider.$(PROJECT_NAME)-monolith
@$(INFO) running locally built provider
@$(KUBECTL) wait provider.pkg $(PROJECT_NAME) --for condition=Healthy --timeout 5m
@$(KUBECTL) wait provider.pkg $(PROJECT_NAME)-monolith --for condition=Healthy --timeout 5m
@$(KUBECTL) -n upbound-system wait --for=condition=Available deployment --all --timeout=5m
@$(OK) running locally built provider

Expand Down
2 changes: 2 additions & 0 deletions apis/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ limitations under the License.
//go:generate bash -c "find ../internal/controller -iname 'zz_*' -delete"
//go:generate bash -c "find ../internal/controller -type d -empty -delete"
//go:generate rm -rf ../examples-generated
//go:generate bash -c "find ../cmd/provider -name 'zz_*' -type f -delete"
//go:generate bash -c "find ../cmd/provider -type d -maxdepth 1 -mindepth 1 -empty -delete"

// Scrape metadata from Terraform registry
//go:generate go run github.com/upbound/upjet/cmd/scraper -n hashicorp/terraform-provider-google -r ../.work/terraform-provider-google/website/docs/r -o ../config/provider-metadata.yaml --prelude-xpath "//text()[contains(., \"subcategory\")]" --resource-prefix google
Expand Down
3 changes: 2 additions & 1 deletion cluster/images/provider-gcp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ RUN apk --no-cache add ca-certificates bash

ARG TARGETOS
ARG TARGETARCH
ARG APIGROUP

ENV USER_ID=65532

Expand Down Expand Up @@ -47,6 +48,6 @@ ENV TERRAFORM_NATIVE_PROVIDER_PATH ${PLUGIN_DIR}/${TERRAFORM_PROVIDER_DOWNLOAD_N
USER ${USER_ID}
EXPOSE 8080

ADD "bin/${TARGETOS}_${TARGETARCH}/provider" /usr/local/bin/provider
ADD "bin/${TARGETOS}_${TARGETARCH}/${APIGROUP}" /usr/local/bin/provider

ENTRYPOINT ["provider"]
56 changes: 47 additions & 9 deletions cluster/images/provider-gcp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,57 @@ include ../../../build/makelib/common.mk

include ../../../build/makelib/imagelight.mk

# ====================================================================================
# XPKG

-include ../../../build/makelib/xpkg.mk

-include ../../../build/makelib/k8s_tools.mk

# ====================================================================================
# Targets

img.build:
@$(INFO) docker build $(IMAGE)
@$(MAKE) BUILD_ARGS="--load" img.build.shared
@$(OK) docker build $(IMAGE)
@$(INFO) Subpackages to build: $(SUBPACKAGES)
@for g in $(SUBPACKAGES); do \
IMAGE=$$(echo $(IMAGE) | sed -r "s/(.*)-/\1-$${g}-/"); \
$(INFO) Building image $${IMAGE}; \
$(MAKE) BUILD_ARGS="--load" IMAGE=$${IMAGE} APIGROUP=$${g} XPKG_REG_ORGS=$(XPKG_REG_ORGS) img.build.shared; \
$(OK) docker build $${IMAGE}; \
done

img.publish:
@$(INFO) Skipping image publish for $(IMAGE)
@echo Publish is deferred to xpkg machinery
@$(OK) Image publish skipped for $(IMAGE)
# make BRANCH_NAME=main SUBPACKAGES=cloudplatform publish
img.publish: $(UP)
@$(INFO) Subpackages to publish: $(SUBPACKAGES)
@for g in $(SUBPACKAGES); do \
PACKAGE=$(XPKG_REG_ORGS)/$(PROJECT_NAME)-$${g}:$(VERSION); \
if [[ $${g} == "monolith" ]]; then PACKAGE=$(XPKG_REG_ORGS)/$(PROJECT_NAME):$(VERSION); fi; \
$(INFO) Pushing package $${PACKAGE}; \
$(UP) xpkg push $${PACKAGE} \
$(foreach p,$(XPKG_LINUX_PLATFORMS),--package $(XPKG_OUTPUT_DIR)/$(p)/$(PROJECT_NAME)-$${g}-$(VERSION).xpkg ) || $(FAIL); \
$(OK) Done processing $${PACKAGE}. Moving to the next package...; \
done || $(FAIL)

img.build.shared:
img.build.shared: $(UP)
@mkdir -p $(IMAGE_TEMP_DIR)/package/crds || $(FAIL)
@mkdir $(IMAGE_TEMP_DIR)/examples || $(FAIL)
@if [[ $(APIGROUP) == "config" ]]; then \
sed -e "s/{{ APIGROUP }}/$(APIGROUP)/g" $(ROOT_DIR)/package/crossplane-config.yaml > $(IMAGE_TEMP_DIR)/package/crossplane.yaml && \
cp $(ROOT_DIR)/package/crds/gcp.* $(IMAGE_TEMP_DIR)/package/crds/ && \
cp -r $(ROOT_DIR)/examples/gcp $(IMAGE_TEMP_DIR)/examples/; \
elif [[ $(APIGROUP) == "monolith" ]]; then \
cp $(ROOT_DIR)/package/crossplane-monolith.yaml $(IMAGE_TEMP_DIR)/package/crossplane.yaml && \
cp -r $(ROOT_DIR)/package/crds $(IMAGE_TEMP_DIR)/package/ && \
cp -r $(ROOT_DIR)/examples $(IMAGE_TEMP_DIR)/; \
else \
sed -e "s|{{ APIGROUP }}|$(APIGROUP)|g" $(ROOT_DIR)/package/crossplane.yaml | sed -e "s|{{ XPKG_REG_ORGS }}|$(XPKG_REG_ORGS)|g" | sed -e "s|{{ VERSION }}|$(VERSION)|g" > $(IMAGE_TEMP_DIR)/package/crossplane.yaml && \
cp $(ROOT_DIR)/package/crds/$(APIGROUP).* $(IMAGE_TEMP_DIR)/package/crds/ && \
cp -r $(ROOT_DIR)/examples/$(APIGROUP) $(IMAGE_TEMP_DIR)/examples/; \
fi || $(FAIL)
@cp Dockerfile $(IMAGE_TEMP_DIR) || $(FAIL)
@cp terraformrc.hcl $(IMAGE_TEMP_DIR) || $(FAIL)
@cp -r $(OUTPUT_DIR)/bin/ $(IMAGE_TEMP_DIR)/bin || $(FAIL)
@mkdir -p $(IMAGE_TEMP_DIR)/bin/$(PLATFORM)/ || $(FAIL)
@cp -r $(OUTPUT_DIR)/bin/$(PLATFORM)/$(APIGROUP) $(IMAGE_TEMP_DIR)/bin/$(PLATFORM)/ || $(FAIL)
@docker buildx build $(BUILD_ARGS) \
--platform $(IMAGE_PLATFORMS) \
--build-arg TERRAFORM_VERSION=$(TERRAFORM_VERSION) \
Expand All @@ -33,8 +67,12 @@ img.build.shared:
--build-arg TERRAFORM_PROVIDER_DOWNLOAD_NAME=$(TERRAFORM_PROVIDER_DOWNLOAD_NAME) \
--build-arg TERRAFORM_PROVIDER_DOWNLOAD_URL_PREFIX=$(TERRAFORM_PROVIDER_DOWNLOAD_URL_PREFIX) \
--build-arg CROSSPLANE_PROVIDER_VERSION=$(VERSION) \
--build-arg APIGROUP=$(APIGROUP) \
-t $(IMAGE) \
$(IMAGE_TEMP_DIR) || $(FAIL)
@$(MAKE) UP=$(UP) XPKG_REG_ORGS=$(XPKG_REG_ORGS) XPKG_REG_ORGS_NO_PROMOTE=$(XPKG_REG_ORGS_NO_PROMOTE) XPKGS=$(PROJECT_NAME)-$(APIGROUP) XPKG_DIR=$(IMAGE_TEMP_DIR)/package XPKG_EXAMPLES_DIR=$(IMAGE_TEMP_DIR)/examples build.xpkg || $(FAIL)

build.xpkg: do.build.xpkgs

img.promote:
@$(INFO) Skipping image promotion from $(FROM_IMAGE) to $(TO_IMAGE)
Expand Down
150 changes: 150 additions & 0 deletions cmd/provider/activedirectory/zz_main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
Copyright 2021 The Crossplane Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"context"
"os"
"path/filepath"
"time"

"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/log/zap"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
xpcontroller "github.com/crossplane/crossplane-runtime/pkg/controller"
"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/resource"

tjcontroller "github.com/upbound/upjet/pkg/controller"
"github.com/upbound/upjet/pkg/terraform"

"github.com/upbound/provider-gcp/apis"
"github.com/upbound/provider-gcp/apis/v1alpha1"
"github.com/upbound/provider-gcp/config"
"github.com/upbound/provider-gcp/internal/clients"
"github.com/upbound/provider-gcp/internal/controller"
"github.com/upbound/provider-gcp/internal/features"

_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)

func main() {
var (
app = kingpin.New(filepath.Base(os.Args[0]), "Terraform based Crossplane provider for GCP").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 checked for drift from the desired state.").Default("10").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()
terraformVersion = app.Flag("terraform-version", "Terraform version.").Required().Envar("TERRAFORM_VERSION").String()
nativeProviderSource = app.Flag("terraform-provider-source", "Terraform provider source.").Required().Envar("TERRAFORM_PROVIDER_SOURCE").String()
providerVersion = app.Flag("terraform-provider-version", "Terraform provider version.").Required().Envar("TERRAFORM_PROVIDER_VERSION").String()
nativeProviderPath = app.Flag("terraform-native-provider-path", "Terraform native provider path for shared execution.").Default("").Envar("TERRAFORM_NATIVE_PROVIDER_PATH").String()

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()
enableManagementPolicies = app.Flag("enable-management-policies", "Enable support for Management Policies.").Default("false").Envar("ENABLE_MANAGEMENT_POLICIES").Bool()
)

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

zl := zap.New(zap.UseDevMode(*debug))
log := logging.NewLogrLogger(zl.WithName("provider-gcp"))
if *debug {
// The controller-runtime runs with a no-op logger by default. It is
// *very* verbose even at info level, so we only provide it a real
// logger when we're running in debug mode.
ctrl.SetLogger(zl)
}

log.Debug("Starting", "sync-interval", syncInterval.String(),
"poll-interval", pollInterval.String(), "max-reconcile-rate", *maxReconcileRate)

cfg, err := ctrl.GetConfig()
kingpin.FatalIfError(err, "Cannot get API server rest config")

mgr, err := ctrl.NewManager(ratelimiter.LimitRESTConfig(cfg, *maxReconcileRate), ctrl.Options{
LeaderElection: *leaderElection,
LeaderElectionID: "crossplane-leader-election-provider-gcp",
SyncPeriod: syncInterval,
LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
LeaseDuration: func() *time.Duration { d := 60 * time.Second; return &d }(),
RenewDeadline: func() *time.Duration { d := 50 * time.Second; return &d }(),
})
kingpin.FatalIfError(err, "Cannot create controller manager")
kingpin.FatalIfError(apis.AddToScheme(mgr.GetScheme()), "Cannot add GCP 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.
var scheduler terraform.ProviderScheduler = terraform.NewNoOpProviderScheduler()
if len(*nativeProviderPath) != 0 {
scheduler = terraform.NewSharedProviderScheduler(log, *pluginProcessTTL, terraform.WithNativeProviderPath(*nativeProviderPath), terraform.WithNativeProviderName("registry.terraform.io/"+*nativeProviderSource))
}

o := tjcontroller.Options{
Options: xpcontroller.Options{
Logger: log,
GlobalRateLimiter: ratelimiter.NewGlobal(*maxReconcileRate),
PollInterval: *pollInterval,
MaxConcurrentReconciles: *maxReconcileRate,
Features: &feature.Flags{},
},
Provider: config.GetProvider(),
WorkspaceStore: terraform.NewWorkspaceStore(log, terraform.WithDisableInit(len(*nativeProviderPath) != 0), terraform.WithProcessReportInterval(*pollInterval)),
SetupFn: clients.TerraformSetupBuilder(*terraformVersion, *nativeProviderSource, *providerVersion, scheduler),
}
if *enableExternalSecretStores {
o.SecretStoreConfigGVK = &v1alpha1.StoreConfigGroupVersionKind
log.Info("Alpha feature enabled", "flag", features.EnableAlphaExternalSecretStores)

// Ensure default store config exists.
kingpin.FatalIfError(resource.Ignore(kerrors.IsAlreadyExists, mgr.GetClient().Create(context.Background(), &v1alpha1.StoreConfig{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: v1alpha1.StoreConfigSpec{
// NOTE(turkenh): We only set required spec and expect optional
// ones to properly be initialized with CRD level default values.
SecretStoreConfig: xpv1.SecretStoreConfig{
DefaultScope: *namespace,
},
},
Status: v1alpha1.StoreConfigStatus{},
})), "cannot create default store config")
}

if *enableManagementPolicies {
o.Features.Enable(features.EnableAlphaManagementPolicies)
log.Info("Alpha feature enabled", "flag", features.EnableAlphaManagementPolicies)
}

kingpin.FatalIfError(controller.Setup_activedirectory(mgr, o), "Cannot setup GCP controllers")
kingpin.FatalIfError(mgr.Start(ctrl.SetupSignalHandler()), "Cannot start controller manager")
}
Loading