Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gateway): allow tenant to recover manifest of active lease #251

Merged
merged 3 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions _run/common-commands.mk
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ send-manifest:
--from "$(KEY_NAME)" \
--provider "$(PROVIDER_ADDRESS)"

.PHONY: get-manifest
get-manifest:
$(PROVIDER_SERVICES) get-manifest \
--dseq "$(DSEQ)" \
--from "$(KEY_NAME)" \
--provider "$(PROVIDER_ADDRESS)"


.PHONY: deployment-create
deployment-create:
$(AKASH) tx deployment create "$(SDL_PATH)" \
Expand Down
35 changes: 35 additions & 0 deletions cmd/provider-services/cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,41 @@ func dseqFromFlags(flags *pflag.FlagSet) (uint64, error) {
return flags.GetUint64(FlagDSeq)
}

func leaseIDFromFlags(cflags *pflag.FlagSet, owner string) (mtypes.LeaseID, error) {
str, err := cflags.GetString(FlagProvider)
if err != nil {
return mtypes.LeaseID{}, err
}

provider, err := sdk.AccAddressFromBech32(str)
if err != nil {
return mtypes.LeaseID{}, err
}

dseq, err := cflags.GetUint64(FlagDSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

gseq, err := cflags.GetUint32(FlagGSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

oseq, err := cflags.GetUint32(FlagOSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

return mtypes.LeaseID{
Owner: owner,
DSeq: dseq,
GSeq: gseq,
OSeq: oseq,
Provider: provider.String(),
}, nil
}

func providerFromFlags(flags *pflag.FlagSet) (sdk.Address, error) {
provider, err := flags.GetString(FlagProvider)
if err != nil {
Expand Down
78 changes: 78 additions & 0 deletions cmd/provider-services/cmd/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
errSubmitManifestFailed = errors.New("submit manifest to some providers has been failed")
)

func ManifestCmds() []*cobra.Command {
return []*cobra.Command{
SendManifestCmd(),
GetManifestCmd(),
}
}

// SendManifestCmd looks up the Providers blockchain information,
// and POSTs the SDL file to the Gateway address.
func SendManifestCmd() *cobra.Command {
Expand All @@ -45,6 +52,77 @@
return cmd
}

// GetManifestCmd reads current manifest from the provider
func GetManifestCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "get-manifest",
Args: cobra.ExactArgs(0),
Short: "Read manifest from provider",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {

Check failure on line 62 in cmd/provider-services/cmd/manifest.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
return err
}

ctx := cmd.Context()

cl, err := aclient.DiscoverQueryClient(ctx, cctx)
if err != nil {
return err
}

cert, err := cutils.LoadAndQueryCertificateForAccount(cmd.Context(), cctx, nil)
if err != nil {
return markRPCServerError(err)
}

lid, err := leaseIDFromFlags(cmd.Flags(), cctx.GetFromAddress().String())
if err != nil {
return err
}

prov, _ := sdk.AccAddressFromBech32(lid.Provider)
gclient, err := gwrest.NewClient(ctx, cl, prov, []tls.Certificate{cert})
if err != nil {
return err
}

mani, err := gclient.GetManifest(ctx, lid)
if err != nil {
return err
}

buf := &bytes.Buffer{}

switch cmd.Flag(flagOutput).Value.String() {
case outputJSON:
err = json.NewEncoder(buf).Encode(mani)
case outputYAML:
err = yaml.NewEncoder(buf).Encode(mani)
}

if err != nil {
return err
}

_, err = fmt.Fprint(cmd.OutOrStdout(), buf.String())

if err != nil {
return err
}

return nil
},
}

addLeaseFlags(cmd)

cmd.Flags().StringP(flagOutput, "o", outputYAML, "output format json|yaml. default yaml")

return cmd
}

func doSendManifest(cmd *cobra.Command, sdlpath string) error {
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/provider-services/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewRootCmd() *cobra.Command {
return nil
}

cmd.AddCommand(SendManifestCmd())
cmd.AddCommand(ManifestCmds()...)
cmd.AddCommand(statusCmd())
cmd.AddCommand(leaseStatusCmd())
cmd.AddCommand(leaseEventsCmd())
Expand Down
41 changes: 41 additions & 0 deletions gateway/rest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Client interface {
Status(ctx context.Context) (*provider.Status, error)
Validate(ctx context.Context, gspec dtypes.GroupSpec) (provider.ValidateGroupSpecResult, error)
SubmitManifest(ctx context.Context, dseq uint64, mani manifest.Manifest) error
GetManifest(ctx context.Context, id mtypes.LeaseID) (manifest.Manifest, error)
LeaseStatus(ctx context.Context, id mtypes.LeaseID) (LeaseStatus, error)
LeaseEvents(ctx context.Context, id mtypes.LeaseID, services string, follow bool) (*LeaseKubeEvents, error)
LeaseLogs(ctx context.Context, id mtypes.LeaseID, services string, follow bool, tailLines int64) (*ServiceLogs, error)
Expand Down Expand Up @@ -425,6 +426,46 @@ func (c *client) SubmitManifest(ctx context.Context, dseq uint64, mani manifest.
return createClientResponseErrorIfNotOK(resp, responseBuf)
}

func (c *client) GetManifest(ctx context.Context, lid mtypes.LeaseID) (manifest.Manifest, error) {
uri, err := makeURI(c.host, getManifestPath(lid))
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
if err != nil {
return nil, err
}

rCl := c.newReqClient(ctx)
resp, err := rCl.hclient.Do(req)

if err != nil {
return nil, err
}

defer func() {
_ = resp.Body.Close()
}()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

err = createClientResponseErrorIfNotOK(resp, bytes.NewBuffer(body))
if err != nil {
return nil, err
}

var mani manifest.Manifest
if err = json.Unmarshal(body, &mani); err != nil {
return nil, err
}

return mani, nil
}

func (c *client) MigrateEndpoints(ctx context.Context, endpoints []string, dseq uint64, gseq uint32) error {
uri, err := makeURI(c.host, "endpoint/migrate")
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions gateway/rest/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func submitManifestPath(dseq uint64) string {
return fmt.Sprintf("deployment/%d/manifest", dseq)
}

func getManifestPath(id mtypes.LeaseID) string {
return fmt.Sprintf("%s/manifest", leasePath(id))
}

func leaseStatusPath(id mtypes.LeaseID) string {
return fmt.Sprintf("%s/status", leasePath(id))
}
Expand Down
40 changes: 35 additions & 5 deletions gateway/rest/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,23 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon

hostnameRouter := router.PathPrefix(hostnamePrefix).Subrouter()
hostnameRouter.Use(requireOwner())
hostnameRouter.HandleFunc(migratePathPrefix, migrateHandler(log, pclient.Hostname(), pclient.ClusterService())).
hostnameRouter.HandleFunc(migratePathPrefix,
migrateHandler(log, pclient.Hostname(), pclient.ClusterService())).
Methods(http.MethodPost)

endpointRouter := router.PathPrefix(endpointPrefix).Subrouter()
endpointRouter.Use(requireOwner())
endpointRouter.HandleFunc(migratePathPrefix, migrateEndpointHandler(log, pclient.ClusterService(), pclient.Cluster())).
endpointRouter.HandleFunc(migratePathPrefix,
migrateEndpointHandler(log, pclient.ClusterService(), pclient.Cluster())).
Methods(http.MethodPost)

// PUT /deployment/manifest
drouter := router.PathPrefix(deploymentPathPrefix).Subrouter()
drouter.Use(
requireOwner(),
requireDeploymentID(),
)

// PUT /deployment/manifest
drouter.HandleFunc("/manifest",
createManifestHandler(log, pclient.Manifest())).
Methods(http.MethodPut)
Expand All @@ -152,6 +154,11 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon
requireLeaseID(),
)

// GET /lease/<lease-id>/manifest
lrouter.HandleFunc("/manifest",
getManifestHandler(log, pclient.Cluster())).
Methods(http.MethodGet)

// GET /lease/<lease-id>/status
lrouter.HandleFunc("/status",
leaseStatusHandler(log, pclient.Cluster(), ctxConfig)).
Expand Down Expand Up @@ -188,7 +195,7 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon

// POST /lease/<lease-id>/shell
lrouter.HandleFunc("/shell",
leaseShellHandler(log, pclient.Manifest(), pclient.Cluster()))
leaseShellHandler(log, pclient.Cluster()))

return router
}
Expand Down Expand Up @@ -306,7 +313,7 @@ type leaseShellResponse struct {
Message string `json:"message,omitempty"`
}

func leaseShellHandler(log log.Logger, mclient pmanifest.Client, cclient cluster.Client) http.HandlerFunc {
func leaseShellHandler(log log.Logger, cclient cluster.Client) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
leaseID := requestLeaseID(req)

Expand Down Expand Up @@ -591,6 +598,29 @@ func createManifestHandler(log log.Logger, mclient pmanifest.Client) http.Handle
}
}

