Skip to content

Commit

Permalink
added read available-component
Browse files Browse the repository at this point in the history
  • Loading branch information
TheFireMike committed Nov 16, 2020
1 parent 1e03db3 commit 5855aa7
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 20 deletions.
39 changes: 39 additions & 0 deletions api/request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,33 @@ func StartAPI() {
// $ref: '#/definitions/OutputError'
e.POST("/read/ups", readUPS)

// swagger:operation POST /read/available-components read readAvailableComponents
// ---
// summary: Returns the available components for the device.
// consumes:
// - application/json
// - application/xml
// produces:
// - application/json
// - application/xml
// parameters:
// - name: body
// in: body
// description: Request to process.
// required: true
// schema:
// $ref: '#/definitions/ReadAvailableComponentsRequest'
// responses:
// 200:
// description: Returns the response.
// schema:
// $ref: '#/definitions/ReadAvailableComponentsResponse'
// 400:
// description: Returns an error with more details in the body.
// schema:
// $ref: '#/definitions/OutputError'
e.POST("/read/available-components", readAvailableComponents)

if viper.GetString("api.certfile") != "" && viper.GetString("api.keyfile") != "" {
e.Logger.Fatal(e.StartTLS(":"+viper.GetString("api.port"), viper.GetString("api.certfile"), viper.GetString("api.keyfile")))
} else {
Expand Down Expand Up @@ -445,6 +472,18 @@ func readUPS(ctx echo.Context) error {
return returnInFormat(ctx, http.StatusOK, resp)
}

func readAvailableComponents(ctx echo.Context) error {
r := request.ReadAvailableComponentsRequest{}
if err := ctx.Bind(&r); err != nil {
return err
}
resp, err := handleAPIRequest(&r, &r.BaseRequest.DeviceData.IPAddress)
if err != nil {
return handleError(ctx, err)
}
return returnInFormat(ctx, http.StatusOK, resp)
}

func handleError(ctx echo.Context, err error) error {
if tholaerr.IsNetworkError(err) {
return returnInFormat(ctx, http.StatusBadRequest, tholaerr.OutputError{Error: "Network error: " + err.Error()})
Expand Down
22 changes: 22 additions & 0 deletions cmd/read_available_components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cmd

import (
"github.com/inexio/thola/core/request"
"github.com/spf13/cobra"
)

func init() {
readCMD.AddCommand(readAvailableComponentsCMD)
}

var readAvailableComponentsCMD = &cobra.Command{
Use: "available-components",
Short: "Returns the available components for the device",
Long: "Returns the available components for the device.",
Run: func(cmd *cobra.Command, args []string) {
request := request.ReadAvailableComponentsRequest{
ReadRequest: getReadRequest(),
}
handleRequest(&request)
},
}
40 changes: 31 additions & 9 deletions core/communicator/device_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type deviceClassComponent byte

// All component enums.
const (
upsComponent deviceClassComponent = iota + 1
interfacesComponent
interfacesComponent deviceClassComponent = iota + 1
upsComponent
)

// deviceClass represents a device class.
Expand Down Expand Up @@ -713,14 +713,11 @@ func (y *yamlDeviceClassConfig) convert() (deviceClassConfig, error) {
config.components = make(map[deviceClassComponent]bool)

for k, v := range y.Components {
switch k {
case "interfaces":
config.components[interfacesComponent] = v
case "ups":
config.components[upsComponent] = v
default:
return deviceClassConfig{}, fmt.Errorf("invalid component type: %s", k)
component, err := createComponent(k)
if err != nil {
return deviceClassConfig{}, err
}
config.components[component] = v
}

return config, nil
Expand Down Expand Up @@ -1360,3 +1357,28 @@ func (l *logicalOperator) validate() error {
}
return nil
}

func createComponent(component string) (deviceClassComponent, error) {
switch component {
case "interfaceComponent":
return interfacesComponent, nil
case "upsComponent":
return upsComponent, nil
default:
return 0, fmt.Errorf("invalid component type: %s", component)
}
}

func (d *deviceClassComponent) toString() (string, error) {
if d == nil {
return "", errors.New("component is empty")
}
switch *d {
case interfacesComponent:
return "interfaceComponent", nil
case upsComponent:
return "upsComponent", nil
default:
return "", errors.New("unknown component")
}
}
17 changes: 17 additions & 0 deletions core/communicator/network_device_communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// NetworkDeviceCommunicator represents a communicator for a device
type NetworkDeviceCommunicator interface {
GetDeviceClass() string
GetAvailableComponents() []string
GetIdentifyProperties(ctx context.Context) (device.Properties, error)
GetUPSComponent(ctx context.Context) (device.UPSComponent, error)
availableCommunicatorFunctions
Expand Down Expand Up @@ -53,6 +54,22 @@ func (c *networkDeviceCommunicator) GetDeviceClass() string {
return c.deviceClassCommunicator.getName()
}

// GetAvailableComponents returns the available Components for the device.
func (c *networkDeviceCommunicator) GetAvailableComponents() []string {
var res []string
components := c.deviceClassCommunicator.getAvailableComponents()
for k, v := range components {
if v {
component, err := k.toString()
if err != nil {
continue
}
res = append(res, component)
}
}
return res
}

func (c *networkDeviceCommunicator) executeWithRecursion(fClass, fCom, fSub adapterFunc, args ...interface{}) (interface{}, error) {
var err1, err2, err3 error

Expand Down
2 changes: 1 addition & 1 deletion core/config/device-classes/generic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: "generic"

config:
components:
interfaces: true
interfaceComponent: true
snmp:
max_repetitions: 20

Expand Down
4 changes: 2 additions & 2 deletions core/config/device-classes/generic/effekta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: effekta

config:
components:
interfaces: false
ups: true
interfaceComponent: false
upsComponent: true

match:
conditions:
Expand Down
4 changes: 2 additions & 2 deletions core/config/device-classes/generic/eltek-webpower.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: eltek-webpower

config:
components:
interfaces: false
ups: true
interfaceComponent: false
upsComponent: true

match:
conditions:
Expand Down
4 changes: 2 additions & 2 deletions core/config/device-classes/generic/enexus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: enexus

config:
components:
interfaces: false
ups: true
interfaceComponent: false
upsComponent: true

match:
logical_operator: OR
Expand Down
4 changes: 2 additions & 2 deletions core/config/device-classes/generic/powerone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: "powerone"

config:
components:
interfaces: false
ups: true
interfaceComponent: false
upsComponent: true

match:
logical_operator: "OR"
Expand Down
14 changes: 14 additions & 0 deletions core/request/client_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@ func (r *ReadUPSRequest) process(ctx context.Context) (Response, error) {
return &res, nil
}

func (r *ReadAvailableComponentsRequest) process(ctx context.Context) (Response, error) {
apiFormat := viper.GetString("target-api-format")
responseBody, err := sendToAPI(ctx, r, "read/available-components", apiFormat)
if err != nil {
return nil, err
}
var res ReadAvailableComponentsResponse
err = parser.ToStruct(responseBody, apiFormat, &res)
if err != nil {
return nil, errors.Wrap(err, "failed to parse api response body to thola response")
}
return &res, nil
}

func checkProcess(ctx context.Context, r Request, apiPath string) Response {
var res CheckResponse
apiFormat := viper.GetString("target-api-format")
Expand Down
20 changes: 20 additions & 0 deletions core/request/read_available_components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package request

// ReadAvailableComponentsRequest
//
// ReadAvailableComponentsRequest is a the request struct for the read available-components request.
//
// swagger:model
type ReadAvailableComponentsRequest struct {
ReadRequest
}

// ReadAvailableComponentsResponse
//
// ReadAvailableComponentsResponse is a the response struct for the read available-components response.
//
// swagger:model
type ReadAvailableComponentsResponse struct {
AvailableComponents []string `yaml:"availableComponents" json:"availableComponents" xml:"availableComponents"`
ReadResponse
}
19 changes: 19 additions & 0 deletions core/request/read_available_components_process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// +build !client

package request

import (
"context"
"github.com/pkg/errors"
)

func (r *ReadAvailableComponentsRequest) process(ctx context.Context) (Response, error) {
com, err := GetCommunicator(ctx, r.BaseRequest)
if err != nil {
return nil, errors.Wrap(err, "failed to get communicator")
}

return &ReadAvailableComponentsResponse{
AvailableComponents: com.GetAvailableComponents(),
}, nil
}
2 changes: 1 addition & 1 deletion doc/api_doc.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"title": "Thola",
"license": {
"name": "BSD",
"url": "https://github.com/inexio/thola/blob/master/LICENSE"
"url": "https://github.com/inexio/thola/blob/main/LICENSE"
},
"version": "1.0.0"
},
Expand Down
2 changes: 1 addition & 1 deletion doc/docs.go → doc/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// Schemes: http, https
// Host: localhost:8237
// Version: 1.0.0
// License: BSD https://github.com/inexio/thola/blob/master/LICENSE
// License: BSD https://github.com/inexio/thola/blob/main/LICENSE
// Consumes:
// - application/json
// - application/xml
Expand Down

0 comments on commit 5855aa7

Please sign in to comment.