-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a hack frontend for rootio action (#207)
The rootio action is dependent on the Hegel `/metadata` endpoint; it requires storage device metadata only. This PR adds the `/metadata` endpoint back to Hegel temporarily until we migrate to exposing hardware data during Tinkerbell Template rendering where the rootio action will be passed its data as parameters. The code lives in a new `hack` frontend to make clear its a hacky thing and with commentary on when it should be deleted. The `/metadata` endpoint was tested by launching a K3D cluster and then launching Hegel manually. A Hardware was submitted to the cluster and the `/metadata` endpoint curled. Relates to #188
- Loading branch information
1 parent
641a6b5
commit 0b02fda
Showing
9 changed files
with
198 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package flatfile | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"github.com/tinkerbell/hegel/internal/frontend/hack" | ||
) | ||
|
||
// GetHackInstance exists to satisfy the hack.Client interface. It is not implemented. | ||
func (b *Backend) GetHackInstance(context.Context, string) (hack.Instance, error) { | ||
return hack.Instance{}, errors.New("unsupported") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package kubernetes | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
|
||
"github.com/tinkerbell/hegel/internal/frontend/hack" | ||
tinkv1 "github.com/tinkerbell/tink/pkg/apis/core/v1alpha1" | ||
) | ||
|
||
func (b *Backend) GetHackInstance(ctx context.Context, ip string) (hack.Instance, error) { | ||
hw, err := b.retrieveByIP(ctx, ip) | ||
if err != nil { | ||
return hack.Instance{}, err | ||
} | ||
|
||
return toHackInstance(hw) | ||
} | ||
|
||
// toHackInstance converts a Tinkerbell Hardware resource to a hack.Instance by marshalling and | ||
// unmarshalling. This works because the Hardware resource has historical roots that align with | ||
// the hack.Instance struct that is derived from the rootio action. See the hack frontend for more | ||
// details. | ||
func toHackInstance(hw tinkv1.Hardware) (hack.Instance, error) { | ||
marshalled, err := json.Marshal(hw.Spec) | ||
if err != nil { | ||
return hack.Instance{}, err | ||
} | ||
|
||
var i hack.Instance | ||
if err := json.Unmarshal(marshalled, &i); err != nil { | ||
return hack.Instance{}, err | ||
} | ||
|
||
return i, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
Package hack contains a frontend that provides a /metadata endpoint for the rootio hub action. | ||
It is not intended to be long lived and will be removed as we migrate to exposing Hardware | ||
data to Tinkerbell templates. In doing so, we can convert the rootio action to accept its inputs | ||
via parameters instead of retrieing them from Hegel and subsequently delete this frontend. | ||
*/ | ||
package hack | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/tinkerbell/hegel/internal/http/request" | ||
) | ||
|
||
// Client is a backend for retrieving hack instance data. | ||
type Client interface { | ||
GetHackInstance(ctx context.Context, ip string) (Instance, error) | ||
} | ||
|
||
// Instance is a representation of the instance metadata. Its based on the rooitio hub action | ||
// and should have just enough information for it to work. | ||
type Instance struct { | ||
Metadata struct { | ||
Instance struct { | ||
Storage struct { | ||
Disks []struct { | ||
Device string `json:"device"` | ||
Partitions []struct { | ||
Label string `json:"label"` | ||
Number int `json:"number"` | ||
Size uint64 `json:"size"` | ||
} `json:"partitions"` | ||
WipeTable bool `json:"wipe_table"` | ||
} `json:"disks"` | ||
Filesystems []struct { | ||
Mount struct { | ||
Create struct { | ||
Options []string `json:"options"` | ||
} `json:"create"` | ||
Device string `json:"device"` | ||
Format string `json:"format"` | ||
Point string `json:"point"` | ||
} `json:"mount"` | ||
} `json:"filesystems"` | ||
} `json:"storage"` | ||
} `json:"instance"` | ||
} `json:"metadata"` | ||
} | ||
|
||
// Configure configures router with a `/metadata` endpoint using client to retrieve instance data. | ||
func Configure(router gin.IRouter, client Client) { | ||
router.GET("/metadata", func(ctx *gin.Context) { | ||
ip, err := request.RemoteAddrIP(ctx.Request) | ||
if err != nil { | ||
_ = ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid remote address")) | ||
} | ||
|
||
instance, err := client.GetHackInstance(ctx, ip) | ||
if err != nil { | ||
_ = ctx.AbortWithError(http.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
ctx.JSON(200, instance) | ||
}) | ||
} |