blob: c8251ffc49aafba5d470985d4b6e0aab989ee0d6 [file] [log] [blame]
package installer
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
type NamespaceCreator interface {
Create(name string) error
}
type ZoneInfo struct {
Zone string
Records string
}
type ZoneStatusFetcher interface {
Fetch(addr string) (string, error)
}
type noOpNamespaceCreator struct{}
func (n *noOpNamespaceCreator) Create(name string) error {
return nil
}
func NewNoOpNamespaceCreator() NamespaceCreator {
return &noOpNamespaceCreator{}
}
type realNamespaceCreator struct {
clientset *kubernetes.Clientset
}
func (n *realNamespaceCreator) Create(name string) error {
_, err := n.clientset.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{
TypeMeta: metav1.TypeMeta{
Kind: " ",
APIVersion: "",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}, metav1.CreateOptions{})
if err != nil && errors.IsAlreadyExists(err) {
return nil
}
return err
}
// TODO(gio): take http client
type realZoneStatusFetcher struct{}
func (f *realZoneStatusFetcher) Fetch(addr string) (string, error) {
fmt.Printf("--- %s\n", addr)
resp, err := http.Get(addr)
if err != nil {
return "", err
}
var buf bytes.Buffer
if _, err := io.Copy(&buf, resp.Body); err != nil {
return "", err
}
return buf.String(), nil
}
func NewNamespaceCreator(kubeconfig string) (NamespaceCreator, error) {
clientset, err := NewKubeConfig(kubeconfig)
if err != nil {
return nil, err
}
return &realNamespaceCreator{clientset}, nil
}
func NewZoneStatusFetcher(kubeconfig string) (ZoneStatusFetcher, error) {
return &realZoneStatusFetcher{}, nil
}
type HelmReleaseMonitor interface {
IsReleased(namespace, name string) (bool, error)
}
type realHelmReleaseMonitor struct {
d dynamic.Interface
}
func (m *realHelmReleaseMonitor) IsReleased(namespace, name string) (bool, error) {
ctx := context.Background()
res, err := m.d.Resource(schema.GroupVersionResource{"helm.toolkit.fluxcd.io", "v2beta1", "helmreleases"}).Namespace(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return false, err
}
b, err := res.MarshalJSON()
if err != nil {
return false, err
}
var hr helmRelease
if err := json.Unmarshal(b, &hr); err != nil {
return false, err
}
for _, c := range hr.Status.Conditions {
if c.Type == "Ready" && c.Status == "True" {
return true, nil
}
}
return false, nil
}
func NewHelmReleaseMonitor(kubeconfig string) (HelmReleaseMonitor, error) {
c, err := NewKubeConfig(kubeconfig)
if err != nil {
return nil, err
}
d := dynamic.New(c.RESTClient())
return &realHelmReleaseMonitor{d}, nil
}
func NewKubeConfig(kubeconfig string) (*kubernetes.Clientset, error) {
if kubeconfig == "" {
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
} else {
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}
}