Skip to content

Commit

Permalink
helpers for CRD
Browse files Browse the repository at this point in the history
  • Loading branch information
argonaut0 committed Aug 27, 2023
1 parent e956d0b commit 4552280
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 20 deletions.
16 changes: 8 additions & 8 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
)

type InstanceRecord struct {
id int64
expiry time.Time
challenge string
Id int64 `json:"id"`
Expiry time.Time `json:"expiry"`
Challenge string `json:"challenge"`
}

func (in *Instancer) InitDB(file string) error {
Expand Down Expand Up @@ -60,9 +60,9 @@ func (in *Instancer) InsertInstanceRecord(ttl time.Duration, challenge string) (
}

return InstanceRecord{
id: id,
expiry: expiry,
challenge: challenge,
Id: id,
Expiry: expiry,
Challenge: challenge,
}, nil
}

Expand Down Expand Up @@ -97,11 +97,11 @@ func (in *Instancer) ReadInstanceRecords() ([]InstanceRecord, error) {
for rows.Next() {
record := InstanceRecord{}
var t int64
err = rows.Scan(&record.id, &record.challenge, &t)
err = rows.Scan(&record.Id, &record.Challenge, &t)
if err != nil {
return records, err
}
record.expiry = time.Unix(t, 0)
record.Expiry = time.Unix(t, 0)
records = append(records, record)
}
err = rows.Err()
Expand Down
37 changes: 26 additions & 11 deletions instancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func InitInstancer() (*Instancer, error) {
echo: echo.New(),
}
in.echo.HideBanner = true
in.echo.HidePort = true
in.log = zlog.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(zerolog.DebugLevel)
in.echo.Logger = NewEchoLog(in.log)
log := in.log.With().Str("component", "instanced-init").Logger()
Expand Down Expand Up @@ -58,6 +59,20 @@ func InitInstancer() (*Instancer, error) {
rest.SetKubernetesDefaults(in.k8sConfig)
log.Debug().Str("config", fmt.Sprintf("%+v", in.k8sConfig)).Msg("loaded kube-api client config")

// Test CRDs
log.Debug().Msg("querying CRDs")
crdChallObjs, err := in.QueryInstancedChallenges("challenges")
if err != nil {
log.Debug().Err(err).Msg("error retrieving challenge definitions from CRDs")
} else {
for k, o := range crdChallObjs {
log.Debug().Str("challenge", k).Msg("parsed challenge from CRD")
for _, v := range o {
log.Debug().Str("kind", v.GetKind()).Str("name", v.GetName()).Str("challenge", k).Msg("parsed resource")
}
}
}

err = in.InitDB("/data/instancer.db")
if err != nil {
log.Fatal().Err(err).Msg("could not init sqlite db")
Expand All @@ -77,9 +92,9 @@ func (in *Instancer) DestoryExpiredInstances() {
log.Info().Int("count", len(instances)).Msg("instances found")
for _, i := range instances {
// Any does not marshall properly
log.Debug().Int64("id", i.id).Time("expiry", i.expiry).Str("challenge", i.challenge).Msg("instance record found")
if time.Now().After(i.expiry) {
log.Info().Int64("id", i.id).Str("challenge", i.challenge).Msg("destroying expired instance")
log.Debug().Int64("id", i.Id).Time("expiry", i.Expiry).Str("challenge", i.Challenge).Msg("instance record found")
if time.Now().After(i.Expiry) {
log.Info().Int64("id", i.Id).Str("challenge", i.Challenge).Msg("destroying expired instance")
err := in.DestroyInstance(i)
if err != nil {
log.Error().Err(err).Msg("error destroying instance")
Expand All @@ -90,20 +105,20 @@ func (in *Instancer) DestoryExpiredInstances() {

func (in *Instancer) DestroyInstance(rec InstanceRecord) error {
log := in.log.With().Str("component", "instanced").Logger()
chal, ok := in.challengeObjs[rec.challenge]
chal, ok := in.challengeObjs[rec.Challenge]
if !ok {
return &ChallengeNotFoundError{rec.challenge}
return &ChallengeNotFoundError{rec.Challenge}
}
for _, o := range chal {
obj := o.DeepCopy()
// todo: set proper name
obj.SetName(fmt.Sprintf("in-%v-%v", obj.GetName(), rec.id))
obj.SetName(fmt.Sprintf("in-%v-%v", obj.GetName(), rec.Id))
err := in.DeleteObject(obj, "challenges")
if err != nil {
log.Warn().Err(err).Str("name", obj.GetName()).Str("kind", obj.GetKind()).Msg("error deleting object")
}
}
err := in.DeleteInstanceRecord(rec.id)
err := in.DeleteInstanceRecord(rec.Id)
if err != nil {
log.Warn().Err(err).Msg("error deleting instance record")
}
Expand All @@ -130,16 +145,16 @@ func (in *Instancer) CreateInstance(challenge string) (InstanceRecord, error) {
if err != nil {
log.Error().Err(err).Msg("could not create instance record")
} else {
log.Info().Time("expiry", rec.expiry).
Str("challenge", rec.challenge).
Int64("id", rec.id).
log.Info().Time("expiry", rec.Expiry).
Str("challenge", rec.Challenge).
Int64("id", rec.Id).
Msg("registered new instance")
}

log.Info().Int("count", len(chal)).Msg("creating objects")
for _, o := range chal {
obj := o.DeepCopy()
obj.SetName(fmt.Sprintf("in-%v-%v", obj.GetName(), rec.id))
obj.SetName(fmt.Sprintf("in-%v-%v", obj.GetName(), rec.Id))
resObj, err := in.CreateObject(obj, "challenges")
log.Debug().Any("object", resObj).Msg("created object")
if err != nil {
Expand Down
74 changes: 74 additions & 0 deletions k8sclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,77 @@ func (in *Instancer) GetObjectResource(unstructObj *unstructured.Unstructured) (

return mapping.Resource, nil
}

func (in *Instancer) QueryInstancedChallenges(namespace string) (map[string][]unstructured.Unstructured, error) {
resource := schema.GroupVersionResource{
Group: "k8s.maplebacon.org",
Version: "unstable",
Resource: "instancedchallenges",
}

client, err := dynamic.NewForConfig(in.k8sConfig)
if err != nil {
return nil, err
}

chalList, err := client.Resource(resource).Namespace(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}

ret := make(map[string][]unstructured.Unstructured)

for _, c := range chalList.Items {
resources, found, err := unstructured.NestedSlice(c.Object, "spec", "resources")
if err != nil || !found {
fmt.Printf("resources not found for challenge crd %v: error=%v", c.GetName(), err)
continue
}

res := make([]unstructured.Unstructured, 0)

for _, r := range resources {
obj, ok := r.(map[string]interface{})
if !ok {
fmt.Printf("could not parse object")
}
res = append(res, unstructured.Unstructured{Object: obj})
}
ret[c.GetName()] = res
}
return ret, nil
}

func (in *Instancer) QueryInstancedChallenge(name string, namespace string) ([]unstructured.Unstructured, error) {
resource := schema.GroupVersionResource{
Group: "k8s.maplebacon.org",
Version: "unstable",
Resource: "instancedchallenges",
}

client, err := dynamic.NewForConfig(in.k8sConfig)
if err != nil {
return nil, err
}

chal, err := client.Resource(resource).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, err
}

resources, found, err := unstructured.NestedSlice(chal.Object, "spec", "resources")
if err != nil || !found {
fmt.Printf("resources not found for challenge crd %v: error=%v", chal.GetName(), err)
return nil, err
}
res := make([]unstructured.Unstructured, 0)
for _, r := range resources {
obj, ok := r.(map[string]interface{})
if !ok {
fmt.Printf("could not parse object")
}
res = append(res, unstructured.Unstructured{Object: obj})
}

return res, nil
}
1 change: 1 addition & 0 deletions operator-experiment/example-instchall.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: "k8s.maplebacon.org/unstable"
kind: InstancedChallenge
metadata:
name: nginx
namespace: challenges
spec:
resources:
- apiVersion: apps/v1
Expand Down
2 changes: 1 addition & 1 deletion webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (in *Instancer) handleInstanceCreate(c echo.Context) error {
return c.JSON(http.StatusInternalServerError, "challenge deploy failed: contact admin")
}
c.Logger().Info("processed request to provision new instance")
return c.JSON(http.StatusAccepted, InstancesResponse{"created", chalName, rec.id})
return c.JSON(http.StatusAccepted, InstancesResponse{"created", chalName, rec.Id})
}

func (in *Instancer) handleInstanceDelete(c echo.Context) error {
Expand Down

0 comments on commit 4552280

Please sign in to comment.