MG-28 - Align Bootstrap with SuperMQ (#31)
Continuous Delivery / Build and Push (push) Has been cancelled
Check License Header / check-license (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled

* refactor: aligh bootstrap with new supermq architecture

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* feat: add sdk and update api docs

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* refactor: rename env variables

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* style: add empty line to config files and bootstrap docker compose file

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* refactor: add supermq sdk to magistrala sdk

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* refactor: extend supermq sdk in magistrala sdk

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* reafctor: update responses

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

* ci: update api docs dir in swagger-ui deployment

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>

---------

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
This commit is contained in:
Felix Gateru
2025-01-10 16:56:17 +03:00
committed by GitHub
parent 3f0bb258c7
commit ec71a5edfd
52 changed files with 7865 additions and 298 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
id: swagger-ui-action
uses: blokovi/swagger-ui-action@main
with:
dir: "./api/openapi"
dir: "./apidocs/openapi"
pattern: "*.yml"
debug: "true"
+1 -1
View File
@@ -15,7 +15,7 @@ USER_REPO ?= $(shell git remote get-url origin | sed -e 's/.*\/\([^/]*\)\/\([^/]
empty:=
space:= $(empty) $(empty)
# Docker compose project name should follow this guidelines: https://docs.docker.com/compose/reference/#use--p-to-specify-a-project-name
DOCKER_PROJECT ?= test #$(shell echo $(subst $(space),,$(USER_REPO)) | tr -c -s '[:alnum:][=-=]' '_' | tr '[:upper:]' '[:lower:]')
DOCKER_PROJECT ?= $(shell echo $(subst $(space),,$(USER_REPO)) | tr -c -s '[:alnum:][=-=]' '_' | tr '[:upper:]' '[:lower:]')
DOCKER_COMPOSE_COMMANDS_SUPPORTED := up down config
DEFAULT_DOCKER_COMPOSE_COMMAND := up
GRPC_MTLS_CERT_FILES_EXISTS = 0
+75
View File
@@ -0,0 +1,75 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package api
import (
"context"
"encoding/json"
"net/http"
"github.com/absmach/magistrala/bootstrap"
api "github.com/absmach/supermq/api/http"
apiutil "github.com/absmach/supermq/api/http/util"
"github.com/absmach/supermq/pkg/errors"
)
// EncodeError encodes an error response.
func EncodeError(ctx context.Context, err error, w http.ResponseWriter) {
var wrapper error
if errors.Contains(err, apiutil.ErrValidation) {
wrapper, err = errors.Unwrap(err)
}
w.Header().Set("Content-Type", api.ContentType)
status, nerr := toStatus(err)
if nerr != nil {
err = unwrap(err)
w.WriteHeader(status)
encodeErrorMessage(err, wrapper, w)
return
}
if wrapper != nil {
err = errors.Wrap(wrapper, err)
}
api.EncodeError(ctx, err, w)
}
func toStatus(err error) (int, error) {
switch {
case errors.Contains(err, bootstrap.ErrExternalKey),
errors.Contains(err, bootstrap.ErrExternalKeySecure):
return http.StatusForbidden, err
case errors.Contains(err, bootstrap.ErrBootstrapState),
errors.Contains(err, bootstrap.ErrAddBootstrap):
return http.StatusBadRequest, err
case errors.Contains(err, bootstrap.ErrBootstrap):
return http.StatusNotFound, err
default:
return 0, nil
}
}
func encodeErrorMessage(err, wrapper error, w http.ResponseWriter) {
if wrapper != nil {
err = errors.Wrap(wrapper, err)
}
if errorVal, ok := err.(errors.Error); ok {
if err := json.NewEncoder(w).Encode(errorVal); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
}
func unwrap(err error) error {
wrapper, err := errors.Unwrap(err)
if wrapper != nil {
return wrapper
}
return err
}
@@ -5,7 +5,7 @@ openapi: 3.0.1
info:
title: Magistrala Bootstrap service
description: |
HTTP API for managing platform things configuration.
HTTP API for managing platform clients configuration.
Some useful links:
- [The Magistrala repository](https://github.com/absmach/magistrala)
contact:
@@ -13,7 +13,7 @@ info:
license:
name: Apache 2.0
url: https://github.com/absmach/magistrala/blob/main/LICENSE
version: 0.14.0
version: 0.15.1
servers:
- url: http://localhost:9013
@@ -27,7 +27,7 @@ tags:
url: https://docs.magistrala.abstractmachines.fr/
paths:
/{domainID}/things/configs:
/{domainID}/clients/configs:
post:
operationId: createConfig
summary: Adds new config
@@ -37,7 +37,7 @@ paths:
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
requestBody:
$ref: "#/components/requestBodies/ConfigCreateReq"
responses:
@@ -60,7 +60,7 @@ paths:
"500":
$ref: "#/components/responses/ServiceError"
"503":
description: Failed to receive response from the things service.
description: Failed to receive response from the clients service.
get:
operationId: getConfigs
summary: Retrieves managed configs
@@ -72,7 +72,7 @@ paths:
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Offset"
- $ref: "#/components/parameters/State"
@@ -88,14 +88,15 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/{domainID}/things/configs/{configId}:
/{domainID}/clients/configs/{configID}:
get:
operationId: getConfig
summary: Retrieves config info (with channels).
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
responses:
"200":
@@ -118,11 +119,11 @@ paths:
description: |
Update is performed by replacing the current resource data with values
provided in a request payload. Note that the owner, ID, external ID,
external key, Magistrala Thing ID and key cannot be changed.
external key, SuperMQ Client ID and key cannot be changed.
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
requestBody:
$ref: "#/components/requestBodies/ConfigUpdateReq"
@@ -148,11 +149,11 @@ paths:
summary: Removes a Config
description: |
Removes a Config. In case of successful removal the service will ensure
that the removed config is disconnected from all of the Magistrala channels.
that the removed config is disconnected from all of the SuperMQ channels.
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
responses:
"204":
@@ -167,7 +168,8 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/{domainID}/things/configs/certs/{configId}:
/{domainID}/clients/configs/certs/{configID}:
patch:
operationId: updateConfigCerts
summary: Updates certs
@@ -177,7 +179,7 @@ paths:
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
requestBody:
$ref: "#/components/requestBodies/ConfigCertUpdateReq"
@@ -199,17 +201,18 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/{domainID}/things/configs/connections/{configId}:
/{domainID}/clients/configs/connections/{configID}:
put:
operationId: updateConfigConnections
summary: Updates channels the thing is connected to
summary: Updates channels the client is connected to
description: |
Update connections performs update of the channel list corresponding
Thing is connected to.
Client is connected to.
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
requestBody:
$ref: "#/components/requestBodies/ConfigConnUpdateReq"
@@ -230,7 +233,8 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/things/bootstrap/{externalId}:
/clients/bootstrap/{externalId}:
get:
operationId: getBootstrapConfig
summary: Retrieves configuration.
@@ -255,7 +259,8 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/things/bootstrap/secure/{externalId}:
/clients/bootstrap/secure/{externalId}:
get:
operationId: getSecureBootstrapConfig
summary: Retrieves configuration.
@@ -281,17 +286,18 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/{domainID}/things/state/{configId}:
/{domainID}/clients/state/{configID}:
put:
operationId: updateConfigState
summary: Updates Config state.
description: |
Updating state represents enabling/disabling Config, i.e. connecting
and disconnecting corresponding Magistrala Thing to the list of Channels.
and disconnecting corresponding SuperMQ Client to the list of Channels.
tags:
- configs
parameters:
- $ref: "auth.yml#/components/parameters/DomainID"
- $ref: "#/components/parameters/DomainID"
- $ref: "#/components/parameters/ConfigId"
requestBody:
$ref: "#/components/requestBodies/ConfigStateUpdateReq"
@@ -310,6 +316,7 @@ paths:
description: Database can't process request.
"500":
$ref: "#/components/responses/ServiceError"
/health:
get:
summary: Retrieves service health check info.
@@ -330,14 +337,14 @@ components:
Config:
type: object
properties:
thing_id:
client_id:
type: string
format: uuid
description: Corresponding Magistrala Thing ID.
magistrala_key:
description: Corresponding SuperMQ Client ID.
magistrala_secret:
type: string
format: uuid
description: Corresponding Magistrala Thing key.
description: Corresponding SuperMQ Client key.
channels:
type: array
minItems: 0
@@ -402,14 +409,14 @@ components:
BootstrapConfig:
type: object
properties:
thing_id:
client_id:
type: string
format: uuid
description: Corresponding Magistrala Thing ID.
thing_key:
description: Corresponding SuperMQ Client ID.
client_key:
type: string
format: uuid
description: Corresponding Magistrala Thing key.
description: Corresponding SuperMQ Client key.
channels:
type: array
minItems: 0
@@ -421,24 +428,18 @@ components:
client_cert:
type: string
description: Client certificate.
client_key:
type: string
description: Key for the client_cert.
ca_cert:
type: string
description: Issuing CA certificate.
required:
- thing_id
- thing_key
- client_id
- client_key
- channels
- content
ConfigUpdateCerts:
type: object
properties:
thing_id:
client_id:
type: string
format: uuid
description: Corresponding Magistrala Thing ID.
description: Corresponding SuperMQ Client ID.
client_cert:
type: string
description: Client certificate.
@@ -449,15 +450,15 @@ components:
type: string
description: Issuing CA certificate.
required:
- thing_id
- thing_key
- client_id
- client_key
- channels
- content
parameters:
ConfigId:
name: configId
description: Unique Config identifier. It's the ID of the corresponding Thing.
name: configID
description: Unique Config identifier. It's the ID of the corresponding Client.
in: path
schema:
type: string
@@ -503,6 +504,15 @@ components:
schema:
type: string
required: false
DomainID:
name: domainID
description: Unique domain identifier.
in: path
schema:
type: string
format: uuid
required: true
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
requestBodies:
ConfigCreateReq:
@@ -519,10 +529,10 @@ components:
external_key:
type: string
description: External key.
thing_id:
client_id:
type: string
format: uuid
description: ID of the corresponding Magistrala Thing.
description: ID of the corresponding SuperMQ Client.
channels:
type: array
minItems: 0
@@ -535,17 +545,17 @@ components:
type: string
client_cert:
type: string
description: Thing Certificate.
description: Client Certificate.
client_key:
type: string
description: Thing Private Key.
description: Client Private Key.
ca_cert:
type: string
required:
- external_id
- external_key
ConfigUpdateReq:
description: JSON-formatted document describing the updated thing.
description: JSON-formatted document describing the updated client.
content:
application/json:
schema:
@@ -559,7 +569,7 @@ components:
- content
- name
ConfigCertUpdateReq:
description: JSON-formatted document describing the updated thing.
description: JSON-formatted document describing the updated client.
content:
application/json:
schema:
@@ -572,7 +582,7 @@ components:
ca_cert:
type: string
ConfigConnUpdateReq:
description: Array if IDs the thing is be connected to.
description: Array if IDs the client is be connected to.
content:
application/json:
schema:
@@ -603,7 +613,7 @@ components:
text/plain:
schema:
type: string
description: Created configuration's relative URL (i.e. /things/configs/{configId}).
description: Created configuration's relative URL (i.e. /clients/configs/{configID}).
ConfigListRes:
description: Data retrieved. Configs from this list don't contain channels.
content:
@@ -620,23 +630,23 @@ components:
update:
operationId: updateConfig
parameters:
configId: $response.body#/id
configID: $response.body#/id
updateCerts:
operationId: updateConfigCerts
parameters:
configId: $response.body#/id
configID: $response.body#/id
updateConnections:
operationId: updateConfigConnections
parameters:
configId: $response.body#/id
configID: $response.body#/id
updateState:
operationId: updateConfigState
parameters:
configId: $response.body#/id
configID: $response.body#/id
delete:
operationId: removeConfig
parameters:
configId: $response.body#/id
configID: $response.body#/id
BootstrapConfigRes:
description: |
Data retrieved. If secure, a response is encrypted using
@@ -652,7 +662,7 @@ components:
content:
application/health+json:
schema:
$ref: "./schemas/HealthInfo.yml"
$ref: "./schemas/health_info.yml"
ConfigUpdateCertsRes:
description: Data retrieved. Config certs updated.
content:
@@ -673,14 +683,14 @@ components:
scheme: bearer
bearerFormat: string
description: |
* Things access: "Authorization: Thing <external_key>"
* Clients access: "Authorization: Client <external_key>"
bootstrapEncAuth:
type: http
scheme: bearer
bearerFormat: aes-sha256-uuid
description: |
* Things access: "Authorization: Thing <external_enc_key>"
* Clients access: "Authorization: Client <external_enc_key>"
Hex-encoded configuration external key encrypted using
the AES algorithm and SHA256 sum of the external key
itself as an encryption key.
+192
View File
@@ -0,0 +1,192 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
context "context"
grpc "google.golang.org/grpc"
mock "github.com/stretchr/testify/mock"
v1 "github.com/absmach/supermq/api/grpc/token/v1"
)
// TokenServiceClient is an autogenerated mock type for the TokenServiceClient type
type TokenServiceClient struct {
mock.Mock
}
type TokenServiceClient_Expecter struct {
mock *mock.Mock
}
func (_m *TokenServiceClient) EXPECT() *TokenServiceClient_Expecter {
return &TokenServiceClient_Expecter{mock: &_m.Mock}
}
// Issue provides a mock function with given fields: ctx, in, opts
func (_m *TokenServiceClient) Issue(ctx context.Context, in *v1.IssueReq, opts ...grpc.CallOption) (*v1.Token, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Issue")
}
var r0 *v1.Token
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.IssueReq, ...grpc.CallOption) (*v1.Token, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.IssueReq, ...grpc.CallOption) *v1.Token); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.Token)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.IssueReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TokenServiceClient_Issue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Issue'
type TokenServiceClient_Issue_Call struct {
*mock.Call
}
// Issue is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.IssueReq
// - opts ...grpc.CallOption
func (_e *TokenServiceClient_Expecter) Issue(ctx interface{}, in interface{}, opts ...interface{}) *TokenServiceClient_Issue_Call {
return &TokenServiceClient_Issue_Call{Call: _e.mock.On("Issue",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *TokenServiceClient_Issue_Call) Run(run func(ctx context.Context, in *v1.IssueReq, opts ...grpc.CallOption)) *TokenServiceClient_Issue_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.IssueReq), variadicArgs...)
})
return _c
}
func (_c *TokenServiceClient_Issue_Call) Return(_a0 *v1.Token, _a1 error) *TokenServiceClient_Issue_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *TokenServiceClient_Issue_Call) RunAndReturn(run func(context.Context, *v1.IssueReq, ...grpc.CallOption) (*v1.Token, error)) *TokenServiceClient_Issue_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: ctx, in, opts
func (_m *TokenServiceClient) Refresh(ctx context.Context, in *v1.RefreshReq, opts ...grpc.CallOption) (*v1.Token, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *v1.Token
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RefreshReq, ...grpc.CallOption) (*v1.Token, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RefreshReq, ...grpc.CallOption) *v1.Token); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.Token)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RefreshReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TokenServiceClient_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type TokenServiceClient_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RefreshReq
// - opts ...grpc.CallOption
func (_e *TokenServiceClient_Expecter) Refresh(ctx interface{}, in interface{}, opts ...interface{}) *TokenServiceClient_Refresh_Call {
return &TokenServiceClient_Refresh_Call{Call: _e.mock.On("Refresh",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *TokenServiceClient_Refresh_Call) Run(run func(ctx context.Context, in *v1.RefreshReq, opts ...grpc.CallOption)) *TokenServiceClient_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RefreshReq), variadicArgs...)
})
return _c
}
func (_c *TokenServiceClient_Refresh_Call) Return(_a0 *v1.Token, _a1 error) *TokenServiceClient_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *TokenServiceClient_Refresh_Call) RunAndReturn(run func(context.Context, *v1.RefreshReq, ...grpc.CallOption) (*v1.Token, error)) *TokenServiceClient_Refresh_Call {
_c.Call.Return(run)
return _c
}
// NewTokenServiceClient creates a new instance of TokenServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewTokenServiceClient(t interface {
mock.TestingT
Cleanup(func())
}) *TokenServiceClient {
mock := &TokenServiceClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+1 -1
View File
@@ -156,7 +156,7 @@ func (req changeStateReq) validate() error {
if req.State != bootstrap.Inactive &&
req.State != bootstrap.Active {
return apiutil.ErrBootstrapState
return bootstrap.ErrBootstrapState
}
return nil
+1 -1
View File
@@ -296,7 +296,7 @@ func TestChangeStateReqValidation(t *testing.T) {
token: "token",
id: "id",
state: bootstrap.State(14),
err: apiutil.ErrBootstrapState,
err: bootstrap.ErrBootstrapState,
},
}
+2 -1
View File
@@ -11,6 +11,7 @@ import (
"net/url"
"strings"
mgapi "github.com/absmach/magistrala/api"
"github.com/absmach/magistrala/bootstrap"
"github.com/absmach/supermq"
api "github.com/absmach/supermq/api/http"
@@ -42,7 +43,7 @@ var (
// MakeHandler returns a HTTP handler for API endpoints.
func MakeHandler(svc bootstrap.Service, authn smqauthn.Authentication, reader bootstrap.ConfigReader, logger *slog.Logger, instanceID string) http.Handler {
opts := []kithttp.ServerOption{
kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, api.EncodeError)),
kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, mgapi.EncodeError)),
}
r := chi.NewRouter()
+11 -5
View File
@@ -13,6 +13,12 @@ import (
"github.com/absmach/supermq/pkg/policies"
)
const (
updatePermission = "update_permission"
readPermission = "read_permission"
deletePermission = "delete_permission"
)
var _ bootstrap.Service = (*authorizationMiddleware)(nil)
type authorizationMiddleware struct {
@@ -37,7 +43,7 @@ func (am *authorizationMiddleware) Add(ctx context.Context, session smqauthn.Ses
}
func (am *authorizationMiddleware) View(ctx context.Context, session smqauthn.Session, id string) (bootstrap.Config, error) {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, policies.ViewPermission, policies.ClientType, id); err != nil {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, readPermission, policies.ClientType, id); err != nil {
return bootstrap.Config{}, err
}
@@ -45,7 +51,7 @@ func (am *authorizationMiddleware) View(ctx context.Context, session smqauthn.Se
}
func (am *authorizationMiddleware) Update(ctx context.Context, session smqauthn.Session, cfg bootstrap.Config) error {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, policies.EditPermission, policies.ClientType, cfg.ClientID); err != nil {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, updatePermission, policies.ClientType, cfg.ClientID); err != nil {
return err
}
@@ -53,7 +59,7 @@ func (am *authorizationMiddleware) Update(ctx context.Context, session smqauthn.
}
func (am *authorizationMiddleware) UpdateCert(ctx context.Context, session smqauthn.Session, clientID, clientCert, clientKey, caCert string) (bootstrap.Config, error) {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, policies.EditPermission, policies.ClientType, clientID); err != nil {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, updatePermission, policies.ClientType, clientID); err != nil {
return bootstrap.Config{}, err
}
@@ -61,7 +67,7 @@ func (am *authorizationMiddleware) UpdateCert(ctx context.Context, session smqau
}
func (am *authorizationMiddleware) UpdateConnections(ctx context.Context, session smqauthn.Session, token, id string, connections []string) error {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, policies.EditPermission, policies.ClientType, id); err != nil {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, updatePermission, policies.ClientType, id); err != nil {
return err
}
@@ -80,7 +86,7 @@ func (am *authorizationMiddleware) List(ctx context.Context, session smqauthn.Se
}
func (am *authorizationMiddleware) Remove(ctx context.Context, session smqauthn.Session, id string) error {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, policies.DeletePermission, policies.ClientType, id); err != nil {
if err := am.authorize(ctx, session.DomainID, policies.UserType, policies.UsersKind, session.DomainUserID, deletePermission, policies.ClientType, id); err != nil {
return err
}
+3
View File
@@ -35,6 +35,9 @@ var (
// ErrAddBootstrap indicates error in adding bootstrap configuration.
ErrAddBootstrap = errors.New("failed to add bootstrap configuration")
// ErrBootstrapState indicates an invalid bootstrap state.
ErrBootstrapState = errors.New("invalid bootstrap state")
// ErrNotInSameDomain indicates entities are not in the same domain.
errNotInSameDomain = errors.New("entities are not in the same domain")
+257
View File
@@ -0,0 +1,257 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
amcerts "github.com/absmach/supermq/certs/pki/amcerts"
mock "github.com/stretchr/testify/mock"
sdk "github.com/absmach/certs/sdk"
)
// Agent is an autogenerated mock type for the Agent type
type Agent struct {
mock.Mock
}
type Agent_Expecter struct {
mock *mock.Mock
}
func (_m *Agent) EXPECT() *Agent_Expecter {
return &Agent_Expecter{mock: &_m.Mock}
}
// Issue provides a mock function with given fields: entityId, ttl, ipAddrs
func (_m *Agent) Issue(entityId string, ttl string, ipAddrs []string) (amcerts.Cert, error) {
ret := _m.Called(entityId, ttl, ipAddrs)
if len(ret) == 0 {
panic("no return value specified for Issue")
}
var r0 amcerts.Cert
var r1 error
if rf, ok := ret.Get(0).(func(string, string, []string) (amcerts.Cert, error)); ok {
return rf(entityId, ttl, ipAddrs)
}
if rf, ok := ret.Get(0).(func(string, string, []string) amcerts.Cert); ok {
r0 = rf(entityId, ttl, ipAddrs)
} else {
r0 = ret.Get(0).(amcerts.Cert)
}
if rf, ok := ret.Get(1).(func(string, string, []string) error); ok {
r1 = rf(entityId, ttl, ipAddrs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Agent_Issue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Issue'
type Agent_Issue_Call struct {
*mock.Call
}
// Issue is a helper method to define mock.On call
// - entityId string
// - ttl string
// - ipAddrs []string
func (_e *Agent_Expecter) Issue(entityId interface{}, ttl interface{}, ipAddrs interface{}) *Agent_Issue_Call {
return &Agent_Issue_Call{Call: _e.mock.On("Issue", entityId, ttl, ipAddrs)}
}
func (_c *Agent_Issue_Call) Run(run func(entityId string, ttl string, ipAddrs []string)) *Agent_Issue_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string), args[2].([]string))
})
return _c
}
func (_c *Agent_Issue_Call) Return(_a0 amcerts.Cert, _a1 error) *Agent_Issue_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *Agent_Issue_Call) RunAndReturn(run func(string, string, []string) (amcerts.Cert, error)) *Agent_Issue_Call {
_c.Call.Return(run)
return _c
}
// ListCerts provides a mock function with given fields: pm
func (_m *Agent) ListCerts(pm sdk.PageMetadata) (amcerts.CertPage, error) {
ret := _m.Called(pm)
if len(ret) == 0 {
panic("no return value specified for ListCerts")
}
var r0 amcerts.CertPage
var r1 error
if rf, ok := ret.Get(0).(func(sdk.PageMetadata) (amcerts.CertPage, error)); ok {
return rf(pm)
}
if rf, ok := ret.Get(0).(func(sdk.PageMetadata) amcerts.CertPage); ok {
r0 = rf(pm)
} else {
r0 = ret.Get(0).(amcerts.CertPage)
}
if rf, ok := ret.Get(1).(func(sdk.PageMetadata) error); ok {
r1 = rf(pm)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Agent_ListCerts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListCerts'
type Agent_ListCerts_Call struct {
*mock.Call
}
// ListCerts is a helper method to define mock.On call
// - pm sdk.PageMetadata
func (_e *Agent_Expecter) ListCerts(pm interface{}) *Agent_ListCerts_Call {
return &Agent_ListCerts_Call{Call: _e.mock.On("ListCerts", pm)}
}
func (_c *Agent_ListCerts_Call) Run(run func(pm sdk.PageMetadata)) *Agent_ListCerts_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(sdk.PageMetadata))
})
return _c
}
func (_c *Agent_ListCerts_Call) Return(_a0 amcerts.CertPage, _a1 error) *Agent_ListCerts_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *Agent_ListCerts_Call) RunAndReturn(run func(sdk.PageMetadata) (amcerts.CertPage, error)) *Agent_ListCerts_Call {
_c.Call.Return(run)
return _c
}
// Revoke provides a mock function with given fields: serialNumber
func (_m *Agent) Revoke(serialNumber string) error {
ret := _m.Called(serialNumber)
if len(ret) == 0 {
panic("no return value specified for Revoke")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(serialNumber)
} else {
r0 = ret.Error(0)
}
return r0
}
// Agent_Revoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Revoke'
type Agent_Revoke_Call struct {
*mock.Call
}
// Revoke is a helper method to define mock.On call
// - serialNumber string
func (_e *Agent_Expecter) Revoke(serialNumber interface{}) *Agent_Revoke_Call {
return &Agent_Revoke_Call{Call: _e.mock.On("Revoke", serialNumber)}
}
func (_c *Agent_Revoke_Call) Run(run func(serialNumber string)) *Agent_Revoke_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *Agent_Revoke_Call) Return(_a0 error) *Agent_Revoke_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *Agent_Revoke_Call) RunAndReturn(run func(string) error) *Agent_Revoke_Call {
_c.Call.Return(run)
return _c
}
// View provides a mock function with given fields: serialNumber
func (_m *Agent) View(serialNumber string) (amcerts.Cert, error) {
ret := _m.Called(serialNumber)
if len(ret) == 0 {
panic("no return value specified for View")
}
var r0 amcerts.Cert
var r1 error
if rf, ok := ret.Get(0).(func(string) (amcerts.Cert, error)); ok {
return rf(serialNumber)
}
if rf, ok := ret.Get(0).(func(string) amcerts.Cert); ok {
r0 = rf(serialNumber)
} else {
r0 = ret.Get(0).(amcerts.Cert)
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(serialNumber)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Agent_View_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'View'
type Agent_View_Call struct {
*mock.Call
}
// View is a helper method to define mock.On call
// - serialNumber string
func (_e *Agent_Expecter) View(serialNumber interface{}) *Agent_View_Call {
return &Agent_View_Call{Call: _e.mock.On("View", serialNumber)}
}
func (_c *Agent_View_Call) Run(run func(serialNumber string)) *Agent_View_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *Agent_View_Call) Return(_a0 amcerts.Cert, _a1 error) *Agent_View_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *Agent_View_Call) RunAndReturn(run func(string) (amcerts.Cert, error)) *Agent_View_Call {
_c.Call.Return(run)
return _c
}
// NewAgent creates a new instance of Agent. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewAgent(t interface {
mock.TestingT
Cleanup(func())
}) *Agent {
mock := &Agent{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+342
View File
@@ -0,0 +1,342 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
context "context"
commonv1 "github.com/absmach/supermq/api/grpc/common/v1"
grpc "google.golang.org/grpc"
mock "github.com/stretchr/testify/mock"
v1 "github.com/absmach/supermq/api/grpc/channels/v1"
)
// ChannelsServiceClient is an autogenerated mock type for the ChannelsServiceClient type
type ChannelsServiceClient struct {
mock.Mock
}
type ChannelsServiceClient_Expecter struct {
mock *mock.Mock
}
func (_m *ChannelsServiceClient) EXPECT() *ChannelsServiceClient_Expecter {
return &ChannelsServiceClient_Expecter{mock: &_m.Mock}
}
// Authorize provides a mock function with given fields: ctx, in, opts
func (_m *ChannelsServiceClient) Authorize(ctx context.Context, in *v1.AuthzReq, opts ...grpc.CallOption) (*v1.AuthzRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Authorize")
}
var r0 *v1.AuthzRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.AuthzReq, ...grpc.CallOption) (*v1.AuthzRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.AuthzReq, ...grpc.CallOption) *v1.AuthzRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.AuthzRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.AuthzReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ChannelsServiceClient_Authorize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Authorize'
type ChannelsServiceClient_Authorize_Call struct {
*mock.Call
}
// Authorize is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.AuthzReq
// - opts ...grpc.CallOption
func (_e *ChannelsServiceClient_Expecter) Authorize(ctx interface{}, in interface{}, opts ...interface{}) *ChannelsServiceClient_Authorize_Call {
return &ChannelsServiceClient_Authorize_Call{Call: _e.mock.On("Authorize",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ChannelsServiceClient_Authorize_Call) Run(run func(ctx context.Context, in *v1.AuthzReq, opts ...grpc.CallOption)) *ChannelsServiceClient_Authorize_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.AuthzReq), variadicArgs...)
})
return _c
}
func (_c *ChannelsServiceClient_Authorize_Call) Return(_a0 *v1.AuthzRes, _a1 error) *ChannelsServiceClient_Authorize_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ChannelsServiceClient_Authorize_Call) RunAndReturn(run func(context.Context, *v1.AuthzReq, ...grpc.CallOption) (*v1.AuthzRes, error)) *ChannelsServiceClient_Authorize_Call {
_c.Call.Return(run)
return _c
}
// RemoveClientConnections provides a mock function with given fields: ctx, in, opts
func (_m *ChannelsServiceClient) RemoveClientConnections(ctx context.Context, in *v1.RemoveClientConnectionsReq, opts ...grpc.CallOption) (*v1.RemoveClientConnectionsRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RemoveClientConnections")
}
var r0 *v1.RemoveClientConnectionsRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RemoveClientConnectionsReq, ...grpc.CallOption) (*v1.RemoveClientConnectionsRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RemoveClientConnectionsReq, ...grpc.CallOption) *v1.RemoveClientConnectionsRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.RemoveClientConnectionsRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RemoveClientConnectionsReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ChannelsServiceClient_RemoveClientConnections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveClientConnections'
type ChannelsServiceClient_RemoveClientConnections_Call struct {
*mock.Call
}
// RemoveClientConnections is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RemoveClientConnectionsReq
// - opts ...grpc.CallOption
func (_e *ChannelsServiceClient_Expecter) RemoveClientConnections(ctx interface{}, in interface{}, opts ...interface{}) *ChannelsServiceClient_RemoveClientConnections_Call {
return &ChannelsServiceClient_RemoveClientConnections_Call{Call: _e.mock.On("RemoveClientConnections",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ChannelsServiceClient_RemoveClientConnections_Call) Run(run func(ctx context.Context, in *v1.RemoveClientConnectionsReq, opts ...grpc.CallOption)) *ChannelsServiceClient_RemoveClientConnections_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RemoveClientConnectionsReq), variadicArgs...)
})
return _c
}
func (_c *ChannelsServiceClient_RemoveClientConnections_Call) Return(_a0 *v1.RemoveClientConnectionsRes, _a1 error) *ChannelsServiceClient_RemoveClientConnections_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ChannelsServiceClient_RemoveClientConnections_Call) RunAndReturn(run func(context.Context, *v1.RemoveClientConnectionsReq, ...grpc.CallOption) (*v1.RemoveClientConnectionsRes, error)) *ChannelsServiceClient_RemoveClientConnections_Call {
_c.Call.Return(run)
return _c
}
// RetrieveEntity provides a mock function with given fields: ctx, in, opts
func (_m *ChannelsServiceClient) RetrieveEntity(ctx context.Context, in *commonv1.RetrieveEntityReq, opts ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RetrieveEntity")
}
var r0 *commonv1.RetrieveEntityRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) *commonv1.RetrieveEntityRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*commonv1.RetrieveEntityRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ChannelsServiceClient_RetrieveEntity_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveEntity'
type ChannelsServiceClient_RetrieveEntity_Call struct {
*mock.Call
}
// RetrieveEntity is a helper method to define mock.On call
// - ctx context.Context
// - in *commonv1.RetrieveEntityReq
// - opts ...grpc.CallOption
func (_e *ChannelsServiceClient_Expecter) RetrieveEntity(ctx interface{}, in interface{}, opts ...interface{}) *ChannelsServiceClient_RetrieveEntity_Call {
return &ChannelsServiceClient_RetrieveEntity_Call{Call: _e.mock.On("RetrieveEntity",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ChannelsServiceClient_RetrieveEntity_Call) Run(run func(ctx context.Context, in *commonv1.RetrieveEntityReq, opts ...grpc.CallOption)) *ChannelsServiceClient_RetrieveEntity_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*commonv1.RetrieveEntityReq), variadicArgs...)
})
return _c
}
func (_c *ChannelsServiceClient_RetrieveEntity_Call) Return(_a0 *commonv1.RetrieveEntityRes, _a1 error) *ChannelsServiceClient_RetrieveEntity_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ChannelsServiceClient_RetrieveEntity_Call) RunAndReturn(run func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error)) *ChannelsServiceClient_RetrieveEntity_Call {
_c.Call.Return(run)
return _c
}
// UnsetParentGroupFromChannels provides a mock function with given fields: ctx, in, opts
func (_m *ChannelsServiceClient) UnsetParentGroupFromChannels(ctx context.Context, in *v1.UnsetParentGroupFromChannelsReq, opts ...grpc.CallOption) (*v1.UnsetParentGroupFromChannelsRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for UnsetParentGroupFromChannels")
}
var r0 *v1.UnsetParentGroupFromChannelsRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.UnsetParentGroupFromChannelsReq, ...grpc.CallOption) (*v1.UnsetParentGroupFromChannelsRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.UnsetParentGroupFromChannelsReq, ...grpc.CallOption) *v1.UnsetParentGroupFromChannelsRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.UnsetParentGroupFromChannelsRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.UnsetParentGroupFromChannelsReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ChannelsServiceClient_UnsetParentGroupFromChannels_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnsetParentGroupFromChannels'
type ChannelsServiceClient_UnsetParentGroupFromChannels_Call struct {
*mock.Call
}
// UnsetParentGroupFromChannels is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.UnsetParentGroupFromChannelsReq
// - opts ...grpc.CallOption
func (_e *ChannelsServiceClient_Expecter) UnsetParentGroupFromChannels(ctx interface{}, in interface{}, opts ...interface{}) *ChannelsServiceClient_UnsetParentGroupFromChannels_Call {
return &ChannelsServiceClient_UnsetParentGroupFromChannels_Call{Call: _e.mock.On("UnsetParentGroupFromChannels",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ChannelsServiceClient_UnsetParentGroupFromChannels_Call) Run(run func(ctx context.Context, in *v1.UnsetParentGroupFromChannelsReq, opts ...grpc.CallOption)) *ChannelsServiceClient_UnsetParentGroupFromChannels_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.UnsetParentGroupFromChannelsReq), variadicArgs...)
})
return _c
}
func (_c *ChannelsServiceClient_UnsetParentGroupFromChannels_Call) Return(_a0 *v1.UnsetParentGroupFromChannelsRes, _a1 error) *ChannelsServiceClient_UnsetParentGroupFromChannels_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ChannelsServiceClient_UnsetParentGroupFromChannels_Call) RunAndReturn(run func(context.Context, *v1.UnsetParentGroupFromChannelsReq, ...grpc.CallOption) (*v1.UnsetParentGroupFromChannelsRes, error)) *ChannelsServiceClient_UnsetParentGroupFromChannels_Call {
_c.Call.Return(run)
return _c
}
// NewChannelsServiceClient creates a new instance of ChannelsServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewChannelsServiceClient(t interface {
mock.TestingT
Cleanup(func())
}) *ChannelsServiceClient {
mock := &ChannelsServiceClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+564
View File
@@ -0,0 +1,564 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
context "context"
clientsv1 "github.com/absmach/supermq/api/grpc/clients/v1"
grpc "google.golang.org/grpc"
mock "github.com/stretchr/testify/mock"
v1 "github.com/absmach/supermq/api/grpc/common/v1"
)
// ClientsServiceClient is an autogenerated mock type for the ClientsServiceClient type
type ClientsServiceClient struct {
mock.Mock
}
type ClientsServiceClient_Expecter struct {
mock *mock.Mock
}
func (_m *ClientsServiceClient) EXPECT() *ClientsServiceClient_Expecter {
return &ClientsServiceClient_Expecter{mock: &_m.Mock}
}
// AddConnections provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) AddConnections(ctx context.Context, in *v1.AddConnectionsReq, opts ...grpc.CallOption) (*v1.AddConnectionsRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for AddConnections")
}
var r0 *v1.AddConnectionsRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.AddConnectionsReq, ...grpc.CallOption) (*v1.AddConnectionsRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.AddConnectionsReq, ...grpc.CallOption) *v1.AddConnectionsRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.AddConnectionsRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.AddConnectionsReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_AddConnections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddConnections'
type ClientsServiceClient_AddConnections_Call struct {
*mock.Call
}
// AddConnections is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.AddConnectionsReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) AddConnections(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_AddConnections_Call {
return &ClientsServiceClient_AddConnections_Call{Call: _e.mock.On("AddConnections",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_AddConnections_Call) Run(run func(ctx context.Context, in *v1.AddConnectionsReq, opts ...grpc.CallOption)) *ClientsServiceClient_AddConnections_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.AddConnectionsReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_AddConnections_Call) Return(_a0 *v1.AddConnectionsRes, _a1 error) *ClientsServiceClient_AddConnections_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_AddConnections_Call) RunAndReturn(run func(context.Context, *v1.AddConnectionsReq, ...grpc.CallOption) (*v1.AddConnectionsRes, error)) *ClientsServiceClient_AddConnections_Call {
_c.Call.Return(run)
return _c
}
// Authenticate provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) Authenticate(ctx context.Context, in *clientsv1.AuthnReq, opts ...grpc.CallOption) (*clientsv1.AuthnRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Authenticate")
}
var r0 *clientsv1.AuthnRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.AuthnReq, ...grpc.CallOption) (*clientsv1.AuthnRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.AuthnReq, ...grpc.CallOption) *clientsv1.AuthnRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*clientsv1.AuthnRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *clientsv1.AuthnReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_Authenticate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Authenticate'
type ClientsServiceClient_Authenticate_Call struct {
*mock.Call
}
// Authenticate is a helper method to define mock.On call
// - ctx context.Context
// - in *clientsv1.AuthnReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) Authenticate(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_Authenticate_Call {
return &ClientsServiceClient_Authenticate_Call{Call: _e.mock.On("Authenticate",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_Authenticate_Call) Run(run func(ctx context.Context, in *clientsv1.AuthnReq, opts ...grpc.CallOption)) *ClientsServiceClient_Authenticate_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*clientsv1.AuthnReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_Authenticate_Call) Return(_a0 *clientsv1.AuthnRes, _a1 error) *ClientsServiceClient_Authenticate_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_Authenticate_Call) RunAndReturn(run func(context.Context, *clientsv1.AuthnReq, ...grpc.CallOption) (*clientsv1.AuthnRes, error)) *ClientsServiceClient_Authenticate_Call {
_c.Call.Return(run)
return _c
}
// RemoveChannelConnections provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) RemoveChannelConnections(ctx context.Context, in *clientsv1.RemoveChannelConnectionsReq, opts ...grpc.CallOption) (*clientsv1.RemoveChannelConnectionsRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RemoveChannelConnections")
}
var r0 *clientsv1.RemoveChannelConnectionsRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.RemoveChannelConnectionsReq, ...grpc.CallOption) (*clientsv1.RemoveChannelConnectionsRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.RemoveChannelConnectionsReq, ...grpc.CallOption) *clientsv1.RemoveChannelConnectionsRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*clientsv1.RemoveChannelConnectionsRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *clientsv1.RemoveChannelConnectionsReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_RemoveChannelConnections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveChannelConnections'
type ClientsServiceClient_RemoveChannelConnections_Call struct {
*mock.Call
}
// RemoveChannelConnections is a helper method to define mock.On call
// - ctx context.Context
// - in *clientsv1.RemoveChannelConnectionsReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) RemoveChannelConnections(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_RemoveChannelConnections_Call {
return &ClientsServiceClient_RemoveChannelConnections_Call{Call: _e.mock.On("RemoveChannelConnections",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_RemoveChannelConnections_Call) Run(run func(ctx context.Context, in *clientsv1.RemoveChannelConnectionsReq, opts ...grpc.CallOption)) *ClientsServiceClient_RemoveChannelConnections_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*clientsv1.RemoveChannelConnectionsReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_RemoveChannelConnections_Call) Return(_a0 *clientsv1.RemoveChannelConnectionsRes, _a1 error) *ClientsServiceClient_RemoveChannelConnections_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_RemoveChannelConnections_Call) RunAndReturn(run func(context.Context, *clientsv1.RemoveChannelConnectionsReq, ...grpc.CallOption) (*clientsv1.RemoveChannelConnectionsRes, error)) *ClientsServiceClient_RemoveChannelConnections_Call {
_c.Call.Return(run)
return _c
}
// RemoveConnections provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) RemoveConnections(ctx context.Context, in *v1.RemoveConnectionsReq, opts ...grpc.CallOption) (*v1.RemoveConnectionsRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RemoveConnections")
}
var r0 *v1.RemoveConnectionsRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RemoveConnectionsReq, ...grpc.CallOption) (*v1.RemoveConnectionsRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RemoveConnectionsReq, ...grpc.CallOption) *v1.RemoveConnectionsRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.RemoveConnectionsRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RemoveConnectionsReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_RemoveConnections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveConnections'
type ClientsServiceClient_RemoveConnections_Call struct {
*mock.Call
}
// RemoveConnections is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RemoveConnectionsReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) RemoveConnections(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_RemoveConnections_Call {
return &ClientsServiceClient_RemoveConnections_Call{Call: _e.mock.On("RemoveConnections",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_RemoveConnections_Call) Run(run func(ctx context.Context, in *v1.RemoveConnectionsReq, opts ...grpc.CallOption)) *ClientsServiceClient_RemoveConnections_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RemoveConnectionsReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_RemoveConnections_Call) Return(_a0 *v1.RemoveConnectionsRes, _a1 error) *ClientsServiceClient_RemoveConnections_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_RemoveConnections_Call) RunAndReturn(run func(context.Context, *v1.RemoveConnectionsReq, ...grpc.CallOption) (*v1.RemoveConnectionsRes, error)) *ClientsServiceClient_RemoveConnections_Call {
_c.Call.Return(run)
return _c
}
// RetrieveEntities provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) RetrieveEntities(ctx context.Context, in *v1.RetrieveEntitiesReq, opts ...grpc.CallOption) (*v1.RetrieveEntitiesRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RetrieveEntities")
}
var r0 *v1.RetrieveEntitiesRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntitiesReq, ...grpc.CallOption) (*v1.RetrieveEntitiesRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntitiesReq, ...grpc.CallOption) *v1.RetrieveEntitiesRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.RetrieveEntitiesRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RetrieveEntitiesReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_RetrieveEntities_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveEntities'
type ClientsServiceClient_RetrieveEntities_Call struct {
*mock.Call
}
// RetrieveEntities is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RetrieveEntitiesReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) RetrieveEntities(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_RetrieveEntities_Call {
return &ClientsServiceClient_RetrieveEntities_Call{Call: _e.mock.On("RetrieveEntities",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_RetrieveEntities_Call) Run(run func(ctx context.Context, in *v1.RetrieveEntitiesReq, opts ...grpc.CallOption)) *ClientsServiceClient_RetrieveEntities_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RetrieveEntitiesReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_RetrieveEntities_Call) Return(_a0 *v1.RetrieveEntitiesRes, _a1 error) *ClientsServiceClient_RetrieveEntities_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_RetrieveEntities_Call) RunAndReturn(run func(context.Context, *v1.RetrieveEntitiesReq, ...grpc.CallOption) (*v1.RetrieveEntitiesRes, error)) *ClientsServiceClient_RetrieveEntities_Call {
_c.Call.Return(run)
return _c
}
// RetrieveEntity provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RetrieveEntity")
}
var r0 *v1.RetrieveEntityRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) (*v1.RetrieveEntityRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) *v1.RetrieveEntityRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.RetrieveEntityRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_RetrieveEntity_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveEntity'
type ClientsServiceClient_RetrieveEntity_Call struct {
*mock.Call
}
// RetrieveEntity is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RetrieveEntityReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) RetrieveEntity(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_RetrieveEntity_Call {
return &ClientsServiceClient_RetrieveEntity_Call{Call: _e.mock.On("RetrieveEntity",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_RetrieveEntity_Call) Run(run func(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption)) *ClientsServiceClient_RetrieveEntity_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RetrieveEntityReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_RetrieveEntity_Call) Return(_a0 *v1.RetrieveEntityRes, _a1 error) *ClientsServiceClient_RetrieveEntity_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_RetrieveEntity_Call) RunAndReturn(run func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) (*v1.RetrieveEntityRes, error)) *ClientsServiceClient_RetrieveEntity_Call {
_c.Call.Return(run)
return _c
}
// UnsetParentGroupFromClient provides a mock function with given fields: ctx, in, opts
func (_m *ClientsServiceClient) UnsetParentGroupFromClient(ctx context.Context, in *clientsv1.UnsetParentGroupFromClientReq, opts ...grpc.CallOption) (*clientsv1.UnsetParentGroupFromClientRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for UnsetParentGroupFromClient")
}
var r0 *clientsv1.UnsetParentGroupFromClientRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.UnsetParentGroupFromClientReq, ...grpc.CallOption) (*clientsv1.UnsetParentGroupFromClientRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *clientsv1.UnsetParentGroupFromClientReq, ...grpc.CallOption) *clientsv1.UnsetParentGroupFromClientRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*clientsv1.UnsetParentGroupFromClientRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *clientsv1.UnsetParentGroupFromClientReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ClientsServiceClient_UnsetParentGroupFromClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnsetParentGroupFromClient'
type ClientsServiceClient_UnsetParentGroupFromClient_Call struct {
*mock.Call
}
// UnsetParentGroupFromClient is a helper method to define mock.On call
// - ctx context.Context
// - in *clientsv1.UnsetParentGroupFromClientReq
// - opts ...grpc.CallOption
func (_e *ClientsServiceClient_Expecter) UnsetParentGroupFromClient(ctx interface{}, in interface{}, opts ...interface{}) *ClientsServiceClient_UnsetParentGroupFromClient_Call {
return &ClientsServiceClient_UnsetParentGroupFromClient_Call{Call: _e.mock.On("UnsetParentGroupFromClient",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *ClientsServiceClient_UnsetParentGroupFromClient_Call) Run(run func(ctx context.Context, in *clientsv1.UnsetParentGroupFromClientReq, opts ...grpc.CallOption)) *ClientsServiceClient_UnsetParentGroupFromClient_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*clientsv1.UnsetParentGroupFromClientReq), variadicArgs...)
})
return _c
}
func (_c *ClientsServiceClient_UnsetParentGroupFromClient_Call) Return(_a0 *clientsv1.UnsetParentGroupFromClientRes, _a1 error) *ClientsServiceClient_UnsetParentGroupFromClient_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ClientsServiceClient_UnsetParentGroupFromClient_Call) RunAndReturn(run func(context.Context, *clientsv1.UnsetParentGroupFromClientReq, ...grpc.CallOption) (*clientsv1.UnsetParentGroupFromClientRes, error)) *ClientsServiceClient_UnsetParentGroupFromClient_Call {
_c.Call.Return(run)
return _c
}
// NewClientsServiceClient creates a new instance of ClientsServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewClientsServiceClient(t interface {
mock.TestingT
Cleanup(func())
}) *ClientsServiceClient {
mock := &ClientsServiceClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+17 -15
View File
@@ -50,8 +50,8 @@ import (
const (
svcName = "bootstrap"
envPrefixDB = "SMQ_BOOTSTRAP_DB_"
envPrefixHTTP = "SMQ_BOOTSTRAP_HTTP_"
envPrefixDB = "MG_BOOTSTRAP_DB_"
envPrefixHTTP = "MG_BOOTSTRAP_HTTP_"
envPrefixAuth = "SMQ_AUTH_GRPC_"
envPrefixDomains = "SMQ_DOMAINS_GRPC_"
defDB = "bootstrap"
@@ -62,18 +62,19 @@ const (
)
type config struct {
LogLevel string `env:"SMQ_BOOTSTRAP_LOG_LEVEL" envDefault:"info"`
EncKey string `env:"SMQ_BOOTSTRAP_ENCRYPT_KEY" envDefault:"12345678910111213141516171819202"`
ESConsumerName string `env:"SMQ_BOOTSTRAP_EVENT_CONSUMER" envDefault:"bootstrap"`
ClientsURL string `env:"SMQ_CLIENTS_URL" envDefault:"http://localhost:9000"`
JaegerURL url.URL `env:"SMQ_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"`
SendTelemetry bool `env:"SMQ_SEND_TELEMETRY" envDefault:"true"`
InstanceID string `env:"SMQ_BOOTSTRAP_INSTANCE_ID" envDefault:""`
ESURL string `env:"SMQ_ES_URL" envDefault:"nats://localhost:4222"`
TraceRatio float64 `env:"SMQ_JAEGER_TRACE_RATIO" envDefault:"1.0"`
SpicedbHost string `env:"SMQ_SPICEDB_HOST" envDefault:"localhost"`
SpicedbPort string `env:"SMQ_SPICEDB_PORT" envDefault:"50051"`
SpicedbPreSharedKey string `env:"SMQ_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"`
LogLevel string `env:"MG_BOOTSTRAP_LOG_LEVEL" envDefault:"info"`
EncKey string `env:"MG_BOOTSTRAP_ENCRYPT_KEY" envDefault:"12345678910111213141516171819202"`
ESConsumerName string `env:"MG_BOOTSTRAP_EVENT_CONSUMER" envDefault:"bootstrap"`
ClientsURL string `env:"SMQ_CLIENTS_URL" envDefault:"http://localhost:9006"`
ChannelsURL string `env:"SMQ_CHANNELS_URL" envDefault:"http://localhost:9005"`
JaegerURL url.URL `env:"SMQ_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"`
SendTelemetry bool `env:"SMQ_SEND_TELEMETRY" envDefault:"true"`
InstanceID string `env:"MG_BOOTSTRAP_INSTANCE_ID" envDefault:""`
ESURL string `env:"SMQ_ES_URL" envDefault:"nats://localhost:4222"`
TraceRatio float64 `env:"SMQ_JAEGER_TRACE_RATIO" envDefault:"1.0"`
SpicedbHost string `env:"SMQ_SPICEDB_HOST" envDefault:"localhost"`
SpicedbPort string `env:"SMQ_SPICEDB_PORT" envDefault:"50051"`
SpicedbPreSharedKey string `env:"SMQ_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"`
}
func main() {
@@ -221,7 +222,8 @@ func newService(ctx context.Context, authz smqauthz.Authorization, policySvc pol
repoConfig := bootstrappg.NewConfigRepository(database, logger)
config := mgsdk.Config{
ClientsURL: cfg.ClientsURL,
ClientsURL: cfg.ClientsURL,
ChannelsURL: cfg.ChannelsURL,
}
sdk := mgsdk.NewSDK(config)
+1 -1
View File
@@ -13,6 +13,7 @@ import (
"reflect"
chclient "github.com/absmach/callhome/pkg/client"
mgsdk "github.com/absmach/magistrala/pkg/sdk"
"github.com/absmach/magistrala/provision"
httpapi "github.com/absmach/magistrala/provision/api"
"github.com/absmach/supermq"
@@ -20,7 +21,6 @@ import (
"github.com/absmach/supermq/clients"
smqlog "github.com/absmach/supermq/logger"
"github.com/absmach/supermq/pkg/errors"
mgsdk "github.com/absmach/supermq/pkg/sdk"
"github.com/absmach/supermq/pkg/server"
httpserver "github.com/absmach/supermq/pkg/server/http"
"github.com/absmach/supermq/pkg/uuid"
+38 -38
View File
@@ -397,46 +397,46 @@ SMQ_WS_ADAPTER_INSTANCE_ID=
## Addons Services
### Bootstrap
SMQ_BOOTSTRAP_LOG_LEVEL=debug
SMQ_BOOTSTRAP_ENCRYPT_KEY=v7aT0HGxJxt2gULzr3RHwf4WIf6DusPp
SMQ_BOOTSTRAP_EVENT_CONSUMER=bootstrap
SMQ_BOOTSTRAP_HTTP_HOST=bootstrap
SMQ_BOOTSTRAP_HTTP_PORT=9013
SMQ_BOOTSTRAP_HTTP_SERVER_CERT=
SMQ_BOOTSTRAP_HTTP_SERVER_KEY=
SMQ_BOOTSTRAP_DB_HOST=bootstrap-db
SMQ_BOOTSTRAP_DB_PORT=5432
SMQ_BOOTSTRAP_DB_USER=supermq
SMQ_BOOTSTRAP_DB_PASS=supermq
SMQ_BOOTSTRAP_DB_NAME=bootstrap
SMQ_BOOTSTRAP_DB_SSL_MODE=disable
SMQ_BOOTSTRAP_DB_SSL_CERT=
SMQ_BOOTSTRAP_DB_SSL_KEY=
SMQ_BOOTSTRAP_DB_SSL_ROOT_CERT=
SMQ_BOOTSTRAP_INSTANCE_ID=
MG_BOOTSTRAP_LOG_LEVEL=debug
MG_BOOTSTRAP_ENCRYPT_KEY=v7aT0HGxJxt2gULzr3RHwf4WIf6DusPp
MG_BOOTSTRAP_EVENT_CONSUMER=bootstrap
MG_BOOTSTRAP_HTTP_HOST=bootstrap
MG_BOOTSTRAP_HTTP_PORT=9013
MG_BOOTSTRAP_HTTP_SERVER_CERT=
MG_BOOTSTRAP_HTTP_SERVER_KEY=
MG_BOOTSTRAP_DB_HOST=bootstrap-db
MG_BOOTSTRAP_DB_PORT=5432
MG_BOOTSTRAP_DB_USER=magistrala
MG_BOOTSTRAP_DB_PASS=magistrala
MG_BOOTSTRAP_DB_NAME=bootstrap
MG_BOOTSTRAP_DB_SSL_MODE=disable
MG_BOOTSTRAP_DB_SSL_CERT=
MG_BOOTSTRAP_DB_SSL_KEY=
MG_BOOTSTRAP_DB_SSL_ROOT_CERT=
MG_BOOTSTRAP_INSTANCE_ID=
### Provision
SMQ_PROVISION_CONFIG_FILE=/configs/config.toml
SMQ_PROVISION_LOG_LEVEL=debug
SMQ_PROVISION_HTTP_PORT=9016
SMQ_PROVISION_ENV_CLIENTS_TLS=false
SMQ_PROVISION_SERVER_CERT=
SMQ_PROVISION_SERVER_KEY=
SMQ_PROVISION_USERS_LOCATION=http://users:9002
SMQ_PROVISION_CLIENTS_LOCATION=http://clients:9006
SMQ_PROVISION_USER=
SMQ_PROVISION_USERNAME=
SMQ_PROVISION_PASS=
SMQ_PROVISION_API_KEY=
SMQ_PROVISION_CERTS_SVC_URL=http://certs:9019
SMQ_PROVISION_X509_PROVISIONING=false
SMQ_PROVISION_BS_SVC_URL=http://bootstrap:9013
SMQ_PROVISION_BS_CONFIG_PROVISIONING=true
SMQ_PROVISION_BS_AUTO_WHITELIST=true
SMQ_PROVISION_BS_CONTENT=
SMQ_PROVISION_CERTS_HOURS_VALID=2400h
SMQ_PROVISION_CERTS_RSA_BITS=2048
SMQ_PROVISION_INSTANCE_ID=
MG_PROVISION_CONFIG_FILE=/configs/config.toml
MG_PROVISION_LOG_LEVEL=debug
MG_PROVISION_HTTP_PORT=9016
MG_PROVISION_ENV_CLIENTS_TLS=false
MG_PROVISION_SERVER_CERT=
MG_PROVISION_SERVER_KEY=
MG_PROVISION_USERS_LOCATION=http://users:9002
MG_PROVISION_CLIENTS_LOCATION=http://clients:9006
MG_PROVISION_USER=
MG_PROVISION_USERNAME=
MG_PROVISION_PASS=
MG_PROVISION_API_KEY=
MG_PROVISION_CERTS_SVC_URL=http://certs:9019
MG_PROVISION_X509_PROVISIONING=false
MG_PROVISION_BS_SVC_URL=http://bootstrap:9013
MG_PROVISION_BS_CONFIG_PROVISIONING=true
MG_PROVISION_BS_AUTO_WHITELIST=true
MG_PROVISION_BS_CONTENT=
MG_PROVISION_CERTS_HOURS_VALID=2400h
MG_PROVISION_CERTS_RSA_BITS=2048
MG_PROVISION_INSTANCE_ID=
### Vault
SMQ_VAULT_HOST=vault
+26 -20
View File
@@ -27,7 +27,7 @@ services:
- magistrala-bootstrap-db-volume:/var/lib/postgresql/data
bootstrap:
image: magistrala/bootstrap:${MG_RELEASE_TAG}
image: ghcr.io/absmach/magistrala/bootstrap:${SMQ_RELEASE_TAG}
container_name: magistrala-bootstrap
depends_on:
- bootstrap-db
@@ -38,7 +38,7 @@ services:
MG_BOOTSTRAP_LOG_LEVEL: ${MG_BOOTSTRAP_LOG_LEVEL}
MG_BOOTSTRAP_ENCRYPT_KEY: ${MG_BOOTSTRAP_ENCRYPT_KEY}
MG_BOOTSTRAP_EVENT_CONSUMER: ${MG_BOOTSTRAP_EVENT_CONSUMER}
MG_ES_URL: ${MG_ES_URL}
SMQ_ES_URL: ${SMQ_ES_URL}
MG_BOOTSTRAP_HTTP_HOST: ${MG_BOOTSTRAP_HTTP_HOST}
MG_BOOTSTRAP_HTTP_PORT: ${MG_BOOTSTRAP_HTTP_PORT}
MG_BOOTSTRAP_HTTP_SERVER_CERT: ${MG_BOOTSTRAP_HTTP_SERVER_CERT}
@@ -52,34 +52,40 @@ services:
MG_BOOTSTRAP_DB_SSL_CERT: ${MG_BOOTSTRAP_DB_SSL_CERT}
MG_BOOTSTRAP_DB_SSL_KEY: ${MG_BOOTSTRAP_DB_SSL_KEY}
MG_BOOTSTRAP_DB_SSL_ROOT_CERT: ${MG_BOOTSTRAP_DB_SSL_ROOT_CERT}
MG_AUTH_GRPC_URL: ${MG_AUTH_GRPC_URL}
MG_AUTH_GRPC_TIMEOUT: ${MG_AUTH_GRPC_TIMEOUT}
MG_AUTH_GRPC_CLIENT_CERT: ${MG_AUTH_GRPC_CLIENT_CERT:+/auth-grpc-client.crt}
MG_AUTH_GRPC_CLIENT_KEY: ${MG_AUTH_GRPC_CLIENT_KEY:+/auth-grpc-client.key}
MG_AUTH_GRPC_SERVER_CA_CERTS: ${MG_AUTH_GRPC_SERVER_CA_CERTS:+/auth-grpc-server-ca.crt}
MG_THINGS_URL: ${MG_THINGS_URL}
MG_JAEGER_URL: ${MG_JAEGER_URL}
MG_JAEGER_TRACE_RATIO: ${MG_JAEGER_TRACE_RATIO}
MG_SEND_TELEMETRY: ${MG_SEND_TELEMETRY}
MG_BOOTSTRAP_INSTANCE_ID: ${MG_BOOTSTRAP_INSTANCE_ID}
MG_SPICEDB_PRE_SHARED_KEY: ${MG_SPICEDB_PRE_SHARED_KEY}
MG_SPICEDB_HOST: ${MG_SPICEDB_HOST}
MG_SPICEDB_PORT: ${MG_SPICEDB_PORT}
SMQ_AUTH_GRPC_URL: ${SMQ_AUTH_GRPC_URL}
SMQ_AUTH_GRPC_TIMEOUT: ${SMQ_AUTH_GRPC_TIMEOUT}
SMQ_AUTH_GRPC_CLIENT_CERT: ${SMQ_AUTH_GRPC_CLIENT_CERT:+/auth-grpc-client.crt}
SMQ_AUTH_GRPC_CLIENT_KEY: ${SMQ_AUTH_GRPC_CLIENT_KEY:+/auth-grpc-client.key}
SMQ_AUTH_GRPC_SERVER_CA_CERTS: ${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+/auth-grpc-server-ca.crt}
SMQ_DOMAINS_GRPC_URL: ${SMQ_DOMAINS_GRPC_URL}
SMQ_DOMAINS_GRPC_TIMEOUT: ${SMQ_DOMAINS_GRPC_TIMEOUT}
SMQ_DOMAINS_GRPC_CLIENT_CERT: ${SMQ_DOMAINS_GRPC_CLIENT_CERT:+/domains-grpc-client.crt}
SMQ_DOMAINS_GRPC_CLIENT_KEY: ${SMQ_DOMAINS_GRPC_CLIENT_KEY:+/domains-grpc-client.key}
SMQ_DOMAINS_GRPC_SERVER_CA_CERTS: ${SMQ_DOMAINS_GRPC_SERVER_CA_CERTS:+/domains-grpc-server-ca.crt}
SMQ_CLIENTS_URL: ${SMQ_CLIENTS_URL}
SMQ_CHANNELS_URL: ${SMQ_CHANNELS_URL}
SMQ_JAEGER_URL: ${SMQ_JAEGER_URL}
SMQ_JAEGER_TRACE_RATIO: ${SMQ_JAEGER_TRACE_RATIO}
SMQ_SEND_TELEMETRY: ${SMQ_SEND_TELEMETRY}
SMQ_SPICEDB_PRE_SHARED_KEY: ${SMQ_SPICEDB_PRE_SHARED_KEY}
SMQ_SPICEDB_HOST: ${SMQ_SPICEDB_HOST}
SMQ_SPICEDB_PORT: ${SMQ_SPICEDB_PORT}
networks:
- magistrala-base-net
volumes:
- type: bind
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${MG_AUTH_GRPC_CLIENT_CERT:-./ssl/certs/dummy/client_cert}
target: /auth-grpc-client${MG_AUTH_GRPC_CLIENT_CERT:+.crt}
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${SMQ_AUTH_GRPC_CLIENT_CERT:-./ssl/certs/dummy/client_cert}
target: /auth-grpc-client${SMQ_AUTH_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${MG_AUTH_GRPC_CLIENT_KEY:-./ssl/certs/dummy/client_key}
target: /auth-grpc-client${MG_AUTH_GRPC_CLIENT_KEY:+.key}
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${SMQ_AUTH_GRPC_CLIENT_KEY:-./ssl/certs/dummy/client_key}
target: /auth-grpc-client${SMQ_AUTH_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${MG_AUTH_GRPC_SERVER_CA_CERTS:-./ssl/certs/dummy/server_ca}
target: /auth-grpc-server-ca${MG_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
source: ${MG_ADDONS_CERTS_PATH_PREFIX}${SMQ_AUTH_GRPC_SERVER_CA_CERTS:-./ssl/certs/dummy/server_ca}
target: /auth-grpc-server-ca${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
+1 -2
View File
@@ -12,7 +12,6 @@ networks:
volumes:
magistrala-certs-db-volume:
services:
certs:
image: magistrala/certs:${MG_RELEASE_TAG}
@@ -118,7 +117,7 @@ services:
AM_JAEGER_URL: ${MG_JAEGER_URL}
AM_JAEGER_TRACE_RATIO: ${MG_JAEGER_TRACE_RATIO}
volumes:
- ./config.yml:/config/config.yml
- ./config.yml:/config/config.yml
ports:
- 9010:9010
- 7012:7012
+5 -7
View File
@@ -175,7 +175,7 @@ services:
- magistrala-base-net
volumes:
- magistrala-domains-db-volume:/var/lib/postgresql/data
domains-redis:
image: redis:7.2.4-alpine
container_name: magistrala-domains-redis
@@ -366,11 +366,11 @@ services:
- ./nginx/snippets:/etc/nginx/snippets
- ./ssl/authorization.js:/etc/nginx/authorization.js
- type: bind
source: ${SMQ_NGINX_SERVER_CERT:-./ssl/certs/supermq-server.crt}
target: /etc/ssl/certs/supermq-server.crt
source: ${SMQ_NGINX_SERVER_CERT:-./ssl/certs/magistrala-server.crt}
target: /etc/ssl/certs/magistrala-server.crt
- type: bind
source: ${SMQ_NGINX_SERVER_KEY:-./ssl/certs/supermq-server.key}
target: /etc/ssl/private/supermq-server.key
source: ${SMQ_NGINX_SERVER_KEY:-./ssl/certs/magistrala-server.key}
target: /etc/ssl/private/magistrala-server.key
- type: bind
source: ${SMQ_NGINX_SERVER_CLIENT_CA:-./ssl/certs/ca.crt}
target: /etc/ssl/certs/ca.crt
@@ -750,7 +750,6 @@ services:
bind:
create_host_path: true
groups-db:
image: postgres:16.2-alpine
container_name: magistrala-groups-db
@@ -853,7 +852,6 @@ services:
bind:
create_host_path: true
jaeger:
image: jaegertracing/all-in-one:1.60
container_name: magistrala-jaeger
+1 -1
View File
@@ -2,4 +2,4 @@
# SPDX-License-Identifier: Apache-2.0
snippets/mqtt-upstream.conf
snippets/mqtt-ws-upstream.conf
snippets/mqtt-ws-upstream.conf
+17 -16
View File
@@ -2,25 +2,26 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0
if [ -z "$MG_MQTT_CLUSTER" ]
then
envsubst '${MG_MQTT_ADAPTER_MQTT_PORT}' < /etc/nginx/snippets/mqtt-upstream-single.conf > /etc/nginx/snippets/mqtt-upstream.conf
envsubst '${MG_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-single.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf
if [ -z "$SMQ_MQTT_CLUSTER" ]; then
envsubst '${SMQ_MQTT_ADAPTER_MQTT_PORT}' </etc/nginx/snippets/mqtt-upstream-single.conf >/etc/nginx/snippets/mqtt-upstream.conf
envsubst '${SMQ_MQTT_ADAPTER_WS_PORT}' </etc/nginx/snippets/mqtt-ws-upstream-single.conf >/etc/nginx/snippets/mqtt-ws-upstream.conf
else
envsubst '${MG_MQTT_ADAPTER_MQTT_PORT}' < /etc/nginx/snippets/mqtt-upstream-cluster.conf > /etc/nginx/snippets/mqtt-upstream.conf
envsubst '${MG_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-cluster.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf
envsubst '${SMQ_MQTT_ADAPTER_MQTT_PORT}' </etc/nginx/snippets/mqtt-upstream-cluster.conf >/etc/nginx/snippets/mqtt-upstream.conf
envsubst '${SMQ_MQTT_ADAPTER_WS_PORT}' </etc/nginx/snippets/mqtt-ws-upstream-cluster.conf >/etc/nginx/snippets/mqtt-ws-upstream.conf
fi
envsubst '
${MG_NGINX_SERVER_NAME}
${MG_AUTH_HTTP_PORT}
${MG_USERS_HTTP_PORT}
${MG_THINGS_HTTP_PORT}
${MG_THINGS_AUTH_HTTP_PORT}
${MG_HTTP_ADAPTER_PORT}
${MG_NGINX_MQTT_PORT}
${MG_NGINX_MQTTS_PORT}
${MG_INVITATIONS_HTTP_PORT}
${MG_WS_ADAPTER_HTTP_PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
${SMQ_NGINX_SERVER_NAME}
${SMQ_DOMAINS_HTTP_PORT}
${SMQ_GROUPS_HTTP_PORT}
${SMQ_USERS_HTTP_PORT}
${SMQ_CLIENTS_HTTP_PORT}
${SMQ_CLIENTS_AUTH_HTTP_PORT}
${SMQ_CHANNELS_HTTP_PORT}
${SMQ_HTTP_ADAPTER_PORT}
${SMQ_NGINX_MQTT_PORT}
${SMQ_NGINX_MQTTS_PORT}
${SMQ_INVITATIONS_HTTP_PORT}
${SMQ_WS_ADAPTER_HTTP_PORT}' </etc/nginx/nginx.conf.template >/etc/nginx/nginx.conf
exec nginx -g "daemon off;"
+5 -5
View File
@@ -40,7 +40,7 @@ http {
listen [::]:443 ssl default_server;
http2 on;
set $dynamic_server_name "$MG_NGINX_SERVER_NAME";
set $dynamic_server_name "$SMQ_NGINX_SERVER_NAME";
if ($dynamic_server_name = '') {
set $dynamic_server_name "localhost";
@@ -197,10 +197,10 @@ stream {
include snippets/mqtt-upstream.conf;
server {
listen ${MG_NGINX_MQTT_PORT};
listen [::]:${MG_NGINX_MQTT_PORT};
listen ${MG_NGINX_MQTTS_PORT} ssl;
listen [::]:${MG_NGINX_MQTTS_PORT} ssl;
listen ${SMQ_NGINX_MQTT_PORT};
listen [::]:${SMQ_NGINX_MQTT_PORT};
listen ${SMQ_NGINX_MQTTS_PORT} ssl;
listen [::]:${SMQ_NGINX_MQTTS_PORT} ssl;
include snippets/ssl.conf;
+4 -4
View File
@@ -217,10 +217,10 @@ stream {
include snippets/ssl-client.conf;
server {
listen ${MG_NGINX_MQTT_PORT};
listen [::]:${MG_NGINX_MQTT_PORT};
listen ${MG_NGINX_MQTTS_PORT} ssl;
listen [::]:${MG_NGINX_MQTTS_PORT} ssl;
listen ${SMQ_NGINX_MQTT_PORT};
listen [::]:${SMQ_NGINX_MQTT_PORT};
listen ${SMQ_NGINX_MQTTS_PORT} ssl;
listen [::]:${SMQ_NGINX_MQTTS_PORT} ssl;
include snippets/ssl.conf;
js_preread authorization.authenticate;
@@ -3,7 +3,7 @@
upstream mqtt_cluster {
least_conn;
server mqtt-adapter-1:${MG_MQTT_ADAPTER_MQTT_PORT};
server mqtt-adapter-2:${MG_MQTT_ADAPTER_MQTT_PORT};
server mqtt-adapter-3:${MG_MQTT_ADAPTER_MQTT_PORT};
}
server mqtt-adapter-1:${SMQ_MQTT_ADAPTER_MQTT_PORT};
server mqtt-adapter-2:${SMQ_MQTT_ADAPTER_MQTT_PORT};
server mqtt-adapter-3:${SMQ_MQTT_ADAPTER_MQTT_PORT};
}
@@ -2,5 +2,5 @@
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_cluster {
server mqtt-adapter:${MG_MQTT_ADAPTER_MQTT_PORT};
}
server mqtt-adapter:${SMQ_MQTT_ADAPTER_MQTT_PORT};
}
@@ -3,7 +3,7 @@
upstream mqtt_ws_cluster {
least_conn;
server mqtt-adapter-1:${MG_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-2:${MG_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-3:${MG_MQTT_ADAPTER_WS_PORT};
}
server mqtt-adapter-1:${SMQ_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-2:${SMQ_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-3:${SMQ_MQTT_ADAPTER_WS_PORT};
}
@@ -2,5 +2,5 @@
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_ws_cluster {
server mqtt-adapter:${MG_MQTT_ADAPTER_WS_PORT};
}
server mqtt-adapter:${SMQ_MQTT_ADAPTER_WS_PORT};
}
+1 -1
View File
@@ -12,4 +12,4 @@ if ($request_method = OPTIONS) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
}
+1 -1
View File
@@ -6,4 +6,4 @@ if ($ssl_client_verify != SUCCESS) {
}
if ($auth_key = '') {
return 403;
}
}
+1 -1
View File
@@ -6,4 +6,4 @@ proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
proxy_read_timeout 7d;
+194
View File
@@ -0,0 +1,194 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
context "context"
commonv1 "github.com/absmach/supermq/api/grpc/common/v1"
grpc "google.golang.org/grpc"
mock "github.com/stretchr/testify/mock"
v1 "github.com/absmach/supermq/api/grpc/domains/v1"
)
// DomainsServiceClient is an autogenerated mock type for the DomainsServiceClient type
type DomainsServiceClient struct {
mock.Mock
}
type DomainsServiceClient_Expecter struct {
mock *mock.Mock
}
func (_m *DomainsServiceClient) EXPECT() *DomainsServiceClient_Expecter {
return &DomainsServiceClient_Expecter{mock: &_m.Mock}
}
// DeleteUserFromDomains provides a mock function with given fields: ctx, in, opts
func (_m *DomainsServiceClient) DeleteUserFromDomains(ctx context.Context, in *v1.DeleteUserReq, opts ...grpc.CallOption) (*v1.DeleteUserRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for DeleteUserFromDomains")
}
var r0 *v1.DeleteUserRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.DeleteUserReq, ...grpc.CallOption) (*v1.DeleteUserRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.DeleteUserReq, ...grpc.CallOption) *v1.DeleteUserRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.DeleteUserRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.DeleteUserReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DomainsServiceClient_DeleteUserFromDomains_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteUserFromDomains'
type DomainsServiceClient_DeleteUserFromDomains_Call struct {
*mock.Call
}
// DeleteUserFromDomains is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.DeleteUserReq
// - opts ...grpc.CallOption
func (_e *DomainsServiceClient_Expecter) DeleteUserFromDomains(ctx interface{}, in interface{}, opts ...interface{}) *DomainsServiceClient_DeleteUserFromDomains_Call {
return &DomainsServiceClient_DeleteUserFromDomains_Call{Call: _e.mock.On("DeleteUserFromDomains",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *DomainsServiceClient_DeleteUserFromDomains_Call) Run(run func(ctx context.Context, in *v1.DeleteUserReq, opts ...grpc.CallOption)) *DomainsServiceClient_DeleteUserFromDomains_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.DeleteUserReq), variadicArgs...)
})
return _c
}
func (_c *DomainsServiceClient_DeleteUserFromDomains_Call) Return(_a0 *v1.DeleteUserRes, _a1 error) *DomainsServiceClient_DeleteUserFromDomains_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *DomainsServiceClient_DeleteUserFromDomains_Call) RunAndReturn(run func(context.Context, *v1.DeleteUserReq, ...grpc.CallOption) (*v1.DeleteUserRes, error)) *DomainsServiceClient_DeleteUserFromDomains_Call {
_c.Call.Return(run)
return _c
}
// RetrieveEntity provides a mock function with given fields: ctx, in, opts
func (_m *DomainsServiceClient) RetrieveEntity(ctx context.Context, in *commonv1.RetrieveEntityReq, opts ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RetrieveEntity")
}
var r0 *commonv1.RetrieveEntityRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) *commonv1.RetrieveEntityRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*commonv1.RetrieveEntityRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DomainsServiceClient_RetrieveEntity_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveEntity'
type DomainsServiceClient_RetrieveEntity_Call struct {
*mock.Call
}
// RetrieveEntity is a helper method to define mock.On call
// - ctx context.Context
// - in *commonv1.RetrieveEntityReq
// - opts ...grpc.CallOption
func (_e *DomainsServiceClient_Expecter) RetrieveEntity(ctx interface{}, in interface{}, opts ...interface{}) *DomainsServiceClient_RetrieveEntity_Call {
return &DomainsServiceClient_RetrieveEntity_Call{Call: _e.mock.On("RetrieveEntity",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *DomainsServiceClient_RetrieveEntity_Call) Run(run func(ctx context.Context, in *commonv1.RetrieveEntityReq, opts ...grpc.CallOption)) *DomainsServiceClient_RetrieveEntity_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*commonv1.RetrieveEntityReq), variadicArgs...)
})
return _c
}
func (_c *DomainsServiceClient_RetrieveEntity_Call) Return(_a0 *commonv1.RetrieveEntityRes, _a1 error) *DomainsServiceClient_RetrieveEntity_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *DomainsServiceClient_RetrieveEntity_Call) RunAndReturn(run func(context.Context, *commonv1.RetrieveEntityReq, ...grpc.CallOption) (*commonv1.RetrieveEntityRes, error)) *DomainsServiceClient_RetrieveEntity_Call {
_c.Call.Return(run)
return _c
}
// NewDomainsServiceClient creates a new instance of DomainsServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDomainsServiceClient(t interface {
mock.TestingT
Cleanup(func())
}) *DomainsServiceClient {
mock := &DomainsServiceClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+7 -7
View File
@@ -5,8 +5,9 @@ go 1.23.4
require (
github.com/0x6flab/namegenerator v1.4.0
github.com/absmach/callhome v0.14.0
github.com/absmach/supermq v0.16.1-0.20241227183413-f12aacd1da31
github.com/authzed/authzed-go v1.2.0
github.com/absmach/certs v0.0.0-20241209153600-91270de67b5a
github.com/absmach/supermq v0.16.1-0.20250110085603-df5d752c4b50
github.com/authzed/authzed-go v1.2.1
github.com/authzed/grpcutil v0.0.0-20240123194739-2ea1e3d2d98b
github.com/caarlos0/env/v11 v11.3.1
github.com/eclipse/paho.mqtt.golang v1.5.0
@@ -38,6 +39,7 @@ require (
gonum.org/v1/gonum v0.15.1
google.golang.org/grpc v1.69.2
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
moul.io/http2curl v1.0.0
)
require (
@@ -45,7 +47,6 @@ require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/absmach/certs v0.0.0-20241209153600-91270de67b5a // indirect
github.com/absmach/senml v1.0.6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
@@ -126,17 +127,16 @@ require (
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241230172942-26aa7a208def // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241230172942-26aa7a208def // indirect
google.golang.org/protobuf v1.36.1 // indirect
google.golang.org/protobuf v1.36.2 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
moul.io/http2curl v1.0.0 // indirect
)
+12 -12
View File
@@ -27,10 +27,10 @@ github.com/absmach/mgate v0.4.5 h1:l6RmrEsR9jxkdb9WHUSecmT0HA41TkZZQVffFfUAIfI=
github.com/absmach/mgate v0.4.5/go.mod h1:IvRIHZexZPEIAPmmaJF0L5DY2ERjj+GxRGitOW4s6qo=
github.com/absmach/senml v1.0.6 h1:WPeIl6vQ00k7ghWSZYT/QP0KUxq2+4zQoaC7240pLFk=
github.com/absmach/senml v1.0.6/go.mod h1:QnJNPy1DJPy0+qUW21PTcH/xoh0LgfYZxTfwriMIvmQ=
github.com/absmach/supermq v0.16.1-0.20241227183413-f12aacd1da31 h1:o3fWtPh4VjOf/0Y5pJcUltKmKKjhvSaI3ShNN98M1C0=
github.com/absmach/supermq v0.16.1-0.20241227183413-f12aacd1da31/go.mod h1:pbDQgySAcpaxn2lXR1kuxKy1vvDDt1Fzo9RY38gRQDw=
github.com/authzed/authzed-go v1.2.0 h1:Ep1sRJMxcArB++kYqHbYKQCb/GgdGZI0cW4gZrJ1K40=
github.com/authzed/authzed-go v1.2.0/go.mod h1:4lkFxvaCISG1roRdnUt35/Sk1StVuMD1QCwTd/BcWcM=
github.com/absmach/supermq v0.16.1-0.20250110085603-df5d752c4b50 h1:ndn1Z9wxUIH5chingm2hy3ZhIMt0+lDjD/CFaBEULbY=
github.com/absmach/supermq v0.16.1-0.20250110085603-df5d752c4b50/go.mod h1:VihyvWijocoz2yhXGAL+qHtid24O+qL/N2lxP2vRf/c=
github.com/authzed/authzed-go v1.2.1 h1:o54aIs0ocDfVJl/rfIt/75vrb6z+tgPuXjMlSsSEwH0=
github.com/authzed/authzed-go v1.2.1/go.mod h1:/+NblSrzA6Lm6vUO3fqZyLh8MDCLUQq2AyJMlHb32DE=
github.com/authzed/grpcutil v0.0.0-20240123194739-2ea1e3d2d98b h1:wbh8IK+aMLTCey9sZasO7b6BWLAJnHHvb79fvWCXwxw=
github.com/authzed/grpcutil v0.0.0-20240123194739-2ea1e3d2d98b/go.mod h1:s3qC7V7XIbiNWERv7Lfljy/Lx25/V1Qlexb0WJuA8uQ=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -464,8 +464,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
@@ -496,8 +496,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -532,8 +532,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -595,8 +595,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+118
View File
@@ -0,0 +1,118 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Code generated by mockery v2.43.2. DO NOT EDIT.
package mocks
import (
context "context"
grpc "google.golang.org/grpc"
mock "github.com/stretchr/testify/mock"
v1 "github.com/absmach/supermq/api/grpc/common/v1"
)
// GroupsServiceClient is an autogenerated mock type for the GroupsServiceClient type
type GroupsServiceClient struct {
mock.Mock
}
type GroupsServiceClient_Expecter struct {
mock *mock.Mock
}
func (_m *GroupsServiceClient) EXPECT() *GroupsServiceClient_Expecter {
return &GroupsServiceClient_Expecter{mock: &_m.Mock}
}
// RetrieveEntity provides a mock function with given fields: ctx, in, opts
func (_m *GroupsServiceClient) RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for RetrieveEntity")
}
var r0 *v1.RetrieveEntityRes
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) (*v1.RetrieveEntityRes, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) *v1.RetrieveEntityRes); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v1.RetrieveEntityRes)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GroupsServiceClient_RetrieveEntity_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveEntity'
type GroupsServiceClient_RetrieveEntity_Call struct {
*mock.Call
}
// RetrieveEntity is a helper method to define mock.On call
// - ctx context.Context
// - in *v1.RetrieveEntityReq
// - opts ...grpc.CallOption
func (_e *GroupsServiceClient_Expecter) RetrieveEntity(ctx interface{}, in interface{}, opts ...interface{}) *GroupsServiceClient_RetrieveEntity_Call {
return &GroupsServiceClient_RetrieveEntity_Call{Call: _e.mock.On("RetrieveEntity",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *GroupsServiceClient_RetrieveEntity_Call) Run(run func(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption)) *GroupsServiceClient_RetrieveEntity_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*v1.RetrieveEntityReq), variadicArgs...)
})
return _c
}
func (_c *GroupsServiceClient_RetrieveEntity_Call) Return(_a0 *v1.RetrieveEntityRes, _a1 error) *GroupsServiceClient_RetrieveEntity_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *GroupsServiceClient_RetrieveEntity_Call) RunAndReturn(run func(context.Context, *v1.RetrieveEntityReq, ...grpc.CallOption) (*v1.RetrieveEntityRes, error)) *GroupsServiceClient_RetrieveEntity_Call {
_c.Call.Return(run)
return _c
}
// NewGroupsServiceClient creates a new instance of GroupsServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewGroupsServiceClient(t interface {
mock.TestingT
Cleanup(func())
}) *GroupsServiceClient {
mock := &GroupsServiceClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+323
View File
@@ -0,0 +1,323 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package sdk
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
apiutil "github.com/absmach/supermq/api/http/util"
"github.com/absmach/supermq/pkg/errors"
smqSDK "github.com/absmach/supermq/pkg/sdk"
)
const (
configsEndpoint = "clients/configs"
bootstrapEndpoint = "clients/bootstrap"
whitelistEndpoint = "clients/state"
bootstrapCertsEndpoint = "clients/configs/certs"
bootstrapConnEndpoint = "clients/configs/connections"
secureEndpoint = "secure"
)
// BootstrapConfig represents Configuration entity. It wraps information about external entity
// as well as info about corresponding SuperMQ entities.
// MGClient represents corresponding SuperMQ Client ID.
// MGKey is key of corresponding SuperMQ Client.
// MGChannels is a list of SuperMQ Channels corresponding SuperMQ Client connects to.
type BootstrapConfig struct {
Channels interface{} `json:"channels,omitempty"`
ExternalID string `json:"external_id,omitempty"`
ExternalKey string `json:"external_key,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
Name string `json:"name,omitempty"`
ClientCert string `json:"client_cert,omitempty"`
ClientKey string `json:"client_key,omitempty"`
CACert string `json:"ca_cert,omitempty"`
Content string `json:"content,omitempty"`
State int `json:"state,omitempty"`
}
func (ts *BootstrapConfig) UnmarshalJSON(data []byte) error {
var rawData map[string]json.RawMessage
if err := json.Unmarshal(data, &rawData); err != nil {
return err
}
if channelData, ok := rawData["channels"]; ok {
var stringData []string
if err := json.Unmarshal(channelData, &stringData); err == nil {
ts.Channels = stringData
} else {
var channels []smqSDK.Channel
if err := json.Unmarshal(channelData, &channels); err == nil {
ts.Channels = channels
} else {
return fmt.Errorf("unsupported channel data type")
}
}
}
if err := json.Unmarshal(data, &struct {
ExternalID *string `json:"external_id,omitempty"`
ExternalKey *string `json:"external_key,omitempty"`
ClientID *string `json:"client_id,omitempty"`
ClientSecret *string `json:"client_secret,omitempty"`
Name *string `json:"name,omitempty"`
ClientCert *string `json:"client_cert,omitempty"`
ClientKey *string `json:"client_key,omitempty"`
CACert *string `json:"ca_cert,omitempty"`
Content *string `json:"content,omitempty"`
State *int `json:"state,omitempty"`
}{
ExternalID: &ts.ExternalID,
ExternalKey: &ts.ExternalKey,
ClientID: &ts.ClientID,
ClientSecret: &ts.ClientSecret,
Name: &ts.Name,
ClientCert: &ts.ClientCert,
ClientKey: &ts.ClientKey,
CACert: &ts.CACert,
Content: &ts.Content,
State: &ts.State,
}); err != nil {
return err
}
return nil
}
func (sdk mgSDK) AddBootstrap(cfg BootstrapConfig, domainID, token string) (string, errors.SDKError) {
data, err := json.Marshal(cfg)
if err != nil {
return "", errors.NewSDKError(err)
}
url := fmt.Sprintf("%s/%s/%s", sdk.bootstrapURL, domainID, configsEndpoint)
headers, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, data, nil, http.StatusOK, http.StatusCreated)
if sdkerr != nil {
return "", sdkerr
}
id := strings.TrimPrefix(headers.Get("Location"), "/clients/configs/")
return id, nil
}
func (sdk mgSDK) Bootstraps(pm PageMetadata, domainID, token string) (BootstrapPage, errors.SDKError) {
endpoint := fmt.Sprintf("%s/%s", domainID, configsEndpoint)
url, err := sdk.withQueryParams(sdk.bootstrapURL, endpoint, pm)
if err != nil {
return BootstrapPage{}, errors.NewSDKError(err)
}
_, body, sdkerr := sdk.processRequest(http.MethodGet, url, token, nil, nil, http.StatusOK)
if sdkerr != nil {
return BootstrapPage{}, sdkerr
}
var bb BootstrapPage
if err = json.Unmarshal(body, &bb); err != nil {
return BootstrapPage{}, errors.NewSDKError(err)
}
return bb, nil
}
func (sdk mgSDK) Whitelist(clientID string, state int, domainID, token string) errors.SDKError {
if clientID == "" {
return errors.NewSDKError(apiutil.ErrMissingID)
}
data, err := json.Marshal(BootstrapConfig{State: state})
if err != nil {
return errors.NewSDKError(err)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, whitelistEndpoint, clientID)
_, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, data, nil, http.StatusCreated, http.StatusOK)
return sdkerr
}
func (sdk mgSDK) ViewBootstrap(id, domainID, token string) (BootstrapConfig, errors.SDKError) {
if id == "" {
return BootstrapConfig{}, errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, configsEndpoint, id)
_, body, err := sdk.processRequest(http.MethodGet, url, token, nil, nil, http.StatusOK)
if err != nil {
return BootstrapConfig{}, err
}
var bc BootstrapConfig
if err := json.Unmarshal(body, &bc); err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
return bc, nil
}
func (sdk mgSDK) UpdateBootstrap(cfg BootstrapConfig, domainID, token string) errors.SDKError {
if cfg.ClientID == "" {
return errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, configsEndpoint, cfg.ClientID)
data, err := json.Marshal(cfg)
if err != nil {
return errors.NewSDKError(err)
}
_, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, data, nil, http.StatusOK)
return sdkerr
}
func (sdk mgSDK) UpdateBootstrapCerts(id, clientCert, clientKey, ca, domainID, token string) (BootstrapConfig, errors.SDKError) {
if id == "" {
return BootstrapConfig{}, errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, bootstrapCertsEndpoint, id)
request := BootstrapConfig{
ClientCert: clientCert,
ClientKey: clientKey,
CACert: ca,
}
data, err := json.Marshal(request)
if err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
_, body, sdkerr := sdk.processRequest(http.MethodPatch, url, token, data, nil, http.StatusOK)
if sdkerr != nil {
return BootstrapConfig{}, sdkerr
}
var bc BootstrapConfig
if err := json.Unmarshal(body, &bc); err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
return bc, nil
}
func (sdk mgSDK) UpdateBootstrapConnection(id string, channels []string, domainID, token string) errors.SDKError {
if id == "" {
return errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, bootstrapConnEndpoint, id)
request := map[string][]string{
"channels": channels,
}
data, err := json.Marshal(request)
if err != nil {
return errors.NewSDKError(err)
}
_, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, data, nil, http.StatusOK)
return sdkerr
}
func (sdk mgSDK) RemoveBootstrap(id, domainID, token string) errors.SDKError {
if id == "" {
return errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, domainID, configsEndpoint, id)
_, _, err := sdk.processRequest(http.MethodDelete, url, token, nil, nil, http.StatusNoContent)
return err
}
func (sdk mgSDK) Bootstrap(externalID, externalKey string) (BootstrapConfig, errors.SDKError) {
if externalID == "" {
return BootstrapConfig{}, errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s", sdk.bootstrapURL, bootstrapEndpoint, externalID)
_, body, err := sdk.processRequest(http.MethodGet, url, smqSDK.ClientPrefix+externalKey, nil, nil, http.StatusOK)
if err != nil {
return BootstrapConfig{}, err
}
var bc BootstrapConfig
if err := json.Unmarshal(body, &bc); err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
return bc, nil
}
func (sdk mgSDK) BootstrapSecure(externalID, externalKey, cryptoKey string) (BootstrapConfig, errors.SDKError) {
if externalID == "" {
return BootstrapConfig{}, errors.NewSDKError(apiutil.ErrMissingID)
}
url := fmt.Sprintf("%s/%s/%s/%s", sdk.bootstrapURL, bootstrapEndpoint, secureEndpoint, externalID)
encExtKey, err := bootstrapEncrypt([]byte(externalKey), cryptoKey)
if err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
_, body, sdkErr := sdk.processRequest(http.MethodGet, url, smqSDK.ClientPrefix+encExtKey, nil, nil, http.StatusOK)
if sdkErr != nil {
return BootstrapConfig{}, sdkErr
}
decBody, decErr := bootstrapDecrypt(body, cryptoKey)
if decErr != nil {
return BootstrapConfig{}, errors.NewSDKError(decErr)
}
var bc BootstrapConfig
if err := json.Unmarshal(decBody, &bc); err != nil {
return BootstrapConfig{}, errors.NewSDKError(err)
}
return bc, nil
}
func bootstrapEncrypt(in []byte, cryptoKey string) (string, error) {
block, err := aes.NewCipher([]byte(cryptoKey))
if err != nil {
return "", err
}
ciphertext := make([]byte, aes.BlockSize+len(in))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], in)
return hex.EncodeToString(ciphertext), nil
}
func bootstrapDecrypt(in []byte, cryptoKey string) ([]byte, error) {
ciphertext := in
block, err := aes.NewCipher([]byte(cryptoKey))
if err != nil {
return nil, err
}
if len(ciphertext) < aes.BlockSize {
return nil, err
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)
return ciphertext, nil
}
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
// Package sdk contains Magistrala SDK.
package sdk
+3859
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package sdk
type PageRes struct {
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
}
// bootstrapsPage contains list of bootstrap configs in a page with proper metadata.
type BootstrapPage struct {
Configs []BootstrapConfig `json:"configs"`
PageRes
}
+270
View File
@@ -0,0 +1,270 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package sdk
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/absmach/supermq/pkg/errors"
smqSDK "github.com/absmach/supermq/pkg/sdk"
"moul.io/http2curl"
)
var _ SDK = (*mgSDK)(nil)
type Metadata map[string]interface{}
type PageMetadata struct {
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Metadata Metadata `json:"metadata,omitempty"`
}
// SDK contains Magistrala API.
//
//go:generate mockery --name SDK --output=./mocks --filename sdk.go --quiet --note "Copyright (c) Abstract Machines"
type SDK interface {
smqSDK.SDK
// AddBootstrap add bootstrap configuration
//
// example:
// cfg := sdk.BootstrapConfig{
// ClientID: "clientID",
// Name: "bootstrap",
// ExternalID: "externalID",
// ExternalKey: "externalKey",
// Channels: []string{"channel1", "channel2"},
// }
// id, _ := sdk.AddBootstrap(cfg, "domainID", "token")
// fmt.Println(id)
AddBootstrap(cfg BootstrapConfig, domainID, token string) (string, errors.SDKError)
// View returns Client Config with given ID belonging to the user identified by the given token.
//
// example:
// bootstrap, _ := sdk.ViewBootstrap("id", "domainID", "token")
// fmt.Println(bootstrap)
ViewBootstrap(id, domainID, token string) (BootstrapConfig, errors.SDKError)
// Update updates editable fields of the provided Config.
//
// example:
// cfg := sdk.BootstrapConfig{
// ClientID: "clientID",
// Name: "bootstrap",
// ExternalID: "externalID",
// ExternalKey: "externalKey",
// Channels: []string{"channel1", "channel2"},
// }
// err := sdk.UpdateBootstrap(cfg, "domainID", "token")
// fmt.Println(err)
UpdateBootstrap(cfg BootstrapConfig, domainID, token string) errors.SDKError
// Update bootstrap config certificates.
//
// example:
// err := sdk.UpdateBootstrapCerts("id", "clientCert", "clientKey", "ca", "domainID", "token")
// fmt.Println(err)
UpdateBootstrapCerts(id string, clientCert, clientKey, ca string, domainID, token string) (BootstrapConfig, errors.SDKError)
// UpdateBootstrapConnection updates connections performs update of the channel list corresponding Client is connected to.
//
// example:
// err := sdk.UpdateBootstrapConnection("id", []string{"channel1", "channel2"}, "domainID", "token")
// fmt.Println(err)
UpdateBootstrapConnection(id string, channels []string, domainID, token string) errors.SDKError
// Remove removes Config with specified token that belongs to the user identified by the given token.
//
// example:
// err := sdk.RemoveBootstrap("id", "domainID", "token")
// fmt.Println(err)
RemoveBootstrap(id, domainID, token string) errors.SDKError
// Bootstrap returns Config to the Client with provided external ID using external key.
//
// example:
// bootstrap, _ := sdk.Bootstrap("externalID", "externalKey")
// fmt.Println(bootstrap)
Bootstrap(externalID, externalKey string) (BootstrapConfig, errors.SDKError)
// BootstrapSecure retrieves a configuration with given external ID and encrypted external key.
//
// example:
// bootstrap, _ := sdk.BootstrapSecure("externalID", "externalKey", "cryptoKey")
// fmt.Println(bootstrap)
BootstrapSecure(externalID, externalKey, cryptoKey string) (BootstrapConfig, errors.SDKError)
// Bootstraps retrieves a list of managed configs.
//
// example:
// pm := sdk.PageMetadata{
// Offset: 0,
// Limit: 10,
// }
// bootstraps, _ := sdk.Bootstraps(pm, "domainID", "token")
// fmt.Println(bootstraps)
Bootstraps(pm PageMetadata, domainID, token string) (BootstrapPage, errors.SDKError)
// Whitelist updates Client state Config with given ID belonging to the user identified by the given token.
//
// example:
// err := sdk.Whitelist("clientID", 1, "domainID", "token")
// fmt.Println(err)
Whitelist(clientID string, state int, domainID, token string) errors.SDKError
}
type mgSDK struct {
bootstrapURL string
client *http.Client
curlFlag bool
smqSDK.SDK
}
// Config contains sdk configuration parameters.
type Config struct {
BootstrapURL string
CertsURL string
HTTPAdapterURL string
ReaderURL string
ClientsURL string
UsersURL string
GroupsURL string
ChannelsURL string
DomainsURL string
InvitationsURL string
JournalURL string
HostURL string
MsgContentType smqSDK.ContentType
TLSVerification bool
CurlFlag bool
}
// NewSDK returns new supermq SDK instance.
func NewSDK(conf Config) SDK {
smqSDK := smqSDK.NewSDK(smqSDK.Config{
CertsURL: conf.CertsURL,
HTTPAdapterURL: conf.HTTPAdapterURL,
ReaderURL: conf.ReaderURL,
ClientsURL: conf.ClientsURL,
UsersURL: conf.UsersURL,
GroupsURL: conf.GroupsURL,
ChannelsURL: conf.ChannelsURL,
DomainsURL: conf.DomainsURL,
InvitationsURL: conf.InvitationsURL,
JournalURL: conf.JournalURL,
HostURL: conf.HostURL,
MsgContentType: conf.MsgContentType,
TLSVerification: conf.TLSVerification,
CurlFlag: conf.CurlFlag,
})
return &mgSDK{
bootstrapURL: conf.BootstrapURL,
client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: !conf.TLSVerification,
},
},
},
curlFlag: conf.CurlFlag,
SDK: smqSDK,
}
}
// processRequest creates and send a new HTTP request, and checks for errors in the HTTP response.
// It then returns the response headers, the response body, and the associated error(s) (if any).
func (sdk mgSDK) processRequest(method, reqUrl, token string, data []byte, headers map[string]string, expectedRespCodes ...int) (http.Header, []byte, errors.SDKError) {
req, err := http.NewRequest(method, reqUrl, bytes.NewReader(data))
if err != nil {
return make(http.Header), []byte{}, errors.NewSDKError(err)
}
// Sets a default value for the Content-Type.
// Overridden if Content-Type is passed in the headers arguments.
req.Header.Add("Content-Type", string(smqSDK.CTJSON))
for key, value := range headers {
req.Header.Add(key, value)
}
if token != "" {
if !strings.Contains(token, smqSDK.ClientPrefix) {
token = smqSDK.BearerPrefix + token
}
req.Header.Set("Authorization", token)
}
if sdk.curlFlag {
curlCommand, err := http2curl.GetCurlCommand(req)
if err != nil {
return nil, nil, errors.NewSDKError(err)
}
log.Println(curlCommand.String())
}
resp, err := sdk.client.Do(req)
if err != nil {
return make(http.Header), []byte{}, errors.NewSDKError(err)
}
defer resp.Body.Close()
sdkerr := errors.CheckError(resp, expectedRespCodes...)
if sdkerr != nil {
return make(http.Header), []byte{}, sdkerr
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return make(http.Header), []byte{}, errors.NewSDKError(err)
}
return resp.Header, body, nil
}
func (sdk mgSDK) withQueryParams(baseURL, endpoint string, pm PageMetadata) (string, error) {
q, err := pm.query()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s?%s", baseURL, endpoint, q), nil
}
func (pm PageMetadata) query() (string, error) {
q := url.Values{}
if pm.Offset != 0 {
q.Add("offset", strconv.FormatUint(pm.Offset, 10))
}
if pm.Limit != 0 {
q.Add("limit", strconv.FormatUint(pm.Limit, 10))
}
if pm.Total != 0 {
q.Add("total", strconv.FormatUint(pm.Total, 10))
}
if pm.Metadata != nil {
md, err := json.Marshal(pm.Metadata)
if err != nil {
return "", errors.NewSDKError(err)
}
q.Add("metadata", string(md))
}
return q.Encode(), nil
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package sdk_test
import (
"os"
"testing"
)
func TestMain(m *testing.M) {
exitCode := m.Run()
os.Exit(exitCode)
}
+17 -16
View File
@@ -8,8 +8,9 @@ import (
"fmt"
"log/slog"
"github.com/absmach/magistrala/pkg/sdk"
"github.com/absmach/supermq/pkg/errors"
sdk "github.com/absmach/supermq/pkg/sdk"
smqSDK "github.com/absmach/supermq/pkg/sdk"
)
const (
@@ -78,8 +79,8 @@ type provisionService struct {
// Result represent what is created with additional info.
type Result struct {
Clients []sdk.Client `json:"clients,omitempty"`
Channels []sdk.Channel `json:"channels,omitempty"`
Clients []smqSDK.Client `json:"clients,omitempty"`
Channels []smqSDK.Channel `json:"channels,omitempty"`
ClientCert map[string]string `json:"client_cert,omitempty"`
ClientKey map[string]string `json:"client_key,omitempty"`
CACert string `json:"ca_cert,omitempty"`
@@ -98,7 +99,7 @@ func New(cfg Config, mgsdk sdk.SDK, logger *slog.Logger) Service {
// Mapping retrieves current configuration.
func (ps *provisionService) Mapping(token string) (map[string]interface{}, error) {
pm := sdk.PageMetadata{
pm := smqSDK.PageMetadata{
Offset: uint64(offset),
Limit: uint64(limit),
}
@@ -113,8 +114,8 @@ func (ps *provisionService) Mapping(token string) (map[string]interface{}, error
// Provision is provision method for creating setup according to
// provision layout specified in config.toml.
func (ps *provisionService) Provision(domainID, token, name, externalID, externalKey string) (res Result, err error) {
var channels []sdk.Channel
var clients []sdk.Client
var channels []smqSDK.Channel
var clients []smqSDK.Client
defer ps.recover(&err, &clients, &channels, &domainID, &token)
token, err = ps.createTokenIfEmpty(token)
@@ -135,7 +136,7 @@ func (ps *provisionService) Provision(domainID, token, name, externalID, externa
c.Metadata[externalIDKey] = externalID
}
cli := sdk.Client{
cli := smqSDK.Client{
Metadata: c.Metadata,
}
if name == "" {
@@ -158,9 +159,9 @@ func (ps *provisionService) Provision(domainID, token, name, externalID, externa
}
for _, channel := range ps.conf.Channels {
ch := sdk.Channel{
ch := smqSDK.Channel{
Name: name + "_" + channel.Name,
Metadata: sdk.Metadata(channel.Metadata),
Metadata: smqSDK.Metadata(channel.Metadata),
}
ch, err := ps.sdk.CreateChannel(ch, domainID, token)
if err != nil {
@@ -182,7 +183,7 @@ func (ps *provisionService) Provision(domainID, token, name, externalID, externa
ClientKey: map[string]string{},
}
var cert sdk.Cert
var cert smqSDK.Cert
var bsConfig sdk.BootstrapConfig
for _, c := range clients {
var chanIDs []string
@@ -218,7 +219,7 @@ func (ps *provisionService) Provision(domainID, token, name, externalID, externa
}
if ps.conf.Bootstrap.X509Provision {
var cert sdk.Cert
var cert smqSDK.Cert
cert, err = ps.sdk.IssueCert(c.ID, ps.conf.Cert.TTL, domainID, token)
if err != nil {
@@ -293,7 +294,7 @@ func (ps *provisionService) createTokenIfEmpty(token string) (string, error) {
return token, ErrMissingCredentials
}
u := sdk.Login{
u := smqSDK.Login{
Username: ps.conf.Server.MgUsername,
Password: ps.conf.Server.MgPass,
}
@@ -305,7 +306,7 @@ func (ps *provisionService) createTokenIfEmpty(token string) (string, error) {
return tkn.AccessToken, nil
}
func (ps *provisionService) updateGateway(domainID, token string, bs sdk.BootstrapConfig, channels []sdk.Channel) error {
func (ps *provisionService) updateGateway(domainID, token string, bs sdk.BootstrapConfig, channels []smqSDK.Channel) error {
var gw Gateway
for _, ch := range channels {
switch ch.Metadata["type"] {
@@ -345,7 +346,7 @@ func (ps *provisionService) errLog(err error) {
}
}
func clean(ps *provisionService, clients []sdk.Client, channels []sdk.Channel, domainID, token string) {
func clean(ps *provisionService, clients []smqSDK.Client, channels []smqSDK.Channel, domainID, token string) {
for _, t := range clients {
err := ps.sdk.DeleteClient(t.ID, domainID, token)
ps.errLog(err)
@@ -356,7 +357,7 @@ func clean(ps *provisionService, clients []sdk.Client, channels []sdk.Channel, d
}
}
func (ps *provisionService) recover(e *error, ths *[]sdk.Client, chs *[]sdk.Channel, dm, tkn *string) {
func (ps *provisionService) recover(e *error, ths *[]smqSDK.Client, chs *[]smqSDK.Channel, dm, tkn *string) {
if e == nil {
return
}
@@ -413,7 +414,7 @@ func (ps *provisionService) recover(e *error, ths *[]sdk.Client, chs *[]sdk.Chan
}
}
func needsBootstrap(th sdk.Client) bool {
func needsBootstrap(th smqSDK.Client) bool {
if th.Metadata == nil {
return false
}
+9 -9
View File
@@ -8,13 +8,13 @@ import (
"testing"
"github.com/absmach/magistrala/internal/testsutil"
sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks"
"github.com/absmach/magistrala/provision"
smqlog "github.com/absmach/supermq/logger"
"github.com/absmach/supermq/pkg/errors"
repoerr "github.com/absmach/supermq/pkg/errors/repository"
svcerr "github.com/absmach/supermq/pkg/errors/service"
sdk "github.com/absmach/supermq/pkg/sdk"
sdkmocks "github.com/absmach/supermq/pkg/sdk/mocks"
smqSDK "github.com/absmach/supermq/pkg/sdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
@@ -50,8 +50,8 @@ func TestMapping(t *testing.T) {
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
pm := sdk.PageMetadata{Offset: uint64(0), Limit: uint64(10)}
repocall := mgsdk.On("Users", pm, c.token).Return(sdk.UsersPage{}, c.sdkerr)
pm := smqSDK.PageMetadata{Offset: uint64(0), Limit: uint64(10)}
repocall := mgsdk.On("Users", pm, c.token).Return(smqSDK.UsersPage{}, c.sdkerr)
content, err := svc.Mapping(c.token)
assert.True(t, errors.Contains(err, c.err), fmt.Sprintf("expected error %v, got %v", c.err, err))
assert.Equal(t, c.content, content)
@@ -215,14 +215,14 @@ func TestCert(t *testing.T) {
mgsdk := new(sdkmocks.SDK)
svc := provision.New(c.config, mgsdk, smqlog.NewMock())
mgsdk.On("Client", c.clientID, c.domainID, mock.Anything).Return(sdk.Client{ID: c.clientID}, c.sdkClientErr)
mgsdk.On("IssueCert", c.clientID, c.config.Cert.TTL, c.domainID, mock.Anything).Return(sdk.Cert{SerialNumber: c.serial}, c.sdkCertErr)
mgsdk.On("ViewCert", c.serial, mock.Anything, mock.Anything).Return(sdk.Cert{Certificate: c.cert, Key: c.key}, c.sdkCertErr)
login := sdk.Login{
mgsdk.On("Client", c.clientID, c.domainID, mock.Anything).Return(smqSDK.Client{ID: c.clientID}, c.sdkClientErr)
mgsdk.On("IssueCert", c.clientID, c.config.Cert.TTL, c.domainID, mock.Anything).Return(smqSDK.Cert{SerialNumber: c.serial}, c.sdkCertErr)
mgsdk.On("ViewCert", c.serial, mock.Anything, mock.Anything).Return(smqSDK.Cert{Certificate: c.cert, Key: c.key}, c.sdkCertErr)
login := smqSDK.Login{
Username: c.config.Server.MgUsername,
Password: c.config.Server.MgPass,
}
mgsdk.On("CreateToken", login).Return(sdk.Token{AccessToken: validToken}, c.sdkTokenErr)
mgsdk.On("CreateToken", login).Return(smqSDK.Token{AccessToken: validToken}, c.sdkTokenErr)
cert, key, err := svc.Cert(c.domainID, c.token, c.clientID, c.ttl)
assert.Equal(t, c.cert, cert)
assert.Equal(t, c.key, key)
+1 -1
View File
@@ -5,7 +5,7 @@
package mocks
import (
readers "github.com/absmach/supermq/readers"
readers "github.com/absmach/magistrala/readers"
mock "github.com/stretchr/testify/mock"
)
+1 -44
View File
@@ -6,53 +6,10 @@ filename: "{{.InterfaceName}}.go"
outpkg: "mocks"
boilerplate-file: "./tools/config/boilerplate.txt"
packages:
github.com/absmach/supermq/api/grpc/clients/v1:
interfaces:
ClientsServiceClient:
config:
dir: "./clients/mocks"
mockname: "ClientsServiceClient"
filename: "clients_client.go"
github.com/absmach/supermq/api/grpc/domains/v1:
interfaces:
DomainsServiceClient:
config:
dir: "./domains/mocks"
mockname: "DomainsServiceClient"
filename: "domains_client.go"
github.com/absmach/supermq/api/grpc/token/v1:
interfaces:
TokenServiceClient:
config:
dir: "./auth/mocks"
mockname: "TokenServiceClient"
filename: "token_client.go"
github.com/absmach/supermq/api/grpc/channels/v1:
interfaces:
ChannelsServiceClient:
config:
dir: "./channels/mocks"
mockname: "ChannelsServiceClient"
filename: "channels_client.go"
github.com/absmach/supermq/api/grpc/groups/v1:
interfaces:
GroupsServiceClient:
config:
dir: "./groups/mocks"
mockname: "GroupsServiceClient"
filename: "groups_client.go"
github.com/absmach/supermq/pkg/sdk:
github.com/absmach/magistrala/pkg/sdk:
interfaces:
SDK:
config:
dir: "./pkg/sdk/mocks"
mockname: "SDK"
filename: "sdk.go"
github.com/absmach/supermq/certs/pki/amcerts:
interfaces:
Agent:
config:
dir: "./certs/mocks"
mockname: "Agent"
filename: "pki.go"
+15 -14
View File
@@ -21,7 +21,8 @@ import (
"time"
"github.com/0x6flab/namegenerator"
sdk "github.com/absmach/supermq/pkg/sdk"
sdk "github.com/absmach/magistrala/pkg/sdk"
supermqSDK "github.com/absmach/supermq/pkg/sdk"
)
const (
@@ -60,7 +61,7 @@ func Provision(conf Config) error {
ttl = "2400h"
)
msgContentType := string(sdk.CTJSONSenML)
msgContentType := string(supermqSDK.CTJSONSenML)
sdkConf := sdk.Config{
ClientsURL: conf.Host,
UsersURL: conf.Host,
@@ -68,15 +69,15 @@ func Provision(conf Config) error {
HTTPAdapterURL: fmt.Sprintf("%s/http", conf.Host),
BootstrapURL: conf.Host,
CertsURL: conf.Host,
MsgContentType: sdk.ContentType(msgContentType),
MsgContentType: supermqSDK.ContentType(msgContentType),
TLSVerification: false,
}
s := sdk.NewSDK(sdkConf)
user := sdk.User{
user := supermqSDK.User{
Email: conf.Email,
Credentials: sdk.Credentials{
Credentials: supermqSDK.Credentials{
Username: conf.Username,
Secret: conf.Password,
},
@@ -95,14 +96,14 @@ func Provision(conf Config) error {
var err error
// Login user
token, err := s.CreateToken(sdk.Login{Username: user.Credentials.Username, Password: user.Credentials.Secret})
token, err := s.CreateToken(supermqSDK.Login{Username: user.Credentials.Username, Password: user.Credentials.Secret})
if err != nil {
return fmt.Errorf("unable to login user: %s", err.Error())
}
// Create new domain
dname := fmt.Sprintf("%s%s", conf.Prefix, namesgenerator.Generate())
domain := sdk.Domain{
domain := supermqSDK.Domain{
Name: dname,
Alias: strings.ToLower(dname),
Permission: "admin",
@@ -113,7 +114,7 @@ func Provision(conf Config) error {
return fmt.Errorf("unable to create domain: %w", err)
}
// Login to domain
token, err = s.CreateToken(sdk.Login{
token, err = s.CreateToken(supermqSDK.Login{
Username: user.Credentials.Username,
Password: user.Credentials.Secret,
})
@@ -147,16 +148,16 @@ func Provision(conf Config) error {
}
// Create clients and channels
clients := make([]sdk.Client, conf.Num)
channels := make([]sdk.Channel, conf.Num)
clients := make([]supermqSDK.Client, conf.Num)
channels := make([]supermqSDK.Channel, conf.Num)
cIDs := []string{}
tIDs := []string{}
fmt.Println("# List of clients that can be connected to MQTT broker")
for i := 0; i < conf.Num; i++ {
clients[i] = sdk.Client{Name: fmt.Sprintf("%s-client-%d", conf.Prefix, i)}
channels[i] = sdk.Channel{Name: fmt.Sprintf("%s-channel-%d", conf.Prefix, i)}
clients[i] = supermqSDK.Client{Name: fmt.Sprintf("%s-client-%d", conf.Prefix, i)}
channels[i] = supermqSDK.Channel{Name: fmt.Sprintf("%s-channel-%d", conf.Prefix, i)}
}
clients, err = s.CreateClients(clients, domain.ID, token.AccessToken)
@@ -164,7 +165,7 @@ func Provision(conf Config) error {
return fmt.Errorf("failed to create the clients: %s", err.Error())
}
var chs []sdk.Channel
var chs []supermqSDK.Channel
for _, c := range channels {
c, err = s.CreateChannel(c, domain.ID, token.AccessToken)
if err != nil {
@@ -257,7 +258,7 @@ func Provision(conf Config) error {
for _, cID := range cIDs {
for _, tID := range tIDs {
conIDs := sdk.Connection{
conIDs := supermqSDK.Connection{
ClientIDs: []string{tID},
ChannelIDs: []string{cID},
Types: []string{"publish", "subscribe"},