-
Notifications
You must be signed in to change notification settings - Fork 0
/
chirpstack.go
154 lines (131 loc) · 5.96 KB
/
chirpstack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package client
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"time"
"github.com/chirpstack/chirpstack/api/go/v4/api"
"github.com/chirpstack/chirpstack/api/go/v4/common"
"github.com/halter-corp/terraform-provider-chirpstack/client/model"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
type Chirpstack interface {
// tenant
CreateTenant(ctx context.Context, tenant *api.Tenant) (string, error)
GetTenant(ctx context.Context, id string) (*api.Tenant, error)
UpdateTenant(ctx context.Context, tenant *api.Tenant) error
DeleteTenant(ctx context.Context, id string) error
ListTenants(ctx context.Context, name string, limit uint32) ([]*api.TenantListItem, error)
// application
ListApplications(ctx context.Context, tenantID, name string, limit uint32) ([]*api.ApplicationListItem, error)
CreateApplication(ctx context.Context, tenantID, name, description string) (string, error)
GetApplication(ctx context.Context, id string) (*api.Application, error)
UpdateApplication(ctx context.Context, application *api.Application) error
DeleteApplication(ctx context.Context, id string) error
// integrations
CreateHttpIntegration(ctx context.Context, integration *api.HttpIntegration) error
GetHttpIntegration(ctx context.Context, applicationId string) (*api.HttpIntegration, error)
UpdateHttpIntegration(ctx context.Context, integration *api.HttpIntegration) error
DeleteHttpIntegration(ctx context.Context, applicationId string) error
// messaging
Enqueue(ctx context.Context, request *api.EnqueueDeviceQueueItemRequest) (*api.EnqueueDeviceQueueItemResponse, error)
MulticastEnqueue(ctx context.Context, request *api.EnqueueMulticastGroupQueueItemRequest) (*api.EnqueueMulticastGroupQueueItemResponse, error)
// multicast group
ListMulticastGroups(ctx context.Context, applicationID, name string, limit uint32) ([]*api.MulticastGroupListItem, error)
GetMulticastGroup(ctx context.Context, id string) (*api.GetMulticastGroupResponse, error)
CreateMulticastGroup(ctx context.Context, applicationID, name string, region common.Region, mcAddr, mcNwkSKey, mcAppSKey string, fCnt uint32, dr, frequency uint32) error
DeleteMulticastGroup(ctx context.Context, id string) error
AddGatewayToMulticastGroup(ctx context.Context, multicastGroupId, gatewayId string) error
RemoveGatewayFromMulticastGroup(ctx context.Context, multicastGroupId, gatewayId string) error
// gateway
ListGateways(ctx context.Context, request *api.ListGatewaysRequest) ([]*api.GatewayListItem, error)
CreateGateway(ctx context.Context, gatewayEui, tenantID string, latitude, longitude, altitude float64, accuracy float32, statsInterval uint32) error
// device
ListDevices(ctx context.Context, applicationID, name string, limit uint32) ([]*api.DeviceListItem, error)
GetDevice(ctx context.Context, deviceEui string) (*model.GetDeviceResponse, error)
CreateDevice(ctx context.Context, applicationID, deviceProfileID, deviceEui, name, joinEui, devAddr, appSKey, nwkSEncKey, appKey string) error
DeleteDevice(ctx context.Context, deviceEui string) error
// device profile
ListDeviceProfiles(ctx context.Context, tenantID, name string, limit uint32) ([]*api.DeviceProfileListItem, error)
GetDeviceProfile(ctx context.Context, id string) (*api.DeviceProfile, error)
CreateDeviceProfile(ctx context.Context, deviceProfile *api.DeviceProfile) (string, error)
UpdateDeviceProfile(ctx context.Context, deviceProfile *api.DeviceProfile) error
DeleteDeviceProfile(ctx context.Context, id string) error
}
type apiToken string
func (a apiToken) GetRequestMetadata(
ctx context.Context,
url ...string,
) (map[string]string, error) {
return map[string]string{
"authorization": fmt.Sprintf("Bearer %s", a),
}, nil
}
func (a apiToken) RequireTransportSecurity() bool {
return false
}
func getCerts(host string, port int) ([]*x509.Certificate, error) {
conf := &tls.Config{
InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", host, port), conf)
if err != nil {
return nil, err
}
defer func() {
_ = conn.Close()
}()
certs := conn.ConnectionState().PeerCertificates
return certs, nil
}
func loadTLSCredentials(host string, port int) (credentials.TransportCredentials, error) {
certs, err := getCerts(host, port)
if err != nil {
return nil, err
}
certPool := x509.NewCertPool()
for _, cert := range certs {
certPool.AddCert(cert)
}
// Create the credentials and return it
config := &tls.Config{
RootCAs: certPool,
}
return credentials.NewTLS(config), nil
}
func GetChirpstackConn(ctx context.Context, host string, port int, apiKey string) (grpc.ClientConnInterface, error) {
tlsCredentials, loadTLSCredErr := loadTLSCredentials(host, port)
if loadTLSCredErr != nil {
return nil, fmt.Errorf("cannot load TLS credentials: %v", loadTLSCredErr)
}
// debug issues with: export GRPC_GO_LOG_SEVERITY_LEVEL=info
optionList := []grpc.DialOption{
grpc.WithBlock(),
grpc.WithPerRPCCredentials(apiToken(apiKey)),
grpc.WithTransportCredentials(tlsCredentials),
}
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
conn, dialErr := grpc.DialContext(ctx, fmt.Sprintf("%s:%d", host, port), optionList...)
return conn, dialErr
}
type chirpstack struct {
tenantServiceClient api.TenantServiceClient
applicationServiceClient api.ApplicationServiceClient
deviceServiceClient api.DeviceServiceClient
deviceProfileServiceClient api.DeviceProfileServiceClient
multicastGroupServiceClient api.MulticastGroupServiceClient
gatewayServiceClient api.GatewayServiceClient
}
func NewChirpstack(conn grpc.ClientConnInterface) Chirpstack {
return &chirpstack{
tenantServiceClient: api.NewTenantServiceClient(conn),
applicationServiceClient: api.NewApplicationServiceClient(conn),
deviceServiceClient: api.NewDeviceServiceClient(conn),
deviceProfileServiceClient: api.NewDeviceProfileServiceClient(conn),
multicastGroupServiceClient: api.NewMulticastGroupServiceClient(conn),
gatewayServiceClient: api.NewGatewayServiceClient(conn),
}
}