Skip to content

Commit

Permalink
FS-878 Add bom router handlers and client APIs to upload Boms and fet…
Browse files Browse the repository at this point in the history
…ch Bom(by AocMacAddress) (#240)

FS-878 Add bom related handler for 2 APIs(both server and client) in server service

use transaction for bomsupload

remove unused and sensitive code and file
  • Loading branch information
Alva8756 authored Sep 7, 2023
1 parent a4fb59f commit 775a5de
Show file tree
Hide file tree
Showing 8 changed files with 577 additions and 10 deletions.
11 changes: 1 addition & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ericlagergren/decimal v0.0.0-20190420051523-6335edbaa640/go.mod h1:mdYyfAkzn9kyJ/kMk/7WE9ufl9lflh+2NvecQ5mAghs=
github.com/ericlagergren/decimal v0.0.0-20211103172832-aca2edc11f73/go.mod h1:5sruVSMrZCk0U4hwRaGD0D8wIMFVsBWQqG74jQDFg4k=
github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw=
github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
Expand Down Expand Up @@ -303,7 +302,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Expand Down Expand Up @@ -667,12 +665,9 @@ github.com/volatiletech/randomize v0.0.1 h1:eE5yajattWqTB2/eN8df4dw+8jwAzBtbdo5s
github.com/volatiletech/randomize v0.0.1/go.mod h1:GN3U0QYqfZ9FOJ67bzax1cqZ5q2xuj2mXrXBjWaRTlY=
github.com/volatiletech/sqlboiler v3.7.1+incompatible h1:dm9/NjDskQVwAarmpeZ2UqLn1NKE8M3WHSHBS4jw2x8=
github.com/volatiletech/sqlboiler v3.7.1+incompatible/go.mod h1:jLfDkkHWPbS2cWRLkyC20vQWaIQsASEY7gM7zSo11Yw=
github.com/volatiletech/sqlboiler/v4 v4.14.2 h1:j5QnlR5/wYDmGDDTutI3BO+4oPBiqYoVrfReVr7VSxA=
github.com/volatiletech/sqlboiler/v4 v4.14.2/go.mod h1:65288sb8jBLnTynTumBK6eU8C2JwWsiPjoPihEfC0/A=
github.com/volatiletech/sqlboiler/v4 v4.15.0 h1:+twm3mA34SaUF6wB9U6QkXxkK8AKkV5EfgMSvcKWeY4=
github.com/volatiletech/sqlboiler/v4 v4.15.0/go.mod h1:s643wqYyCQ7Ak2hMVxH7kTS0+lFPNlj+gHKUIukJ0YA=
github.com/volatiletech/strmangle v0.0.1/go.mod h1:F6RA6IkB5vq0yTG4GQ0UsbbRcl3ni9P76i+JrTBKFFg=
github.com/volatiletech/strmangle v0.0.4/go.mod h1:ycDvbDkjDvhC0NUU8w3fWwl5JEMTV56vTKXzR3GeR+0=
github.com/volatiletech/strmangle v0.0.5 h1:CompJPy+lAi9h+YU/IzBR4X2RDRuAuEIP+kjFdyZXcU=
github.com/volatiletech/strmangle v0.0.5/go.mod h1:ycDvbDkjDvhC0NUU8w3fWwl5JEMTV56vTKXzR3GeR+0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand All @@ -690,8 +685,6 @@ go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.hollow.sh/toolbox v0.6.1 h1:3E6JofImSCe63XayczbGfDxIXUjmBziMBBmbwook8WA=
go.hollow.sh/toolbox v0.6.1/go.mod h1:nl+5RDDyYY/+wukOUzHHX2mOyWKRjlTOXUcGxny+tns=
go.infratographer.com/x v0.3.6 h1:3wjfkKtjtZ3mmvzOvWka5HlHqsTR++RxfxZtP0YeJN8=
go.infratographer.com/x v0.3.6/go.mod h1:AMNcTkqb+yHLCbnZtiiHTC7QvN+4MOpzdOhqHXfKQUk=
go.infratographer.com/x v0.3.7 h1:kkykoVtC8XrmvC4oZwHWa/15+dv9RhQHgSm8KoEb/Nc=
go.infratographer.com/x v0.3.7/go.mod h1:/zbDM9njbWzUDCA9pkbi1z/v4VZjGsVHx+SPycSgIhg=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
Expand Down Expand Up @@ -788,8 +781,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
Expand Down Expand Up @@ -1080,7 +1071,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
3 changes: 3 additions & 0 deletions internal/dbtools/testtools.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ func cleanDB(t *testing.T) {

// don't delete the builtin ServerCredentialTypes. Those are expected to exist for the application to work
deleteFixture(ctx, t, models.ServerCredentialTypes(models.ServerCredentialTypeWhere.Builtin.EQ(false)))
deleteFixture(ctx, t, models.AocMacAddresses())
deleteFixture(ctx, t, models.BMCMacAddresses())
deleteFixture(ctx, t, models.BomInfos())

testDB.Exec("SET sql_safe_updates = true;")
}
Expand Down
78 changes: 78 additions & 0 deletions pkg/api/v1/bom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package serverservice

import (
"strings"

"github.com/pkg/errors"
"github.com/volatiletech/null/v8"

"go.hollow.sh/serverservice/internal/models"
)

// Bom provides a struct to map the bom_info table.
// Naming conversion is strange here just in order to make it consistent
// with generated BomInfo.
type Bom struct {
SerialNum string `json:"serial_num"` // physical serial number listed outside of a server
AocMacAddress string `json:"aoc_mac_address"` // Aoc is alternative name of the fiber channel card MAC address
BmcMacAddress string `json:"bmc_mac_address"`
NumDefiPmi string `json:"num_defi_pmi"`
NumDefPWD string `json:"num_def_pwd"` // DefPWD is the IPMI Password in the portal
Metro string `json:"metro"`
}

// AocMacAddressBom provides a struct to map the aoc_mac_address table.
type AocMacAddressBom struct {
AocMacAddress string `json:"aoc_mac_address"`
SerialNum string `json:"serial_num"`
}

// toDBModel converts Bom to BomInfo.
func (b *Bom) toDBModel() (*models.BomInfo, error) {
if b.SerialNum == "" {
return nil, errors.Errorf("the primary key serial-num can not be blank")
}

dbB := &models.BomInfo{
SerialNum: b.SerialNum,
AocMacAddress: null.StringFrom(b.AocMacAddress),
BMCMacAddress: null.StringFrom(b.BmcMacAddress),
NumDefiPmi: null.StringFrom(b.NumDefiPmi),
NumDefPWD: null.StringFrom(b.NumDefPWD),
Metro: null.StringFrom(b.Metro),
}

return dbB, nil
}

// toDBModel converts BomInfo to Bom.
func (b *Bom) fromDBModel(bomInfo *models.BomInfo) error {
b.SerialNum = bomInfo.SerialNum
b.AocMacAddress = bomInfo.AocMacAddress.String
b.BmcMacAddress = bomInfo.BMCMacAddress.String
b.NumDefiPmi = bomInfo.NumDefiPmi.String
b.NumDefPWD = bomInfo.NumDefPWD.String
b.Metro = bomInfo.Metro.String

return nil
}

// toAocMacAddressDBModels converts Bom to one or multiple AocMacAddress.
func (b *Bom) toAocMacAddressDBModels() ([]*models.AocMacAddress, error) {
if b.AocMacAddress == "" {
return nil, errors.Errorf("the primary key aoc-mac-address can not be blank")
}

dbAs := []*models.AocMacAddress{}

AocMacAddrs := strings.Split(b.AocMacAddress, ",")
for _, aocMacAddr := range AocMacAddrs {
dbA := &models.AocMacAddress{
SerialNum: b.SerialNum,
AocMacAddress: aocMacAddr,
}
dbAs = append(dbAs, dbA)
}

return dbAs, nil
}
18 changes: 18 additions & 0 deletions pkg/api/v1/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ func (r *Router) Routes(rg *gin.RouterGroup) {
srvCmpntFwSets.DELETE("/:uuid", amw.RequiredScopes(deleteScopes("server-component-firmware-sets")), r.serverComponentFirmwareSetDelete)
srvCmpntFwSets.POST("/:uuid/remove-firmware", amw.RequiredScopes(deleteScopes("server-component-firmware-sets")), r.serverComponentFirmwareSetRemoveFirmware)
}

// /bill-of-materials
srvBoms := rg.Group("/bill-of-materials")
{
// /bill-of-materials/batch-boms-upload
uploadFile := srvBoms.Group("/batch-upload")
{
uploadFile.POST("", amw.RequiredScopes(createScopes("batch-upload")), r.bomsUpload)
}

// /bill-of-materials/aoc-mac-address
srvBomByAocMacAddress := srvBoms.Group("/aoc-mac-address")
{
srvBomByAocMacAddress.GET("/:aoc_mac_address", amw.RequiredScopes(readScopes("aoc-mac-address")), r.getBomFromAocMacAddress)
}

// TODO: support query by bmc-mac-address
}
}