func getManifestHandler(log log.Logger, cclient cluster.ReadClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
found, grp, err := cclient.GetManifestGroup(r.Context(), requestLeaseID(r))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

if !found {
http.Error(w, "lease not found", http.StatusNotFound)
return
}

mgrp, _, err := grp.FromCRD()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

writeJSON(log, w, &manifest.Manifest{mgrp})
}
}

func leaseKubeEventsHandler(log log.Logger, cclient cluster.ReadClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
upgrader := websocket.Upgrader{
Expand Down
6 changes: 3 additions & 3 deletions pkg/apis/akash.network/v2beta2/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (m *Manifest) Deployment() (ctypes.IDeployment, error) {
return nil, err
}

group, schedulerParams, err := m.Spec.Group.fromCRD()
group, schedulerParams, err := m.Spec.Group.FromCRD()
if err != nil {
return nil, err
}
Expand All @@ -185,8 +185,8 @@ func (m *Manifest) Deployment() (ctypes.IDeployment, error) {
}, nil
}

// toAkash returns akash group details formatted from manifest group
func (m *ManifestGroup) fromCRD() (mani.Group, []*SchedulerParams, error) {
// FromCRD returns akash group details formatted from manifest group
func (m *ManifestGroup) FromCRD() (mani.Group, []*SchedulerParams, error) {
am := mani.Group{
Name: m.Name,
Services: make([]mani.Service, 0, len(m.Services)),
Expand Down
Loading