mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
8eb1fac9ad
* Refactor and update dependencies in the project - Updated go.sum to replace `github.com/absmach/magistrala` with `github.com/absmach/supermq` across various modules. - Removed VSock configuration from environment variables and QEMU arguments. - Updated QEMU configuration and related tests to remove references to guest CID and VSock. - Added new HTTP transport layer for API endpoints in the manager. - Introduced Prometheus monitoring configuration with alert rules and Alertmanager setup. - Updated service and VM interfaces to remove unused methods and references. - Refactored tests to align with the new structure and dependencies. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add MaxVMs configuration and enforce limit on VM creation Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive tests for HTTP transport handlers and endpoints Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add test case for exceeding maximum number of VMs in TestRun Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Improve error handling in TestHandlerWithCustomRouter to ensure response writing is checked Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Update dependencies to latest versions - Upgrade cel.dev/expr from v0.23.0 to v0.24.0 - Upgrade github.com/absmach/supermq from v0.16.0 to v0.17.0 - Upgrade github.com/cenkalti/backoff from v4.3.0 to v5.0.2 - Upgrade github.com/cncf/xds/go to v0.0.0-20250501225837-2ac532fd4443 - Upgrade github.com/go-chi/chi/v5 from v5.2.1 to v5.2.2 - Upgrade github.com/go-jose/go-jose/v3 from v3.0.3 to v3.0.4 - Upgrade github.com/gofrs/uuid/v5 from v5.3.0 to v5.3.2 - Upgrade github.com/prometheus/client_golang from v1.22.0 to v1.23.0 - Upgrade github.com/prometheus/client_model from v0.6.1 to v0.6.2 - Upgrade github.com/prometheus/common from v0.62.0 to v0.65.0 - Upgrade github.com/prometheus/procfs from v0.15.1 to v0.16.1 - Upgrade go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from v0.60.0 to v0.62.0 - Upgrade go.opentelemetry.io/otel/exporters/otlp/otlptrace from v1.36.0 to v1.37.0 - Upgrade golang.org/x/crypto from v0.39.0 to v0.40.0 - Upgrade golang.org/x/sys from v0.33.0 to v0.34.0 - Upgrade golang.org/x/text from v0.26.0 to v0.27.0 - Upgrade golang.org/x/time from v0.11.0 to v0.12.0 - Upgrade google.golang.org/grpc from v1.73.0 to v1.74.2 Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
203 lines
4.7 KiB
Go
203 lines
4.7 KiB
Go
// Copyright (c) Ultraviolet
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package grpc
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
)
|
|
|
|
type security int
|
|
|
|
const (
|
|
withoutTLS security = iota
|
|
withTLS
|
|
withmTLS
|
|
withaTLS
|
|
withmaTLS
|
|
)
|
|
|
|
const (
|
|
AttestationReportSize = 0x4A0
|
|
WithMATLS = "with maTLS"
|
|
WithATLS = "with aTLS"
|
|
WithTLS = "with TLS"
|
|
)
|
|
|
|
var (
|
|
errGrpcConnect = errors.New("failed to connect to grpc server")
|
|
errGrpcClose = errors.New("failed to close grpc connection")
|
|
errCertificateParse = errors.New("failed to parse x509 certificate")
|
|
errAttVerification = errors.New("certificat is not self signed")
|
|
errFailedToLoadClientCertKey = errors.New("failed to load client certificate and key")
|
|
errFailedToLoadRootCA = errors.New("failed to load root ca file")
|
|
)
|
|
|
|
type ClientConfiguration interface {
|
|
GetBaseConfig() BaseConfig
|
|
}
|
|
|
|
type BaseConfig struct {
|
|
URL string `env:"URL" envDefault:"localhost:7001"`
|
|
Timeout time.Duration `env:"TIMEOUT" envDefault:"60s"`
|
|
ClientCert string `env:"CLIENT_CERT" envDefault:""`
|
|
ClientKey string `env:"CLIENT_KEY" envDefault:""`
|
|
ServerCAFile string `env:"SERVER_CA_CERTS" envDefault:""`
|
|
}
|
|
|
|
type AgentClientConfig struct {
|
|
BaseConfig
|
|
AttestationPolicy string `env:"ATTESTATION_POLICY" envDefault:""`
|
|
AttestedTLS bool `env:"ATTESTED_TLS" envDefault:"false"`
|
|
ProductName string `env:"PRODUCT_NAME" envDefault:"Milan"`
|
|
}
|
|
|
|
type ManagerClientConfig struct {
|
|
BaseConfig
|
|
}
|
|
|
|
type CVMClientConfig struct {
|
|
BaseConfig
|
|
}
|
|
|
|
func (a BaseConfig) GetBaseConfig() BaseConfig {
|
|
return a
|
|
}
|
|
|
|
func (a AgentClientConfig) GetBaseConfig() BaseConfig {
|
|
return a.BaseConfig
|
|
}
|
|
|
|
func (a CVMClientConfig) GetBaseConfig() BaseConfig {
|
|
return a.BaseConfig
|
|
}
|
|
|
|
type Client interface {
|
|
Close() error
|
|
Secure() string
|
|
Connection() *grpc.ClientConn
|
|
}
|
|
|
|
type client struct {
|
|
*grpc.ClientConn
|
|
cfg ClientConfiguration
|
|
secure security
|
|
}
|
|
|
|
var _ Client = (*client)(nil)
|
|
|
|
func NewClient(cfg ClientConfiguration) (Client, error) {
|
|
conn, secure, err := connect(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &client{
|
|
ClientConn: conn,
|
|
cfg: cfg,
|
|
secure: secure,
|
|
}, nil
|
|
}
|
|
|
|
func (c *client) Close() error {
|
|
if err := c.ClientConn.Close(); err != nil {
|
|
return errors.Wrap(errGrpcClose, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *client) Secure() string {
|
|
switch c.secure {
|
|
case withTLS:
|
|
return WithTLS
|
|
case withmTLS:
|
|
return "with mTLS"
|
|
case withaTLS:
|
|
return "with aTLS"
|
|
case withmaTLS:
|
|
return WithMATLS
|
|
default:
|
|
return "without TLS"
|
|
}
|
|
}
|
|
|
|
func (c *client) Connection() *grpc.ClientConn {
|
|
return c.ClientConn
|
|
}
|
|
|
|
func connect(cfg ClientConfiguration) (*grpc.ClientConn, security, error) {
|
|
opts := []grpc.DialOption{
|
|
grpc.WithStatsHandler(otelgrpc.NewClientHandler()),
|
|
}
|
|
secure := withoutTLS
|
|
|
|
if agcfg, ok := cfg.(AgentClientConfig); ok && agcfg.AttestedTLS {
|
|
tc, sec, err := setupATLS(agcfg)
|
|
if err != nil {
|
|
return nil, secure, err
|
|
}
|
|
|
|
opts = append(opts, grpc.WithTransportCredentials(tc))
|
|
|
|
secure = sec
|
|
} else {
|
|
conf := cfg.GetBaseConfig()
|
|
transportCreds, sec, err := loadTLSConfig(conf.ServerCAFile, conf.ClientCert, conf.ClientKey)
|
|
if err != nil {
|
|
return nil, secure, err
|
|
}
|
|
opts = append(opts, grpc.WithTransportCredentials(transportCreds))
|
|
secure = sec
|
|
}
|
|
|
|
conn, err := grpc.Dial(cfg.GetBaseConfig().URL, opts...)
|
|
if err != nil {
|
|
return nil, secure, errors.Wrap(errGrpcConnect, err)
|
|
}
|
|
return conn, secure, nil
|
|
}
|
|
|
|
func loadTLSConfig(serverCAFile, clientCert, clientKey string) (credentials.TransportCredentials, security, error) {
|
|
tlsConfig := &tls.Config{}
|
|
secure := withoutTLS
|
|
tc := insecure.NewCredentials()
|
|
|
|
if serverCAFile != "" {
|
|
rootCA, err := os.ReadFile(serverCAFile)
|
|
if err != nil {
|
|
return nil, secure, errors.Wrap(errFailedToLoadRootCA, err)
|
|
}
|
|
if len(rootCA) > 0 {
|
|
capool := x509.NewCertPool()
|
|
if !capool.AppendCertsFromPEM(rootCA) {
|
|
return nil, secure, fmt.Errorf("failed to append root ca to tls.Config")
|
|
}
|
|
tlsConfig.RootCAs = capool
|
|
secure = withTLS
|
|
tc = credentials.NewTLS(tlsConfig)
|
|
}
|
|
}
|
|
|
|
if clientCert != "" || clientKey != "" {
|
|
certificate, err := tls.LoadX509KeyPair(clientCert, clientKey)
|
|
if err != nil {
|
|
return nil, secure, errors.Wrap(errFailedToLoadClientCertKey, err)
|
|
}
|
|
tlsConfig.Certificates = []tls.Certificate{certificate}
|
|
secure = withmTLS
|
|
tc = credentials.NewTLS(tlsConfig)
|
|
}
|
|
|
|
return tc, secure, nil
|
|
}
|