From 4c568fddd8e5120370db9774c15ae485305f547c Mon Sep 17 00:00:00 2001 From: Alex Lovell-Troy Date: Wed, 17 Jan 2024 11:45:23 -0500 Subject: [PATCH 1/2] hygiene and infrastructure changes --- .github/workflows/ochami.yml | 41 ++++++++ .gitignore | 1 + .goreleaser.yaml | 1 - CHANGELOG.md | 16 +++ Dockerfile | 6 +- LICENSE | 2 +- README.md | 4 +- cmd/cloud-init-server/handlers.go | 167 ++++++++++++++++++++++++++++++ cmd/cloud-init-server/main.go | 157 ++-------------------------- cmd/cloud-init-server/store.go | 15 +++ go.mod | 63 ++++++++++- go.sum | 27 +++-- internal/smdclient/SMDclient.go | 28 +++-- 13 files changed, 349 insertions(+), 179 deletions(-) create mode 100644 .github/workflows/ochami.yml create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 cmd/cloud-init-server/handlers.go create mode 100644 cmd/cloud-init-server/store.go diff --git a/.github/workflows/ochami.yml b/.github/workflows/ochami.yml new file mode 100644 index 0000000..5417015 --- /dev/null +++ b/.github/workflows/ochami.yml @@ -0,0 +1,41 @@ +# This workflow will build and release a golang-based microservice +# using goreleaser any time a new version tag is pushed to the repository + +name: Release with goreleaser + +on: + push: + tags: + - v* +permissions: write-all # Necessary for creating containers + +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - name: Set up Go 1.21 + uses: actions/setup-go@v5 + with: + go-version: 1.21 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Docker Login + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-tags: 1 + fetch-depth: 1 + - name: Release with goreleaser + uses: goreleaser/goreleaser-action@v5 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + version: latest + args: release --clean diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53c37a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 0cc46b1..8e4014e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -36,7 +36,6 @@ dockers: - LICENSE - CHANGELOG.md - README.md - - .version archives: - format: tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d964b07 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.0.4] - 2024-01-17 + +### Added + +- Initial release +- Created SMD client +- Added memory-based store +- Able to provide cloud-init payloads that work with newly booted nodes +- Build and release with goreleaser \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 122360a..29dc004 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,14 +34,14 @@ RUN set -ex \ && apk add --no-cache curl # Get the boot-script-service from the builder stage. -COPY cloud-init-service /usr/local/bin/ -COPY .version / +COPY cloud-init-server /usr/local/bin/ + # nobody 65534:65534 USER 65534:65534 # Set up the command to start the service. -CMD /usr/local/bin/cloud-init-service \ +CMD /usr/local/bin/cloud-init-server \ --ci-listen ":27777" \ --smd-endpoint "http://localhost:27779" diff --git a/LICENSE b/LICENSE index 0ff8d63..6e7dcec 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 OpenCHAMI +Copyright © 2024 Triad National Security, LLC. This program was produced under U.S. Government contract 89233218CNA000001 for Los Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC for the U.S. Department of Energy/National Nuclear Security Administration. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index bb59f4a..c8edb49 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# harbor +# Cloud-Init -Microservice that servers out cloud-init configs +OpenCHAMI cloud-init server that retrieves detailed inventory information from SMD and uses it to create cloud-init payloads customized for each node in an ochami-based cluster diff --git a/cmd/cloud-init-server/handlers.go b/cmd/cloud-init-server/handlers.go new file mode 100644 index 0000000..961fba2 --- /dev/null +++ b/cmd/cloud-init-server/handlers.go @@ -0,0 +1,167 @@ +package main + +import ( + "fmt" + "net/http" + + "github.com/OpenCHAMI/cloud-init/internal/memstore" + "github.com/OpenCHAMI/cloud-init/internal/smdclient" + "github.com/OpenCHAMI/cloud-init/pkg/citypes" + "github.com/gin-gonic/gin" + "github.com/gosimple/slug" + yaml "gopkg.in/yaml.v2" +) + +type CiHandler struct { + store ciStore + sm *smdclient.SMDClient +} + +func NewCiHandler(s ciStore, c *smdclient.SMDClient) *CiHandler { + return &CiHandler{ + store: s, + sm: c, + } +} + +// ListEntries godoc +// @Summary List all cloud-init entries +// @Description List all cloud-init entries +// @Produce json +// @Success 200 {object} map[string]CI +// @Router /harbor [get] +func (h CiHandler) ListEntries(c *gin.Context) { + ci, err := h.store.List() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + + c.JSON(200, ci) +} + +// AddEntry godoc +// @Summary Add a new cloud-init entry +// @Description Add a new cloud-init entry +// @Accept json +// @Produce json +// @Param ci body CI true "Cloud-init entry to add" +// @Success 200 {string} string "name of the new entry" +// @Failure 400 {string} string "bad request" +// @Failure 500 {string} string "internal server error" +// @Router /harbor [post] +func (h CiHandler) AddEntry(c *gin.Context) { + var ci citypes.CI + if err := c.ShouldBindJSON(&ci); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + id := slug.Make(ci.Name) + + err := h.store.Add(id, ci) + if err != nil { + if err == memstore.ExistingEntryErr { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, ci.Name) +} + +// GetEntry godoc +// @Summary Get a cloud-init entry +// @Description Get a cloud-init entry +// @Produce json +// @Param id path string true "ID of the cloud-init entry to get" +// @Success 200 {object} CI +// @Failure 404 {string} string "not found" +// @Router /harbor/{id} [get] +func (h CiHandler) GetEntry(c *gin.Context) { + id := c.Param("id") + + ci, err := h.store.Get(id, h.sm) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + } + + c.JSON(200, ci) +} + +func (h CiHandler) GetUserData(c *gin.Context) { + id := c.Param("id") + + ci, err := h.store.Get(id, h.sm) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + } + ud, err := yaml.Marshal(ci.CIData.UserData) + if err != nil { + fmt.Print(err) + } + s := fmt.Sprintf("#cloud-config\n%s", string(ud[:])) + //c.Header("Content-Type", "text/yaml") + c.Data(200, "text/yaml", []byte(s)) +} + +func (h CiHandler) GetMetaData(c *gin.Context) { + id := c.Param("id") + + ci, err := h.store.Get(id, h.sm) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + } + + c.YAML(200, ci.CIData.MetaData) +} + +func (h CiHandler) GetVendorData(c *gin.Context) { + id := c.Param("id") + + ci, err := h.store.Get(id, h.sm) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + } + + c.YAML(200, ci.CIData.VendorData) +} + +func (h CiHandler) UpdateEntry(c *gin.Context) { + var ci citypes.CI + if err := c.ShouldBindJSON(&ci); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + id := c.Param("id") + + err := h.store.Update(id, ci) + if err != nil { + if err == memstore.NotFoundErr { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, id) +} + +func (h CiHandler) DeleteEntry(c *gin.Context) { + id := c.Param("id") + + err := h.store.Remove(id) + if err != nil { + if err == memstore.NotFoundErr { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success"}) +} diff --git a/cmd/cloud-init-server/main.go b/cmd/cloud-init-server/main.go index 3e736e3..d37648c 100644 --- a/cmd/cloud-init-server/main.go +++ b/cmd/cloud-init-server/main.go @@ -1,19 +1,15 @@ package main import ( - "fmt" - "net/http" "flag" - yaml "gopkg.in/yaml.v2" - "github.com/gin-gonic/gin" - "github.com/gosimple/slug" + "github.com/OpenCHAMI/cloud-init/internal/memstore" - "github.com/OpenCHAMI/cloud-init/pkg/citypes" "github.com/OpenCHAMI/cloud-init/internal/smdclient" + "github.com/gin-gonic/gin" ) var ( - ciEndpoint = ":27777" + ciEndpoint = ":27777" smdEndpoint = "http://localhost:27779" ) @@ -30,152 +26,11 @@ func main() { router.GET("/harbor", ciHandler.ListEntries) router.POST("/harbor", ciHandler.AddEntry) router.GET("/harbor/:id", ciHandler.GetEntry) - router.GET("/harbor/:id/user-data",ciHandler.GetUserData) - router.GET("/harbor/:id/meta-data",ciHandler.GetMetaData) - router.GET("/harbor/:id/vendor-data",ciHandler.GetVendorData) + router.GET("/harbor/:id/user-data", ciHandler.GetUserData) + router.GET("/harbor/:id/meta-data", ciHandler.GetMetaData) + router.GET("/harbor/:id/vendor-data", ciHandler.GetVendorData) router.PUT("/harbor/:id", ciHandler.UpdateEntry) router.DELETE("harbor/:id", ciHandler.DeleteEntry) - router.Run(ciEndpoint) } - - -type CiHandler struct { - store ciStore - sm *smdclient.SMDClient -} - -func NewCiHandler(s ciStore, c *smdclient.SMDClient) *CiHandler { - return &CiHandler{ - store: s, - sm: c, - } -} - -type ciStore interface { - Add(name string, ci citypes.CI) error - Get(name string, sm *smdclient.SMDClient) (citypes.CI, error) - List() (map[string]citypes.CI, error) - Update(name string, ci citypes.CI) error - Remove(name string) error -} - -func (h CiHandler) ListEntries(c *gin.Context) { - ci, err := h.store.List() - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - } - - c.JSON(200, ci) -} - -func (h CiHandler) AddEntry(c *gin.Context) { - var ci citypes.CI - if err := c.ShouldBindJSON(&ci); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - id := slug.Make(ci.Name) - - err := h.store.Add(id, ci) - if err != nil { - if err == memstore.ExistingEntryErr { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - return - } - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusOK, ci.Name) -} - -func (h CiHandler) GetEntry(c *gin.Context) { - id := c.Param("id") - - ci, err := h.store.Get(id, h.sm) - if err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - } - - c.JSON(200, ci) -} - -func (h CiHandler) GetUserData(c *gin.Context) { - id := c.Param("id") - - ci, err := h.store.Get(id, h.sm) - if err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - } - ud,err := yaml.Marshal(ci.CIData.UserData) - if err != nil { - fmt.Print(err) - } - s := fmt.Sprintf("#cloud-config\n%s", string(ud[:])) - //c.Header("Content-Type", "text/yaml") - c.Data(200,"text/yaml", []byte(s)) -} - -func (h CiHandler) GetMetaData(c *gin.Context) { - id := c.Param("id") - - ci, err := h.store.Get(id, h.sm) - if err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - } - - c.YAML(200, ci.CIData.MetaData) -} - -func (h CiHandler) GetVendorData(c *gin.Context) { - id := c.Param("id") - - ci, err := h.store.Get(id, h.sm) - if err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - } - - c.YAML(200, ci.CIData.VendorData) -} - -func (h CiHandler) UpdateEntry(c *gin.Context) { - var ci citypes.CI - if err := c.ShouldBindJSON(&ci); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - id := c.Param("id") - - err := h.store.Update(id, ci) - if err != nil { - if err == memstore.NotFoundErr { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - return - } - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusOK, id) -} - - -func (h CiHandler) DeleteEntry(c *gin.Context) { - id := c.Param("id") - - err := h.store.Remove(id) - if err != nil { - if err == memstore.NotFoundErr { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - return - } - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusOK, gin.H{"status": "success"}) -} diff --git a/cmd/cloud-init-server/store.go b/cmd/cloud-init-server/store.go new file mode 100644 index 0000000..01399f0 --- /dev/null +++ b/cmd/cloud-init-server/store.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/OpenCHAMI/cloud-init/internal/smdclient" + "github.com/OpenCHAMI/cloud-init/pkg/citypes" +) + +// ciStore is an interface for storing cloud-init entries +type ciStore interface { + Add(name string, ci citypes.CI) error + Get(name string, sm *smdclient.SMDClient) (citypes.CI, error) + List() (map[string]citypes.CI, error) + Update(name string, ci citypes.CI) error + Remove(name string) error +} diff --git a/go.mod b/go.mod index 060c3db..1bd25c5 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,62 @@ -module cloud-init-server +module github.com/OpenCHAMI/cloud-init -go 1.20 +go 1.21 + +require github.com/OpenCHAMI/smd/v2 v2.12.15 + +require ( + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require ( + github.com/Cray-HPE/hms-base v1.15.1 // indirect + github.com/Cray-HPE/hms-certs v1.4.0 // indirect + github.com/Cray-HPE/hms-securestorage v1.13.0 // indirect + github.com/cenkalti/backoff/v3 v3.2.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gin-gonic/gin v1.9.1 + github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/gosimple/slug v1.13.1 + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.4 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/hashicorp/vault/api v1.9.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/samber/lo v1.39.0 + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/time v0.3.0 // indirect + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/go.sum b/go.sum index b8a04ad..f2727a8 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,9 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583j github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -37,6 +40,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -44,6 +49,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -55,6 +62,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= @@ -70,6 +79,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= +github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -111,6 +122,8 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -138,6 +151,8 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -158,6 +173,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= @@ -168,8 +184,6 @@ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -184,8 +198,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -206,14 +218,10 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -225,6 +233,8 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -236,6 +246,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/internal/smdclient/SMDclient.go b/internal/smdclient/SMDclient.go index 6aa275c..ae1c7d6 100644 --- a/internal/smdclient/SMDclient.go +++ b/internal/smdclient/SMDclient.go @@ -1,12 +1,12 @@ package smdclient import ( - "net/http" "encoding/json" - "time" - "io" "errors" + "io" + "net/http" "strings" + "time" "github.com/OpenCHAMI/smd/v2/pkg/sm" ) @@ -14,25 +14,30 @@ import ( // Add client usage examples // unit testing // golang lint +// Expand this client to handle more of the SMD API and work more directly with the resources it manages var ( - UnMarsharlError = errors.New("Can not unmarshal JSON") + UnMarsharlError = errors.New("Can not unmarshal JSON") ) +// godoc ? +// SMDClient is a client for SMD type SMDClient struct { - smdClient *http.Client + smdClient *http.Client smdBaseURL string } +// NewSMDClient creates a new SMDClient which connects to the SMD server at baseurl func NewSMDClient(baseurl string) *SMDClient { c := &http.Client{Timeout: 2 * time.Second} - return &SMDClient { + return &SMDClient{ smdClient: c, smdBaseURL: baseurl, } } -func (s *SMDClient) getSMD(ep string, smd interface{}) error { +// getSMD is a helper function to initialize the SMDClient +func (s *SMDClient) getSMD(ep string, smd interface{}) error { url := s.smdBaseURL + ep resp, err := s.smdClient.Get(url) if err != nil { @@ -48,24 +53,25 @@ func (s *SMDClient) getSMD(ep string, smd interface{}) error { return nil } - +// IDfromMAC returns the ID of the xname that has the MAC address func (s *SMDClient) IDfromMAC(mac string) (string, error) { endpointData := new(sm.ComponentEndpointArray) ep := "/hsm/v2/Inventory/ComponentEndpoints/" s.getSMD(ep, endpointData) - for _,ep := range endpointData.ComponentEndpoints { + for _, ep := range endpointData.ComponentEndpoints { id := ep.ID nics := ep.RedfishSystemInfo.EthNICInfo - for _,v := range nics { + for _, v := range nics { if strings.EqualFold(mac, v.MACAddress) { return id, nil } - } + } } return "", errors.New("MAC " + mac + " not found for an xname in CompenentEndpoints") } +// GroupMembership returns the group labels for the xname with the given ID func (s *SMDClient) GroupMembership(id string) ([]string, error) { ml := new(sm.Membership) ep := "/hsm/v2/memberships/" + id From b27898b9a096bf319a52217481c5db899754be9d Mon Sep 17 00:00:00 2001 From: Alex Lovell-Troy Date: Wed, 17 Jan 2024 11:45:56 -0500 Subject: [PATCH 2/2] Fixing a final static analysis check --- internal/smdclient/SMDclient.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/smdclient/SMDclient.go b/internal/smdclient/SMDclient.go index ae1c7d6..9569e6f 100644 --- a/internal/smdclient/SMDclient.go +++ b/internal/smdclient/SMDclient.go @@ -17,7 +17,7 @@ import ( // Expand this client to handle more of the SMD API and work more directly with the resources it manages var ( - UnMarsharlError = errors.New("Can not unmarshal JSON") + ErrUnmarshal = errors.New("cannot unmarshal JSON") ) // godoc ? @@ -46,9 +46,9 @@ func (s *SMDClient) getSMD(ep string, smd interface{}) error { // check http retrun value defer resp.Body.Close() // ioutil is deprecated - body, err := io.ReadAll(resp.Body) + body, _ := io.ReadAll(resp.Body) if err := json.Unmarshal(body, smd); err != nil { - return UnMarsharlError + return ErrUnmarshal } return nil }