package pkg import ( "errors" "fmt" "github.rackspace.com/gorax/clients/sshAPI" "github.rackspace.com/gorax/tools/util" ) // SNMPAllowedAddressesPatch will insert the supplied addresses, keeping any existing ones. func (f5 *F5) SNMPAllowedAddressesPatch(addresses []string) error { if len(addresses) < 1 { return nil } cmdString := "modify /sys snmp allowed-addresses add { " for _, a := range addresses { if !util.ValidIpV4(a) { return fmt.Errorf("'%s' is not a valid IPv4 address", a) } cmdString += fmt.Sprintf("%s ", a) } cmdString += "}" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("addresses added successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } // SNMPAllowedAddressesPut Warning, PUT will REPLACE all existing addresses with this data set. Use PATCH if you're not CERTAIN func (f5 *F5) SNMPAllowedAddressesPut(addresses []string) error { if len(addresses) < 1 { return nil } cmdString := "modify /sys snmp allowed-addresses replace-all-with { " for _, a := range addresses { if !util.ValidIpV4(a) { return fmt.Errorf("'%s' is not a valid IPv4 address", a) } cmdString += fmt.Sprintf("%s ", a) } cmdString += "}" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) f5.Config.SNMPConfig.AllowedAddresses = addresses return nil } // SNMPAllowedAddressesDelete : will remove any matching addresses from the SNMP allowed-addresses list, leaving others in place. func (f5 *F5) SNMPAllowedAddressesDelete(addresses []string) error { if len(addresses) < 1 { return nil } cmdString := "modify /sys snmp allowed-addresses delete { " for _, a := range addresses { if !util.ValidIpV4(a) { return fmt.Errorf("'%s' is not a valid IPv4 address", a) } cmdString += fmt.Sprintf("%s ", a) } cmdString += "}" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("addresses added successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPUserPost(u *SNMPUser) error { if u == nil { return errors.New("empty data for user") } if u.Id == "" || u.UserName == "" { return errors.New("ID and Username must be populated (and usually identical)") } if u.AuthPassword != "" && u.AuthPasswordEncrypted != "" { return errors.New("AuthPassword and AuthPasswordEncrypted are mutually exclusive") } if u.PrivPassword != "" && u.PrivPasswordEncrypted != "" { return errors.New("PrivPassword and PrivPasswordEncrypted are mutually exclusive") } cmdString := fmt.Sprintf("modify /sys snmp users add { %s { username %s ", u.Id, u.UserName) if u.AuthProtocol != "" { cmdString += fmt.Sprintf("auth-protocol %s ", u.AuthProtocol) } if u.AuthPassword != "" { cmdString += fmt.Sprintf("auth-password %s ", u.AuthPassword) } if u.AuthPasswordEncrypted != "" { cmdString += fmt.Sprintf("auth-password-encrypted %s ", u.AuthPasswordEncrypted) } if u.PrivProtocol != "" { cmdString += fmt.Sprintf("privacy-protocol %s ", u.PrivProtocol) } if u.PrivPassword != "" { cmdString += fmt.Sprintf("privacy-password %s ", u.PrivPassword) } if u.PrivPasswordEncrypted != "" { cmdString += fmt.Sprintf("privacy-password-encrypted %s ", u.PrivPasswordEncrypted) } if u.SecurityLevel != "" { cmdString += fmt.Sprintf("security-level %s ", u.SecurityLevel) } if u.Access != "" { cmdString += fmt.Sprintf("access %s ", u.Access) } if u.Description != "" { cmdString += fmt.Sprintf("description \"%s\" ", u.Description) } if u.OidSubset != "" { cmdString += fmt.Sprintf("oid-subset %s ", u.OidSubset) } cmdString += "} }" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("user added successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPUserPatch(u *SNMPUser) error { if u == nil { return errors.New("empty data for user") } if u.Id == "" { return errors.New("ID must be populated") } if u.AuthPassword != "" && u.AuthPasswordEncrypted != "" { return errors.New("AuthPassword and AuthPasswordEncrypted are mutually exclusive") } if u.PrivPassword != "" && u.PrivPasswordEncrypted != "" { return errors.New("PrivPassword and PrivPasswordEncrypted are mutually exclusive") } cmdString := fmt.Sprintf("modify /sys snmp users modify { %s { ", u.Id) if u.UserName != "" { cmdString += fmt.Sprintf("username %s ", u.AuthProtocol) } if u.AuthProtocol != "" { cmdString += fmt.Sprintf("auth-protocol %s ", u.AuthProtocol) } if u.AuthPassword != "" { cmdString += fmt.Sprintf("auth-password %s ", u.AuthPassword) } if u.AuthPasswordEncrypted != "" { cmdString += fmt.Sprintf("auth-password-encrypted %s ", u.AuthPasswordEncrypted) } if u.PrivProtocol != "" { cmdString += fmt.Sprintf("privacy-protocol %s ", u.PrivProtocol) } if u.PrivPassword != "" { cmdString += fmt.Sprintf("privacy-password %s ", u.PrivPassword) } if u.PrivPasswordEncrypted != "" { cmdString += fmt.Sprintf("privacy-password-encrypted %s ", u.PrivPasswordEncrypted) } if u.SecurityLevel != "" { cmdString += fmt.Sprintf("security-level %s ", u.SecurityLevel) } if u.Access != "" { cmdString += fmt.Sprintf("access %s ", u.Access) } if u.Description != "" { cmdString += fmt.Sprintf("description \"%s\" ", u.Description) } if u.OidSubset != "" { cmdString += fmt.Sprintf("oid-subset %s ", u.OidSubset) } cmdString += "} }" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("user modified successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPUserPut(u *SNMPUser, ignoreMissing bool) error { if u == nil { return errors.New("empty data for user") } if u.Id == "" || u.UserName == "" { return errors.New("ID and Username must be populated (and usually identical)") } if u.AuthPassword != "" && u.AuthPasswordEncrypted != "" { return errors.New("AuthPassword and AuthPasswordEncrypted are mutually exclusive") } if u.PrivPassword != "" && u.PrivPasswordEncrypted != "" { return errors.New("PrivPassword and PrivPasswordEncrypted are mutually exclusive") } err := f5.SNMPUserDelete(u.Id, ignoreMissing) if err != nil { return fmt.Errorf("eror removing user to overwrite: %s", err.Error()) } err = f5.SNMPUserPost(u) if err != nil { return fmt.Errorf("user removed to overwrite, but Error replacing user: %s", err.Error()) } return nil } func (f5 *F5) SNMPUserDelete(id string, ignoreMissing bool) error { if id == "" { return nil } cmdString := fmt.Sprintf("modify /sys snmp users delete { %s }", id) var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { errString := f5Resp[1] if !(notFoundRegex.MatchString(errString) && ignoreMissing) { return errors.New(f5Resp[1]) } } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("user deleted successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPCommunityPost(c *SNMPCommunity) error { if c == nil { return errors.New("empty data for community") } if c.Id == "" || c.CommunityName == "" || c.Source == "" { return errors.New("community must have at least ID, CommunityName, and Source") } cmdString := fmt.Sprintf("modify /sys snmp communities add { %s { community-name %s source %s ", c.Id, c.CommunityName, c.Source) if c.OidSubset != "" { cmdString += fmt.Sprintf("oid-subset %s ", c.OidSubset) } if c.Access != "" { cmdString += fmt.Sprintf("access %s ", c.Access) } if c.Description != "" { cmdString += fmt.Sprintf("oid-subset \"%s\" ", c.Description) } cmdString += "} }" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("community added successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPCommunityPatch(c *SNMPCommunity) error { if c == nil { return errors.New("empty data for community") } if c.Id == "" { return errors.New("community must have ID populated") } cmdString := fmt.Sprintf("modify /sys snmp communities modify { %s { ", c.Id) if c.CommunityName != "" { cmdString += fmt.Sprintf("community-name %s ", c.CommunityName) } if c.Source != "" { cmdString += fmt.Sprintf("source %s ", c.Source) } if c.OidSubset != "" { cmdString += fmt.Sprintf("oid-subset %s ", c.OidSubset) } if c.Access != "" { cmdString += fmt.Sprintf("access %s ", c.Access) } if c.Description != "" { cmdString += fmt.Sprintf("description \"%s\" ", c.Description) } cmdString += "} }" var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { return errors.New(f5Resp[1]) } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("community modified successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil } func (f5 *F5) SNMPCommunityPut(c *SNMPCommunity, ignoreMissing bool) error { if c == nil { return errors.New("empty data for community") } if c.Id == "" || c.CommunityName == "" || c.Source == "" { return errors.New("community must have at least ID, CommunityName, and Source") } err := f5.SNMPCommunityDelete(c.Id, ignoreMissing) if err != nil { return fmt.Errorf("error removing community to overwrite: %s", err.Error()) } err = f5.SNMPCommunityPost(c) if err != nil { return fmt.Errorf("community removed to overwrite, but Error replacing user: %s", err.Error()) } return nil } func (f5 *F5) SNMPCommunityDelete(id string, ignoreMissing bool) error { if id == "" { return nil } cmdString := fmt.Sprintf("modify /sys snmp communities delete { %s }", id) var cmd []*sshAPI.Command cmd = append(cmd, sshAPI.ReCommandCreate(cmdString, 30, promptRegex)) res, err := f5.sshClient.PostCommands(cmd) if err != nil { return err } for _, resp := range res.Commands { if f5Resp := cmdResponseRegex.FindStringSubmatch(*resp.Response); f5Resp != nil { errString := f5Resp[1] if !(notFoundRegex.MatchString(errString) && ignoreMissing) { return errors.New(f5Resp[1]) } } } f5.AppendCommands(res) err = f5.GetSNMP() if err != nil { return fmt.Errorf("user deleted successfully but f5 refresh (GetSNMP) failed with: %s", err.Error()) } return nil }