mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-06 21:24:16 +08:00
added comments
This commit is contained in:
parent
b2df99e2c0
commit
677d9fcc8d
6 changed files with 160 additions and 135 deletions
|
@ -443,19 +443,18 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
// Deletes the network role from MQ
|
||||
event := mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteRoleCmd,
|
||||
RoleName: network,
|
||||
},
|
||||
event := mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteRoleCmd,
|
||||
RoleName: network,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
}
|
||||
logger.Log(1, r.Header.Get("user"), "deleted network", network)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -504,21 +503,20 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
// Create Role with acls for the network
|
||||
event := mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: network.NetID,
|
||||
Textname: "Network wide role with Acls for nodes",
|
||||
Acls: mq.FetchNetworkAcls(network.NetID),
|
||||
},
|
||||
event := mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: network.NetID,
|
||||
Textname: "Network wide role with Acls for nodes",
|
||||
Acls: mq.FetchNetworkAcls(network.NetID),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
}
|
||||
|
||||
if servercfg.IsClientMode() != "off" {
|
||||
|
|
|
@ -100,46 +100,46 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
|
|||
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||
return
|
||||
}
|
||||
event := mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
// creates network role, node role,node client (added here to resolve any missing configuration in MQ)
|
||||
event := mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: result.Network,
|
||||
Textname: "Network wide role with Acls for nodes",
|
||||
Acls: mq.FetchNetworkAcls(result.Network),
|
||||
},
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: result.Network,
|
||||
Textname: "Network wide role with Acls for nodes",
|
||||
Acls: mq.FetchNetworkAcls(result.Network),
|
||||
},
|
||||
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", result.ID),
|
||||
Acls: mq.FetchNodeAcls(result.ID),
|
||||
Textname: "Role for node " + result.Name,
|
||||
},
|
||||
{
|
||||
Command: mq.CreateClientCmd,
|
||||
Username: result.ID,
|
||||
Password: authRequest.Password,
|
||||
Textname: result.Name,
|
||||
Roles: []mq.MqDynSecRole{
|
||||
{
|
||||
Rolename: fmt.Sprintf("%s-%s", "Node", result.ID),
|
||||
Priority: -1,
|
||||
},
|
||||
{
|
||||
Rolename: result.Network,
|
||||
Priority: -1,
|
||||
},
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", result.ID),
|
||||
Acls: mq.FetchNodeAcls(result.ID),
|
||||
Textname: "Role for node " + result.Name,
|
||||
},
|
||||
{
|
||||
Command: mq.CreateClientCmd,
|
||||
Username: result.ID,
|
||||
Password: authRequest.Password,
|
||||
Textname: result.Name,
|
||||
Roles: []mq.MqDynSecRole{
|
||||
{
|
||||
Rolename: fmt.Sprintf("%s-%s", "Node", result.ID),
|
||||
Priority: -1,
|
||||
},
|
||||
{
|
||||
Rolename: result.Network,
|
||||
Priority: -1,
|
||||
},
|
||||
Groups: make([]mq.MqDynSecGroup, 0),
|
||||
},
|
||||
Groups: make([]mq.MqDynSecGroup, 0),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
errorResponse.Code = http.StatusInternalServerError
|
||||
errorResponse.Message = fmt.Sprintf("could not create mq client for node [%s]: %v", result.ID, err)
|
||||
return
|
||||
|
@ -662,53 +662,51 @@ func createNode(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
// Delete Any Existing Client with this ID.
|
||||
event := mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteClientCmd,
|
||||
Username: node.ID,
|
||||
},
|
||||
event := mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteClientCmd,
|
||||
Username: node.ID,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
}
|
||||
// Create client for this node in Mq
|
||||
event = mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),
|
||||
Acls: mq.FetchNodeAcls(node.ID),
|
||||
Textname: "Role for node " + node.Name,
|
||||
},
|
||||
{
|
||||
Command: mq.CreateClientCmd,
|
||||
Username: node.ID,
|
||||
Password: nodePassword,
|
||||
Textname: node.Name,
|
||||
Roles: []mq.MqDynSecRole{
|
||||
{
|
||||
Rolename: fmt.Sprintf("%s-%s", "Node", node.ID),
|
||||
Priority: -1,
|
||||
},
|
||||
{
|
||||
Rolename: node.Network,
|
||||
Priority: -1,
|
||||
},
|
||||
event = mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.CreateRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),
|
||||
Acls: mq.FetchNodeAcls(node.ID),
|
||||
Textname: "Role for node " + node.Name,
|
||||
},
|
||||
{
|
||||
Command: mq.CreateClientCmd,
|
||||
Username: node.ID,
|
||||
Password: nodePassword,
|
||||
Textname: node.Name,
|
||||
Roles: []mq.MqDynSecRole{
|
||||
{
|
||||
Rolename: fmt.Sprintf("%s-%s", "Node", node.ID),
|
||||
Priority: -1,
|
||||
},
|
||||
{
|
||||
Rolename: node.Network,
|
||||
Priority: -1,
|
||||
},
|
||||
Groups: make([]mq.MqDynSecGroup, 0),
|
||||
},
|
||||
Groups: make([]mq.MqDynSecGroup, 0),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
}
|
||||
|
||||
response := models.NodeGet{
|
||||
|
@ -1046,24 +1044,23 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
event := mq.DynSecAction{
|
||||
Payload: mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", nodeid),
|
||||
},
|
||||
{
|
||||
Command: mq.DeleteClientCmd,
|
||||
Username: nodeid,
|
||||
},
|
||||
// deletes node related role and client
|
||||
event := mq.MqDynsecPayload{
|
||||
Commands: []mq.MqDynSecCmd{
|
||||
{
|
||||
Command: mq.DeleteRoleCmd,
|
||||
RoleName: fmt.Sprintf("%s-%s", "Node", nodeid),
|
||||
},
|
||||
{
|
||||
Command: mq.DeleteClientCmd,
|
||||
Username: nodeid,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
|
||||
event.Payload.Commands, err.Error()))
|
||||
event.Commands, err.Error()))
|
||||
}
|
||||
logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
|
||||
logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
|
||||
|
|
70
mq/dynsec.go
70
mq/dynsec.go
|
@ -18,38 +18,53 @@ import (
|
|||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
const DynamicSecSubTopic = "$CONTROL/dynamic-security/#"
|
||||
const DynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
|
||||
// DynamicSecSubTopic - constant for dynamic security subscription topic
|
||||
const dynamicSecSubTopic = "$CONTROL/dynamic-security/#"
|
||||
|
||||
// DynamicSecPubTopic - constant for dynamic security subscription topic
|
||||
const dynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
|
||||
|
||||
// mq client for admin
|
||||
var mqAdminClient mqtt.Client
|
||||
|
||||
var (
|
||||
CreateClientCmd = "createClient"
|
||||
const (
|
||||
// constant for client command
|
||||
CreateClientCmd = "createClient"
|
||||
// constant for disable command
|
||||
DisableClientCmd = "disableClient"
|
||||
DeleteClientCmd = "deleteClient"
|
||||
ModifyClientCmd = "modifyClient"
|
||||
)
|
||||
// constant for delete client command
|
||||
DeleteClientCmd = "deleteClient"
|
||||
// constant for modify client command
|
||||
ModifyClientCmd = "modifyClient"
|
||||
|
||||
var (
|
||||
// constant for create role command
|
||||
CreateRoleCmd = "createRole"
|
||||
// constant for delete role command
|
||||
DeleteRoleCmd = "deleteRole"
|
||||
)
|
||||
|
||||
const (
|
||||
// constant for admin user name
|
||||
mqAdminUserName = "Netmaker-Admin"
|
||||
// constant for server user name
|
||||
mqNetmakerServerUserName = "Netmaker-Server"
|
||||
// constant for exporter user name
|
||||
mqExporterUserName = "Netmaker-Exporter"
|
||||
)
|
||||
|
||||
// struct for dynamic security file
|
||||
type dynJSON struct {
|
||||
Clients []client `json:"clients"`
|
||||
Roles []role `json:"roles"`
|
||||
DefaultAcl defaultAccessAcl `json:"defaultACLAccess"`
|
||||
}
|
||||
|
||||
var (
|
||||
mqAdminUserName string = "Netmaker-Admin"
|
||||
mqNetmakerServerUserName string = "Netmaker-Server"
|
||||
mqExporterUserName string = "Netmaker-Exporter"
|
||||
)
|
||||
|
||||
// struct for client role
|
||||
type clientRole struct {
|
||||
Rolename string `json:"rolename"`
|
||||
}
|
||||
|
||||
// struct for MQ client
|
||||
type client struct {
|
||||
Username string `json:"username"`
|
||||
TextName string `json:"textName"`
|
||||
|
@ -59,11 +74,13 @@ type client struct {
|
|||
Roles []clientRole `json:"roles"`
|
||||
}
|
||||
|
||||
// struct for MQ role
|
||||
type role struct {
|
||||
Rolename string `json:"rolename"`
|
||||
Acls []Acl `json:"acls"`
|
||||
}
|
||||
|
||||
// struct for default acls
|
||||
type defaultAccessAcl struct {
|
||||
PublishClientSend bool `json:"publishClientSend"`
|
||||
PublishClientReceive bool `json:"publishClientReceive"`
|
||||
|
@ -71,22 +88,19 @@ type defaultAccessAcl struct {
|
|||
Unsubscribe bool `json:"unsubscribe"`
|
||||
}
|
||||
|
||||
type dynCnf struct {
|
||||
Clients []client `json:"clients"`
|
||||
Roles []role `json:"roles"`
|
||||
DefaultACLAccess defaultAccessAcl `json:"defaultACLAccess"`
|
||||
}
|
||||
|
||||
// MqDynSecGroup - struct for MQ client group
|
||||
type MqDynSecGroup struct {
|
||||
Groupname string `json:"groupname"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// MqDynSecRole - struct for MQ client role
|
||||
type MqDynSecRole struct {
|
||||
Rolename string `json:"rolename"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// Acl - struct for MQ acls
|
||||
type Acl struct {
|
||||
AclType string `json:"acltype"`
|
||||
Topic string `json:"topic"`
|
||||
|
@ -94,6 +108,7 @@ type Acl struct {
|
|||
Allow bool `json:"allow"`
|
||||
}
|
||||
|
||||
// MqDynSecCmd - struct for MQ dynamic security command
|
||||
type MqDynSecCmd struct {
|
||||
Command string `json:"command"`
|
||||
Username string `json:"username"`
|
||||
|
@ -107,19 +122,18 @@ type MqDynSecCmd struct {
|
|||
Roles []MqDynSecRole `json:"roles"`
|
||||
}
|
||||
|
||||
type DynSecAction struct {
|
||||
Payload MqDynsecPayload
|
||||
}
|
||||
|
||||
// MqDynsecPayload - struct for dynamic security command payload
|
||||
type MqDynsecPayload struct {
|
||||
Commands []MqDynSecCmd `json:"commands"`
|
||||
}
|
||||
|
||||
// encodePasswordToPBKDF2 - encodes the given password with PBKDF2 hashing for MQ
|
||||
func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLength int) string {
|
||||
binaryEncoded := pbkdf2.Key([]byte(password), []byte(salt), iterations, keyLength, sha512.New)
|
||||
return base64.StdEncoding.EncodeToString(binaryEncoded)
|
||||
}
|
||||
|
||||
// Configure - configures the dynamic initial configuration for MQ
|
||||
func Configure() error {
|
||||
if servercfg.Is_EE {
|
||||
dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
|
||||
|
@ -155,14 +169,15 @@ func Configure() error {
|
|||
return os.WriteFile(path, data, 0755)
|
||||
}
|
||||
|
||||
func PublishEventToDynSecTopic(event DynSecAction) error {
|
||||
// PublishEventToDynSecTopic - publishes the message to dynamic security topic
|
||||
func PublishEventToDynSecTopic(payload MqDynsecPayload) error {
|
||||
|
||||
d, err := json.Marshal(event.Payload)
|
||||
d, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var connecterr error
|
||||
if token := mqAdminClient.Publish(DynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
|
||||
if token := mqAdminClient.Publish(dynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
|
||||
if token.Error() == nil {
|
||||
connecterr = errors.New("connect timeout")
|
||||
} else {
|
||||
|
@ -172,6 +187,7 @@ func PublishEventToDynSecTopic(event DynSecAction) error {
|
|||
return connecterr
|
||||
}
|
||||
|
||||
// watchDynSecTopic - message handler for dynamic security responses
|
||||
func watchDynSecTopic(client mqtt.Client, msg mqtt.Message) {
|
||||
|
||||
logger.Log(1, fmt.Sprintf("----->WatchDynSecTopic Message: %+v", string(msg.Payload())))
|
||||
|
|
|
@ -10,15 +10,21 @@ import (
|
|||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
var (
|
||||
AdminRole string = "admin"
|
||||
ServerRole string = "server"
|
||||
ExporterRole string = "exporter"
|
||||
const (
|
||||
// constant for admin role
|
||||
adminRole = "admin"
|
||||
// constant for server role
|
||||
serverRole = "server"
|
||||
// constant for exporter role
|
||||
exporterRole = "exporter"
|
||||
|
||||
// const for dynamic security file
|
||||
dynamicSecurityFile = "dynamic-security.json"
|
||||
)
|
||||
|
||||
var (
|
||||
dynamicSecurityFile = "dynamic-security.json"
|
||||
dynConfig = dynJSON{
|
||||
// default configuration of dynamic security
|
||||
dynConfig = dynJSON{
|
||||
Clients: []client{
|
||||
{
|
||||
Username: mqAdminUserName,
|
||||
|
@ -28,7 +34,7 @@ var (
|
|||
Iterations: 0,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: AdminRole,
|
||||
Rolename: adminRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -40,14 +46,14 @@ var (
|
|||
Iterations: 0,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: ServerRole,
|
||||
Rolename: serverRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Roles: []role{
|
||||
{
|
||||
Rolename: AdminRole,
|
||||
Rolename: adminRole,
|
||||
Acls: []Acl{
|
||||
{
|
||||
AclType: "publishClientSend",
|
||||
|
@ -106,7 +112,7 @@ var (
|
|||
},
|
||||
},
|
||||
{
|
||||
Rolename: ServerRole,
|
||||
Rolename: serverRole,
|
||||
Acls: []Acl{
|
||||
{
|
||||
AclType: "publishClientSend",
|
||||
|
@ -169,12 +175,12 @@ var (
|
|||
Iterations: 101,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: ExporterRole,
|
||||
Rolename: exporterRole,
|
||||
},
|
||||
},
|
||||
}
|
||||
exporterMQRole = role{
|
||||
Rolename: ExporterRole,
|
||||
Rolename: exporterRole,
|
||||
Acls: []Acl{
|
||||
{
|
||||
AclType: "publishClientReceive",
|
||||
|
@ -186,6 +192,7 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// DynListCLientsCmdResp - struct for list clients response from MQ
|
||||
type DynListCLientsCmdResp struct {
|
||||
Responses []struct {
|
||||
Command string `json:"command"`
|
||||
|
@ -194,11 +201,13 @@ type DynListCLientsCmdResp struct {
|
|||
} `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)
|
||||
|
@ -214,6 +223,7 @@ func GetAdminClient() (mqtt.Client, 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)
|
||||
|
@ -254,6 +264,7 @@ func ListClients(client mqtt.Client) (ListClientsData, error) {
|
|||
return resp, errors.New("resp not found")
|
||||
}
|
||||
|
||||
// FetchNetworkAcls - fetches network acls
|
||||
func FetchNetworkAcls(network string) []Acl {
|
||||
return []Acl{
|
||||
{
|
||||
|
@ -269,6 +280,7 @@ func FetchNetworkAcls(network string) []Acl {
|
|||
}
|
||||
}
|
||||
|
||||
// FetchNodeAcls -fetches node acls
|
||||
func FetchNodeAcls(nodeID string) []Acl {
|
||||
return []Acl{
|
||||
|
||||
|
|
3
mq/mq.go
3
mq/mq.go
|
@ -22,12 +22,13 @@ var peer_force_send = 0
|
|||
|
||||
var mqclient mqtt.Client
|
||||
|
||||
// SetUpAdminClient - sets up admin client for the MQ
|
||||
func SetUpAdminClient() {
|
||||
opts := mqtt.NewClientOptions()
|
||||
setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
|
||||
mqAdminClient = mqtt.NewClient(opts)
|
||||
opts.SetOnConnectHandler(func(client mqtt.Client) {
|
||||
if token := client.Subscribe(DynamicSecSubTopic, 0, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
if token := client.Subscribe(dynamicSecSubTopic, 0, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
client.Disconnect(240)
|
||||
logger.Log(0, "Dynamic security client subscription failed")
|
||||
}
|
||||
|
|
|
@ -622,6 +622,7 @@ func GetMQServerPort() string {
|
|||
return port
|
||||
}
|
||||
|
||||
// GetMqAdminPassword - fetches the MQ Admin password
|
||||
func GetMqAdminPassword() string {
|
||||
password := ""
|
||||
if os.Getenv("MQ_ADMIN_PASSWORD") != "" {
|
||||
|
|
Loading…
Add table
Reference in a new issue