added csr approver
This commit is contained in:
parent
b0e048ba9d
commit
bc750389dc
14 changed files with 852 additions and 310 deletions
126
pkg/pvecloud/cloud.go
Normal file
126
pkg/pvecloud/cloud.go
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
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 pvecloud
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
pve "git.giftfish.de/ston1th/pve-go"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
)
|
||||
|
||||
const (
|
||||
providerName = pve.PVEScheme
|
||||
scheme = providerName + "://"
|
||||
)
|
||||
|
||||
type cloud struct {
|
||||
client *pve.Client
|
||||
instances cloudprovider.Instances
|
||||
instancesV2 cloudprovider.InstancesV2
|
||||
//zones cloudprovider.Zones
|
||||
//routes cloudprovider.Routes
|
||||
//network string
|
||||
}
|
||||
|
||||
func newCloud(_ io.Reader) (cloudprovider.Interface, error) {
|
||||
api := os.Getenv("PVE_API")
|
||||
if api == "" {
|
||||
return nil, fmt.Errorf("missing required env PVE_API")
|
||||
}
|
||||
user := os.Getenv("PVE_USER")
|
||||
if user == "" {
|
||||
return nil, fmt.Errorf("missing required env PVE_USER")
|
||||
}
|
||||
pass := os.Getenv("PVE_PASSWORD")
|
||||
if pass == "" {
|
||||
return nil, fmt.Errorf("missing required env PVE_PASSWORD")
|
||||
}
|
||||
//node := os.Getenv("NODE_NAME")
|
||||
|
||||
insecure, _ := strconv.ParseBool(os.Getenv("PVE_INSECURE"))
|
||||
client := pve.NewClient(
|
||||
pve.WithEndpoint(api),
|
||||
pve.WithCredentials(user, pass),
|
||||
pve.WithInsecureClient(insecure),
|
||||
//pvego.WithDebugWriter(os.Stderr),
|
||||
)
|
||||
|
||||
return &cloud{
|
||||
client: client,
|
||||
instances: newInstances(client),
|
||||
//zones: newZones(client, nodeName),
|
||||
//routes: nil,
|
||||
//network: network,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) {
|
||||
}
|
||||
|
||||
func (c *cloud) Instances() (cloudprovider.Instances, bool) {
|
||||
return c.instances, true
|
||||
}
|
||||
|
||||
func (c *cloud) InstancesV2() (cloudprovider.InstancesV2, bool) {
|
||||
return c.instancesV2, true
|
||||
}
|
||||
|
||||
func (c *cloud) Zones() (cloudprovider.Zones, bool) {
|
||||
//return c.zones, true
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (c *cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (c *cloud) Clusters() (cloudprovider.Clusters, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (c *cloud) Routes() (cloudprovider.Routes, bool) {
|
||||
return nil, false
|
||||
/*
|
||||
if len(c.network) > 0 {
|
||||
r, err := newRoutes(c.client, c.network)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
return nil, false // If no network is configured, disable the routes part
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
func (c *cloud) ProviderName() string {
|
||||
return providerName
|
||||
}
|
||||
|
||||
func (c *cloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *cloud) HasClusterID() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
cloudprovider.RegisterCloudProvider(providerName, func(config io.Reader) (cloudprovider.Interface, error) {
|
||||
return newCloud(config)
|
||||
})
|
||||
}
|
||||
130
pkg/pvecloud/instances.go
Normal file
130
pkg/pvecloud/instances.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
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 pvecloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
|
||||
pve "git.giftfish.de/ston1th/pve-go"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// InstanceType is not implemented
|
||||
const InstanceType = "pveServer"
|
||||
|
||||
type instances struct {
|
||||
client *pve.Client
|
||||
}
|
||||
|
||||
func newInstances(client *pve.Client) *instances {
|
||||
return &instances{client}
|
||||
}
|
||||
|
||||
func (i *instances) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) {
|
||||
server, err := getServerByProviderID(ctx, i.client, providerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.nodeAddresses(ctx, server), nil
|
||||
}
|
||||
|
||||
func (i *instances) NodeAddresses(ctx context.Context, nodeName types.NodeName) ([]v1.NodeAddress, error) {
|
||||
server, err := getServerByName(ctx, i.client, string(nodeName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
server, err = getServerByProviderID(ctx, i.client, server.K8sID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.nodeAddresses(ctx, server), nil
|
||||
}
|
||||
|
||||
func (i *instances) InstanceID(ctx context.Context, nodeName types.NodeName) (string, error) {
|
||||
ref, err := getServerRefByName(ctx, i.client, string(nodeName))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimPrefix(ref.K8sID(), scheme), nil
|
||||
}
|
||||
|
||||
func (i *instances) InstanceType(ctx context.Context, nodeName types.NodeName) (string, error) {
|
||||
return InstanceType, nil
|
||||
}
|
||||
|
||||
func (i *instances) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) {
|
||||
return InstanceType, nil
|
||||
}
|
||||
|
||||
func (i *instances) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error {
|
||||
return cloudprovider.NotImplemented
|
||||
}
|
||||
|
||||
func (i *instances) CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error) {
|
||||
return types.NodeName(hostname), nil
|
||||
}
|
||||
|
||||
func (i *instances) InstanceExistsByProviderID(ctx context.Context, providerID string) (exists bool, err error) {
|
||||
server, err := getServerByProviderID(ctx, i.client, providerID)
|
||||
if err != nil && err != cloudprovider.InstanceNotFound {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
exists = server != nil
|
||||
return
|
||||
}
|
||||
|
||||
func (i *instances) InstanceShutdownByProviderID(ctx context.Context, providerID string) (isOff bool, err error) {
|
||||
server, err := getServerByProviderID(ctx, i.client, providerID)
|
||||
if err != nil && err != cloudprovider.InstanceNotFound {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
isOff = server != nil && server.Status == pve.ServerStatusStopped
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO
|
||||
func (i *instances) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) {
|
||||
addrs, err := i.NodeAddressesByProviderID(ctx, providerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cloudprovider.InstanceMetadata{
|
||||
ProviderID: providerID,
|
||||
NodeAddresses: addrs,
|
||||
}, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (i *instances) nodeAddresses(ctx context.Context, srv *pve.Server) []v1.NodeAddress {
|
||||
var internalIP string
|
||||
ipc := srv.IPConfig.Get(0)
|
||||
if ipc != nil {
|
||||
ip, _, err := net.ParseCIDR(ipc.IPv4CIDR)
|
||||
if err == nil {
|
||||
internalIP = ip.String()
|
||||
}
|
||||
}
|
||||
addrs := []v1.NodeAddress{
|
||||
{Type: v1.NodeHostName, Address: srv.Name},
|
||||
{Type: v1.NodeInternalIP, Address: internalIP},
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
91
pkg/pvecloud/instancesv2.go
Normal file
91
pkg/pvecloud/instancesv2.go
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
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 pvecloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
|
||||
pve "git.giftfish.de/ston1th/pve-go"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type instancesV2 struct {
|
||||
client *pve.Client
|
||||
}
|
||||
|
||||
func newInstancesV2(client *pve.Client) *instancesV2 {
|
||||
return &instancesV2{client}
|
||||
}
|
||||
|
||||
func (i *instancesV2) InstanceExists(ctx context.Context, node *v1.Node) (exists bool, err error) {
|
||||
server, err := i.getServer(ctx, node)
|
||||
if err != nil && err != cloudprovider.InstanceNotFound {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
exists = server != nil
|
||||
return
|
||||
}
|
||||
|
||||
func (i *instancesV2) InstanceShutdown(ctx context.Context, node *v1.Node) (isOff bool, err error) {
|
||||
server, err := i.getServer(ctx, node)
|
||||
if err != nil && err != cloudprovider.InstanceNotFound {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
isOff = server != nil && server.Status == pve.ServerStatusStopped
|
||||
return
|
||||
}
|
||||
|
||||
func (i *instancesV2) getServer(ctx context.Context, node *v1.Node) (server *pve.Server, err error) {
|
||||
if node.Spec.ProviderID != "" {
|
||||
server, err = getServerByProviderID(ctx, i.client, node.Spec.ProviderID)
|
||||
return
|
||||
}
|
||||
server, err = getServerByName(ctx, i.client, node.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return getServerByProviderID(ctx, i.client, server.K8sID())
|
||||
}
|
||||
|
||||
func (i *instancesV2) nodeAddresses(ctx context.Context, srv *pve.Server) []v1.NodeAddress {
|
||||
var internalIP string
|
||||
ipc := srv.IPConfig.Get(0)
|
||||
if ipc != nil {
|
||||
ip, _, err := net.ParseCIDR(ipc.IPv4CIDR)
|
||||
if err == nil {
|
||||
internalIP = ip.String()
|
||||
}
|
||||
}
|
||||
addrs := []v1.NodeAddress{
|
||||
{Type: v1.NodeHostName, Address: srv.Name},
|
||||
{Type: v1.NodeInternalIP, Address: internalIP},
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
func (i *instancesV2) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {
|
||||
server, err := i.getServer(ctx, node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cloudprovider.InstanceMetadata{
|
||||
ProviderID: server.K8sID(),
|
||||
InstanceType: InstanceType,
|
||||
NodeAddresses: i.nodeAddresses(ctx, server),
|
||||
}, nil
|
||||
}
|
||||
44
pkg/pvecloud/util.go
Normal file
44
pkg/pvecloud/util.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
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 pvecloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pve "git.giftfish.de/ston1th/pve-go"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
)
|
||||
|
||||
func getServerRefByName(ctx context.Context, c *pve.Client, name string) (ref *pve.ServerRef, err error) {
|
||||
ref, err = c.Pool.FindServerByName(ctx, "", name)
|
||||
if err == pve.ErrServerNotFound {
|
||||
return nil, cloudprovider.InstanceNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getServerByName(ctx context.Context, c *pve.Client, name string) (srv *pve.Server, err error) {
|
||||
ref, err := getServerRefByName(ctx, c, name)
|
||||
if err == pve.ErrServerNotFound {
|
||||
return nil, cloudprovider.InstanceNotFound
|
||||
}
|
||||
return c.Server.GetByRef(ctx, ref)
|
||||
}
|
||||
|
||||
func getServerByProviderID(ctx context.Context, c *pve.Client, providerID string) (srv *pve.Server, err error) {
|
||||
srv, err = c.Server.GetByURL(ctx, providerID)
|
||||
if err == pve.ErrServerNotFound {
|
||||
return nil, cloudprovider.InstanceNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue