mirror of https://github.com/kubernetes/kops.git
codegen + updated headers + refactoring after reviews
This commit is contained in:
parent
284e98288e
commit
f7f89080c6
|
@ -26,6 +26,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kops/pkg/apis/kops/model"
|
"k8s.io/kops/pkg/apis/kops/model"
|
||||||
"k8s.io/kops/upup/pkg/fi/utils"
|
"k8s.io/kops/upup/pkg/fi/utils"
|
||||||
|
@ -210,35 +211,40 @@ func (b *BootstrapScript) buildEnvironmentVariables(cluster *kops.Cluster) (map[
|
||||||
}
|
}
|
||||||
|
|
||||||
if cluster.Spec.GetCloudProvider() == kops.CloudProviderScaleway {
|
if cluster.Spec.GetCloudProvider() == kops.CloudProviderScaleway {
|
||||||
|
errList := []error(nil)
|
||||||
|
|
||||||
region, err := scw.ParseRegion(os.Getenv("SCW_DEFAULT_REGION"))
|
region, err := scw.ParseRegion(os.Getenv("SCW_DEFAULT_REGION"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing SCW_DEFAULT_REGION: %w", err)
|
errList = append(errList, fmt.Errorf("error parsing SCW_DEFAULT_REGION: %w", err))
|
||||||
}
|
}
|
||||||
env["SCW_DEFAULT_REGION"] = string(region)
|
|
||||||
|
|
||||||
zone, err := scw.ParseZone(os.Getenv("SCW_DEFAULT_ZONE"))
|
zone, err := scw.ParseZone(os.Getenv("SCW_DEFAULT_ZONE"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing SCW_DEFAULT_ZONE: %w", err)
|
errList = append(errList, fmt.Errorf("error parsing SCW_DEFAULT_ZONE: %w", err))
|
||||||
}
|
}
|
||||||
env["SCW_DEFAULT_ZONE"] = string(zone)
|
|
||||||
|
|
||||||
|
// We make sure that the credentials env vars are defined
|
||||||
scwAccessKey := os.Getenv("SCW_ACCESS_KEY")
|
scwAccessKey := os.Getenv("SCW_ACCESS_KEY")
|
||||||
if scwAccessKey == "" {
|
if scwAccessKey == "" {
|
||||||
return nil, fmt.Errorf("SCW_ACCESS_KEY has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_ACCESS_KEY has to be set as an environment variable"))
|
||||||
}
|
}
|
||||||
env["SCW_ACCESS_KEY"] = scwAccessKey
|
|
||||||
|
|
||||||
scwSecretKey := os.Getenv("SCW_SECRET_KEY")
|
scwSecretKey := os.Getenv("SCW_SECRET_KEY")
|
||||||
if scwSecretKey == "" {
|
if scwSecretKey == "" {
|
||||||
return nil, fmt.Errorf("SCW_SECRET_KEY has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_SECRET_KEY has to be set as an environment variable"))
|
||||||
}
|
}
|
||||||
env["SCW_SECRET_KEY"] = scwSecretKey
|
|
||||||
|
|
||||||
scwProjectID := os.Getenv("SCW_DEFAULT_PROJECT_ID")
|
scwProjectID := os.Getenv("SCW_DEFAULT_PROJECT_ID")
|
||||||
if scwProjectID == "" {
|
if scwProjectID == "" {
|
||||||
return nil, fmt.Errorf("SCW_DEFAULT_PROJECT_ID has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_DEFAULT_PROJECT_ID has to be set as an environment variable"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In theory all these variables will have been checked in NewScwCloud already
|
||||||
|
if len(errList) != 0 {
|
||||||
|
return nil, errors.NewAggregate(errList)
|
||||||
|
}
|
||||||
|
|
||||||
|
env["SCW_DEFAULT_REGION"] = string(region)
|
||||||
|
env["SCW_DEFAULT_ZONE"] = string(zone)
|
||||||
|
env["SCW_ACCESS_KEY"] = scwAccessKey
|
||||||
|
env["SCW_SECRET_KEY"] = scwSecretKey
|
||||||
env["SCW_DEFAULT_PROJECT_ID"] = scwProjectID
|
env["SCW_DEFAULT_PROJECT_ID"] = scwProjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scalewaymodel
|
package scalewaymodel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scalewaymodel
|
package scalewaymodel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scalewaymodel
|
package scalewaymodel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# See the OWNERS docs at https://go.k8s.io/owners
|
# See the OWNERS docs at https://go.k8s.io/owners
|
||||||
labels:
|
labels:
|
||||||
- area/provider/scaleway
|
- area/provider/scaleway
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scaleway
|
package scaleway
|
||||||
|
|
||||||
import "k8s.io/kops/upup/pkg/fi"
|
import "k8s.io/kops/upup/pkg/fi"
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||||
"github.com/scaleway/scaleway-sdk-go/scw"
|
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
kopsv "k8s.io/kops"
|
kopsv "k8s.io/kops"
|
||||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||||
|
@ -44,23 +45,23 @@ const (
|
||||||
type ScwCloud interface {
|
type ScwCloud interface {
|
||||||
fi.Cloud
|
fi.Cloud
|
||||||
|
|
||||||
|
ClusterName(tags []string) string
|
||||||
|
DNS() (dnsprovider.Interface, error)
|
||||||
|
ProviderID() kops.CloudProviderID
|
||||||
Region() string
|
Region() string
|
||||||
Zone() string
|
Zone() string
|
||||||
ProviderID() kops.CloudProviderID
|
|
||||||
DNS() (dnsprovider.Interface, error)
|
|
||||||
ClusterName(tags []string) string
|
|
||||||
|
|
||||||
AccountService() *account.API
|
AccountService() *account.API
|
||||||
InstanceService() *instance.API
|
InstanceService() *instance.API
|
||||||
|
|
||||||
GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error)
|
|
||||||
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
|
|
||||||
GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error)
|
|
||||||
DeleteGroup(group *cloudinstances.CloudInstanceGroup) error
|
DeleteGroup(group *cloudinstances.CloudInstanceGroup) error
|
||||||
FindVPCInfo(id string) (*fi.VPCInfo, error)
|
|
||||||
DetachInstance(instance *cloudinstances.CloudInstance) error
|
|
||||||
DeregisterInstance(instance *cloudinstances.CloudInstance) error
|
|
||||||
DeleteInstance(i *cloudinstances.CloudInstance) error
|
DeleteInstance(i *cloudinstances.CloudInstance) error
|
||||||
|
DeregisterInstance(instance *cloudinstances.CloudInstance) error
|
||||||
|
DetachInstance(instance *cloudinstances.CloudInstance) error
|
||||||
|
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
|
||||||
|
FindVPCInfo(id string) (*fi.VPCInfo, error)
|
||||||
|
GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error)
|
||||||
|
GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error)
|
||||||
|
|
||||||
GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error)
|
GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error)
|
||||||
GetClusterVolumes(clusterName string) ([]*instance.Volume, error)
|
GetClusterVolumes(clusterName string) ([]*instance.Volume, error)
|
||||||
|
@ -86,31 +87,37 @@ type scwCloudImplementation struct {
|
||||||
// NewScwCloud returns a Cloud with a Scaleway Client using the env vars SCW_ACCESS_KEY, SCW_SECRET_KEY,
|
// NewScwCloud returns a Cloud with a Scaleway Client using the env vars SCW_ACCESS_KEY, SCW_SECRET_KEY,
|
||||||
// SCW_DEFAULT_PROJECT_ID, SCW_DEFAULT_REGION and SCW_DEFAULT_ZONE
|
// SCW_DEFAULT_PROJECT_ID, SCW_DEFAULT_REGION and SCW_DEFAULT_ZONE
|
||||||
func NewScwCloud(tags map[string]string) (ScwCloud, error) {
|
func NewScwCloud(tags map[string]string) (ScwCloud, error) {
|
||||||
|
errList := []error(nil)
|
||||||
|
|
||||||
region, err := scw.ParseRegion(os.Getenv("SCW_DEFAULT_REGION"))
|
region, err := scw.ParseRegion(os.Getenv("SCW_DEFAULT_REGION"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing SCW_DEFAULT_REGION: %w", err)
|
errList = append(errList, fmt.Errorf("error parsing SCW_DEFAULT_REGION: %w", err))
|
||||||
}
|
}
|
||||||
zone, err := scw.ParseZone(os.Getenv("SCW_DEFAULT_ZONE"))
|
zone, err := scw.ParseZone(os.Getenv("SCW_DEFAULT_ZONE"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing SCW_DEFAULT_ZONE: %w", err)
|
errList = append(errList, fmt.Errorf("error parsing SCW_DEFAULT_ZONE: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// We make sure that the credentials env vars are defined
|
// We make sure that the credentials env vars are defined
|
||||||
scwAccessKey := os.Getenv("SCW_ACCESS_KEY")
|
scwAccessKey := os.Getenv("SCW_ACCESS_KEY")
|
||||||
if scwAccessKey == "" {
|
if scwAccessKey == "" {
|
||||||
return nil, fmt.Errorf("SCW_ACCESS_KEY has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_ACCESS_KEY has to be set as an environment variable"))
|
||||||
}
|
}
|
||||||
scwSecretKey := os.Getenv("SCW_SECRET_KEY")
|
scwSecretKey := os.Getenv("SCW_SECRET_KEY")
|
||||||
if scwSecretKey == "" {
|
if scwSecretKey == "" {
|
||||||
return nil, fmt.Errorf("SCW_SECRET_KEY has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_SECRET_KEY has to be set as an environment variable"))
|
||||||
}
|
}
|
||||||
scwProjectID := os.Getenv("SCW_DEFAULT_PROJECT_ID")
|
scwProjectID := os.Getenv("SCW_DEFAULT_PROJECT_ID")
|
||||||
if scwProjectID == "" {
|
if scwProjectID == "" {
|
||||||
return nil, fmt.Errorf("SCW_DEFAULT_PROJECT_ID has to be set as an environment variable")
|
errList = append(errList, fmt.Errorf("SCW_DEFAULT_PROJECT_ID has to be set as an environment variable"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errList) != 0 {
|
||||||
|
return nil, errors.NewAggregate(errList)
|
||||||
}
|
}
|
||||||
|
|
||||||
scwClient, err := scw.NewClient(
|
scwClient, err := scw.NewClient(
|
||||||
scw.WithUserAgent("kubernetes-kops/"+kopsv.Version),
|
scw.WithUserAgent(KopsUserAgentPrefix+kopsv.Version),
|
||||||
scw.WithEnv(),
|
scw.WithEnv(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -127,14 +134,6 @@ func NewScwCloud(tags map[string]string) (ScwCloud, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) Region() string {
|
|
||||||
return string(s.region)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scwCloudImplementation) Zone() string {
|
|
||||||
return string(s.zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scwCloudImplementation) ClusterName(tags []string) string {
|
func (s *scwCloudImplementation) ClusterName(tags []string) string {
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
if strings.HasPrefix(tag, TagClusterName) {
|
if strings.HasPrefix(tag, TagClusterName) {
|
||||||
|
@ -144,13 +143,21 @@ func (s *scwCloudImplementation) ClusterName(tags []string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *scwCloudImplementation) DNS() (dnsprovider.Interface, error) {
|
||||||
|
klog.V(8).Infof("Scaleway DNS is not implemented yet")
|
||||||
|
return nil, fmt.Errorf("DNS is not implemented yet for Scaleway")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) ProviderID() kops.CloudProviderID {
|
func (s *scwCloudImplementation) ProviderID() kops.CloudProviderID {
|
||||||
return kops.CloudProviderScaleway
|
return kops.CloudProviderScaleway
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) DNS() (dnsprovider.Interface, error) {
|
func (s *scwCloudImplementation) Region() string {
|
||||||
//TODO(Mia-Cross) implement me
|
return string(s.region)
|
||||||
panic("Scaleway doesn't have a DNS yet")
|
}
|
||||||
|
|
||||||
|
func (s *scwCloudImplementation) Zone() string {
|
||||||
|
return string(s.zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) AccountService() *account.API {
|
func (s *scwCloudImplementation) AccountService() *account.API {
|
||||||
|
@ -161,10 +168,15 @@ func (s *scwCloudImplementation) InstanceService() *instance.API {
|
||||||
return s.instanceAPI
|
return s.instanceAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindVPCInfo is not implemented yet, it's only here to satisfy the fi.Cloud interface
|
func (s *scwCloudImplementation) DeleteGroup(group *cloudinstances.CloudInstanceGroup) error {
|
||||||
func (s *scwCloudImplementation) FindVPCInfo(id string) (*fi.VPCInfo, error) {
|
toDelete := append(group.NeedUpdate, group.Ready...)
|
||||||
klog.V(8).Info("FindVPCInfo is not implemented yet for Scaleway")
|
for _, cloudInstance := range toDelete {
|
||||||
return nil, fmt.Errorf("scaleway cloud provider does not support VPC at this time")
|
err := s.DeleteInstance(cloudInstance)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error deleting group %q: %w", group.HumanName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) DeleteInstance(i *cloudinstances.CloudInstance) error {
|
func (s *scwCloudImplementation) DeleteInstance(i *cloudinstances.CloudInstance) error {
|
||||||
|
@ -189,24 +201,30 @@ func (s *scwCloudImplementation) DeleteInstance(i *cloudinstances.CloudInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInstance) error {
|
func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInstance) error {
|
||||||
//TODO(Mia-Cross) implement me
|
klog.V(8).Infof("Scaleway DeregisterInstance is not implemented yet")
|
||||||
panic("implement me")
|
return fmt.Errorf("DeregisterInstance is not implemented yet for Scaleway")
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scwCloudImplementation) DeleteGroup(group *cloudinstances.CloudInstanceGroup) error {
|
|
||||||
toDelete := append(group.NeedUpdate, group.Ready...)
|
|
||||||
for _, cloudInstance := range toDelete {
|
|
||||||
err := s.DeleteInstance(cloudInstance)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error deleting group %q: %w", group.HumanName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) DetachInstance(i *cloudinstances.CloudInstance) error {
|
func (s *scwCloudImplementation) DetachInstance(i *cloudinstances.CloudInstance) error {
|
||||||
//TODO(Mia-Cross) implement me
|
klog.V(8).Infof("Scaleway DetachInstance is not implemented yet")
|
||||||
panic("implement me")
|
return fmt.Errorf("DetachInstance is not implemented yet for Scaleway")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindClusterStatus was used before etcd-manager to check the etcd cluster status and prevent unsupported changes.
|
||||||
|
func (s *scwCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {
|
||||||
|
klog.V(8).Info("Scaleway FindClusterStatus is not implemented")
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindVPCInfo is not implemented yet, it's only here to satisfy the fi.Cloud interface
|
||||||
|
func (s *scwCloudImplementation) FindVPCInfo(id string) (*fi.VPCInfo, error) {
|
||||||
|
klog.V(8).Info("Scaleway doesn't have a VPC yet so FindVPCInfo is not implemented")
|
||||||
|
return nil, fmt.Errorf("FindVPCInfo is not implemented yet for Scaleway")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scwCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
|
||||||
|
klog.V(8).Info("Scaleway doesn't have load-balancers yet so GetApiIngressStatus is not implemented")
|
||||||
|
return nil, fmt.Errorf("GetApiIngressStatus is not implemented yet for Scaleway")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
func (s *scwCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||||
|
@ -219,24 +237,18 @@ func (s *scwCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instanceg
|
||||||
return nil, fmt.Errorf("failed to find server groups: %w", err)
|
return nil, fmt.Errorf("failed to find server groups: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for igName, serverGroup := range serverGroups {
|
for _, ig := range instancegroups {
|
||||||
var instanceGroup *kops.InstanceGroup
|
serverGroup, ok := serverGroups[ig.Name]
|
||||||
for _, ig := range instancegroups {
|
if !ok {
|
||||||
if igName == ig.Name {
|
|
||||||
instanceGroup = ig
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if instanceGroup == nil {
|
|
||||||
if warnUnmatched {
|
if warnUnmatched {
|
||||||
klog.Warningf("Server group %q has no corresponding instance group", igName)
|
klog.Warningf("Server group %q has no corresponding instance group", ig.Name)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
groups[instanceGroup.Name], err = buildCloudGroup(instanceGroup, serverGroup, nodeMap)
|
groups[ig.Name], err = buildCloudGroup(ig, serverGroup, nodeMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build cloud group for instance group %q: %w", instanceGroup.Name, err)
|
return nil, fmt.Errorf("failed to build cloud group for instance group %q: %w", ig.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,16 +307,6 @@ func buildCloudGroup(ig *kops.InstanceGroup, sg []*instance.Server, nodeMap map[
|
||||||
return cloudInstanceGroup, nil
|
return cloudInstanceGroup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scwCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {
|
|
||||||
klog.V(8).Info("FindClusterStatus is not implemented yet for Scaleway")
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scwCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
|
|
||||||
//TODO(Mia-Cross) implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scwCloudImplementation) GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error) {
|
func (s *scwCloudImplementation) GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error) {
|
||||||
request := &instance.ListServersRequest{
|
request := &instance.ListServersRequest{
|
||||||
Zone: s.zone,
|
Zone: s.zone,
|
||||||
|
@ -372,14 +374,12 @@ func (s *scwCloudImplementation) DeleteServer(server *instance.Server) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("delete server %s: error deleting instance: %w", server.ID, err)
|
return fmt.Errorf("delete server %s: error deleting instance: %w", server.ID, err)
|
||||||
}
|
}
|
||||||
for {
|
_, err = s.instanceAPI.WaitForServer(&instance.WaitForServerRequest{
|
||||||
_, err := s.instanceAPI.GetServer(&instance.GetServerRequest{
|
ServerID: server.ID,
|
||||||
Zone: s.zone,
|
Zone: s.zone,
|
||||||
ServerID: server.ID,
|
})
|
||||||
})
|
if !is404Error(err) {
|
||||||
if is404Error(err) {
|
return fmt.Errorf("delete server %s: error waiting for instance after deletion: %w", server.ID, err)
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We delete the volumes that were attached to the server (including etcd volumes)
|
// We delete the volumes that were attached to the server (including etcd volumes)
|
||||||
|
@ -404,5 +404,14 @@ func (s *scwCloudImplementation) DeleteVolume(volume *instance.Volume) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to delete volume %s: %w", volume.ID, err)
|
return fmt.Errorf("failed to delete volume %s: %w", volume.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = s.instanceAPI.WaitForVolume(&instance.WaitForVolumeRequest{
|
||||||
|
VolumeID: volume.ID,
|
||||||
|
Zone: s.zone,
|
||||||
|
})
|
||||||
|
if !is404Error(err) {
|
||||||
|
return fmt.Errorf("delete server %s: error waiting for volume after deletion: %w", volume.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scaleway
|
package scaleway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# See the OWNERS docs at https://go.k8s.io/owners
|
# See the OWNERS docs at https://go.k8s.io/owners
|
||||||
labels:
|
labels:
|
||||||
- area/provider/scaleway
|
- area/provider/scaleway
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scalewaytasks
|
package scalewaytasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -59,59 +75,37 @@ func (s *Instance) Run(c *fi.Context) error {
|
||||||
return fi.DefaultDeltaRunMethod(s, c)
|
return fi.DefaultDeltaRunMethod(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *Instance) RenderScw(c *fi.Context, a, e, changes *Instance) error {
|
func (_ *Instance) RenderScw(c *fi.Context, actual, expected, changes *Instance) error {
|
||||||
cloud := c.Cloud.(scaleway.ScwCloud)
|
cloud := c.Cloud.(scaleway.ScwCloud)
|
||||||
instanceService := cloud.InstanceService()
|
instanceService := cloud.InstanceService()
|
||||||
zone := scw.Zone(fi.StringValue(e.Zone))
|
zone := scw.Zone(fi.StringValue(expected.Zone))
|
||||||
|
|
||||||
userData, err := fi.ResourceAsBytes(*e.UserData)
|
userData, err := fi.ResourceAsBytes(*expected.UserData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error rendering instances: %w", err)
|
return fmt.Errorf("error rendering instances: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var newInstanceCount int
|
newInstanceCount := expected.Count
|
||||||
if a == nil {
|
if actual != nil {
|
||||||
newInstanceCount = e.Count
|
if expected.Count == actual.Count {
|
||||||
} else {
|
|
||||||
expectedCount := e.Count
|
|
||||||
actualCount := a.Count
|
|
||||||
|
|
||||||
if expectedCount == actualCount {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
newInstanceCount = expected.Count - actual.Count
|
||||||
if actualCount > expectedCount {
|
|
||||||
igInstances, err := cloud.GetClusterServers(cloud.ClusterName(a.Tags), a.Name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error deleting instance: %w", err)
|
|
||||||
}
|
|
||||||
for _, igInstance := range igInstances {
|
|
||||||
err = cloud.DeleteServer(igInstance)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error deleting instance of group %s: %w", igInstance.Name, err)
|
|
||||||
}
|
|
||||||
actualCount--
|
|
||||||
if expectedCount == actualCount {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newInstanceCount = expectedCount - actualCount
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If newInstanceCount > 0, we need to create new instances for this group
|
||||||
for i := 0; i < newInstanceCount; i++ {
|
for i := 0; i < newInstanceCount; i++ {
|
||||||
|
|
||||||
// We create the instance
|
// We create the instance
|
||||||
srv, err := instanceService.CreateServer(&instance.CreateServerRequest{
|
srv, err := instanceService.CreateServer(&instance.CreateServerRequest{
|
||||||
Zone: zone,
|
Zone: zone,
|
||||||
Name: fi.StringValue(e.Name),
|
Name: fi.StringValue(expected.Name),
|
||||||
CommercialType: fi.StringValue(e.CommercialType),
|
CommercialType: fi.StringValue(expected.CommercialType),
|
||||||
Image: fi.StringValue(e.Image),
|
Image: fi.StringValue(expected.Image),
|
||||||
Tags: e.Tags,
|
Tags: expected.Tags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating instance of group %q: %w", fi.StringValue(e.Name), err)
|
return fmt.Errorf("error creating instance of group %q: %w", fi.StringValue(expected.Name), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We wait for the instance to be ready
|
// We wait for the instance to be ready
|
||||||
|
@ -120,7 +114,7 @@ func (_ *Instance) RenderScw(c *fi.Context, a, e, changes *Instance) error {
|
||||||
Zone: zone,
|
Zone: zone,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error waiting for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(e.Name), err)
|
return fmt.Errorf("error waiting for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(expected.Name), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We load the cloud-init script in the instance user data
|
// We load the cloud-init script in the instance user data
|
||||||
|
@ -131,7 +125,7 @@ func (_ *Instance) RenderScw(c *fi.Context, a, e, changes *Instance) error {
|
||||||
Content: bytes.NewBuffer(userData),
|
Content: bytes.NewBuffer(userData),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error setting 'cloud-init' in user-data for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(e.Name), err)
|
return fmt.Errorf("error setting 'cloud-init' in user-data for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(expected.Name), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We start the instance
|
// We start the instance
|
||||||
|
@ -141,7 +135,7 @@ func (_ *Instance) RenderScw(c *fi.Context, a, e, changes *Instance) error {
|
||||||
Action: instance.ServerActionPoweron,
|
Action: instance.ServerActionPoweron,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error powering on instance %s of group %q: %w", srv.Server.ID, fi.StringValue(e.Name), err)
|
return fmt.Errorf("error powering on instance %s of group %q: %w", srv.Server.ID, fi.StringValue(expected.Name), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We wait for the instance to be ready
|
// We wait for the instance to be ready
|
||||||
|
@ -150,15 +144,31 @@ func (_ *Instance) RenderScw(c *fi.Context, a, e, changes *Instance) error {
|
||||||
Zone: zone,
|
Zone: zone,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error waiting for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(e.Name), err)
|
return fmt.Errorf("error waiting for instance %s of group %q: %w", srv.Server.ID, fi.StringValue(expected.Name), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If newInstanceCount < 0, we need to delete instances of this group
|
||||||
|
for i := 0; i > expected.Count; i-- {
|
||||||
|
|
||||||
|
igInstances, err := cloud.GetClusterServers(cloud.ClusterName(actual.Tags), actual.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error deleting instance: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, igInstance := range igInstances {
|
||||||
|
err = cloud.DeleteServer(igInstance)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error deleting instance of group %s: %w", igInstance.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *Instance) CheckChanges(a, e, changes *Instance) error {
|
func (_ *Instance) CheckChanges(actual, expected, changes *Instance) error {
|
||||||
if a != nil {
|
if actual != nil {
|
||||||
if changes.Name != nil {
|
if changes.Name != nil {
|
||||||
return fi.CannotChangeField("Name")
|
return fi.CannotChangeField("Name")
|
||||||
}
|
}
|
||||||
|
@ -172,16 +182,16 @@ func (_ *Instance) CheckChanges(a, e, changes *Instance) error {
|
||||||
return fi.CannotChangeField("Image")
|
return fi.CannotChangeField("Image")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if e.Name == nil {
|
if expected.Name == nil {
|
||||||
return fi.RequiredField("Name")
|
return fi.RequiredField("Name")
|
||||||
}
|
}
|
||||||
if e.Zone == nil {
|
if expected.Zone == nil {
|
||||||
return fi.RequiredField("Zone")
|
return fi.RequiredField("Zone")
|
||||||
}
|
}
|
||||||
if e.CommercialType == nil {
|
if expected.CommercialType == nil {
|
||||||
return fi.RequiredField("CommercialType")
|
return fi.RequiredField("CommercialType")
|
||||||
}
|
}
|
||||||
if e.Image == nil {
|
if expected.Image == nil {
|
||||||
return fi.RequiredField("Image")
|
return fi.RequiredField("Image")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
//go:build !ignore_autogenerated
|
||||||
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by fitask. DO NOT EDIT.
|
||||||
|
|
||||||
|
package scalewaytasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/kops/upup/pkg/fi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Instance
|
||||||
|
|
||||||
|
var _ fi.HasLifecycle = &Instance{}
|
||||||
|
|
||||||
|
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||||
|
func (o *Instance) GetLifecycle() fi.Lifecycle {
|
||||||
|
return o.Lifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||||
|
func (o *Instance) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||||
|
o.Lifecycle = lifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fi.HasName = &Instance{}
|
||||||
|
|
||||||
|
// GetName returns the Name of the object, implementing fi.HasName
|
||||||
|
func (o *Instance) GetName() *string {
|
||||||
|
return o.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||||
|
func (o *Instance) String() string {
|
||||||
|
return fi.TaskAsString(o)
|
||||||
|
}
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 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 scalewaytasks
|
package scalewaytasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -46,25 +62,25 @@ func (s *SSHKey) Find(c *fi.Context) (*SSHKey, error) {
|
||||||
|
|
||||||
klog.V(2).Infof("found matching SSH key named %q", *s.Name)
|
klog.V(2).Infof("found matching SSH key named %q", *s.Name)
|
||||||
k := keysResp.SSHKeys[0]
|
k := keysResp.SSHKeys[0]
|
||||||
actual := &SSHKey{
|
sshKey := &SSHKey{
|
||||||
ID: fi.String(k.ID),
|
ID: fi.String(k.ID),
|
||||||
Name: fi.String(k.Name),
|
Name: fi.String(k.Name),
|
||||||
KeyPairFingerPrint: fi.String(k.Fingerprint),
|
KeyPairFingerPrint: fi.String(k.Fingerprint),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid spurious changes
|
// Avoid spurious changes
|
||||||
if strings.Contains(fi.StringValue(actual.KeyPairFingerPrint), fi.StringValue(s.KeyPairFingerPrint)) {
|
if strings.Contains(fi.StringValue(sshKey.KeyPairFingerPrint), fi.StringValue(s.KeyPairFingerPrint)) {
|
||||||
klog.V(2).Infof("SSH key fingerprints match; assuming public keys match")
|
klog.V(2).Infof("SSH key fingerprints match; assuming public keys match")
|
||||||
actual.PublicKey = s.PublicKey
|
sshKey.PublicKey = s.PublicKey
|
||||||
actual.KeyPairFingerPrint = s.KeyPairFingerPrint
|
sshKey.KeyPairFingerPrint = s.KeyPairFingerPrint
|
||||||
} else {
|
} else {
|
||||||
klog.V(2).Infof("Computed SSH key fingerprint mismatch: %q %q", fi.StringValue(s.KeyPairFingerPrint), fi.StringValue(actual.KeyPairFingerPrint))
|
klog.V(2).Infof("Computed SSH key fingerprint mismatch: %q %q", fi.StringValue(s.KeyPairFingerPrint), fi.StringValue(sshKey.KeyPairFingerPrint))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore "system" fields
|
// Ignore "system" fields
|
||||||
actual.Lifecycle = s.Lifecycle
|
sshKey.Lifecycle = s.Lifecycle
|
||||||
|
|
||||||
return actual, nil
|
return sshKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSHKey) Run(c *fi.Context) error {
|
func (s *SSHKey) Run(c *fi.Context) error {
|
||||||
|
@ -84,8 +100,8 @@ func (s *SSHKey) Run(c *fi.Context) error {
|
||||||
return fi.DefaultDeltaRunMethod(s, c)
|
return fi.DefaultDeltaRunMethod(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSHKey) CheckChanges(a, e, changes *SSHKey) error {
|
func (s *SSHKey) CheckChanges(actual, expected, changes *SSHKey) error {
|
||||||
if a != nil {
|
if actual != nil {
|
||||||
if changes.Name != nil {
|
if changes.Name != nil {
|
||||||
return fi.CannotChangeField("Name")
|
return fi.CannotChangeField("Name")
|
||||||
}
|
}
|
||||||
|
@ -93,12 +109,12 @@ func (s *SSHKey) CheckChanges(a, e, changes *SSHKey) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SSHKey) RenderScw(c *fi.Context, a, e, changes *SSHKey) error {
|
func (*SSHKey) RenderScw(c *fi.Context, actual, expected, changes *SSHKey) error {
|
||||||
cloud := c.Cloud.(scaleway.ScwCloud)
|
cloud := c.Cloud.(scaleway.ScwCloud)
|
||||||
|
|
||||||
if a == nil {
|
if actual == nil {
|
||||||
|
|
||||||
name := fi.StringValue(e.Name)
|
name := fi.StringValue(expected.Name)
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return fi.RequiredField("Name")
|
return fi.RequiredField("Name")
|
||||||
}
|
}
|
||||||
|
@ -107,8 +123,8 @@ func (*SSHKey) RenderScw(c *fi.Context, a, e, changes *SSHKey) error {
|
||||||
keyArgs := &account.CreateSSHKeyRequest{
|
keyArgs := &account.CreateSSHKeyRequest{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
if e.PublicKey != nil {
|
if expected.PublicKey != nil {
|
||||||
d, err := fi.ResourceAsString(*e.PublicKey)
|
d, err := fi.ResourceAsString(*expected.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error rendering SSH public key: %w", err)
|
return fmt.Errorf("error rendering SSH public key: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -119,14 +135,14 @@ func (*SSHKey) RenderScw(c *fi.Context, a, e, changes *SSHKey) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating SSH keypair: %w", err)
|
return fmt.Errorf("error creating SSH keypair: %w", err)
|
||||||
}
|
}
|
||||||
e.KeyPairFingerPrint = fi.String(key.Fingerprint)
|
expected.KeyPairFingerPrint = fi.String(key.Fingerprint)
|
||||||
klog.V(2).Infof("Created a new SSH keypair, id=%q fingerprint=%q", key.ID, key.Fingerprint)
|
klog.V(2).Infof("Created a new SSH keypair, id=%q fingerprint=%q", key.ID, key.Fingerprint)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
e.KeyPairFingerPrint = a.KeyPairFingerPrint
|
expected.KeyPairFingerPrint = actual.KeyPairFingerPrint
|
||||||
klog.V(2).Infof("Using an existing SSH keypair, fingerprint=%q", fi.StringValue(e.KeyPairFingerPrint))
|
klog.V(2).Infof("Using an existing SSH keypair, fingerprint=%q", fi.StringValue(expected.KeyPairFingerPrint))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
//go:build !ignore_autogenerated
|
||||||
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by fitask. DO NOT EDIT.
|
||||||
|
|
||||||
|
package scalewaytasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/kops/upup/pkg/fi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SSHKey
|
||||||
|
|
||||||
|
var _ fi.HasLifecycle = &SSHKey{}
|
||||||
|
|
||||||
|
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||||
|
func (o *SSHKey) GetLifecycle() fi.Lifecycle {
|
||||||
|
return o.Lifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||||
|
func (o *SSHKey) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||||
|
o.Lifecycle = lifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fi.HasName = &SSHKey{}
|
||||||
|
|
||||||
|
// GetName returns the Name of the object, implementing fi.HasName
|
||||||
|
func (o *SSHKey) GetName() *string {
|
||||||
|
return o.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||||
|
func (o *SSHKey) String() string {
|
||||||
|
return fi.TaskAsString(o)
|
||||||
|
}
|
Loading…
Reference in New Issue