func createScopes(items ...string) []string {
Expand Down
81 changes: 81 additions & 0 deletions pkg/api/v1/router_bom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package serverservice

import (
"database/sql"

"github.com/cockroachdb/cockroach-go/v2/crdb"
"github.com/gin-gonic/gin"
"github.com/volatiletech/sqlboiler/v4/boil"
"github.com/volatiletech/sqlboiler/v4/queries/qm"

"go.hollow.sh/serverservice/internal/models"
)

func (r *Router) bomsUpload(c *gin.Context) {
var boms []Bom
if err := c.ShouldBindJSON(&boms); err != nil {
badRequestResponse(c, "invalid payload: []Bom{}", err)
return
}

err := crdb.ExecuteTx(c.Request.Context(), r.DB.DB, nil, func(tx *sql.Tx) error {
for _, bom := range boms {
dbBomInfo, err := (bom).toDBModel()
if err != nil {
return err
}

if err := dbBomInfo.Insert(c.Request.Context(), r.DB, boil.Infer()); err != nil {
return err
}

dbAocMacAddrsBoms, err := (bom).toAocMacAddressDBModels()
if err != nil {
return err
}

for _, dbAocMacAddrsBom := range dbAocMacAddrsBoms {
if err := dbAocMacAddrsBom.Insert(c.Request.Context(), r.DB, boil.Infer()); err != nil {
return err
}
}
}
return nil
})
if err != nil {
dbErrorResponse(c, err)
return
}

createdResponse(c, "")
}

func (r *Router) getBomFromAocMacAddress(c *gin.Context) {
mods := []qm.QueryMod{
qm.Where("aoc_mac_address=?", c.Param("aoc_mac_address")),
}

aocMacAddr, err := models.AocMacAddresses(mods...).One(c.Request.Context(), r.DB)
if err != nil {
dbErrorResponse(c, err)
return
}

mods = []qm.QueryMod{
qm.Where("serial_num=?", aocMacAddr.SerialNum),
}

bomInfo, err := models.BomInfos(mods...).One(c.Request.Context(), r.DB)
if err != nil {
dbErrorResponse(c, err)
return
}

bom := Bom{}
if err = bom.fromDBModel(bomInfo); err != nil {
dbErrorResponse(c, err)
return
}

itemResponse(c, bom)
}
Loading

0 comments on commit 775a5de

Please sign in to comment.