func (b *backend) periodicFunc(req *logical.Request) error {
	if b.nextTidyTime.IsZero() || !time.Now().Before(b.nextTidyTime) {
		safety_buffer := 15552000
		tidyBlacklistConfigEntry, err := b.lockedConfigTidyRoleTags(req.Storage)
		if err != nil {
			return err
		}
		skipBlacklistTidy := false
		if tidyBlacklistConfigEntry != nil {
			if tidyBlacklistConfigEntry.DisablePeriodicTidy {
				skipBlacklistTidy = true
			}
			safety_buffer = tidyBlacklistConfigEntry.SafetyBuffer
		}
		if !skipBlacklistTidy {
			b.tidyBlacklistRoleTag(req.Storage, safety_buffer)
		}
		safety_buffer = 259200
		tidyWhitelistConfigEntry, err := b.lockedConfigTidyIdentities(req.Storage)
		if err != nil {
			return err
		}
		skipWhitelistTidy := false
		if tidyWhitelistConfigEntry != nil {
			if tidyWhitelistConfigEntry.DisablePeriodicTidy {
				skipWhitelistTidy = true
			}
			safety_buffer = tidyWhitelistConfigEntry.SafetyBuffer
		}
		if !skipWhitelistTidy {
			b.tidyWhitelistIdentity(req.Storage, safety_buffer)
		}
		b.nextTidyTime = time.Now().Add(b.tidyCooldownPeriod)
	}
	return nil
}
periodicFunc performs the tasks that the backend wishes to do periodically.
Currently this will be triggered once in a minute by the RollbackManager.

The tasks being done currently by this function are to cleanup the expired
entries of both blacklist role tags and whitelist identities. Tidying is done
not once in a minute, but once in an hour, controlled by 'tidyCooldownPeriod'.
Tidying of blacklist and whitelist are by default enabled. This can be
changed using `config/tidy/roletags` and `config/tidy/identities` endpoints.
package awsec2
import (
	"sync"
	"time"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/vault/helper/salt"
	"github.com/hashicorp/vault/logical"
	"github.com/hashicorp/vault/logical/framework"
)
func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
	b, err := Backend(conf)
	if err != nil {
		return nil, err
	}
	return b.Setup(conf)
}
type backend struct {
	*framework.Backend
	Salt *salt.Salt
	configMutex sync.RWMutex
	roleMutex sync.RWMutex
	blacklistMutex sync.RWMutex
	tidyBlacklistCASGuard uint32
	tidyWhitelistCASGuard uint32
	tidyCooldownPeriod time.Duration
	nextTidyTime time.Time
	EC2ClientsMap map[string]*ec2.EC2
	IAMClientsMap map[string]*iam.IAM
}
func Backend(conf *logical.BackendConfig) (*backend, error) {
	salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
		HashFunc: salt.SHA256Hash,
	})
	if err != nil {
		return nil, err
	}
	b := &backend{
		tidyCooldownPeriod: time.Hour,
		Salt:               salt,
		EC2ClientsMap:      make(map[string]*ec2.EC2),
		IAMClientsMap:      make(map[string]*iam.IAM),
	}
	b.Backend = &framework.Backend{
		PeriodicFunc: b.periodicFunc,
		AuthRenew:    b.pathLoginRenew,
		Help:         backendHelp,
		PathsSpecial: &logical.Paths{
			Unauthenticated: []string{
				"login",
			},
		},
		Paths: []*framework.Path{
			pathLogin(b),
			pathListRole(b),
			pathListRoles(b),
			pathRole(b),
			pathRoleTag(b),
			pathConfigClient(b),
			pathConfigCertificate(b),
			pathConfigTidyRoletagBlacklist(b),
			pathConfigTidyIdentityWhitelist(b),
			pathListCertificates(b),
			pathListRoletagBlacklist(b),
			pathRoletagBlacklist(b),
			pathTidyRoletagBlacklist(b),
			pathListIdentityWhitelist(b),
			pathIdentityWhitelist(b),
			pathTidyIdentityWhitelist(b),
		},
	}
	return b, nil
}