Skip to content

Commit

Permalink
Merge pull request #1908 from fluxcd/ssa
Browse files Browse the repository at this point in the history
Implement server-side apply
  • Loading branch information
stefanprodan authored Oct 8, 2021
2 parents 9227722 + 2b4d615 commit 0e74779
Show file tree
Hide file tree
Showing 41 changed files with 251 additions and 223 deletions.
1 change: 0 additions & 1 deletion .github/aur/flux-bin/.SRCINFO.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pkgbase = flux-bin
arch = armv7h
arch = aarch64
license = APACHE
optdepends = kubectl
source_x86_64 = flux-bin-${PKGVER}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v1/flux_${PKGVER}_linux_amd64.tar.gz
source_armv6h = flux-bin-${PKGVER}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v1/flux_${PKGVER}_linux_arm.tar.gz
source_armv7h = flux-bin-${PKGVER}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v1/flux_${PKGVER}_linux_arm.tar.gz
Expand Down
3 changes: 1 addition & 2 deletions .github/aur/flux-bin/PKGBUILD.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ pkgdesc="Open and extensible continuous delivery solution for Kubernetes"
url="https://fluxcd.io/"
arch=("x86_64" "armv6h" "armv7h" "aarch64")
license=("APACHE")
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
optdepends=('bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source_x86_64=(
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_amd64.tar.gz"
Expand Down
1 change: 0 additions & 1 deletion .github/aur/flux-go/.SRCINFO.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pkgbase = flux-go
license = APACHE
makedepends = go
depends = glibc
optdepends = kubectl
provides = flux-bin
conflicts = flux-bin
replaces = flux-cli
Expand Down
3 changes: 1 addition & 2 deletions .github/aur/flux-go/PKGBUILD.template
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ conflicts=("flux-bin")
replaces=("flux-cli")
depends=("glibc")
makedepends=('go>=1.16', 'kustomize>=3.0')
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
optdepends=('bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/archive/v${pkgver}.tar.gz"
Expand Down
1 change: 0 additions & 1 deletion .github/aur/flux-scm/.SRCINFO.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pkgbase = flux-scm
license = APACHE
makedepends = go
depends = glibc
optdepends = kubectl
provides = flux-bin
conflicts = flux-bin
source = git+https://github.com/fluxcd/flux2.git
Expand Down
3 changes: 1 addition & 2 deletions .github/aur/flux-scm/PKGBUILD.template
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ provides=("flux-bin")
conflicts=("flux-bin")
depends=("glibc")
makedepends=('go>=1.16', 'kustomize>=3.0')
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
optdepends=('bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
"git+https://github.com/fluxcd/flux2.git"
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ jobs:
--path="./deploy/overlays/dev" \
--prune=true \
--interval=5m \
--validation=client \
--health-check="Deployment/frontend.dev" \
--health-check="Deployment/backend.dev" \
--health-check-timeout=3m
Expand Down
3 changes: 0 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ brews:
folder: Formula
homepage: "https://fluxcd.io/"
description: "Flux CLI"
dependencies:
- name: kubectl
type: optional
install: |
bin.install "flux"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM alpine:3.13 as builder
RUN apk add --no-cache ca-certificates curl

ARG ARCH=linux/amd64
ARG KUBECTL_VER=1.20.4
ARG KUBECTL_VER=1.22.2

RUN curl -sL https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \
-o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl && \
Expand Down
75 changes: 21 additions & 54 deletions cmd/flux/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ package main

import (
"context"
"encoding/json"
"os"
"os/exec"
"time"

"github.com/Masterminds/semver/v3"
"github.com/spf13/cobra"
v1 "k8s.io/api/apps/v1"
apimachineryversion "k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"

Expand Down Expand Up @@ -56,8 +53,11 @@ type checkFlags struct {
extraComponents []string
}

type kubectlVersion struct {
ClientVersion *apimachineryversion.Info `json:"clientVersion"`
var kubernetesConstraints = []string{
">=1.19.0-0",
">=1.16.11-0 <=1.16.15-0",
">=1.17.7-0 <=1.17.17-0",
">=1.18.4-0 <=1.18.20-0",
}

var checkArgs checkFlags
Expand All @@ -73,19 +73,12 @@ func init() {
}

func runCheckCmd(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()

logger.Actionf("checking prerequisites")
checkFailed := false

fluxCheck()

if !kubectlCheck(ctx, ">=1.18.0-0") {
checkFailed = true
}

if !kubernetesCheck(">=1.16.0-0") {
if !kubernetesCheck(kubernetesConstraints) {
checkFailed = true
}

Expand Down Expand Up @@ -130,43 +123,7 @@ func fluxCheck() {
}
}

func kubectlCheck(ctx context.Context, constraint string) bool {
_, err := exec.LookPath("kubectl")
if err != nil {
logger.Failuref("kubectl not found")
return false
}

kubectlArgs := []string{"version", "--client", "--output", "json"}
output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...)
if err != nil {
logger.Failuref("kubectl version can't be determined")
return false
}

kv := &kubectlVersion{}
if err = json.Unmarshal([]byte(output), kv); err != nil {
logger.Failuref("kubectl version output can't be unmarshalled")
return false
}

v, err := version.ParseVersion(kv.ClientVersion.GitVersion)
if err != nil {
logger.Failuref("kubectl version can't be parsed")
return false
}

c, _ := semver.NewConstraint(constraint)
if !c.Check(v) {
logger.Failuref("kubectl version %s < %s", v.Original(), constraint)
return false
}

logger.Successf("kubectl %s %s", v.String(), constraint)
return true
}

func kubernetesCheck(constraint string) bool {
func kubernetesCheck(constraints []string) bool {
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
if err != nil {
logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
Expand All @@ -191,13 +148,23 @@ func kubernetesCheck(constraint string) bool {
return false
}

c, _ := semver.NewConstraint(constraint)
if !c.Check(v) {
logger.Failuref("Kubernetes version %s < %s", v.Original(), constraint)
var valid bool
var vrange string
for _, constraint := range constraints {
c, _ := semver.NewConstraint(constraint)
if c.Check(v) {
valid = true
vrange = constraint
break
}
}

if !valid {
logger.Failuref("Kubernetes version %s does not match %s", v.Original(), constraints[0])
return false
}

logger.Successf("Kubernetes %s %s", v.String(), constraint)
logger.Successf("Kubernetes %s %s", v.String(), vrange)
return true
}

Expand Down
2 changes: 0 additions & 2 deletions cmd/flux/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ func TestCheckPre(t *testing.T) {
t.Fatalf("Error unmarshalling: %v", err.Error())
}

clientVersion := strings.TrimPrefix(versions["clientVersion"].GitVersion, "v")
serverVersion := strings.TrimPrefix(versions["serverVersion"].GitVersion, "v")

cmd := cmdTestCase{
args: "check --pre",
assert: assertGoldenTemplateFile("testdata/check/check_pre.golden", map[string]string{
"clientVersion": clientVersion,
"serverVersion": serverVersion,
}),
}
Expand Down
12 changes: 5 additions & 7 deletions cmd/flux/create_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta"

"github.com/fluxcd/flux2/internal/flags"
Expand All @@ -49,7 +49,6 @@ var createKsCmd = &cobra.Command{
--path="./examples/contour/" \
--prune=true \
--interval=10m \
--validation=client \
--health-check="Deployment/contour.projectcontour" \
--health-check="DaemonSet/envoy.projectcontour" \
--health-check-timeout=3m
Expand All @@ -60,17 +59,15 @@ var createKsCmd = &cobra.Command{
--source=GitRepository/webapp \
--path="./deploy/overlays/dev" \
--prune=true \
--interval=5m \
--validation=client
--interval=5m
# Create a Kustomization using a source from a different namespace
flux create kustomization podinfo \
--namespace=default \
--source=GitRepository/podinfo.flux-system \
--path="./deploy/overlays/dev" \
--prune=true \
--interval=5m \
--validation=client
--interval=5m
# Create a Kustomization resource that references a Bucket
flux create kustomization secrets \
Expand Down Expand Up @@ -108,6 +105,8 @@ func init() {
createKsCmd.Flags().Var(&kustomizationArgs.decryptionProvider, "decryption-provider", kustomizationArgs.decryptionProvider.Description())
createKsCmd.Flags().StringVar(&kustomizationArgs.decryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption")
createKsCmd.Flags().StringVar(&kustomizationArgs.targetNamespace, "target-namespace", "", "overrides the namespace of all Kustomization objects reconciled by this Kustomization")
createKsCmd.Flags().MarkDeprecated("validation", "this arg is no longer used, all resources are validated using server-side apply dry-run")

createCmd.AddCommand(createKsCmd)
}

Expand Down Expand Up @@ -158,7 +157,6 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
Namespace: kustomizationArgs.source.Namespace,
},
Suspend: false,
Validation: kustomizationArgs.validation,
TargetNamespace: kustomizationArgs.targetNamespace,
},
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/delete_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package main
import (
"github.com/spf13/cobra"

kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
)

var deleteKsCmd = &cobra.Command{
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/export_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
)

var exportKsCmd = &cobra.Command{
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/get_all.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta1"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/get_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime"

kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
)

var getKsCmd = &cobra.Command{
Expand Down
25 changes: 10 additions & 15 deletions cmd/flux/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ If a previous version is installed, then an in-place upgrade will be performed.`
flux install --version=latest --namespace=flux-system
# Install a specific version and a series of components
flux install --dry-run --version=v0.0.7 --components="source-controller,kustomize-controller"
flux install --version=v0.0.7 --components="source-controller,kustomize-controller"
# Install Flux onto tainted Kubernetes nodes
flux install --toleration-keys=node.kubernetes.io/dedicated-to-flux
# Dry-run install with manifests preview
flux install --dry-run --verbose
# Dry-run install
flux install --export | kubectl apply --dry-run=client -f-
# Write install manifests to file
flux install --export > flux-system.yaml`,
Expand Down Expand Up @@ -102,6 +102,7 @@ func init() {
"list of toleration keys used to schedule the components pods onto nodes with matching taints")
installCmd.Flags().MarkHidden("manifests")
installCmd.Flags().MarkDeprecated("arch", "multi-arch container image is now available for AMD64, ARMv7 and ARM64")
installCmd.Flags().MarkDeprecated("dry-run", "use 'flux install --export | kubectl apply --dry-run=client -f-'")
rootCmd.AddCommand(installCmd)
}

Expand Down Expand Up @@ -188,24 +189,18 @@ func installCmdRun(cmd *cobra.Command, args []string) error {

logger.Successf("manifests build completed")
logger.Actionf("installing components in %s namespace", rootArgs.namespace)
applyOutput := utils.ModeStderrOS
if rootArgs.verbose {
applyOutput = utils.ModeOS
}

kubectlArgs := []string{"apply", "-f", filepath.Join(tmpDir, manifest.Path)}
if installArgs.dryRun {
kubectlArgs = append(kubectlArgs, "--dry-run=client")
applyOutput = utils.ModeOS
logger.Successf("install dry-run finished")
return nil
}
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {

applyOutput, err := utils.Apply(ctx, rootArgs.kubeconfig, rootArgs.kubecontext, filepath.Join(tmpDir, manifest.Path))
if err != nil {
return fmt.Errorf("install failed: %w", err)
}

if installArgs.dryRun {
logger.Successf("install dry-run finished")
return nil
}
fmt.Fprintln(os.Stderr, applyOutput)

kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package main
import (
"sigs.k8s.io/controller-runtime/pkg/client"

kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
)

// kustomizev1.Kustomization
Expand Down
2 changes: 1 addition & 1 deletion cmd/flux/kustomization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func TestKustomizationFromGit(t *testing.T) {
"testdata/kustomization/create_source_git.golden",
},
{
"create kustomization tkfg --source=tkfg --path=./deploy/overlays/dev --prune=true --interval=5m --validation=client --health-check=Deployment/frontend.dev --health-check=Deployment/backend.dev --health-check-timeout=3m",
"create kustomization tkfg --source=tkfg --path=./deploy/overlays/dev --prune=true --interval=5m --health-check=Deployment/frontend.dev --health-check=Deployment/backend.dev --health-check-timeout=3m",
"testdata/kustomization/create_kustomization_from_git.golden",
},
{
Expand Down
3 changes: 1 addition & 2 deletions cmd/flux/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.`,
flux check --pre
# Install the latest version of Flux
flux install --version=master
flux install
# Create a source for a public Git repository
flux create source git webapp-latest \
Expand All @@ -66,7 +66,6 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.`,
--path="./deploy/webapp/" \
--prune=true \
--interval=5m \
--validation=client \
--health-check="Deployment/backend.webapp" \
--health-check="Deployment/frontend.webapp" \
--health-check-timeout=2m
Expand Down
Loading

0 comments on commit 0e74779

Please sign in to comment.