123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- package mq
- import (
- "encoding/json"
- "errors"
- "fmt"
- "time"
- mqtt "github.com/eclipse/paho.mqtt.golang"
- "github.com/gravitl/netmaker/servercfg"
- )
- const (
- // constant for admin role
- adminRole = "admin"
- // constant for server role
- serverRole = "server"
- // constant for exporter role
- exporterRole = "exporter"
- // constant for node role
- NodeRole = "node"
- // HostGenericRole constant for host role
- HostGenericRole = "host"
- // const for dynamic security file
- dynamicSecurityFile = "dynamic-security.json"
- )
- var (
- // default configuration of dynamic security
- dynConfigInI = dynJSON{
- Clients: []client{
- {
- Username: mqAdminUserName,
- TextName: "netmaker admin user",
- Password: "",
- Salt: "",
- Iterations: 0,
- Roles: []clientRole{
- {
- Rolename: adminRole,
- },
- },
- },
- {
- Username: mqNetmakerServerUserName,
- TextName: "netmaker server user",
- Password: "",
- Salt: "",
- Iterations: 0,
- Roles: []clientRole{
- {
- Rolename: serverRole,
- },
- },
- },
- exporterMQClient,
- },
- Roles: []role{
- {
- Rolename: adminRole,
- Acls: fetchAdminAcls(),
- },
- {
- Rolename: serverRole,
- Acls: fetchServerAcls(),
- },
- {
- Rolename: HostGenericRole,
- Acls: fetchNodeAcls(),
- },
- exporterMQRole,
- },
- DefaultAcl: defaultAccessAcl{
- PublishClientSend: false,
- PublishClientReceive: true,
- Subscribe: false,
- Unsubscribe: true,
- },
- }
- exporterMQClient = client{
- Username: mqExporterUserName,
- TextName: "netmaker metrics exporter",
- Password: "",
- Salt: "",
- Iterations: 101,
- Roles: []clientRole{
- {
- Rolename: exporterRole,
- },
- },
- }
- exporterMQRole = role{
- Rolename: exporterRole,
- Acls: fetchExporterAcls(),
- }
- )
- // DynListCLientsCmdResp - struct for list clients response from MQ
- type DynListCLientsCmdResp struct {
- Responses []struct {
- Command string `json:"command"`
- Error string `json:"error"`
- Data ListClientsData `json:"data"`
- } `json:"responses"`
- }
- // ListClientsData - struct for list clients data
- type ListClientsData struct {
- Clients []string `json:"clients"`
- TotalCount int `json:"totalCount"`
- }
- // GetAdminClient - fetches admin client of the MQ
- func GetAdminClient() (mqtt.Client, error) {
- opts := mqtt.NewClientOptions()
- setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
- mqclient := mqtt.NewClient(opts)
- var connecterr error
- if token := mqclient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
- if token.Error() == nil {
- connecterr = errors.New("connect timeout")
- } else {
- connecterr = token.Error()
- }
- }
- return mqclient, connecterr
- }
- // ListClients - to list all clients in the MQ
- func ListClients(client mqtt.Client) (ListClientsData, error) {
- respChan := make(chan mqtt.Message, 10)
- defer close(respChan)
- command := "listClients"
- resp := ListClientsData{}
- msg := MqDynsecPayload{
- Commands: []MqDynSecCmd{
- {
- Command: command,
- },
- },
- }
- client.Subscribe("$CONTROL/dynamic-security/v1/response", 2, mqtt.MessageHandler(func(c mqtt.Client, m mqtt.Message) {
- respChan <- m
- }))
- defer client.Unsubscribe()
- d, _ := json.Marshal(msg)
- token := client.Publish("$CONTROL/dynamic-security/v1", 2, true, d)
- if !token.WaitTimeout(30) || token.Error() != nil {
- var err error
- if token.Error() == nil {
- err = errors.New("connection timeout")
- } else {
- err = token.Error()
- }
- return resp, err
- }
- for m := range respChan {
- msg := DynListCLientsCmdResp{}
- json.Unmarshal(m.Payload(), &msg)
- for _, mI := range msg.Responses {
- if mI.Command == command {
- return mI.Data, nil
- }
- }
- }
- return resp, errors.New("resp not found")
- }
- // fetches host related acls
- func fetchHostAcls(hostID string) []Acl {
- return []Acl{
- {
- AclType: "publishClientReceive",
- Topic: fmt.Sprintf("peers/host/%s/#", hostID),
- Priority: -1,
- Allow: true,
- },
- }
- }
- // FetchNetworkAcls - fetches network acls
- func FetchNetworkAcls(network string) []Acl {
- return []Acl{
- {
- AclType: "publishClientReceive",
- Topic: fmt.Sprintf("update/%s/#", network),
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: fmt.Sprintf("peers/%s/#", network),
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: fmt.Sprintf("proxy/%s/#", network),
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "unsubscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- }
- }
- // DeleteNetworkRole - deletes a network role from DynSec system
- func DeleteNetworkRole(network string) error {
- // Deletes the network role from MQ
- event := MqDynsecPayload{
- Commands: []MqDynSecCmd{
- {
- Command: DeleteRoleCmd,
- RoleName: network,
- },
- },
- }
- return publishEventToDynSecTopic(event)
- }
- func deleteHostRole(hostID string) error {
- // Deletes the hostID role from MQ
- event := MqDynsecPayload{
- Commands: []MqDynSecCmd{
- {
- Command: DeleteRoleCmd,
- RoleName: getHostRoleName(hostID),
- },
- },
- }
- return publishEventToDynSecTopic(event)
- }
- // CreateNetworkRole - createss a network role from DynSec system
- func CreateNetworkRole(network string) error {
- // Create Role with acls for the network
- event := MqDynsecPayload{
- Commands: []MqDynSecCmd{
- {
- Command: CreateRoleCmd,
- RoleName: network,
- Textname: "Network wide role with Acls for nodes",
- Acls: FetchNetworkAcls(network),
- },
- },
- }
- return publishEventToDynSecTopic(event)
- }
- // creates role for the host with ID.
- func createHostRole(hostID string) error {
- // Create Role with acls for the host
- event := MqDynsecPayload{
- Commands: []MqDynSecCmd{
- {
- Command: CreateRoleCmd,
- RoleName: getHostRoleName(hostID),
- Textname: "host role with Acls for hosts",
- Acls: fetchHostAcls(hostID),
- },
- },
- }
- return publishEventToDynSecTopic(event)
- }
- func getHostRoleName(hostID string) string {
- return fmt.Sprintf("host-%s", hostID)
- }
- // serverAcls - fetches server role related acls
- func fetchServerAcls() []Acl {
- return []Acl{
- {
- AclType: "publishClientSend",
- Topic: "peers/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "proxy/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "peers/host/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "update/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "metrics_exporter",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "ping/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "update/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "signal/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "metrics/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "unsubscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- }
- }
- // fetchNodeAcls - fetches node related acls
- func fetchNodeAcls() []Acl {
- // keeping node acls generic as of now.
- return []Acl{
- {
- AclType: "publishClientSend",
- Topic: "signal/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "update/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "ping/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "metrics/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "unsubscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- }
- }
- // fetchExporterAcls - fetch exporter role related acls
- func fetchExporterAcls() []Acl {
- return []Acl{
- {
- AclType: "publishClientReceive",
- Topic: "metrics_exporter",
- Allow: true,
- Priority: -1,
- },
- {
- AclType: "subscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "unsubscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- }
- }
- // fetchAdminAcls - fetches admin role related acls
- func fetchAdminAcls() []Acl {
- return []Acl{
- {
- AclType: "publishClientSend",
- Topic: "$CONTROL/dynamic-security/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "$CONTROL/dynamic-security/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "$CONTROL/dynamic-security/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "$SYS/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "$SYS/#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientReceive",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "subscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "unsubscribePattern",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- {
- AclType: "publishClientSend",
- Topic: "#",
- Priority: -1,
- Allow: true,
- },
- }
- }
|