Skip to content

Commit

Permalink
Merge pull request kubernetes-sigs#2 from kubernetes-sigs/master
Browse files Browse the repository at this point in the history
Sync latest repo
  • Loading branch information
snehala27 authored Apr 30, 2020
2 parents 9eafc6e + 7177d6a commit 98bd6fb
Show file tree
Hide file tree
Showing 38 changed files with 465 additions and 400 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
!/api/**
!/cloud/**
!/controllers/**
!/exp/**
!/pkg/**
!/main.go
!/go.mod
Expand Down
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ KUBECTL=$(TOOLS_BIN_DIR)/kubectl
KUSTOMIZE := $(abspath $(TOOLS_BIN_DIR)/kustomize)
MOCKGEN := $(TOOLS_BIN_DIR)/mockgen
RELEASE_NOTES := $(TOOLS_DIR)/$(RELEASE_NOTES_BIN)
EXP_DIR := exp

# Define Docker related variables. Releases should modify and double check these vars.
REGISTRY ?= gcr.io/$(shell gcloud config get-value project)
Expand Down Expand Up @@ -172,26 +173,28 @@ generate: ## Generate code

.PHONY: generate-go
generate-go: $(CONTROLLER_GEN) $(MOCKGEN) $(CONVERSION_GEN) ## Runs Go related generate targets
go generate ./...
$(CONTROLLER_GEN) \
paths=./api/... \
paths=./$(EXP_DIR)/api/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt

$(CONVERSION_GEN) \
--input-dirs=./api/v1alpha2 \
--output-file-base=zz_generated.conversion \
--go-header-file=./hack/boilerplate/boilerplate.generatego.txt
go generate ./...

.PHONY: generate-manifests
generate-manifests: $(CONTROLLER_GEN) ## Generate manifests e.g. CRD, RBAC etc.
$(CONTROLLER_GEN) \
paths=./api/... \
paths=./$(EXP_DIR)/api/... \
crd:crdVersions=v1 \
output:crd:dir=$(CRD_ROOT) \
output:webhook:dir=$(WEBHOOK_ROOT) \
webhook
$(CONTROLLER_GEN) \
paths=./controllers/... \
paths=./$(EXP_DIR)/controllers/... \
output:rbac:dir=$(RBAC_ROOT) \
rbac:roleName=manager-role

Expand Down Expand Up @@ -338,7 +341,7 @@ create-management-cluster: $(KUSTOMIZE) $(ENVSUBST)
@echo 'Set kubectl context to the kind management cluster by running "kubectl config set-context kind-capz"'

.PHONY: create-workload-cluster
create-workload-cluster: $(KUSTOMIZE) $(ENVSUBST)
create-workload-cluster: $(ENVSUBST)
# Create workload Cluster.
$(ENVSUBST) < $(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE) | kubectl apply -f -

Expand Down
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ hybrid deployments of Kubernetes.

Check out the [Cluster API Quick Start][quickstart] to create your first Kubernetes cluster on Azure using Cluster API.

## Features

TODO

---
------

## Support Policy

Expand All @@ -47,7 +43,7 @@ Each version of Cluster API for Azure will attempt to support at least two Kuber

**NOTE:** As the versioning for this project is tied to the versioning of Cluster API, future modifications to this policy may be made to more closely align with other providers in the Cluster API ecosystem.

---
------

## Documentation

Expand Down
30 changes: 0 additions & 30 deletions api/v1alpha2/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions api/v1alpha3/azuremachine_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2020 The Kubernetes 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 v1alpha3

import (
"crypto/rand"
"crypto/rsa"

"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
)

// SetDefaultSSHPublicKey sets the default SSHPublicKey for an AzureMachine
func (m *AzureMachine) SetDefaultSSHPublicKey() error {
sshKeyData := m.Spec.SSHPublicKey
if sshKeyData == "" {
privateKey, perr := rsa.GenerateKey(rand.Reader, 2048)
if perr != nil {
return errors.Wrap(perr, "Failed to generate private key")
}

publicRsaKey, perr := ssh.NewPublicKey(&privateKey.PublicKey)
if perr != nil {
return errors.Wrap(perr, "Failed to generate public key")
}
m.Spec.SSHPublicKey = string(ssh.MarshalAuthorizedKey(publicRsaKey))
}

return nil
}
60 changes: 60 additions & 0 deletions api/v1alpha3/azuremachine_default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2020 The Kubernetes 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 v1alpha3

import (
"testing"

. "github.com/onsi/gomega"
)

func TestAzureMachine_SetDefaultSSHPublicKey(t *testing.T) {
g := NewWithT(t)

type test struct {
machine *AzureMachine
}

existingPublicKey := "testpublickey"
publicKeyExistTest := test{machine: createMachineWithSSHPublicKey(t, existingPublicKey)}
publicKeyNotExistTest := test{machine: createMachineWithSSHPublicKey(t, "")}

err := publicKeyExistTest.machine.SetDefaultSSHPublicKey()
g.Expect(err).To(BeNil())
g.Expect(publicKeyExistTest.machine.Spec.SSHPublicKey).To(Equal(existingPublicKey))

err = publicKeyNotExistTest.machine.SetDefaultSSHPublicKey()
g.Expect(err).To(BeNil())
g.Expect(publicKeyNotExistTest.machine.Spec.SSHPublicKey).To(Not(BeEmpty()))
}

func createMachineWithSSHPublicKey(t *testing.T, sshPublicKey string) *AzureMachine {
return &AzureMachine{
Spec: AzureMachineSpec{
SSHPublicKey: sshPublicKey,
Image: &Image{
SharedGallery: &AzureSharedGalleryImage{
SubscriptionID: "SUB123",
ResourceGroup: "RG123",
Name: "NAME123",
Gallery: "GALLERY1",
Version: "1.0.0",
},
},
},
}
}
34 changes: 34 additions & 0 deletions api/v1alpha3/azuremachine_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright 2020 The Kubernetes 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 v1alpha3

import (
"golang.org/x/crypto/ssh"
"k8s.io/apimachinery/pkg/util/validation/field"
)

// ValidateSSHKey validates an SSHKey
func ValidateSSHKey(sshKey string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)); err != nil {
allErrs = append(allErrs, field.Required(fldPath, "the SSH public key is not valid"))
return allErrs
}

return allErrs
}
65 changes: 65 additions & 0 deletions api/v1alpha3/azuremachine_validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2020 The Kubernetes 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 v1alpha3

import (
"crypto/rand"
"crypto/rsa"
"testing"

. "github.com/onsi/gomega"
"golang.org/x/crypto/ssh"
"k8s.io/apimachinery/pkg/util/validation/field"
)

func TestAzureMachine_ValidateSSHKey(t *testing.T) {
g := NewWithT(t)

tests := []struct {
name string
sshKey string
wantErr bool
}{
{
name: "valid ssh key",
sshKey: generateSSHPublicKey(),
wantErr: false,
},
{
name: "invalid ssh key",
sshKey: "invalid ssh key",
wantErr: true,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := ValidateSSHKey(tc.sshKey, field.NewPath("sshPublicKey"))
if tc.wantErr {
g.Expect(err).ToNot(HaveLen(0))
} else {
g.Expect(err).To(HaveLen(0))
}
})
}
}

func generateSSHPublicKey() string {
privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
publicRsaKey, _ := ssh.NewPublicKey(&privateKey.PublicKey)
return string(ssh.MarshalAuthorizedKey(publicRsaKey))
}
22 changes: 22 additions & 0 deletions api/v1alpha3/azuremachine_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,25 @@ func (m *AzureMachine) ValidateCreate() error {
m.Name, errs)
}

if errs := ValidateSSHKey(m.Spec.SSHPublicKey, field.NewPath("sshPublicKey")); len(errs) > 0 {
return apierrors.NewInvalid(
GroupVersion.WithKind("AzureMachine").GroupKind(),
m.Name, errs)
}

return nil
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (m *AzureMachine) ValidateUpdate(old runtime.Object) error {
machinelog.Info("validate update", "name", m.Name)

if errs := ValidateSSHKey(m.Spec.SSHPublicKey, field.NewPath("sshPublicKey")); len(errs) > 0 {
return apierrors.NewInvalid(
GroupVersion.WithKind("AzureMachine").GroupKind(),
m.Name, errs)
}

return nil
}

Expand All @@ -65,3 +77,13 @@ func (m *AzureMachine) ValidateDelete() error {

return nil
}

// Default implements webhookutil.defaulter so a webhook will be registered for the type
func (m *AzureMachine) Default() {
machinelog.Info("default", "name", m.Name)

err := m.SetDefaultSSHPublicKey()
if err != nil {
machinelog.Error(err, "SetDefaultSshPublicKey failed")
}
}
Loading

0 comments on commit 98bd6fb

Please sign in to comment.