Skip to content

Instantly share code, notes, and snippets.

@sabre1041
Created November 13, 2020 14:50
Show Gist options
  • Select an option

  • Save sabre1041/792e2c123133bd3c7c36da4ce92e867b to your computer and use it in GitHub Desktop.

Select an option

Save sabre1041/792e2c123133bd3c7c36da4ce92e867b to your computer and use it in GitHub Desktop.
etcd-pv-renamer.go
package main
import (
"bytes"
"context"
"crypto/tls"
"flag"
"fmt"
"os"
"strconv"
"strings"
"time"
"go.etcd.io/etcd/clientv3"
"go.etcd.io/etcd/pkg/transport"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/kubectl/pkg/scheme"
)
type Iscsi struct {
Lun string
Portals string
TargetPortal string
Iqn string
}
type NFS struct {
Server string
Path string
}
func main() {
var name, endpoint, keyFile, certFile, caFile, iscsiLun, iscsiPortals, iscsiTargetPortal, iscsiIqn, nfsServer, nfsPath string
flag.StringVar(&endpoint, "endpoint", getenv("ETCDCTL_ENDPOINTS"), "etcd endpoint.")
flag.StringVar(&keyFile, "key", getenv("ETCDCTL_KEY"), "TLS client key.")
flag.StringVar(&certFile, "cert", getenv("ETCDCTL_CERT"), "TLS client certificate.")
flag.StringVar(&caFile, "cacert", getenv("ETCDCTL_CACERT"), "Server TLS CA certificate.")
flag.StringVar(&name, "name", "", "PersistentVolume Name.")
flag.StringVar(&iscsiLun, "iscsilun", "", "iSCSI Lun.")
flag.StringVar(&iscsiPortals, "iscsiportals", "", "iSCSI Portals")
flag.StringVar(&iscsiTargetPortal, "iscsitargetportal", "", "iSCSI Target Portal")
flag.StringVar(&iscsiIqn, "iscsiiqn", "", "iSCSI Lun iqn")
flag.StringVar(&nfsServer, "nfsserver", "", "NFS Server")
flag.StringVar(&nfsPath, "nfspath", "", "NFS Path")
flag.Parse()
var tlsConfig *tls.Config
tlsInfo := transport.TLSInfo{
CertFile: certFile,
KeyFile: keyFile,
TrustedCAFile: caFile,
}
var err error
tlsConfig, err = tlsInfo.ClientConfig()
if err != nil {
fmt.Printf("ERROR: unable to create client config: %v\n", err)
os.Exit(1)
}
config := clientv3.Config{
Endpoints: strings.Split(endpoint, ","),
TLS: tlsConfig,
DialTimeout: 5 * time.Second,
}
client, err := clientv3.New(config)
if err != nil {
fmt.Printf("ERROR: unable to connect to etcd: %v\n", err)
os.Exit(1)
}
defer client.Close()
pvKey := fmt.Sprintf("/kubernetes.io/persistentvolumes/%s", name)
resp, err := clientv3.NewKV(client).Get(context.Background(), pvKey)
if err != nil {
fmt.Printf("Error Getting PersistentVolume: %v\n", err.Error())
}
decoder := scheme.Codecs.UniversalDeserializer()
obj, _, _ := decoder.Decode(resp.Kvs[0].Value, nil, nil)
pv := obj.(*v1.PersistentVolume)
if pv.Spec.NFS != nil {
pv = updateNfsPv(pv, &NFS{
Path: nfsPath,
Server: nfsServer,
})
} else if pv.Spec.ISCSI != nil {
updateIscsiPv(pv, &Iscsi{
Iqn: iscsiIqn,
Lun: iscsiLun,
Portals: iscsiPortals,
TargetPortal: iscsiTargetPortal,
})
} else {
fmt.Println("Error: PersistentVolume is not either NFS or ISCSI")
os.Exit(1)
}
protoSerializer := protobuf.NewSerializer(scheme.Scheme, scheme.Scheme)
newObj := new(bytes.Buffer)
protoSerializer.Encode(pv, newObj)
_, err = clientv3.NewKV(client).Put(context.Background(), pvKey, newObj.String())
if err != nil {
fmt.Printf("put to key %s %s\n", pvKey, err)
}
}
func updateIscsiPv(pv *v1.PersistentVolume, iscsi *Iscsi) {
if len(iscsi.Iqn) != 0 {
pv.Spec.ISCSI.IQN = iscsi.Iqn
}
if len(iscsi.Lun) != 0 {
lun, err := strconv.Atoi(iscsi.Lun)
if err != nil {
fmt.Println("Error converting lun. Error: %v\n", err.Error())
os.Exit(1)
}
pv.Spec.ISCSI.Lun = int32(lun)
}
if len(iscsi.Portals) != 0 {
pv.Spec.ISCSI.Portals = strings.Split(iscsi.Portals, ",")
}
if len(iscsi.TargetPortal) != 0 {
pv.Spec.ISCSI.TargetPortal = iscsi.TargetPortal
}
}
func updateNfsPv(pv *v1.PersistentVolume, nfs *NFS) *v1.PersistentVolume {
if len(nfs.Server) != 0 {
pv.Spec.NFS.Server = nfs.Server
}
if len(nfs.Path) != 0 {
pv.Spec.NFS.Path = nfs.Path
}
return pv
}
func getenv(key string) string {
if value, exists := os.LookupEnv(key); exists {
return value
}
return ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment