func (c *C7000) applyAddLdapGroupBayAccess(group string) (err error) {
	bladebays := bladeBays{}
	for b := 1; b <= 16; b++ {
		baynumber := bayNumber{Text: b}
		access := access{Text: true}
		blade := blade{Hpoa: "hpoa.xsd", BayNumber: baynumber, Access: access}
		bladebays.Blade = append(bladebays.Blade, blade)
	}
	interconnecttraybays := interconnectTrayBays{}
	for t := 1; t <= 8; t++ {
		access := access{Text: true}
		baynumber := bayNumber{Text: t}
		interconnecttray := interconnectTray{Hpoa: "hpoa.xsd", Access: access, BayNumber: baynumber}
		interconnecttraybays.InterconnectTray = append(interconnecttraybays.InterconnectTray, interconnecttray)
	}
	bayz := bays{
		Hpoa:                 "hpoa.xsd",
		OaAccess:             oaAccess{Text: true},
		BladeBays:            bladebays,
		InterconnectTrayBays: interconnecttraybays,
	}
	payload := addLdapGroupBayAccess{
		LdapGroup: ldapGroup{Text: group},
		Bays:      bayz,
	}
	statusCode, _, err := c.postXML(payload)
	if statusCode != 200 || err != nil {
		c.log.V(1).Info("LDAP applyAddLdapGroupBayAccess apply request returned non 200.",
			"step", "applyAddLdapGroupBayAccess",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	c.log.V(1).Info("Ldap interconnect and bay ACLs added.",
		"IP", c.ip,
		"Model", c.HardwareType(),
		"Group", group,
	)
	return err
}
Set blade, interconnect access
<hpoa:addLdapGroupBayAccess>
<hpoa:ldapGroup>bmcAdmins</hpoa:ldapGroup>
<hpoa:bays xmlns:hpoa="hpoa.xsd">
<hpoa:oaAccess>true</hpoa:oaAccess>
<hpoa:bladeBays>
<hpoa:blade xmlns:hpoa="hpoa.xsd">
<hpoa:bayNumber>1</hpoa:bayNumber>
<hpoa:access>true</hpoa:access>
</hpoa:blade>
<hpoa:blade xmlns:hpoa="hpoa.xsd">
<hpoa:bayNumber>2</hpoa:bayNumber>
<hpoa:access>true</hpoa:access>
</hpoa:blade>
.... repeat for number of blades in a c7000 chassis ~ 16 max
</hpoa:bladeBays>
<hpoa:interconnectTrayBays>
<hpoa:interconnectTray xmlns:hpoa="hpoa.xsd">
<hpoa:bayNumber>1</hpoa:bayNumber>
<hpoa:access>true</hpoa:access>
</hpoa:interconnectTray>
<hpoa:interconnectTray xmlns:hpoa="hpoa.xsd">
<hpoa:bayNumber>2</hpoa:bayNumber>
<hpoa:access>true</hpoa:access>
</hpoa:interconnectTray>
...  repeat for number of interconnect bays in chassis ~ 8
<hpoa:interconnectTrayBays>
</hpoa:bays>
</hpoa:addLdapGroupBayAccess>
package c7000
import (
	"crypto/x509"
	"errors"
	"github.com/bmc-toolbox/bmclib/cfgresources"
	"github.com/bmc-toolbox/bmclib/devices"
	"github.com/bmc-toolbox/bmclib/internal"
)
var _ devices.Configure = (*C7000)(nil)
func (c *C7000) Resources() []string {
	return []string{
		"user",
		"syslog",
		"license",
		"ntp",
		"ldap_group",
		"ldap",
	}
}
func (c *C7000) ResourcesSetup() []string {
	return []string{
		"add_blade_bmc_admins",
		"remove_blade_bmc_users",
		"dynamicpower",
		"bladespower",
	}
}
func (c *C7000) isRoleValid(role string) bool {
	validRoles := []string{"admin", "user"}
	for _, v := range validRoles {
		if role == v {
			return true
		}
	}
	return false
}
func (c *C7000) ApplyCfg(config *cfgresources.ResourcesConfig) (err error) {
	return nil
}
func (c *C7000) Power(cfg *cfgresources.Power) (err error) {
	return err
}
func (c *C7000) Ldap(cfg *cfgresources.Ldap) (err error) {
	err = c.applysetLdapInfo4(cfg)
	if err != nil {
		c.log.V(1).Info("applyLdapParams returned error.",
			"step", "applyLdapParams",
			"resource", "Ldap",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	err = c.applyEnableLdapAuth(cfg.Enable)
	if err != nil {
		c.log.V(1).Info("applyLdapParams returned error.",
			"step", "applyLdapParams",
			"resource", "Ldap",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	return err
}
func (c *C7000) applysetLdapInfo4(cfg *cfgresources.Ldap) (err error) {
	if cfg.Server == "" {
		c.log.V(1).Info("Ldap resource parameter Server required but not declared.",
			"step", "applysetLdapInfo4",
			"Model", c.HardwareType(),
		)
		return err
	}
	if cfg.Port == 0 {
		c.log.V(1).Info("Ldap resource parameter Port required but not declared.",
			"step", "applysetLdapInfo4",
			"Model", c.HardwareType(),
		)
		return err
	}
	if cfg.BaseDn == "" {
		c.log.V(1).Info("Ldap resource parameter BaseDn required but not declared.",
			"step", "applysetLdapInfo4",
		)
		return err
	}
	searchcontexts := SearchContexts{Hpoa: "hpoa.xsd"}
	searchcontexts.SearchContext = append(searchcontexts.SearchContext, SearchContext{Text: cfg.BaseDn})
	for s := 1; s <= 6; s++ {
		searchcontexts.SearchContext = append(searchcontexts.SearchContext, SearchContext{Text: ""})
	}
	payload := setLdapInfo4{
		DirectoryServerAddress:   cfg.Server,
		DirectoryServerSslPort:   cfg.Port,
		DirectoryServerGCPort:    0,
		UserNtAccountNameMapping: false,
		EnableServiceAccount:     false,
		ServiceAccountName:       "",
		ServiceAccountPassword:   "",
		SearchContexts:           searchcontexts,
	}
	statusCode, _, err := c.postXML(payload)
	if statusCode != 200 || err != nil {
		c.log.V(1).Info("Ldap applysetLdapInfo4 apply request returned non 200.",
			"step", "applysetLdapInfo4",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	c.log.V(1).Info("Ldap Server parameters applied.",
		"IP", c.ip,
		"Model", c.HardwareType(),
	)
	return err
}
func (c *C7000) applyEnableLdapAuth(enable bool) (err error) {
	payload := enableLdapAuthentication{EnableLdap: enable, EnableLocalUsers: true}
	statusCode, _, err := c.postXML(payload)
	if statusCode != 200 || err != nil {
		c.log.V(1).Info("Ldap applyEnableLdapAuth apply request returned non 200.",
			"step", "applyEnableLdapAuth",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	c.log.V(1).Info("Ldap Enabled.",
		"IP", c.ip,
		"Model", c.HardwareType(),
	)
	return err
}
func (c *C7000) LdapGroups(cfgGroups []*cfgresources.LdapGroup, cfgLdap *cfgresources.Ldap) (err error) {
	for _, group := range cfgGroups {
		if group.Group == "" {
			c.log.V(1).Info("Ldap resource parameter Group required but not declared.",
				"step", "applyLdapGroupParams",
				"Model", c.HardwareType(),
				"Ldap role", group.Role,
			)
			return
		}
		if !group.Enable {
			err = c.applyRemoveLdapGroup(group.Group)
			if err != nil {
				c.log.V(1).Info("Remove Ldap Group returned error.",
					"step", "applyRemoveLdapGroup",
					"resource", "Ldap",
					"IP", c.ip,
					"Model", c.HardwareType(),
					"Error", internal.ErrStringOrEmpty(err),
				)
				return
			}
			continue
		}
		if !c.isRoleValid(group.Role) {
			c.log.V(1).Info("Ldap resource Role must be a valid role: admin OR user.",
				"step", "applyLdapGroupParams",
				"role", group.Role,
				"Model", c.HardwareType(),
			)
			return
		}
		err = c.applyAddLdapGroup(group.Group)
		if err != nil {
			c.log.V(1).Info("addLdapGroup returned error.",
				"step", "applyAddLdapGroup",
				"resource", "Ldap",
				"IP", c.ip,
				"Model", c.HardwareType(),
				"Error", internal.ErrStringOrEmpty(err),
			)
			return
		}
		err = c.applyLdapGroupBayACL(group.Role, group.Group)
		if err != nil {
			c.log.V(1).Info("addLdapGroup returned error.",
				"step", "setLdapGroupBayACL",
				"resource", "Ldap",
				"IP", c.ip,
				"Model", c.HardwareType(),
				"Error", internal.ErrStringOrEmpty(err),
			)
			return
		}
		err = c.applyAddLdapGroupBayAccess(group.Group)
		if err != nil {
			c.log.V(1).Info("addLdapGroup returned error.",
				"step", "applyAddLdapGroupBayAccess",
				"resource", "Ldap",
				"IP", c.ip,
				"Model", c.HardwareType(),
				"Error", internal.ErrStringOrEmpty(err),
			)
			return
		}
	}
	c.log.V(1).Info("Ldap config applied",
		"IP", c.ip,
		"Model", c.HardwareType(),
	)
	return
}
func (c *C7000) applyRemoveLdapGroup(group string) (err error) {
	payload := removeLdapGroup{LdapGroup: ldapGroup{Text: group}}
	statusCode, _, err := c.postXML(payload)
	if statusCode == 200 || statusCode == 500 {  
		c.log.V(1).Info("Ldap applyRemoveLdapGroup applied.",
			"step", "applyRemoveLdapGroup",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
		)
		return nil
	}
	if statusCode >= 300 || err != nil {
		c.log.V(1).Info("Ldap applyRemoveLdapGroup request returned non 200.",
			"step", "applyRemoveLdapGroup",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
		)
		return err
	}
	c.log.V(1).Info("Ldap group removed.",
		"IP", c.ip,
		"Model", c.HardwareType(),
		"Group", group,
	)
	return nil
}
func (c *C7000) applyAddLdapGroup(group string) (err error) {
	payload := addLdapGroup{LdapGroup: ldapGroup{Text: group}}
	statusCode, _, err := c.postXML(payload)
	if statusCode == 200 || statusCode == 500 {  
		c.log.V(1).Info("Ldap applyAddLdapGroup applied.",
			"step", "applyAddLdapGroup",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
		)
		return nil
	}
	if statusCode >= 300 || err != nil {
		c.log.V(1).Info("Ldap applyAddLdapGroup request returned non 200.",
			"step", "applyAddLdapGroup",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
		)
		return err
	}
	c.log.V(1).Info("Ldap group added.",
		"IP", c.ip,
		"Model", c.HardwareType(),
	)
	return nil
}
func (c *C7000) applyLdapGroupBayACL(role string, group string) (err error) {
	var userACL string
	if role == "admin" {
		userACL = "ADMINISTRATOR"
	} else {
		userACL = "USER"
	}
	payload := setLdapGroupBayACL{LdapGroup: ldapGroup{Text: group}, ACL: ACL{Text: userACL}}
	statusCode, _, err := c.postXML(payload)
	if statusCode != 200 || err != nil {
		c.log.V(1).Info("LDAP applyLdapGroupBayACL request returned non 200.",
			"step", "applyLdapGroupBayACL",
			"IP", c.ip,
			"Model", c.HardwareType(),
			"statusCode", statusCode,
			"Error", internal.ErrStringOrEmpty(err),
		)
		return err
	}
	c.log.V(1).Info("Ldap group ACL added.",
		"IP", c.ip,
		"Model", c.HardwareType(),
		"Role", role,
		"Group", group,
	)
	return err
}