mirror of https://github.com/kubernetes/kops.git
protokube is operational
This commit is contained in:
parent
3ecab76be8
commit
f155834bf7
|
|
@ -218,12 +218,6 @@ type ClusterSpec struct {
|
||||||
Karpenter *KarpenterConfig `json:"karpenter,omitempty"`
|
Karpenter *KarpenterConfig `json:"karpenter,omitempty"`
|
||||||
// PodIdentityWebhook determines the EKS Pod Identity Webhook configuration.
|
// PodIdentityWebhook determines the EKS Pod Identity Webhook configuration.
|
||||||
PodIdentityWebhook *PodIdentityWebhookConfig `json:"podIdentityWebhook,omitempty"`
|
PodIdentityWebhook *PodIdentityWebhookConfig `json:"podIdentityWebhook,omitempty"`
|
||||||
// Scaleway configures the Scaleway cloud provider.
|
|
||||||
Scaleway *ScalewaySpec `json:"scaleway,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalewaySpec configures the Scaleway cloud provider
|
|
||||||
type ScalewaySpec struct {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodIdentityWebhookConfig configures an EKS Pod Identity Webhook.
|
// PodIdentityWebhookConfig configures an EKS Pod Identity Webhook.
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,14 @@ func run() error {
|
||||||
}
|
}
|
||||||
cloudProvider = azureVolumes
|
cloudProvider = azureVolumes
|
||||||
|
|
||||||
|
} else if cloud == "scaleway" {
|
||||||
|
scwCloudProvider, err := protokube.NewScwCloudProvider()
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Error initializing Scaleway: %q", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
cloudProvider = scwCloudProvider
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
klog.Errorf("Unknown cloud %q", cloud)
|
klog.Errorf("Unknown cloud %q", cloud)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||||
|
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kops/protokube/pkg/gossip"
|
||||||
|
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SeedProvider struct {
|
||||||
|
scwClient *scw.Client
|
||||||
|
tag string
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ gossip.SeedProvider = &SeedProvider{}
|
||||||
|
|
||||||
|
func NewSeedProvider(scwClient *scw.Client, clusterName string) (*SeedProvider, error) {
|
||||||
|
return &SeedProvider{
|
||||||
|
scwClient: scwClient,
|
||||||
|
tag: clusterName,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SeedProvider) GetSeeds() ([]string, error) {
|
||||||
|
var seeds []string
|
||||||
|
|
||||||
|
instanceAPI := instance.NewAPI(p.scwClient)
|
||||||
|
zone, ok := p.scwClient.GetDefaultZone()
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("could not determine default region from client")
|
||||||
|
}
|
||||||
|
servers, err := instanceAPI.ListServers(&instance.ListServersRequest{
|
||||||
|
Zone: zone,
|
||||||
|
Tags: []string{fmt.Sprintf("%s=%s", scaleway.TagClusterName, p.tag)},
|
||||||
|
}, scw.WithAllPages())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get matching servers: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, server := range servers.Servers {
|
||||||
|
if server.PrivateIP == nil || *server.PrivateIP == "" {
|
||||||
|
klog.Warningf("failed to find private ip of the server %s(%s)", server.Name, server.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(4).Infof("Appending gossip seed %s(%s): %q", server.Name, server.ID, *server.PrivateIP)
|
||||||
|
seeds = append(seeds, *server.PrivateIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(4).Infof("Get seeds function done now")
|
||||||
|
return seeds, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
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 protokube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||||
|
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
kopsv "k8s.io/kops"
|
||||||
|
"k8s.io/kops/protokube/pkg/gossip"
|
||||||
|
gossipscw "k8s.io/kops/protokube/pkg/gossip/scaleway"
|
||||||
|
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ScwCloudProvider defines the Scaleway Cloud volume implementation.
|
||||||
|
type ScwCloudProvider struct {
|
||||||
|
scwClient *scw.Client
|
||||||
|
server *instance.Server
|
||||||
|
serverIP net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ CloudProvider = &ScwCloudProvider{}
|
||||||
|
|
||||||
|
// NewScwCloudProvider returns a new Scaleway Cloud volume provider.
|
||||||
|
func NewScwCloudProvider() (*ScwCloudProvider, error) {
|
||||||
|
metadataAPI := instance.NewMetadataAPI()
|
||||||
|
metadata, err := metadataAPI.GetMetadata()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to retrieve server metadata: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverID := metadata.ID
|
||||||
|
klog.V(4).Infof("Found ID of the running server: %v", serverID)
|
||||||
|
|
||||||
|
zoneID := metadata.Location.ZoneID
|
||||||
|
zone, err := scw.ParseZone(zoneID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to parse Scaleway zone: %s", err)
|
||||||
|
}
|
||||||
|
klog.V(4).Infof("Found zone of the running server: %v", zone)
|
||||||
|
|
||||||
|
privateIP := metadata.PrivateIP
|
||||||
|
klog.V(4).Infof("Found first private net IP of the running server: %q", privateIP)
|
||||||
|
|
||||||
|
scwClient, err := scw.NewClient(
|
||||||
|
scw.WithUserAgent(scaleway.KopsUserAgentPrefix+kopsv.Version),
|
||||||
|
scw.WithEnv(),
|
||||||
|
scw.WithDefaultZone(zone),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceAPI := instance.NewAPI(scwClient)
|
||||||
|
server, err := instanceAPI.GetServer(&instance.GetServerRequest{
|
||||||
|
ServerID: serverID,
|
||||||
|
Zone: zone,
|
||||||
|
})
|
||||||
|
if err != nil || server == nil {
|
||||||
|
return nil, fmt.Errorf("failed to get the running server: %s", err)
|
||||||
|
}
|
||||||
|
klog.V(4).Infof("Found the running server: %q", server.Server.Name)
|
||||||
|
|
||||||
|
s := &ScwCloudProvider{
|
||||||
|
scwClient: scwClient,
|
||||||
|
server: server.Server,
|
||||||
|
serverIP: net.IP(privateIP),
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ScwCloudProvider) InstanceID() string {
|
||||||
|
return fmt.Sprintf("%s-%s", s.server.Name, s.server.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ScwCloudProvider) InstanceInternalIP() net.IP {
|
||||||
|
return s.serverIP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ScwCloudProvider) GossipSeeds() (gossip.SeedProvider, error) {
|
||||||
|
for _, tag := range s.server.Tags {
|
||||||
|
if !strings.HasPrefix(tag, scaleway.TagClusterName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
clusterName := strings.TrimPrefix(tag, scaleway.TagClusterName+"=")
|
||||||
|
return gossipscw.NewSeedProvider(s.scwClient, clusterName)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to find cluster name label for running server: %v", s.server.Tags)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
const (
|
||||||
|
TagClusterName = "kops.k8s.io/cluster"
|
||||||
|
KopsUserAgentPrefix = "kubernetes-kops/"
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue