diff --git a/Makefile b/Makefile index ee7d1144de..99b9dc4d32 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ check: fmt vet lint test ## Check your code .PHONY: unit unit: # Run unit test - $(DOCKER_CMD) go test -race -cover ./cmd/... ./pkg/cloud/... + $(DOCKER_CMD) go test -race -cover ./cmd/... ./pkg/... .PHONY: integration integration: ## Run integration test diff --git a/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types.go b/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types.go index f7c29199bf..caddff1336 100644 --- a/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types.go +++ b/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types.go @@ -37,17 +37,17 @@ const ( // It containsk AWS-specific status information. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type AWSMachineProviderStatus struct { - metav1.TypeMeta + metav1.TypeMeta `json:",inline"` // InstanceID is the instance ID of the machine created in AWS - InstanceID *string + InstanceID *string `json:"instanceId"` // InstanceState is the state of the AWS instance for this machine - InstanceState *string + InstanceState *string `json:"instanceState"` // Conditions is a set of conditions associated with the Machine to indicate // errors or other status - Conditions []AWSMachineProviderCondition + Conditions []AWSMachineProviderCondition `json:"conditions"` } // AWSMachineProviderConditionType is a valid value for AWSMachineProviderCondition.Type @@ -63,21 +63,21 @@ const ( // AWSMachineProviderCondition is a condition in a AWSMachineProviderStatus type AWSMachineProviderCondition struct { // Type is the type of the condition. - Type AWSMachineProviderConditionType + Type AWSMachineProviderConditionType `json:"type"` // Status is the status of the condition. - Status corev1.ConditionStatus + Status corev1.ConditionStatus `json:"status"` // LastProbeTime is the last time we probed the condition. // +optional - LastProbeTime metav1.Time + LastProbeTime metav1.Time `json:"lastProbeTime"` // LastTransitionTime is the last time the condition transitioned from one status to another. // +optional - LastTransitionTime metav1.Time + LastTransitionTime metav1.Time `json:"lastTransitionTime"` // Reason is a unique, one-word, CamelCase reason for the condition's last transition. // +optional - Reason string + Reason string `json:"reason"` // Message is a human-readable message indicating details about last transition. // +optional - Message string + Message string `json:"message"` } // +genclient @@ -90,52 +90,52 @@ type AWSMachineProviderConfig struct { metav1.ObjectMeta `json:"metadata,omitempty"` // AMI is the reference to the AMI from which to create the machine instance. - AMI AWSResourceReference + AMI AWSResourceReference `json:"ami"` // InstanceType is the type of instance to create. Example: m4.xlarge - InstanceType string + InstanceType string `json:"instanceType"` // Tags is the set of tags to add to apply to an instance, in addition to the ones // added by default by the actuator. These tags are additive. The actuator will ensure // these tags are present, but will not remove any other tags that may exist on the // instance. - Tags []TagSpecification + Tags []TagSpecification `json:"tags"` // IAMInstanceProfile is a reference to an IAM role to assign to the instance - IAMInstanceProfile *AWSResourceReference + IAMInstanceProfile *AWSResourceReference `json:"iamInstanceProfile"` // UserDataSecret contains a local reference to a secret that contains the // UserData to apply to the instance - UserDataSecret *corev1.LocalObjectReference + UserDataSecret *corev1.LocalObjectReference `json:"userDataSecret"` // CredentialsSecret is a reference to the secret with AWS credentials. Otherwise, defaults to permissions // provided by attached IAM role where the actuator is running. - CredentialsSecret *corev1.LocalObjectReference + CredentialsSecret *corev1.LocalObjectReference `json:"credentialsSecret"` // KeyName is the name of the KeyPair to use for SSH - KeyName *string + KeyName *string `json:"keyName"` // DeviceIndex is the index of the device on the instance for the network interface attachment. // Defaults to 0. - DeviceIndex int64 + DeviceIndex int64 `json:"deviceIndex"` // PublicIP specifies whether the instance should get a public IP. If not present, // it should use the default of its subnet. - PublicIP *bool + PublicIP *bool `json:"publicIp"` // SecurityGroups is an array of references to security groups that should be applied to the // instance. - SecurityGroups []AWSResourceReference + SecurityGroups []AWSResourceReference `json:"securityGroups"` // Subnet is a reference to the subnet to use for this instance - Subnet AWSResourceReference + Subnet AWSResourceReference `json:"subnet"` // Placement specifies where to create the instance in AWS - Placement Placement + Placement Placement `json:"placement"` // LoadBalancerNames is the names of the load balancers to which the new instance // should be added once it is created. - LoadBalancerNames []string + LoadBalancerNames []string `json:"loadBalancerIds"` } // AWSResourceReference is a reference to a specific AWS resource by ID, ARN, or filters. @@ -143,40 +143,40 @@ type AWSMachineProviderConfig struct { // a validation error. type AWSResourceReference struct { // ID of resource - ID *string + ID *string `json:"id"` // ARN of resource - ARN *string + ARN *string `json:"arn"` // Filters is a set of filters used to identify a resource - Filters []Filter + Filters []Filter `json:"filters"` } // Placement indicates where to create the instance in AWS type Placement struct { // Region is the region to use to create the instance - Region string + Region string `json:"region"` // AvailabilityZone is the availability zone of the instance - AvailabilityZone string + AvailabilityZone string `json:"availabilityZone"` } // Filter is a filter used to identify an AWS resource type Filter struct { // Name of the filter. Filter names are case-sensitive. - Name string + Name string `json:"name"` // Values includes one or more filter values. Filter values are case-sensitive. - Values []string + Values []string `json:"values"` } // TagSpecification is the name/value pair for a tag type TagSpecification struct { // Name of the tag - Name string + Name string `json:"name"` // Value of the tag - Value string + Value string `json:"value"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types_test.go b/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types_test.go deleted file mode 100644 index 5810d1ed54..0000000000 --- a/pkg/apis/awsproviderconfig/v1alpha1/awsmachineproviderconfig_types_test.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2018 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 v1alpha1 - -import ( - "testing" - - "github.com/onsi/gomega" - "golang.org/x/net/context" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -func TestStorageAWSMachineProviderConfig(t *testing.T) { - key := types.NamespacedName{ - Name: "foo", - Namespace: "default", - } - created := &AWSMachineProviderConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: "default", - }} - g := gomega.NewGomegaWithT(t) - - // Test Create - fetched := &AWSMachineProviderConfig{} - g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) - - g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) - g.Expect(fetched).To(gomega.Equal(created)) - - // Test Updating the Labels - updated := fetched.DeepCopy() - updated.Labels = map[string]string{"hello": "world"} - g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) - - g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) - g.Expect(fetched).To(gomega.Equal(updated)) - - // Test Delete - g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) - g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) -} diff --git a/pkg/apis/awsproviderconfig/v1alpha1/register.go b/pkg/apis/awsproviderconfig/v1alpha1/register.go index 39031e4b9f..bc2f4a0dd4 100644 --- a/pkg/apis/awsproviderconfig/v1alpha1/register.go +++ b/pkg/apis/awsproviderconfig/v1alpha1/register.go @@ -72,8 +72,8 @@ func NewCodec() (*AWSProviderConfigCodec, error) { return &codec, nil } -// DecodeFromProviderConfig deserialises an object from the provider config -func (codec *AWSProviderConfigCodec) DecodeFromProviderConfig(providerConfig clusterv1.ProviderConfig, out runtime.Object) error { +// DecodeProviderConfig deserialises an object from the provider config +func (codec *AWSProviderConfigCodec) DecodeProviderConfig(providerConfig *clusterv1.ProviderConfig, out runtime.Object) error { if providerConfig.Value != nil { _, _, err := codec.decoder.Decode(providerConfig.Value.Raw, nil, out) if err != nil { @@ -83,8 +83,8 @@ func (codec *AWSProviderConfigCodec) DecodeFromProviderConfig(providerConfig clu return nil } -// EncodeToProviderConfig serialises an object to the provider config -func (codec *AWSProviderConfigCodec) EncodeToProviderConfig(in runtime.Object) (*clusterv1.ProviderConfig, error) { +// EncodeProviderConfig serialises an object to the provider config +func (codec *AWSProviderConfigCodec) EncodeProviderConfig(in runtime.Object) (*clusterv1.ProviderConfig, error) { var buf bytes.Buffer if err := codec.encoder.Encode(in, &buf); err != nil { return nil, fmt.Errorf("encoding failed: %v", err) diff --git a/pkg/apis/awsproviderconfig/v1alpha1/register_test.go b/pkg/apis/awsproviderconfig/v1alpha1/register_test.go new file mode 100644 index 0000000000..43490121e7 --- /dev/null +++ b/pkg/apis/awsproviderconfig/v1alpha1/register_test.go @@ -0,0 +1,139 @@ +package v1alpha1 + +import ( + apiv1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "reflect" + "testing" + "time" +) + +func TestEncodeAndDecodeProviderStatus(t *testing.T) { + + codec, err := NewCodec() + if err != nil { + t.Fatal(err) + } + time := metav1.Time{ + Time: time.Date(2018, 6, 3, 0, 0, 0, 0, time.Local), + } + + instanceState := "running" + instanceID := "id" + providerStatus := &AWSMachineProviderStatus{ + TypeMeta: metav1.TypeMeta{ + Kind: "AWSMachineProviderStatus", + APIVersion: "awsproviderconfig.k8s.io/v1alpha1", + }, + InstanceState: &instanceState, + InstanceID: &instanceID, + Conditions: []AWSMachineProviderCondition{ + { + Type: "MachineCreation", + Status: "True", + Reason: "MachineCreationSucceeded", + Message: "machine successfully created", + LastTransitionTime: time, + LastProbeTime: time, + }, + }, + } + providerStatusEncoded, err := codec.EncodeProviderStatus(providerStatus) + if err != nil { + t.Error(err) + } + + providerStatusDecoded := &AWSMachineProviderStatus{} + codec.DecodeProviderStatus(providerStatusEncoded, providerStatusDecoded) + if !reflect.DeepEqual(providerStatus, providerStatusDecoded) { + t.Errorf("failed EncodeProviderStatus/DecodeProviderStatus. Expected: %+v, got: %+v", providerStatus, providerStatusDecoded) + } +} + +func TestEncodeAndDecodeProviderConfig(t *testing.T) { + codec, err := NewCodec() + if err != nil { + t.Fatal(err) + } + + publicIP := true + amiID := "id" + awsCredentialsSecretName := "test" + clusterID := "test" + + providerConfig := &AWSMachineProviderConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "AWSMachineProviderConfig", + APIVersion: "awsproviderconfig.k8s.io/v1alpha1", + }, + AMI: AWSResourceReference{ + Filters: []Filter{ + { + Name: "tag:image_stage", + Values: []string{"base"}, + }, + { + Name: "tag:operating_system", + Values: []string{"rhel"}, + }, + { + Name: "tag:ready", + Values: []string{"yes"}, + }, + }, + ID: &amiID, + }, + CredentialsSecret: &apiv1.LocalObjectReference{ + Name: awsCredentialsSecretName, + }, + InstanceType: "m4.xlarge", + Placement: Placement{ + Region: "us-east-1", + AvailabilityZone: "us-east-1a", + }, + Subnet: AWSResourceReference{ + Filters: []Filter{ + { + Name: "tag:Name", + Values: []string{clusterID}, + }, + }, + }, + Tags: []TagSpecification{ + { + Name: "openshift-node-group-config", + Value: "node-config-master", + }, + { + Name: "host-type", + Value: "master", + }, + { + Name: "sub-host-type", + Value: "default", + }, + }, + SecurityGroups: []AWSResourceReference{ + { + Filters: []Filter{ + { + Name: "tag:Name", + Values: []string{clusterID}, + }, + }, + }, + }, + PublicIP: &publicIP, + } + + providerConfigEncoded, err := codec.EncodeProviderConfig(providerConfig) + if err != nil { + t.Fatal(err) + } + providerConfigDecoded := &AWSMachineProviderConfig{} + codec.DecodeProviderConfig(providerConfigEncoded, providerConfigDecoded) + + if !reflect.DeepEqual(providerConfig, providerConfigDecoded) { + t.Errorf("failed EncodeProviderConfig/DecodeProviderConfig. Expected: %+v, got: %+v", providerConfig, providerConfigDecoded) + } +} diff --git a/pkg/apis/awsproviderconfig/v1alpha1/v1alpha1_suite_test.go b/pkg/apis/awsproviderconfig/v1alpha1/v1alpha1_suite_test.go deleted file mode 100644 index 361eddda3a..0000000000 --- a/pkg/apis/awsproviderconfig/v1alpha1/v1alpha1_suite_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2018 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 v1alpha1 - -import ( - "log" - "os" - "path/filepath" - "testing" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" -) - -var cfg *rest.Config -var c client.Client - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")}, - } - - err := SchemeBuilder.AddToScheme(scheme.Scheme) - if err != nil { - log.Fatal(err) - } - - if cfg, err = t.Start(); err != nil { - log.Fatal(err) - } - - if c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil { - log.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} diff --git a/pkg/cloud/aws/actuators/machine/actuator.go b/pkg/cloud/aws/actuators/machine/actuator.go index e71b7e66c5..ade7cdfa36 100644 --- a/pkg/cloud/aws/actuators/machine/actuator.go +++ b/pkg/cloud/aws/actuators/machine/actuator.go @@ -74,7 +74,7 @@ type ActuatorParams struct { } type codec interface { - DecodeFromProviderConfig(clusterv1.ProviderConfig, runtime.Object) error + DecodeProviderConfig(*clusterv1.ProviderConfig, runtime.Object) error DecodeProviderStatus(*runtime.RawExtension, runtime.Object) error EncodeProviderStatus(runtime.Object) (*runtime.RawExtension, error) } @@ -261,7 +261,7 @@ func getSubnetIDs(subnet providerconfigv1.AWSResourceReference, client awsclient // CreateMachine starts a new AWS instance as described by the cluster and machine resources func (a *Actuator) CreateMachine(cluster *clusterv1.Cluster, machine *clusterv1.Machine) (*ec2.Instance, error) { - machineProviderConfig, err := ProviderConfigMachine(machine) + machineProviderConfig, err := ProviderConfigFromMachine(machine) if err != nil { glog.Errorf("error decoding MachineProviderConfig: %v", err) return nil, err @@ -441,7 +441,7 @@ func (a *Actuator) Delete(cluster *clusterv1.Cluster, machine *clusterv1.Machine // DeleteMachine deletes an AWS instance func (a *Actuator) DeleteMachine(cluster *clusterv1.Cluster, machine *clusterv1.Machine) error { - machineProviderConfig, err := ProviderConfigMachine(machine) + machineProviderConfig, err := ProviderConfigFromMachine(machine) if err != nil { glog.Errorf("error decoding MachineProviderConfig: %v", err) return err @@ -477,7 +477,7 @@ func (a *Actuator) DeleteMachine(cluster *clusterv1.Cluster, machine *clusterv1. func (a *Actuator) Update(cluster *clusterv1.Cluster, machine *clusterv1.Machine) error { glog.Info("updating machine") - machineProviderConfig, err := ProviderConfigMachine(machine) + machineProviderConfig, err := ProviderConfigFromMachine(machine) if err != nil { glog.Errorf("error decoding MachineProviderConfig: %v", err) return err @@ -575,7 +575,7 @@ func (a *Actuator) Describe(cluster *clusterv1.Cluster, machine *clusterv1.Machi } func (a *Actuator) getMachineInstances(cluster *clusterv1.Cluster, machine *clusterv1.Machine) ([]*ec2.Instance, error) { - machineProviderConfig, err := ProviderConfigMachine(machine) + machineProviderConfig, err := ProviderConfigFromMachine(machine) if err != nil { glog.Errorf("error decoding MachineProviderConfig: %v", err) return nil, err diff --git a/pkg/cloud/aws/actuators/machine/actuator_test.go b/pkg/cloud/aws/actuators/machine/actuator_test.go index 395b5db8a7..edcdff4ea5 100644 --- a/pkg/cloud/aws/actuators/machine/actuator_test.go +++ b/pkg/cloud/aws/actuators/machine/actuator_test.go @@ -122,7 +122,7 @@ func testMachineAPIResources(clusterID string) (*clusterv1.Machine, *clusterv1.C if err != nil { return nil, nil, nil, nil, fmt.Errorf("failed creating codec: %v", err) } - config, err := codec.EncodeToProviderConfig(machinePc) + config, err := codec.EncodeProviderConfig(machinePc) if err != nil { return nil, nil, nil, nil, fmt.Errorf("encodeToProviderConfig failed: %v", err) } diff --git a/pkg/cloud/aws/actuators/machine/utils.go b/pkg/cloud/aws/actuators/machine/utils.go index 18ee6f658b..7a3921c0aa 100644 --- a/pkg/cloud/aws/actuators/machine/utils.go +++ b/pkg/cloud/aws/actuators/machine/utils.go @@ -180,9 +180,9 @@ func TerminateInstances(client awsclient.Client, instances []*ec2.Instance) erro return nil } -// ProviderConfigMachine gets the machine provider config MachineSetSpec from the +// ProviderConfigFromMachine gets the machine provider config MachineSetSpec from the // specified cluster-api MachineSpec. -func ProviderConfigMachine(machine *clusterv1.Machine) (*providerconfigv1.AWSMachineProviderConfig, error) { +func ProviderConfigFromMachine(machine *clusterv1.Machine) (*providerconfigv1.AWSMachineProviderConfig, error) { var config providerconfigv1.AWSMachineProviderConfig if err := yaml.Unmarshal(machine.Spec.ProviderConfig.Value.Raw, &config); err != nil { return nil, err diff --git a/test/utils/manifests.go b/test/utils/manifests.go index e173f2430c..9f98f99491 100644 --- a/test/utils/manifests.go +++ b/test/utils/manifests.go @@ -91,7 +91,7 @@ func TestingMachineProviderConfig(awsCredentialsSecretName string, clusterID str if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("failed creating codec: %v", err) } - config, err := codec.EncodeToProviderConfig(machinePc) + config, err := codec.EncodeProviderConfig(machinePc) if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("EncodeToProviderConfig failed: %v", err) } @@ -153,7 +153,7 @@ func MasterMachineProviderConfig(awsCredentialsSecretName, masterUserDataSecretN if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("failed creating codec: %v", err) } - config, err := codec.EncodeToProviderConfig(machinePc) + config, err := codec.EncodeProviderConfig(machinePc) if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("EncodeToProviderConfig failed: %v", err) } @@ -215,7 +215,7 @@ func WorkerMachineSetProviderConfig(awsCredentialsSecretName, workerUserDataSecr if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("failed creating codec: %v", err) } - config, err := codec.EncodeToProviderConfig(machinePc) + config, err := codec.EncodeProviderConfig(machinePc) if err != nil { return clusterv1alpha1.ProviderConfig{}, fmt.Errorf("EncodeToProviderConfig failed: %v", err) }