func (l *iniLoader) SaveCredentials(profile string, cred *AwsCredentials) error {
	if cred == nil || (len(cred.SamlPassword) < 1 && len(cred.WebIdentityPassword) < 1) {
		return errors.New("invalid credentials, can not be nil or empty")
	}
	if len(profile) < 1 {
		return errors.New("profile name can not be empty")
	}
	src := config.DefaultSharedCredentialsFilename()
	if e, ok := os.LookupEnv("AWS_SHARED_CREDENTIALS_FILE"); ok {
		src = e
	}
	f, err := loadFile(src)
	if err != nil {
		return err
	}
	if err = f.Section(profile).ReflectFrom(cred); err != nil {
		return err
	}
	return writeFile(f, src, 0600)
}
SaveCredentials writes the data in cred to the AWS credentials file, using the profile name specified by the profile
parameter. The value of the field containing the password value is stored as-is from the object, any encryption/
obfuscation is expected to be completed before entering this method.  This method assumes you know what you are doing
and does not check that the profile exists before writing data, it will happily overwrite existing credentials if
the profile already exists in the file.
package config
import (
	"errors"
	"fmt"
	"github.com/aws/aws-sdk-go-v2/config"
	"gopkg.in/ini.v1"
	"os"
	"path/filepath"
	"strings"
)
var DefaultIniLoader = new(iniLoader)
type iniLoader bool
func (l *iniLoader) Config(profile string, sources ...interface{}) (*AwsConfig, error) {
	file, err := resolveConfigSources(sources...)
	if err != nil {
		return nil, err
	}
	c := new(AwsConfig)
	if len(profile) < 1 {
		profile = config.DefaultSharedConfigProfile
	} else {
		_ = file.Section(config.DefaultSharedConfigProfile).MapTo(c)
	}
	s, err := lookupProfile(file, profile)
	if err != nil {
		return c, err
	}
	pc := new(AwsConfig)
	if err := s.MapTo(pc); err != nil {
		return c, err
	}
	c.MergeIn(pc)
	if len(c.SrcProfile) > 0 {
		src := new(AwsConfig)
		src.ProfileName = c.SrcProfile
		_ = file.Section(config.DefaultSharedConfigProfile).MapTo(src)  
		sp, err := lookupProfile(file, c.SrcProfile)
		if err != nil {
			return nil, err
		}
		if err := sp.MapTo(c); err != nil {
			return nil, err
		}
		if err := sp.MapTo(src); err != nil {
			return nil, err
		}
		c.MergeIn(pc)
		c.sourceProfile = src
	}
	c.ProfileName = profile
	return c, nil
}
func (l *iniLoader) Credentials(profile string, sources ...interface{}) (*AwsCredentials, error) {
	file, err := resolveCredentialSources(sources...)
	if err != nil {
		return nil, err
	}
	if len(profile) < 1 {
		profile = strings.ToLower(ini.DefaultSection)
	}
	s, err := file.GetSection(profile)
	if err != nil {
		return nil, err
	}
	c := new(AwsCredentials)
	if err := s.MapTo(c); err != nil {
		return nil, err
	}
	return c, nil
}
func (l *iniLoader) Roles(sources ...interface{}) ([]string, error) {
	roles := make([]string, 0)
	if p, err := l.Profiles(sources...); err == nil {
		for k, v := range p {
			if v {
				roles = append(roles, k)
			}
		}
	} else {
		return nil, err
	}
	return roles, nil
}
func (l *iniLoader) Profiles(sources ...interface{}) (map[string]bool, error) {
	file, err := resolveConfigSources(sources...)
	if err != nil {
		return nil, err
	}
	profiles := make(map[string]bool)
	for _, s := range file.Sections() {
		if s.Name() == ini.DefaultSection {
			continue
		}
		var isRole bool
		name := strings.TrimPrefix(s.Name(), "profile ")
		if s.HasKey("role_arn") {
			isRole = true
		}
		profiles[name] = isRole
	}
	return profiles, nil
}
func (l *iniLoader) SaveProfile(cfg *AwsConfig) error {
	if cfg == nil || len(cfg.ProfileName) < 1 || len(cfg.RoleArn) < 1 {
		return errors.New("invalid configuration, can not be nil or have empty profile name or role arn")
	}
	src := config.DefaultSharedConfigFilename()
	if e, ok := os.LookupEnv("AWS_CONFIG_FILE"); ok {
		src = e
	}
	f, err := loadFile(src)
	if err != nil {
		return err
	}
	if err = f.Section(fmt.Sprintf("profile %s", cfg.ProfileName)).ReflectFrom(cfg); err != nil {
		return err
	}
	return writeFile(f, src, 0600)
}