/
manifest.go
145 lines (117 loc) · 3.25 KB
/
manifest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package cmd
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
sdkclient "github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
dtypes "github.com/virtengine/virtengine/x/deployment/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
virtengineclient "github.com/virtengine/virtengine/client"
gwrest "github.com/virtengine/virtengine/provider/gateway/rest"
"github.com/virtengine/virtengine/sdl"
cutils "github.com/virtengine/virtengine/x/cert/utils"
)
var (
errSubmitManifestFailed = errors.New("submit manifest to some providers has been failed")
)
// SendManifestCmd looks up the Providers blockchain information,
// and POSTs the SDL file to the Gateway address.
func SendManifestCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send-manifest <sdl-path>",
Args: cobra.ExactArgs(1),
Short: "Submit manifest to provider(s)",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
return doSendManifest(cmd, args[0])
},
}
addManifestFlags(cmd)
cmd.Flags().StringP(flagOutput, "o", outputText, "output format text|json|yaml. default text")
return cmd
}
func doSendManifest(cmd *cobra.Command, sdlpath string) error {
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
return err
}
sdl, err := sdl.ReadFile(sdlpath)
if err != nil {
return err
}
mani, err := sdl.Manifest()
if err != nil {
return err
}
cert, err := cutils.LoadAndQueryCertificateForAccount(cmd.Context(), cctx, cctx.Keyring)
if err != nil {
return err
}
dseq, err := dseqFromFlags(cmd.Flags())
if err != nil {
return err
}
// owner address in FlagFrom has already been validated thus save to just pull its value as string
leases, err := leasesForDeployment(cmd.Context(), cctx, cmd.Flags(), dtypes.DeploymentID{
Owner: cctx.GetFromAddress().String(),
DSeq: dseq,
})
if err != nil {
return err
}
type result struct {
Provider sdk.Address `json:"provider" yaml:"provider"`
Status string `json:"status" yaml:"status"`
Error error `json:"error,omitempty" yaml:"error,omitempty"`
}
results := make([]result, len(leases))
submitFailed := false
for i, lid := range leases {
prov, _ := sdk.AccAddressFromBech32(lid.Provider)
gclient, err := gwrest.NewClient(virtengineclient.NewQueryClientFromCtx(cctx), prov, []tls.Certificate{cert})
if err != nil {
return err
}
err = gclient.SubmitManifest(context.Background(), dseq, mani)
res := result{
Provider: prov,
Status: "PASS",
Error: err,
}
if err != nil {
res.Status = "FAIL"
submitFailed = true
}
results[i] = res
}
buf := &bytes.Buffer{}
switch cmd.Flag(flagOutput).Value.String() {
case outputText:
for _, res := range results {
_, _ = fmt.Fprintf(buf, "provider: %s\n\tstatus: %s\n", res.Provider, res.Status)
if res.Error != nil {
_, _ = fmt.Fprintf(buf, "\terror: %v\n", res.Error)
}
}
case outputJSON:
err = json.NewEncoder(buf).Encode(results)
case outputYAML:
err = yaml.NewEncoder(buf).Encode(results)
}
if err != nil {
return err
}
_, err = fmt.Fprint(cmd.OutOrStdout(), buf.String())
if err != nil {
return err
}
if submitFailed {
return errSubmitManifestFailed
}
return nil
}