<commit_before>package wayffunctionaltest

var (
	testAttributes = map[string][]string{
		"cn":                          {"Anton Banton Cantonsen"},
		"displayName":                 {"Anton Banton Cantonsen"},
		"eduPersonAffiliation":        {"alum"},
		"eduPersonAssurance":          {"2"},
		"eduPersonEntitlement":        {"https://example.com/course101"},
		"eduPersonPrimaryAffiliation": {"student"},
		"eduPersonPrincipalName":      {"joe@this.is.not.a.valid.idp"},
		"eduPersonScopedAffiliation":  {"student@this.is.not.a.valid.idp", "member@this.is.not.a.valid.idp"},
		"entryUUID":                   {"entryUUID"},
		"gn":                          {`Anton Banton <SamlRequest id="abc">abc</SamlRequest>`},
		"mail":                        {"joe@example.com"},
		"norEduPersonLIN":             {"123456789"},
		"organizationName":            {"Orphanage - home for the homeless"},
		"preferredLanguage":           {"da"},
		"schacCountryOfCitizenship":   {"dk"},
		"schacHomeOrganizationType":   {"abc"},
		"schacPersonalUniqueID":       {"urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234"},
		"sn":                          {"Cantonsen"},
	}

	jwt2SAMLPreflight = `{
  "AssertionConsumerServiceURL": [
    "https://wayf.wayf.dk/module.php/saml/sp/saml2-acs.php/wayf.wayf.dk"
  ],
  "ForceAuthn": null,
  "IsPassive": null,
  "Issuer": [
    "https://wayf.wayf.dk"
  ],
  "RequesterID": [
    "https://wayfsp.wayf.dk"
  ],
  "commonfederations": [
    "true"
  ],
  "hub": [
    "true"
  ],
  "idpfeds": [
    "WAYF",
    "HUBIDP",
    "oes.dk"
  ],
  "protocol": [
    "AuthnRequest"
  ],
  "spfeds": [
    "WAYF"
  ]
} https://wayfsp.wayf.dk
`

    modstAttributes = `eduPersonAssurance https://modst.dk/sso/claims/assurancelevel https://modst.dk/sso/claims
    2
eduPersonPrincipalName http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name https://modst.dk/sso/claims
    joe@this.is.not.a.valid.idp
eduPersonPrincipalName https://modst.dk/sso/claims/userid https://modst.dk/sso/claims
    joe@this.is.not.a.valid.idp
entryUUID https://modst.dk/sso/claims/uniqueid https://modst.dk/sso/claims
    entryUUID
gn https://modst.dk/sso/claims/givenname https://modst.dk/sso/claims
    Anton Banton <SamlRequest id="abc">abc</SamlRequest>
mail https://modst.dk/sso/claims/email https://modst.dk/sso/claims
    joe@example.com
modstlogonmethod https://modst.dk/sso/claims/logonmethod https://modst.dk/sso/claims
    username-password-protected-transport
oioCvrNumberIdentifier https://modst.dk/sso/claims/cvr https://modst.dk/sso/claims
    12345678
sn https://modst.dk/sso/claims/surname https://modst.dk/sso/claims
    Cantonsen
`

    fullAttributeSet = `cn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Anton Banton Cantonsen
eduPersonAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    alum
    member
    student
eduPersonAssurance urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    2
eduPersonEntitlement urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    https://example.com/course101
eduPersonPrimaryAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    student
eduPersonPrincipalName urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    joe@this.is.not.a.valid.idp
eduPersonScopedAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    alum@this.is.not.a.valid.idp
    member@this.is.not.a.valid.idp
    student@this.is.not.a.valid.idp
eduPersonTargetedID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    {{.eptid}}
entryUUID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    entryUUID
gn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Anton Banton <SamlRequest id="abc">abc</SamlRequest>
mail urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    joe@example.com
norEduPersonLIN urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    123456789
organizationName urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Orphanage - home for the homeless
preferredLanguage urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    da
schacCountryOfCitizenship urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    dk
schacDateOfBirth urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    18580824
schacHomeOrganization urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    this.is.not.a.valid.idp
schacHomeOrganizationType urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    urn:mace:terena.org:schac:homeOrganizationType:int:other
schacPersonalUniqueID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234
schacYearOfBirth urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    1858
sn NameStandIn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Cantonsen
sn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Cantonsen
`
	fullAttributeSetJSON = `{
    "NameStandIn": [
        "Cantonsen"
    ],
    "aud": "https://wayfsp.wayf.dk",
    "cn": [
        "Anton Banton Cantonsen"
    ],
    "eduPersonAffiliation": [
        "alum",
        "student",
        "member"
    ],
    "eduPersonAssurance": [
        "2"
    ],
    "eduPersonEntitlement": [
        "https://example.com/course101"
    ],
    "eduPersonPrimaryAffiliation": [
        "student"
    ],
    "eduPersonPrincipalName": [
        "joe@this.is.not.a.valid.idp"
    ],
    "eduPersonScopedAffiliation": [
        "student@this.is.not.a.valid.idp",
        "member@this.is.not.a.valid.idp",
        "alum@this.is.not.a.valid.idp"
    ],
    "eduPersonTargetedID": [
        "WAYF-DK-c52a92a5467ae336a2be77cd06719c645e72dfd2"
    ],
    "entryUUID": [
        "entryUUID"
    ],
    "exp": "1234",
    "gn": [
        "Anton Banton \u003cSamlRequest id=\"abc\"\u003eabc\u003c/SamlRequest\u003e"
    ],
    "iat": "1234",
    "iss": "https://wayf.wayf.dk",
    "mail": [
        "joe@example.com"
    ],
    "nbf": "1234",
    "norEduPersonLIN": [
        "123456789"
    ],
    "organizationName": [
        "Orphanage - home for the homeless"
    ],
    "preferredLanguage": [
        "da"
    ],
    "saml:AuthenticatingAuthority": [
        "https://this.is.not.a.valid.idp"
    ],
    "schacCountryOfCitizenship": [
        "dk"
    ],
    "schacDateOfBirth": [
        "18580824"
    ],
    "schacHomeOrganization": [
        "this.is.not.a.valid.idp"
    ],
    "schacHomeOrganizationType": [
        "urn:mace:terena.org:schac:homeOrganizationType:int:other"
    ],
    "schacPersonalUniqueID": [
        "urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234"
    ],
    "schacYearOfBirth": [
        "1858"
    ],
    "sn": [
        "Cantonsen"
    ]
}
`

)
<commit_msg>Updated test attributes' org name<commit_after>package wayffunctionaltest

var (
	testAttributes = map[string][]string{
		"cn":                          {"Anton Banton Cantonsen"},
		"displayName":                 {"Anton Banton Cantonsen"},
		"eduPersonAffiliation":        {"alum"},
		"eduPersonAssurance":          {"2"},
		"eduPersonEntitlement":        {"https://example.com/course101"},
		"eduPersonPrimaryAffiliation": {"student"},
		"eduPersonPrincipalName":      {"joe@this.is.not.a.valid.idp"},
		"eduPersonScopedAffiliation":  {"student@this.is.not.a.valid.idp", "member@this.is.not.a.valid.idp"},
		"entryUUID":                   {"entryUUID"},
		"gn":                          {`Anton Banton <SamlRequest id="abc">abc</SamlRequest>`},
		"mail":                        {"joe@example.com"},
		"norEduPersonLIN":             {"123456789"},
		"organizationName":            {"This Is Not A Valid IdP!"},
		"preferredLanguage":           {"da"},
		"schacCountryOfCitizenship":   {"dk"},
		"schacHomeOrganizationType":   {"abc"},
		"schacPersonalUniqueID":       {"urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234"},
		"sn":                          {"Cantonsen"},
	}

	jwt2SAMLPreflight = `{
  "AssertionConsumerServiceURL": [
    "https://wayf.wayf.dk/module.php/saml/sp/saml2-acs.php/wayf.wayf.dk"
  ],
  "ForceAuthn": null,
  "IsPassive": null,
  "Issuer": [
    "https://wayf.wayf.dk"
  ],
  "RequesterID": [
    "https://wayfsp.wayf.dk"
  ],
  "commonfederations": [
    "true"
  ],
  "hub": [
    "true"
  ],
  "idpfeds": [
    "WAYF",
    "HUBIDP",
    "oes.dk"
  ],
  "protocol": [
    "AuthnRequest"
  ],
  "spfeds": [
    "WAYF"
  ]
} https://wayfsp.wayf.dk
`

    modstAttributes = `eduPersonAssurance https://modst.dk/sso/claims/assurancelevel https://modst.dk/sso/claims
    2
eduPersonPrincipalName http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name https://modst.dk/sso/claims
    joe@this.is.not.a.valid.idp
eduPersonPrincipalName https://modst.dk/sso/claims/userid https://modst.dk/sso/claims
    joe@this.is.not.a.valid.idp
entryUUID https://modst.dk/sso/claims/uniqueid https://modst.dk/sso/claims
    entryUUID
gn https://modst.dk/sso/claims/givenname https://modst.dk/sso/claims
    Anton Banton <SamlRequest id="abc">abc</SamlRequest>
mail https://modst.dk/sso/claims/email https://modst.dk/sso/claims
    joe@example.com
modstlogonmethod https://modst.dk/sso/claims/logonmethod https://modst.dk/sso/claims
    username-password-protected-transport
oioCvrNumberIdentifier https://modst.dk/sso/claims/cvr https://modst.dk/sso/claims
    12345678
sn https://modst.dk/sso/claims/surname https://modst.dk/sso/claims
    Cantonsen
`

    fullAttributeSet = `cn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Anton Banton Cantonsen
eduPersonAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    alum
    member
    student
eduPersonAssurance urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    2
eduPersonEntitlement urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    https://example.com/course101
eduPersonPrimaryAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    student
eduPersonPrincipalName urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    joe@this.is.not.a.valid.idp
eduPersonScopedAffiliation urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    alum@this.is.not.a.valid.idp
    member@this.is.not.a.valid.idp
    student@this.is.not.a.valid.idp
eduPersonTargetedID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    {{.eptid}}
entryUUID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    entryUUID
gn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Anton Banton <SamlRequest id="abc">abc</SamlRequest>
mail urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    joe@example.com
norEduPersonLIN urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    123456789
organizationName urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    This Is Not A Valid IdP!
preferredLanguage urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    da
schacCountryOfCitizenship urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    dk
schacDateOfBirth urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    18580824
schacHomeOrganization urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    this.is.not.a.valid.idp
schacHomeOrganizationType urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    urn:mace:terena.org:schac:homeOrganizationType:int:other
schacPersonalUniqueID urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234
schacYearOfBirth urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    1858
sn NameStandIn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Cantonsen
sn urn:oasis:names:tc:SAML:2.0:attrname-format:basic
    Cantonsen
`
	fullAttributeSetJSON = `{
    "NameStandIn": [
        "Cantonsen"
    ],
    "aud": "https://wayfsp.wayf.dk",
    "cn": [
        "Anton Banton Cantonsen"
    ],
    "eduPersonAffiliation": [
        "alum",
        "student",
        "member"
    ],
    "eduPersonAssurance": [
        "2"
    ],
    "eduPersonEntitlement": [
        "https://example.com/course101"
    ],
    "eduPersonPrimaryAffiliation": [
        "student"
    ],
    "eduPersonPrincipalName": [
        "joe@this.is.not.a.valid.idp"
    ],
    "eduPersonScopedAffiliation": [
        "student@this.is.not.a.valid.idp",
        "member@this.is.not.a.valid.idp",
        "alum@this.is.not.a.valid.idp"
    ],
    "eduPersonTargetedID": [
        "WAYF-DK-c52a92a5467ae336a2be77cd06719c645e72dfd2"
    ],
    "entryUUID": [
        "entryUUID"
    ],
    "exp": "1234",
    "gn": [
        "Anton Banton \u003cSamlRequest id=\"abc\"\u003eabc\u003c/SamlRequest\u003e"
    ],
    "iat": "1234",
    "iss": "https://wayf.wayf.dk",
    "mail": [
        "joe@example.com"
    ],
    "nbf": "1234",
    "norEduPersonLIN": [
        "123456789"
    ],
    "organizationName": [
        "This Is Not A Valid IdP!"
    ],
    "preferredLanguage": [
        "da"
    ],
    "saml:AuthenticatingAuthority": [
        "https://this.is.not.a.valid.idp"
    ],
    "schacCountryOfCitizenship": [
        "dk"
    ],
    "schacDateOfBirth": [
        "18580824"
    ],
    "schacHomeOrganization": [
        "this.is.not.a.valid.idp"
    ],
    "schacHomeOrganizationType": [
        "urn:mace:terena.org:schac:homeOrganizationType:int:other"
    ],
    "schacPersonalUniqueID": [
        "urn:mace:terena.org:schac:personalUniqueID:dk:CPR:2408586234"
    ],
    "schacYearOfBirth": [
        "1858"
    ],
    "sn": [
        "Cantonsen"
    ]
}
`

)
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"os"
	"time"

	"github.com/Shopify/themekit/kit"
)

// WatchCommand watches directories for changes, and updates the remote theme
func WatchCommand(args Args, done chan bool) {
	if len(args.ThemeClients) == 0 {
		args.ThemeClients = []kit.ThemeClient{args.ThemeClient}
	}

	eventLog := args.EventLog

	for _, client := range args.ThemeClients {
		config := client.GetConfiguration()
		concurrency := config.Concurrency
		logEvent(message(fmt.Sprintf("Spawning %d workers for %s", concurrency, config.Domain)), eventLog)

		args.ThemeClient = client
		watchForChangesAndIssueWork(args, eventLog)
	}
}

func watchForChangesAndIssueWork(args Args, eventLog chan kit.ThemeEvent) {
	client := args.ThemeClient
	config := client.GetConfiguration()
	bucket := client.LeakyBucket()
	bucket.TopUp()

	foreman := kit.NewForeman(bucket)
	foreman.OnIdle = func() {
		if len(args.NotifyFile) > 0 {
			os.Create(args.NotifyFile)
			os.Chtimes(args.NotifyFile, time.Now(), time.Now())
		}
	}
	watcher := constructFileWatcher(args.Directory, config)
	foreman.JobQueue = watcher
	foreman.IssueWork()

	for i := 0; i < config.Concurrency; i++ {
		workerName := fmt.Sprintf("%s Worker #%d", config.Domain, i)
		go spawnWorker(workerName, foreman.WorkerQueue, client, eventLog)
	}
}

func spawnWorker(workerName string, queue chan kit.AssetEvent, client kit.ThemeClient, eventLog chan kit.ThemeEvent) {
	logEvent(workerSpawnEvent(workerName), eventLog)
	for {
		asset := <-queue
		if asset.Asset().IsValid() {
			workerEvent := basicEvent{
				Title:     "FS Event",
				EventType: asset.Type().String(),
				Target:    asset.Asset().Key,
				Etype:     "fsevent",
				Formatter: func(b basicEvent) string {
					return fmt.Sprintf(
						"Received %s event on %s",
						kit.GreenText(b.EventType),
						kit.BlueText(b.Target),
					)
				},
			}
			logEvent(workerEvent, eventLog)
			logEvent(client.Perform(asset), eventLog)
		}
	}
}

func constructFileWatcher(dir string, config kit.Configuration) chan kit.AssetEvent {
	filter := kit.NewEventFilterFromPatternsAndFiles(config.IgnoredFiles, config.Ignores)
	watcher, err := kit.NewFileWatcher(dir, true, filter)
	if err != nil {
		kit.NotifyError(err)
	}
	return watcher
}

func workerSpawnEvent(workerName string) kit.ThemeEvent {
	return basicEvent{
		Title:     "Worker",
		Target:    workerName,
		Etype:     "basicEvent",
		EventType: "worker",
		Formatter: func(b basicEvent) string {
			return fmt.Sprintf("%s ready to upload local changes", b.Target)
		},
	}
}
<commit_msg>history problem<commit_after>package commands

import (
	"os"

	"github.com/Shopify/themekit/kit"
	"github.com/Shopify/themekit/theme"
)

// WatchCommand watches directories for changes, and updates the remote theme
func WatchCommand(args Args, done chan bool) {
	if len(args.ThemeClients) == 0 {
		args.ThemeClients = []kit.ThemeClient{args.ThemeClient}
	}

	eventLog := args.EventLog

	for _, client := range args.ThemeClients {
		config := client.GetConfiguration()
		concurrency := config.Concurrency
		logEvent(message(fmt.Sprintf("Spawning %d workers for %s", concurrency, config.Domain)), eventLog)

		args.ThemeClient = client
		watchForChangesAndIssueWork(args, eventLog)
	}
}

// UploadCommand add file(s) to theme
func UploadCommand(args Args, done chan bool) {
	rawEvents, throttledEvents := prepareChannel(args)
	logs := args.ThemeClient.Process(throttledEvents, done)
	mergeEvents(args.EventLog, []chan kit.ThemeEvent{logs})
	go enqueueUploadEvents(args.ThemeClient, args.Filenames, rawEvents)
}

func enqueueUploadEvents(client kit.ThemeClient, filenames []string, events chan kit.AssetEvent) {
	root, _ := os.Getwd()
	if len(filenames) == 0 {
		for _, asset := range client.LocalAssets(root) {
			events <- kit.NewUploadEvent(asset)
		}
	} else {
		for _, filename := range filenames {
			asset, err := theme.LoadAsset(root, filename)
			if err == nil {
				events <- kit.NewUploadEvent(asset)
			}
		}
	}
	close(events)
}
<|endoftext|>


<commit_before>package gameserverconfigs

import (
	"errors"
	"fmt"

	"gopkg.in/gcfg.v1"
)

const (
	TypeLogin ServerType = iota
	TypeShard

	DBRead DBConfigType = iota
	DBWrite
	DBReadStatic
)

type ServerType int
type DBConfigType int

type Config struct {
	PathToConfig string

	Server struct {
		Type    ServerType
		ID      uint64
		Version uint64

		Port          string
		LogPath       string
		DebuggingMode uint64

		ServerSecretKey string

		Bugsnag string

		APITimeoutSeconds uint64
	}

	LoginServer struct {
		RDBName string
		RDBUser string
		RDBHost string
		RDBPass string
		RDBPort string

		WDBName string
		WDBUser string
		WDBHost string
		WDBPass string
		WDBPort string

		RStaticDBName string
		RStaticDBUser string
		RStaticDBHost string
		RStaticDBPass string
		RStaticDBPort string
	}

	ShardServer struct {
		RDBName string
		RDBUser string
		RDBHost string
		RDBPass string
		RDBPort string

		WDBName string
		WDBUser string
		WDBHost string
		WDBPass string
		WDBPort string
	}
}

func New(
	serverType ServerType, serverVersion uint64, pathToConfig string) (*Config, error) {
	c := new(Config)
	err := gcfg.ReadFileInto(c, pathToConfig)
	if err != nil {
		return nil, err
	}

	if serverType != TypeLogin && serverType != TypeShard {
		return nil, errors.New("unknown config type")
	}
	c.Server.Type = serverType

	if serverVersion == 0 {
		return nil, errors.New("server version undefined")
	}
	c.Server.Version = serverVersion

	c.PathToConfig = pathToConfig

	if c.Server.APITimeoutSeconds == 0 {
		return nil, errors.New("undefined api timeout")
	}

	return c, nil
}

func (c *Config) DBConfig(t DBConfigType) (
	*struct{ DBUser, DBPass, DBHost, DBPort, DBName string }, error) {
	if c.Server.Type == TypeLogin {
		switch t {
		default:
			return nil, fmt.Errorf("unknown login server db type: %s", string(t))

		case DBRead:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.RDBName,
				DBUser: c.LoginServer.RDBUser,
				DBHost: c.LoginServer.RDBHost,
				DBPass: c.LoginServer.RDBPass,
				DBPort: c.LoginServer.RDBPort}, nil

		case DBWrite:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.WDBName,
				DBUser: c.LoginServer.WDBUser,
				DBHost: c.LoginServer.WDBHost,
				DBPass: c.LoginServer.WDBPass,
				DBPort: c.LoginServer.WDBPort}, nil

		case DBReadStatic:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.RStaticDBName,
				DBUser: c.LoginServer.RStaticDBUser,
				DBHost: c.LoginServer.RStaticDBHost,
				DBPass: c.LoginServer.RStaticDBPass,
				DBPort: c.LoginServer.RStaticDBPort}, nil
		}

	} else if c.Server.Type == TypeShard {
		switch t {
		default:
			return nil, fmt.Errorf("unknown shard server db type: %s", string(t))

		case DBRead:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.ShardServer.RDBName,
				DBUser: c.ShardServer.RDBUser,
				DBHost: c.ShardServer.RDBHost,
				DBPass: c.ShardServer.RDBPass,
				DBPort: c.ShardServer.RDBPort}, nil

		case DBWrite:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.ShardServer.WDBName,
				DBUser: c.ShardServer.WDBUser,
				DBHost: c.ShardServer.WDBHost,
				DBPass: c.ShardServer.WDBPass,
				DBPort: c.ShardServer.WDBPort}, nil
		}
	}

	return nil, fmt.Errorf("unknown server type: %s", string(c.Server.Type))
}
<commit_msg>minor<commit_after>package gameserverconfigs

import (
	"errors"
	"fmt"

	"gopkg.in/gcfg.v1"
)

const (
	TypeLogin ServerType = iota
	TypeShard

	DBRead DBConfigType = iota
	DBWrite
	DBReadStatic
)

type ServerType int
type DBConfigType int

type Config struct {
	PathToConfig string

	Server struct {
		Type    ServerType
		ID      uint64
		Version uint64

		ListenAddress string
		LogPath       string
		DebuggingMode uint64

		ServerSecretKey string

		Bugsnag string

		APITimeoutSeconds uint64
	}

	LoginServer struct {
		RDBName string
		RDBUser string
		RDBHost string
		RDBPass string
		RDBPort string

		WDBName string
		WDBUser string
		WDBHost string
		WDBPass string
		WDBPort string

		RStaticDBName string
		RStaticDBUser string
		RStaticDBHost string
		RStaticDBPass string
		RStaticDBPort string
	}

	ShardServer struct {
		RDBName string
		RDBUser string
		RDBHost string
		RDBPass string
		RDBPort string

		WDBName string
		WDBUser string
		WDBHost string
		WDBPass string
		WDBPort string
	}
}

func New(
	serverType ServerType, serverVersion uint64, pathToConfig string) (*Config, error) {
	c := new(Config)
	err := gcfg.ReadFileInto(c, pathToConfig)
	if err != nil {
		return nil, err
	}

	if serverType != TypeLogin && serverType != TypeShard {
		return nil, errors.New("unknown config type")
	}
	c.Server.Type = serverType

	if serverVersion == 0 {
		return nil, errors.New("server version undefined")
	}
	c.Server.Version = serverVersion

	c.PathToConfig = pathToConfig

	if c.Server.APITimeoutSeconds == 0 {
		return nil, errors.New("undefined api timeout")
	}

	return c, nil
}

func (c *Config) DBConfig(t DBConfigType) (
	*struct{ DBUser, DBPass, DBHost, DBPort, DBName string }, error) {
	if c.Server.Type == TypeLogin {
		switch t {
		default:
			return nil, fmt.Errorf("unknown login server db type: %s", string(t))

		case DBRead:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.RDBName,
				DBUser: c.LoginServer.RDBUser,
				DBHost: c.LoginServer.RDBHost,
				DBPass: c.LoginServer.RDBPass,
				DBPort: c.LoginServer.RDBPort}, nil

		case DBWrite:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.WDBName,
				DBUser: c.LoginServer.WDBUser,
				DBHost: c.LoginServer.WDBHost,
				DBPass: c.LoginServer.WDBPass,
				DBPort: c.LoginServer.WDBPort}, nil

		case DBReadStatic:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.LoginServer.RStaticDBName,
				DBUser: c.LoginServer.RStaticDBUser,
				DBHost: c.LoginServer.RStaticDBHost,
				DBPass: c.LoginServer.RStaticDBPass,
				DBPort: c.LoginServer.RStaticDBPort}, nil
		}

	} else if c.Server.Type == TypeShard {
		switch t {
		default:
			return nil, fmt.Errorf("unknown shard server db type: %s", string(t))

		case DBRead:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.ShardServer.RDBName,
				DBUser: c.ShardServer.RDBUser,
				DBHost: c.ShardServer.RDBHost,
				DBPass: c.ShardServer.RDBPass,
				DBPort: c.ShardServer.RDBPort}, nil

		case DBWrite:
			return &struct{ DBUser, DBPass, DBHost, DBPort, DBName string }{
				DBName: c.ShardServer.WDBName,
				DBUser: c.ShardServer.WDBUser,
				DBHost: c.ShardServer.WDBHost,
				DBPass: c.ShardServer.WDBPass,
				DBPort: c.ShardServer.WDBPort}, nil
		}
	}

	return nil, fmt.Errorf("unknown server type: %s", string(c.Server.Type))
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Shreyas Khare <skhare@rapid7.com>
// See LICENSE for licensing information

package main

import (
	"net/http"
	"io/ioutil"
	"io"
	"text/template"
	"os"
	"log"
	"encoding/csv"
	"strings"
)

const path = "standard_schemes.go"

var schemesTmpl = template.Must(template.New("schemes").Parse(`// Generated by schemesgen

package xurls

// Schemes is a sorted list of all IANA assigned schemes.
//
// Source:
//   https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv
var StdSchemes = []string{
{{range $scheme := .Schemes}}` + "\t`" + `{{$scheme}}` + "`" + `,
{{end}}}
`))

func schemeList() []string {
	resp, _ := http.Get("https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv")
	file, _ := ioutil.ReadAll(resp.Body)
	r := csv.NewReader(strings.NewReader(string(file)))
	r.Read() //ignore headers
	schemes := make([]string,0)
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		schemes = append(schemes,record[0])
	}
	return schemes
}

func writeSchemes(schemes []string) error {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()
	return schemesTmpl.Execute(f, struct {
		Schemes []string
	}{
		Schemes: schemes,
	})
}

func main() {
	schemes := schemeList()
	log.Printf("Generating %s...", path)
	if err := writeSchemes(schemes); err != nil {
		log.Fatalf("Could not write path: %v", err)
	}
}
<commit_msg>Runnig gofmt and addressing some comments<commit_after>// Copyright (c) 2017, Shreyas Khare <skhare@rapid7.com>
// See LICENSE for licensing information

package main

import (
	"encoding/csv"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"text/template"
)

const path = "standard_schemes.go"

var schemesTmpl = template.Must(template.New("schemes").Parse(`// Generated by schemesgen

package xurls

// Schemes is a sorted list of all IANA assigned schemes.
//
// Source:
//   https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv
var StdSchemes = []string{
{{range $scheme := .Schemes}}` + "\t`" + `{{$scheme}}` + "`" + `,
{{end}}}
`))

func schemeList() []string {
	resp, err := http.Get("https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	r := csv.NewReader(resp.Body)
	r.Read() //ignore headers
	schemes := make([]string, 0)
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		schemes = append(schemes, record[0])
	}
	return schemes
}

func writeSchemes(schemes []string) error {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()
	return schemesTmpl.Execute(f, struct {
		Schemes []string
	}{
		Schemes: schemes,
	})
}

func main() {
	schemes := schemeList()
	log.Printf("Generating %s...", path)
	if err := writeSchemes(schemes); err != nil {
		log.Fatalf("Could not write path: %v", err)
	}
}
<|endoftext|>


<commit_before>package common

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
)

//-------------------------------------------------------
// hex and ints

// keeps N bytes of the conversion
func NumberToBytes(num interface{}, N int) []byte {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.BigEndian, num)
	if err != nil {
		// TODO: get this guy a return error?
	}
	//fmt.Println("btyes!", buf.Bytes())
	if buf.Len() > N {
		return buf.Bytes()[buf.Len()-N:]
	}
	return buf.Bytes()
}

// s can be string, hex, or int.
// returns properly formatted 32byte hex value
func Coerce2Hex(s string) string {
	//fmt.Println("coercing to hex:", s)
	// is int?
	i, err := strconv.Atoi(s)
	if err == nil {
		return "0x" + hex.EncodeToString(NumberToBytes(int32(i), i/256+1))
	}
	// is already prefixed hex?
	if len(s) > 1 && s[:2] == "0x" {
		if len(s)%2 == 0 {
			return s
		}
		return "0x0" + s[2:]
	}
	// is unprefixed hex?
	if len(s) > 32 {
		return "0x" + s
	}
	pad := strings.Repeat("\x00", (32-len(s))) + s
	ret := "0x" + hex.EncodeToString([]byte(pad))
	//fmt.Println("result:", ret)
	return ret
}

func CoerceHexAndPad(aa string, padright bool) string {
	if !IsHex(aa) {
		//first try and convert to int
		n, err := strconv.Atoi(aa)
		if err != nil {
			// right pad strings
			if padright {
				aa = "0x" + fmt.Sprintf("%x", aa) + fmt.Sprintf("%0"+strconv.Itoa(64-len(aa)*2)+"s", "")
			} else {
				aa = "0x" + fmt.Sprintf("%x", aa)
			}
		} else {
			aa = "0x" + fmt.Sprintf("%x", n)
		}
	}
	return aa
}

func IsHex(s string) bool {
	if len(s) < 2 {
		return false
	}
	if s[:2] == "0x" {
		return true
	}
	return false
}

func AddHex(s string) string {
	if len(s) < 2 {
		return "0x" + s
	}

	if s[:2] != "0x" {
		return "0x" + s
	}

	return s
}

func StripHex(s string) string {
	if len(s) > 1 {
		if s[:2] == "0x" {
			s = s[2:]
			if len(s)%2 != 0 {
				s = "0" + s
			}
			return s
		}
	}
	return s
}

func StripZeros(s string) string {
	i := 0
	for ; i < len(s); i++ {
		if s[i] != '0' {
			break
		}
	}
	return s[i:]
}

func Bytes2Hex(d []byte) string {
	return hex.EncodeToString(d)
}

func RightPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[0:len(slice)], slice)

	return padded
}

func LeftPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[l-len(slice):], slice)

	return padded
}

func LeftPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return zeros + str

}

func RightPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return str + zeros

}

func UnLeftPadBytes(slice []byte) []byte {
	var l int
	for i, b := range slice {
		if (b != byte(0)) {
			l = i
			break
		}
	}
	unpadded := make([]byte, len(slice)-l)
	copy(unpadded, slice[l:len(slice)])

	return unpadded
}

func UnRightPadBytes(slice []byte) []byte {
	var l int
	for i, b := range slice {
		if (b == byte(0)) {
			l = i
			break
		}
	}
	unpadded := make([]byte, l)
	copy(unpadded, slice[:l])

	return unpadded
}

func Address(slice []byte) (addr []byte) {
	if len(slice) < 20 {
		addr = LeftPadBytes(slice, 20)
	} else if len(slice) > 20 {
		addr = slice[len(slice)-20:]
	} else {
		addr = slice
	}

	addr = CopyBytes(addr)

	return
}

func AddressStringToBytes(addr string) []byte {
	var slice []byte
	for i := 0; i < len(addr); i++ {
		a, _ := hex.DecodeString(addr[i:i+2])
		slice = append(slice, a[0])
		i++
	}
	return slice
}

// Copy bytes
//
// Returns an exact copy of the provided bytes
func CopyBytes(b []byte) (copiedBytes []byte) {
	copiedBytes = make([]byte, len(b))
	copy(copiedBytes, b)

	return
}<commit_msg>strip ones for solidity negative ints<commit_after>package common

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
)

//-------------------------------------------------------
// hex and ints

// keeps N bytes of the conversion
func NumberToBytes(num interface{}, N int) []byte {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.BigEndian, num)
	if err != nil {
		// TODO: get this guy a return error?
	}
	//fmt.Println("btyes!", buf.Bytes())
	if buf.Len() > N {
		return buf.Bytes()[buf.Len()-N:]
	}
	return buf.Bytes()
}

// s can be string, hex, or int.
// returns properly formatted 32byte hex value
func Coerce2Hex(s string) string {
	//fmt.Println("coercing to hex:", s)
	// is int?
	i, err := strconv.Atoi(s)
	if err == nil {
		return "0x" + hex.EncodeToString(NumberToBytes(int32(i), i/256+1))
	}
	// is already prefixed hex?
	if len(s) > 1 && s[:2] == "0x" {
		if len(s)%2 == 0 {
			return s
		}
		return "0x0" + s[2:]
	}
	// is unprefixed hex?
	if len(s) > 32 {
		return "0x" + s
	}
	pad := strings.Repeat("\x00", (32-len(s))) + s
	ret := "0x" + hex.EncodeToString([]byte(pad))
	//fmt.Println("result:", ret)
	return ret
}

func CoerceHexAndPad(aa string, padright bool) string {
	if !IsHex(aa) {
		//first try and convert to int
		n, err := strconv.Atoi(aa)
		if err != nil {
			// right pad strings
			if padright {
				aa = "0x" + fmt.Sprintf("%x", aa) + fmt.Sprintf("%0"+strconv.Itoa(64-len(aa)*2)+"s", "")
			} else {
				aa = "0x" + fmt.Sprintf("%x", aa)
			}
		} else {
			aa = "0x" + fmt.Sprintf("%x", n)
		}
	}
	return aa
}

func IsHex(s string) bool {
	if len(s) < 2 {
		return false
	}
	if s[:2] == "0x" {
		return true
	}
	return false
}

func AddHex(s string) string {
	if len(s) < 2 {
		return "0x" + s
	}

	if s[:2] != "0x" {
		return "0x" + s
	}

	return s
}

func StripHex(s string) string {
	if len(s) > 1 {
		if s[:2] == "0x" {
			s = s[2:]
			if len(s)%2 != 0 {
				s = "0" + s
			}
			return s
		}
	}
	return s
}

func StripZeros(s string) string {
	i := 0
	for ; i < len(s); i++ {
		if s[i] != '0' {
			break
		}
	}
	return s[i:]
}

func StripOnes(s string) string {
	i := 0
	for ; i < len(s); i++ {
		if s[i:i+1] != "01" {
			break
		}
	}
	return s[i:]
}

func Bytes2Hex(d []byte) string {
	return hex.EncodeToString(d)
}

func RightPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[0:len(slice)], slice)

	return padded
}

func LeftPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[l-len(slice):], slice)

	return padded
}

func LeftPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return zeros + str

}

func RightPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return str + zeros

}

func UnLeftPadBytes(slice []byte) []byte {
	var l int
	for i, b := range slice {
		if b != byte(0) {
			l = i
			break
		}
	}
	unpadded := make([]byte, len(slice)-l)
	copy(unpadded, slice[l:])

	return unpadded
}

func UnRightPadBytes(slice []byte) []byte {
	var l int
	for i, b := range slice {
		if b == byte(0) {
			l = i
			break
		}
	}
	unpadded := make([]byte, l)
	copy(unpadded, slice[:l])

	return unpadded
}

func Address(slice []byte) (addr []byte) {
	if len(slice) < 20 {
		addr = LeftPadBytes(slice, 20)
	} else if len(slice) > 20 {
		addr = slice[len(slice)-20:]
	} else {
		addr = slice
	}

	addr = CopyBytes(addr)

	return
}

func AddressStringToBytes(addr string) []byte {
	var slice []byte
	for i := 0; i < len(addr); i++ {
		a, _ := hex.DecodeString(addr[i : i+2])
		slice = append(slice, a[0])
		i++
	}
	return slice
}

// Copy bytes
//
// Returns an exact copy of the provided bytes
func CopyBytes(b []byte) (copiedBytes []byte) {
	copiedBytes = make([]byte, len(b))
	copy(copiedBytes, b)

	return
}
<|endoftext|>


<commit_before>// gtype.go
// This file contains gobject type definition
package gobject
/*
#include <glib-object.h>

static inline const gchar* get_type_name(GValue v) { return G_VALUE_TYPE_NAME(&v); }

static inline const gchar* getTypeName(void * o) { return G_OBJECT_TYPE_NAME(o); }
static inline GType getTypeId(void * o) { return G_OBJECT_TYPE(o); }

static inline GObject* to_GObject(void* o) { return G_OBJECT(o); }

static inline GType getGValueType(GValue* v) {
	return G_VALUE_TYPE(v);
}

static inline const gchar* getGValueTypeName(GValue* v) {
	return G_VALUE_TYPE_NAME(v);
}

static inline gboolean is_type_object(GType t) {
	return G_TYPE_IS_OBJECT(t);
}

static inline gboolean _is_type_enum(GType t) {
	return G_TYPE_IS_ENUM(t);
}

static inline gboolean _is_type_flags(GType t) {
	return G_TYPE_IS_FLAGS(t);
}

static inline gboolean is_type_boxed(GType t) {
	return G_TYPE_IS_BOXED(t);
}

static inline gboolean boxed_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_BOXED(v);
}

static inline gboolean pointer_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_POINTER(v);
}

static inline gboolean object_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_OBJECT(v);
}

static inline gboolean _enum_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_ENUM(v);
}

static inline gboolean _flags_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_FLAGS(v);
}

static inline gboolean _pointer_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_POINTER(v);
}

*/
import "C"
import "unsafe"

//-----------------------------------------------------------------------
// GType
//-----------------------------------------------------------------------
type GType int

type GValueError struct {
	Err string
}

func (e GValueError) Error() string {
	return e.Err
}

// Function interface for converting C values to Go
type FuncToGo func(unsafe.Pointer) interface{}

// GoTypes registration map
// This map holds gobject types as GType
// and conversion function to Go type
// Every module has to register it's own type and conversion function
var gtypes map[GType]FuncToGo

// IsObjectType returns true if given type is derived from GObject
func IsObjectType(t GType) bool {
	b := C.is_type_object(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsEnumType returns true if given type is derived from GEnum
func IsEnumType(t GType) bool {
	b := C._is_type_enum(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsFlagsType returns true if given type is derived from GFlags
func IsFlagsType(t GType) bool {
	b := C._is_type_flags(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsBoxedType returns true if given type is derived from GBoxed
func IsBoxedType(t GType) bool {
	b := C.is_type_boxed(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}

// Get Type ID
func GetTypeID(obj unsafe.Pointer) GType {
	t := C.getTypeId(obj)
	return GType(t)
}

// Get Type Name
func GetTypeName(obj unsafe.Pointer) string {
	tn := C.getTypeName(obj)
	return GoString(unsafe.Pointer(tn))
}

func RegisterCType(typename GType, f FuncToGo) {
	gtypes[typename] = f
}

func ConvertToGo(obj unsafe.Pointer, typeid ...GType) (interface{}, error) {
	if obj == nil {
		return nil, GValueError{"Conversion Error"}
	}
	var id GType

	if len(typeid) > 0 {
		id = typeid[0]
	} else {
		id = GetTypeID(obj)
	}
	if f, ok := gtypes[id]; ok {
		res := f(obj)
		return res, nil
	}

	return nil, GValueError{"Unknown Type"}
}

// Function interface for converting Go values to C
type FuncToC func(interface{}) *GValue

var ctypes map[GType]FuncToC

func RegisterGoType(typeid GType, f FuncToC) {
	ctypes[typeid] = f
}

// GValue
type GValue struct {
	gtype GType
	value *C.GValue
}

func NewGValueFromNative(gv unsafe.Pointer) *GValue {
	cgv := (*C.GValue)(gv)
	newGV := &GValue{0, cgv}
	newGV.ReInitializeType()
	return newGV
}

func (self GValue) ToCGValue() unsafe.Pointer {
	return unsafe.Pointer(self.value)
}

func (self *GValue) ReInitializeType() {
	t := C.getGValueType(self.value)
	self.gtype = GType(t)
}

func (self GValue) GetTypeName() string {
	tn := C.getGValueTypeName(self.value)
	return GoString(unsafe.Pointer(tn))
}

func (self GValue) GetTypeID() GType {
	return self.gtype
}

func (self GValue) GetPtr() unsafe.Pointer {
	t := self.gtype
	switch {
	case IsObjectType(t):
		return unsafe.Pointer(C.g_value_get_object(self.value))
	case IsEnumType(t):
		e := C.g_value_get_enum(self.value)
		return unsafe.Pointer(&e)
	case IsFlagsType(t):
		f := C.g_value_get_flags(self.value)
		return unsafe.Pointer(&f)
	case IsBoxedType(t):
		b := C.g_value_get_boxed(self.value)
		return unsafe.Pointer(&b)
	case t == G_TYPE_STRING:
		return unsafe.Pointer(C.g_value_get_string(self.value))
	case t == G_TYPE_BOOLEAN:
		b := C.g_value_get_boolean(self.value)
		return unsafe.Pointer(&b)
	case t == G_TYPE_CHAR:
		c := C.g_value_get_char(self.value)
		return unsafe.Pointer(&c)
	case t == G_TYPE_INT:
		i := C.g_value_get_int(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_LONG:
		l := C.g_value_get_long(self.value)
		return unsafe.Pointer(&l)
	case t == G_TYPE_INT64:
		i := C.g_value_get_int64(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_UCHAR:
		c := C.g_value_get_uchar(self.value)
		return unsafe.Pointer(&c)
	case t == G_TYPE_UINT:
		i := C.g_value_get_uint(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_ULONG:
		l := C.g_value_get_ulong(self.value)
		return unsafe.Pointer(&l)
	case t == G_TYPE_UINT64:
		i := C.g_value_get_uint64(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_FLOAT:
		f := C.g_value_get_float(self.value)
		return unsafe.Pointer(&f)
	case t == G_TYPE_DOUBLE:
		d := C.g_value_get_double(self.value)
		return unsafe.Pointer(&d)
	}

	p := C.g_value_get_pointer(self.value)
	return unsafe.Pointer(p)
}

func (self GValue) Free() {
	C.g_value_unset(self.value)
}

func CreateCGValue(tn GType, object ...unsafe.Pointer) *GValue {
	var cv C.GValue
	C.g_value_init(&cv, C.GType(tn))

	// If no data, then return Gvalue initialized with default
	if len(object) == 0 {
		gv := GValue{tn, &cv}
		return &gv
	}
	obj := object[0]

	// Foundamental types are special
	// TODO: Handle more cases, like creating GValue from GdkEvents
	switch {
	case IsObjectType(tn):
		C.g_value_set_object(&cv, C.gpointer(obj))
	case IsEnumType(tn):
		C.g_value_set_enum(&cv, *((*C.gint)(obj)))
	case IsFlagsType(tn):
		C.g_value_set_flags(&cv, *((*C.guint)(obj)))
	case IsBoxedType(tn):
		C.g_value_take_boxed(&cv, C.gconstpointer(obj))
	case tn == G_TYPE_STRING:
		C.g_value_take_string(&cv, (*C.gchar)(obj))
	case tn == G_TYPE_BOOLEAN:
		C.g_value_set_boolean(&cv, *((*C.gboolean)(obj)))
	case tn == G_TYPE_CHAR:
		C.g_value_set_char(&cv, *((*C.gchar)(obj)))
	case tn == G_TYPE_INT:
		C.g_value_set_int(&cv, *((*C.gint)(obj)))
	case tn == G_TYPE_LONG:
		C.g_value_set_long(&cv, *((*C.glong)(obj)))
	case tn == G_TYPE_INT64:
		C.g_value_set_int64(&cv, *((*C.gint64)(obj)))
	case tn == G_TYPE_UCHAR:
		C.g_value_set_uchar(&cv, *((*C.guchar)(obj)))
	case tn == G_TYPE_UINT:
		C.g_value_set_uint(&cv, *((*C.guint)(obj)))
	case tn == G_TYPE_ULONG:
		C.g_value_set_ulong(&cv, *((*C.gulong)(obj)))
	case tn == G_TYPE_UINT64:
		C.g_value_set_uint64(&cv, *((*C.guint64)(obj)))
	case tn == G_TYPE_FLOAT:
		C.g_value_set_float(&cv, *((*C.gfloat)(obj)))
	case tn == G_TYPE_DOUBLE:
		C.g_value_set_double(&cv, *((*C.gdouble)(obj)))
	case tn == G_TYPE_POINTER:
		C.g_value_set_pointer(&cv, C.gpointer(obj))
	}

	gv := GValue{tn, &cv}
	return &gv
}

func ConvertToC(gotype interface{}) *GValue {
	// Test first for fundamental types
	switch gotype.(type) {
	case string:
		return ctypes[G_TYPE_STRING](gotype.(string))
	case bool:
		return ctypes[G_TYPE_BOOLEAN](gotype.(bool))
	case int8:
		return ctypes[G_TYPE_CHAR](gotype.(byte))
	case int:
		return ctypes[G_TYPE_INT](gotype.(int))
	case int32:
		return ctypes[G_TYPE_LONG](gotype.(int32))
	case int64:
		return ctypes[G_TYPE_INT64](gotype.(int64))
	case byte:
		return ctypes[G_TYPE_UCHAR](gotype.(uint8))
	case uint:
		return ctypes[G_TYPE_UINT](gotype.(uint))
	case uint32:
		return ctypes[G_TYPE_ULONG](gotype.(uint32))
	case uint64:
		return ctypes[G_TYPE_UINT64](gotype.(uint64))
	case float32:
		return ctypes[G_TYPE_FLOAT](gotype.(float32))
	case float64:
		return ctypes[G_TYPE_DOUBLE](gotype.(float64))
	case ObjectLike:
		o := gotype.(ObjectLike)
		t := GetTypeFromInstance(o.ToNative())
		if f, ok := ctypes[t]; ok {
			return f(o)
		}
	case BoxedLike:
		o := gotype.(BoxedLike)
		t := o.GetBoxType()
		if f, ok := ctypes[t]; ok {
			return f(o)
		}
	}
	return nil
}

func init() {
	C.g_type_init()
	gtypes = make(map[GType]FuncToGo)
	ctypes = make(map[GType]FuncToC)
}
<commit_msg>Fixed bug in value extract for GBoxed type. Added support for Enum and Flags type in ConvertToGo func.<commit_after>// gtype.go
// This file contains gobject type definition
package gobject
/*
#include <glib-object.h>

static inline const gchar* get_type_name(GValue v) { return G_VALUE_TYPE_NAME(&v); }

static inline const gchar* getTypeName(void * o) { return G_OBJECT_TYPE_NAME(o); }
static inline GType getTypeId(void * o) { return G_OBJECT_TYPE(o); }

static inline GObject* to_GObject(void* o) { return G_OBJECT(o); }

static inline GType getGValueType(GValue* v) {
	return G_VALUE_TYPE(v);
}

static inline const gchar* getGValueTypeName(GValue* v) {
	return G_VALUE_TYPE_NAME(v);
}

static inline gboolean is_type_object(GType t) {
	return G_TYPE_IS_OBJECT(t);
}

static inline gboolean _is_type_enum(GType t) {
	return G_TYPE_IS_ENUM(t);
}

static inline gboolean _is_type_flags(GType t) {
	return G_TYPE_IS_FLAGS(t);
}

static inline gboolean is_type_boxed(GType t) {
	return G_TYPE_IS_BOXED(t);
}

static inline gboolean boxed_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_BOXED(v);
}

static inline gboolean pointer_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_POINTER(v);
}

static inline gboolean object_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_OBJECT(v);
}

static inline gboolean _enum_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_ENUM(v);
}

static inline gboolean _flags_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_FLAGS(v);
}

static inline gboolean _pointer_in_gvalue(GValue* v) {
	return G_VALUE_HOLDS_POINTER(v);
}

*/
import "C"
import "unsafe"

//-----------------------------------------------------------------------
// GType
//-----------------------------------------------------------------------
type GType int

type GValueError struct {
	Err string
}

func (e GValueError) Error() string {
	return e.Err
}

// Function interface for converting C values to Go
type FuncToGo func(unsafe.Pointer) interface{}

// GoTypes registration map
// This map holds gobject types as GType
// and conversion function to Go type
// Every module has to register it's own type and conversion function
var gtypes map[GType]FuncToGo

// IsObjectType returns true if given type is derived from GObject
func IsObjectType(t GType) bool {
	b := C.is_type_object(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsEnumType returns true if given type is derived from GEnum
func IsEnumType(t GType) bool {
	b := C._is_type_enum(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsFlagsType returns true if given type is derived from GFlags
func IsFlagsType(t GType) bool {
	b := C._is_type_flags(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}
// IsBoxedType returns true if given type is derived from GBoxed
func IsBoxedType(t GType) bool {
	b := C.is_type_boxed(C.GType(t))
	return GoBool(unsafe.Pointer(&b))
}

// Get Type ID
func GetTypeID(obj unsafe.Pointer) GType {
	t := C.getTypeId(obj)
	return GType(t)
}

// Get Type Name
func GetTypeName(obj unsafe.Pointer) string {
	tn := C.getTypeName(obj)
	return GoString(unsafe.Pointer(tn))
}

func RegisterCType(typename GType, f FuncToGo) {
	gtypes[typename] = f
}

func ConvertToGo(obj unsafe.Pointer, typeid ...GType) (interface{}, error) {
	if obj == nil {
		return nil, GValueError{"Conversion Error"}
	}
	var id GType

	if len(typeid) > 0 {
		id = typeid[0]
	} else {
		id = GetTypeID(obj)
	}
	if f, ok := gtypes[id]; ok {
		res := f(obj)
		return res, nil
	}

	if IsFlagsType(id) {
		return uint(*((*C.guint)(obj))), nil
	}

	if IsEnumType(id) {
		e := *((*C.gint)(obj))
		return int(e), nil
	}

	return nil, GValueError{"Unknown Type"}
}

// Function interface for converting Go values to C
type FuncToC func(interface{}) *GValue

var ctypes map[GType]FuncToC

func RegisterGoType(typeid GType, f FuncToC) {
	ctypes[typeid] = f
}

// GValue
type GValue struct {
	gtype GType
	value *C.GValue
}

func NewGValueFromNative(gv unsafe.Pointer) *GValue {
	cgv := (*C.GValue)(gv)
	newGV := &GValue{0, cgv}
	newGV.ReInitializeType()
	return newGV
}

func (self GValue) ToCGValue() unsafe.Pointer {
	return unsafe.Pointer(self.value)
}

func (self *GValue) ReInitializeType() {
	t := C.getGValueType(self.value)
	self.gtype = GType(t)
}

func (self GValue) GetTypeName() string {
	tn := C.getGValueTypeName(self.value)
	return GoString(unsafe.Pointer(tn))
}

func (self GValue) GetTypeID() GType {
	return self.gtype
}

func (self GValue) GetPtr() unsafe.Pointer {
	t := self.gtype
	switch {
	case IsObjectType(t):
		return unsafe.Pointer(C.g_value_get_object(self.value))
	case IsEnumType(t):
		e := C.g_value_get_enum(self.value)
		return unsafe.Pointer(&e)
	case IsFlagsType(t):
		f := C.g_value_get_flags(self.value)
		return unsafe.Pointer(&f)
	case IsBoxedType(t):
		b := C.g_value_get_boxed(self.value)
		return unsafe.Pointer(b)
	case t == G_TYPE_STRING:
		return unsafe.Pointer(C.g_value_get_string(self.value))
	case t == G_TYPE_BOOLEAN:
		b := C.g_value_get_boolean(self.value)
		return unsafe.Pointer(&b)
	case t == G_TYPE_CHAR:
		c := C.g_value_get_char(self.value)
		return unsafe.Pointer(&c)
	case t == G_TYPE_INT:
		i := C.g_value_get_int(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_LONG:
		l := C.g_value_get_long(self.value)
		return unsafe.Pointer(&l)
	case t == G_TYPE_INT64:
		i := C.g_value_get_int64(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_UCHAR:
		c := C.g_value_get_uchar(self.value)
		return unsafe.Pointer(&c)
	case t == G_TYPE_UINT:
		i := C.g_value_get_uint(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_ULONG:
		l := C.g_value_get_ulong(self.value)
		return unsafe.Pointer(&l)
	case t == G_TYPE_UINT64:
		i := C.g_value_get_uint64(self.value)
		return unsafe.Pointer(&i)
	case t == G_TYPE_FLOAT:
		f := C.g_value_get_float(self.value)
		return unsafe.Pointer(&f)
	case t == G_TYPE_DOUBLE:
		d := C.g_value_get_double(self.value)
		return unsafe.Pointer(&d)
	}

	p := C.g_value_get_pointer(self.value)
	return unsafe.Pointer(p)
}

func (self GValue) Free() {
	C.g_value_unset(self.value)
}

func CreateCGValue(tn GType, object ...unsafe.Pointer) *GValue {
	var cv C.GValue
	C.g_value_init(&cv, C.GType(tn))

	// If no data, then return Gvalue initialized with default
	if len(object) == 0 {
		gv := GValue{tn, &cv}
		return &gv
	}
	obj := object[0]

	// Foundamental types are special
	// TODO: Handle more cases, like creating GValue from GdkEvents
	switch {
	case IsObjectType(tn):
		C.g_value_set_object(&cv, C.gpointer(obj))
	case IsEnumType(tn):
		C.g_value_set_enum(&cv, *((*C.gint)(obj)))
	case IsFlagsType(tn):
		C.g_value_set_flags(&cv, *((*C.guint)(obj)))
	case IsBoxedType(tn):
		C.g_value_take_boxed(&cv, C.gconstpointer(obj))
	case tn == G_TYPE_STRING:
		C.g_value_take_string(&cv, (*C.gchar)(obj))
	case tn == G_TYPE_BOOLEAN:
		C.g_value_set_boolean(&cv, *((*C.gboolean)(obj)))
	case tn == G_TYPE_CHAR:
		C.g_value_set_char(&cv, *((*C.gchar)(obj)))
	case tn == G_TYPE_INT:
		C.g_value_set_int(&cv, *((*C.gint)(obj)))
	case tn == G_TYPE_LONG:
		C.g_value_set_long(&cv, *((*C.glong)(obj)))
	case tn == G_TYPE_INT64:
		C.g_value_set_int64(&cv, *((*C.gint64)(obj)))
	case tn == G_TYPE_UCHAR:
		C.g_value_set_uchar(&cv, *((*C.guchar)(obj)))
	case tn == G_TYPE_UINT:
		C.g_value_set_uint(&cv, *((*C.guint)(obj)))
	case tn == G_TYPE_ULONG:
		C.g_value_set_ulong(&cv, *((*C.gulong)(obj)))
	case tn == G_TYPE_UINT64:
		C.g_value_set_uint64(&cv, *((*C.guint64)(obj)))
	case tn == G_TYPE_FLOAT:
		C.g_value_set_float(&cv, *((*C.gfloat)(obj)))
	case tn == G_TYPE_DOUBLE:
		C.g_value_set_double(&cv, *((*C.gdouble)(obj)))
	case tn == G_TYPE_POINTER:
		C.g_value_set_pointer(&cv, C.gpointer(obj))
	}

	gv := GValue{tn, &cv}
	return &gv
}

func ConvertToC(gotype interface{}) *GValue {
	// Test first for fundamental types
	switch gotype.(type) {
	case string:
		return ctypes[G_TYPE_STRING](gotype.(string))
	case bool:
		return ctypes[G_TYPE_BOOLEAN](gotype.(bool))
	case int8:
		return ctypes[G_TYPE_CHAR](gotype.(byte))
	case int:
		return ctypes[G_TYPE_INT](gotype.(int))
	case int32:
		return ctypes[G_TYPE_LONG](gotype.(int32))
	case int64:
		return ctypes[G_TYPE_INT64](gotype.(int64))
	case byte:
		return ctypes[G_TYPE_UCHAR](gotype.(uint8))
	case uint:
		return ctypes[G_TYPE_UINT](gotype.(uint))
	case uint32:
		return ctypes[G_TYPE_ULONG](gotype.(uint32))
	case uint64:
		return ctypes[G_TYPE_UINT64](gotype.(uint64))
	case float32:
		return ctypes[G_TYPE_FLOAT](gotype.(float32))
	case float64:
		return ctypes[G_TYPE_DOUBLE](gotype.(float64))
	case ObjectLike:
		o := gotype.(ObjectLike)
		t := GetTypeFromInstance(o.ToNative())
		if f, ok := ctypes[t]; ok {
			return f(o)
		}
	case BoxedLike:
		o := gotype.(BoxedLike)
		t := o.GetBoxType()
		if f, ok := ctypes[t]; ok {
			return f(o)
		}
	}
	return nil
}

func init() {
	C.g_type_init()
	gtypes = make(map[GType]FuncToGo)
	ctypes = make(map[GType]FuncToC)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.

// golint lints the Go source files named on its command line.
package main

import (
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/golang/lint"
)

var minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\tgolint [flags] # runs on package in current directory\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] package\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] directory\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] files... # must be a single package\n")
	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	switch flag.NArg() {
	case 0:
		lintDir(".")
	case 1:
		arg := flag.Arg(0)
		if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-4]) {
			for _, dirname := range allPackagesInFS(arg) {
				lintDir(dirname)
			}
		} else if isDir(arg) {
			lintDir(arg)
		} else if exists(arg) {
			lintFiles(arg)
		} else {
			for _, pkgname := range importPaths([]string{arg}) {
				lintPackage(pkgname)
			}
		}
	default:
		lintFiles(flag.Args()...)
	}
}

func isDir(filename string) bool {
	fi, err := os.Stat(filename)
	return err == nil && fi.IsDir()
}

func exists(filename string) bool {
	_, err := os.Stat(filename)
	return err == nil
}

func lintFiles(filenames ...string) {
	files := make(map[string][]byte)
	for _, filename := range filenames {
		src, err := ioutil.ReadFile(filename)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			continue
		}
		files[filename] = src
	}

	l := new(lint.Linter)
	ps, err := l.LintFiles(files)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		return
	}
	for _, p := range ps {
		if p.Confidence >= *minConfidence {
			fmt.Printf("%v: %s\n", p.Position, p.Text)
		}
	}
}

func lintDir(dirname string) {
	pkg, err := build.ImportDir(dirname, 0)
	lintImportedPackage(pkg, err)
}

func lintPackage(pkgname string) {
	pkg, err := build.Import(pkgname, ".", 0)
	lintImportedPackage(pkg, err)
}

func lintImportedPackage(pkg *build.Package, err error) {
	if err != nil {
		if _, nogo := err.(*build.NoGoError); nogo {
			// Don't complain if the failure is due to no Go source files.
			return
		}
		fmt.Fprintln(os.Stderr, err)
		return
	}

	var files []string
	files = append(files, pkg.GoFiles...)
	files = append(files, pkg.TestGoFiles...)
	if pkg.Dir != "." {
		for i, f := range files {
			files[i] = filepath.Join(pkg.Dir, f)
		}
	}
	// TODO(dsymonds): Do foo_test too (pkg.XTestGoFiles)

	lintFiles(files...)
}
<commit_msg>Lint files that use cgo.<commit_after>// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.

// golint lints the Go source files named on its command line.
package main

import (
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/golang/lint"
)

var minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\tgolint [flags] # runs on package in current directory\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] package\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] directory\n")
	fmt.Fprintf(os.Stderr, "\tgolint [flags] files... # must be a single package\n")
	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	switch flag.NArg() {
	case 0:
		lintDir(".")
	case 1:
		arg := flag.Arg(0)
		if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-4]) {
			for _, dirname := range allPackagesInFS(arg) {
				lintDir(dirname)
			}
		} else if isDir(arg) {
			lintDir(arg)
		} else if exists(arg) {
			lintFiles(arg)
		} else {
			for _, pkgname := range importPaths([]string{arg}) {
				lintPackage(pkgname)
			}
		}
	default:
		lintFiles(flag.Args()...)
	}
}

func isDir(filename string) bool {
	fi, err := os.Stat(filename)
	return err == nil && fi.IsDir()
}

func exists(filename string) bool {
	_, err := os.Stat(filename)
	return err == nil
}

func lintFiles(filenames ...string) {
	files := make(map[string][]byte)
	for _, filename := range filenames {
		src, err := ioutil.ReadFile(filename)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			continue
		}
		files[filename] = src
	}

	l := new(lint.Linter)
	ps, err := l.LintFiles(files)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		return
	}
	for _, p := range ps {
		if p.Confidence >= *minConfidence {
			fmt.Printf("%v: %s\n", p.Position, p.Text)
		}
	}
}

func lintDir(dirname string) {
	pkg, err := build.ImportDir(dirname, 0)
	lintImportedPackage(pkg, err)
}

func lintPackage(pkgname string) {
	pkg, err := build.Import(pkgname, ".", 0)
	lintImportedPackage(pkg, err)
}

func lintImportedPackage(pkg *build.Package, err error) {
	if err != nil {
		if _, nogo := err.(*build.NoGoError); nogo {
			// Don't complain if the failure is due to no Go source files.
			return
		}
		fmt.Fprintln(os.Stderr, err)
		return
	}

	var files []string
	files = append(files, pkg.GoFiles...)
	files = append(files, pkg.CgoFiles...)
	files = append(files, pkg.TestGoFiles...)
	if pkg.Dir != "." {
		for i, f := range files {
			files[i] = filepath.Join(pkg.Dir, f)
		}
	}
	// TODO(dsymonds): Do foo_test too (pkg.XTestGoFiles)

	lintFiles(files...)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/sagemaker"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsSagemakerModel() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSagemakerModelCreate,
		Read:   resourceAwsSagemakerModelRead,
		Update: resourceAwsSagemakerModelUpdate,
		Delete: resourceAwsSagemakerModelDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"name": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				ValidateFunc: validateSagemakerName,
			},

			"primary_container": {
				Type:     schema.TypeList,
				MaxItems: 1,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"container_hostname": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerName,
						},

						"image": {
							Type:         schema.TypeString,
							Required:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerImage,
						},

						"model_data_url": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerModelDataUrl,
						},

						"environment": {
							Type:         schema.TypeMap,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerEnvironment,
						},
					},
				},
			},

			"vpc_config": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"subnets": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
						"security_group_ids": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
					},
				},
			},

			"execution_role_arn": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"enable_network_isolation": {
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
			},

			"container": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"container_hostname": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerName,
						},

						"image": {
							Type:         schema.TypeString,
							Required:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerImage,
						},

						"model_data_url": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerModelDataUrl,
						},

						"environment": {
							Type:         schema.TypeMap,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerEnvironment,
						},
					},
				},
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsSagemakerModelCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else {
		name = resource.UniqueId()
	}

	createOpts := &sagemaker.CreateModelInput{
		ModelName: aws.String(name),
	}

	if v, ok := d.GetOk("primary_container"); ok {
		m := v.([]interface{})[0].(map[string]interface{})
		createOpts.PrimaryContainer = expandContainer(m)
	}

	if v, ok := d.GetOk("container"); ok {
		containers := expandContainers(v.([]interface{}))
		createOpts.SetContainers(containers)
	}

	if v, ok := d.GetOk("execution_role_arn"); ok {
		createOpts.SetExecutionRoleArn(v.(string))
	}

	if v, ok := d.GetOk("tags"); ok {
		createOpts.SetTags(tagsFromMapSagemaker(v.(map[string]interface{})))
	}

	if v, ok := d.GetOk("vpc_config"); ok {
		vpcConfig := expandSageMakerVpcConfigRequest(v.([]interface{}))
		createOpts.SetVpcConfig(vpcConfig)
	}

	if v, ok := d.GetOk("enable_network_isolation"); ok {
		createOpts.SetEnableNetworkIsolation(v.(bool))
	}

	log.Printf("[DEBUG] Sagemaker model create config: %#v", *createOpts)
	_, err := retryOnAwsCode("ValidationException", func() (interface{}, error) {
		return conn.CreateModel(createOpts)
	})

	if err != nil {
		return fmt.Errorf("error creating Sagemaker model: %s", err)
	}
	d.SetId(name)

	return resourceAwsSagemakerModelRead(d, meta)
}

func expandSageMakerVpcConfigRequest(l []interface{}) *sagemaker.VpcConfig {
	if len(l) == 0 {
		return nil
	}

	m := l[0].(map[string]interface{})

	return &sagemaker.VpcConfig{
		SecurityGroupIds: expandStringSet(m["security_group_ids"].(*schema.Set)),
		Subnets:          expandStringSet(m["subnets"].(*schema.Set)),
	}
}

func resourceAwsSagemakerModelRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	request := &sagemaker.DescribeModelInput{
		ModelName: aws.String(d.Id()),
	}

	model, err := conn.DescribeModel(request)
	if err != nil {
		if sagemakerErr, ok := err.(awserr.Error); ok && sagemakerErr.Code() == "ValidationException" {
			log.Printf("[INFO] unable to find the sagemaker model resource and therefore it is removed from the state: %s", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("error reading Sagemaker model %s: %s", d.Id(), err)
	}

	if err := d.Set("arn", model.ModelArn); err != nil {
		return fmt.Errorf("unable to set arn for sagemaker model %q: %+v", d.Id(), err)
	}
	if err := d.Set("name", model.ModelName); err != nil {
		return err
	}
	if err := d.Set("execution_role_arn", model.ExecutionRoleArn); err != nil {
		return err
	}
	if err := d.Set("enable_network_isolation", model.EnableNetworkIsolation); err != nil {
		return err
	}
	if err := d.Set("primary_container", flattenContainer(model.PrimaryContainer)); err != nil {
		return err
	}
	if err := d.Set("container", flattenContainers(model.Containers)); err != nil {
		return err
	}
	if err := d.Set("vpc_config", flattenSageMakerVpcConfigResponse(model.VpcConfig)); err != nil {
		return fmt.Errorf("error setting vpc_config: %s", err)
	}

	tagsOutput, err := conn.ListTags(&sagemaker.ListTagsInput{
		ResourceArn: model.ModelArn,
	})
	if err != nil {
		return fmt.Errorf("error listing tags of Sagemaker model %s: %s", d.Id(), err)
	}

	if err := d.Set("tags", tagsToMapSagemaker(tagsOutput.Tags)); err != nil {
		return err
	}
	return nil
}

func flattenSageMakerVpcConfigResponse(vpcConfig *sagemaker.VpcConfig) []map[string]interface{} {
	if vpcConfig == nil {
		return []map[string]interface{}{}
	}

	m := map[string]interface{}{
		"security_group_ids": schema.NewSet(schema.HashString, flattenStringList(vpcConfig.SecurityGroupIds)),
		"subnets":            schema.NewSet(schema.HashString, flattenStringList(vpcConfig.Subnets)),
	}

	return []map[string]interface{}{m}
}

func resourceAwsSagemakerModelUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	d.Partial(true)

	if err := setSagemakerTags(conn, d); err != nil {
		return err
	} else {
		d.SetPartial("tags")
	}

	d.Partial(false)

	return resourceAwsSagemakerModelRead(d, meta)
}

func resourceAwsSagemakerModelDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	deleteOpts := &sagemaker.DeleteModelInput{
		ModelName: aws.String(d.Id()),
	}
	log.Printf("[INFO] Deleting Sagemaker model: %s", d.Id())

	return resource.Retry(5*time.Minute, func() *resource.RetryError {
		_, err := conn.DeleteModel(deleteOpts)
		if err == nil {
			return nil
		}

		sagemakerErr, ok := err.(awserr.Error)
		if !ok {
			return resource.NonRetryableError(err)
		}

		if sagemakerErr.Code() == "ResourceNotFound" {
			return resource.RetryableError(err)
		}

		return resource.NonRetryableError(fmt.Errorf("error deleting Sagemaker model: %s", err))
	})
}

func expandContainer(m map[string]interface{}) *sagemaker.ContainerDefinition {
	container := sagemaker.ContainerDefinition{
		Image: aws.String(m["image"].(string)),
	}

	if v, ok := m["container_hostname"]; ok && v.(string) != "" {
		container.ContainerHostname = aws.String(v.(string))
	}
	if v, ok := m["model_data_url"]; ok && v.(string) != "" {
		container.ModelDataUrl = aws.String(v.(string))
	}
	if v, ok := m["environment"]; ok {
		container.Environment = stringMapToPointers(v.(map[string]interface{}))
	}

	return &container
}

func expandContainers(a []interface{}) []*sagemaker.ContainerDefinition {
	containers := make([]*sagemaker.ContainerDefinition, 0, len(a))

	for _, m := range a {
		containers = append(containers, expandContainer(m.(map[string]interface{})))
	}

	return containers
}

func flattenContainer(container *sagemaker.ContainerDefinition) []interface{} {
	if container == nil {
		return []interface{}{}
	}

	cfg := make(map[string]interface{})

	cfg["image"] = *container.Image

	if container.ContainerHostname != nil {
		cfg["container_hostname"] = *container.ContainerHostname
	}
	if container.ModelDataUrl != nil {
		cfg["model_data_url"] = *container.ModelDataUrl
	}
	if container.Environment != nil {
		cfg["environment"] = flattenEnvironment(container.Environment)
	}

	return []interface{}{cfg}
}

func flattenContainers(containers []*sagemaker.ContainerDefinition) []interface{} {
	fContainers := make([]interface{}, 0, len(containers))
	for _, container := range containers {
		fContainers = append(fContainers, flattenContainer(container)[0].(map[string]interface{}))
	}
	return fContainers
}

func flattenEnvironment(env map[string]*string) map[string]string {
	m := map[string]string{}
	for k, v := range env {
		m[k] = *v
	}
	return m
}
<commit_msg>Adding VPC config (#2)<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/sagemaker"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsSagemakerModel() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSagemakerModelCreate,
		Read:   resourceAwsSagemakerModelRead,
		Update: resourceAwsSagemakerModelUpdate,
		Delete: resourceAwsSagemakerModelDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"name": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				ValidateFunc: validateSagemakerName,
			},

			"primary_container": {
				Type:     schema.TypeList,
				MaxItems: 1,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"container_hostname": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerName,
						},

						"image": {
							Type:         schema.TypeString,
							Required:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerImage,
						},

						"model_data_url": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerModelDataUrl,
						},

						"environment": {
							Type:         schema.TypeMap,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerEnvironment,
						},
					},
				},
			},

			"vpc_config": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"subnets": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
						"security_group_ids": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
					},
				},
			},

			"vpc_config": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				ForceNew: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"subnets": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
						},
						"security_group_ids": {
							Type:     schema.TypeSet,
							Required: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
						},
					},
				},
			},

			"execution_role_arn": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"enable_network_isolation": {
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
			},

			"container": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"container_hostname": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerName,
						},

						"image": {
							Type:         schema.TypeString,
							Required:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerImage,
						},

						"model_data_url": {
							Type:         schema.TypeString,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerModelDataUrl,
						},

						"environment": {
							Type:         schema.TypeMap,
							Optional:     true,
							ForceNew:     true,
							ValidateFunc: validateSagemakerEnvironment,
						},
					},
				},
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsSagemakerModelCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else {
		name = resource.UniqueId()
	}

	createOpts := &sagemaker.CreateModelInput{
		ModelName: aws.String(name),
	}

	if v, ok := d.GetOk("primary_container"); ok {
		m := v.([]interface{})[0].(map[string]interface{})
		createOpts.PrimaryContainer = expandContainer(m)
	}

	if v, ok := d.GetOk("container"); ok {
		containers := expandContainers(v.([]interface{}))
		createOpts.SetContainers(containers)
	}

	if v, ok := d.GetOk("execution_role_arn"); ok {
		createOpts.SetExecutionRoleArn(v.(string))
	}

	if v, ok := d.GetOk("tags"); ok {
		createOpts.SetTags(tagsFromMapSagemaker(v.(map[string]interface{})))
	}

	if v, ok := d.GetOk("vpc_config"); ok {
		vpcConfig := expandSageMakerVpcConfigRequest(v.([]interface{}))
		createOpts.SetVpcConfig(vpcConfig)
	}

	if v, ok := d.GetOk("enable_network_isolation"); ok {
		createOpts.SetEnableNetworkIsolation(v.(bool))
	}

	if v, ok := d.GetOk("vpc_config"); ok {
		vpcConfig := expandSageMakerVpcConfigRequest(v.([]interface{}))
		createOpts.SetVpcConfig(vpcConfig)
	}

	log.Printf("[DEBUG] Sagemaker model create config: %#v", *createOpts)
	_, err := retryOnAwsCode("ValidationException", func() (interface{}, error) {
		return conn.CreateModel(createOpts)
	})

	if err != nil {
		return fmt.Errorf("error creating Sagemaker model: %s", err)
	}
	d.SetId(name)

	return resourceAwsSagemakerModelRead(d, meta)
}

func expandSageMakerVpcConfigRequest(l []interface{}) *sagemaker.VpcConfig {
	if len(l) == 0 {
		return nil
	}

	m := l[0].(map[string]interface{})

	return &sagemaker.VpcConfig{
		SecurityGroupIds: expandStringSet(m["security_group_ids"].(*schema.Set)),
		Subnets:          expandStringSet(m["subnets"].(*schema.Set)),
	}
}

func expandSageMakerVpcConfigRequest(l []interface{}) *sagemaker.VpcConfig {
	if len(l) == 0 {
		return nil
	}

	m := l[0].(map[string]interface{})

	return &sagemaker.VpcConfig{
		SecurityGroupIds: expandStringSet(m["security_group_ids"].(*schema.Set)),
		Subnets:          expandStringSet(m["subnets"].(*schema.Set)),
	}
}

func resourceAwsSagemakerModelRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	request := &sagemaker.DescribeModelInput{
		ModelName: aws.String(d.Id()),
	}

	model, err := conn.DescribeModel(request)
	if err != nil {
		if sagemakerErr, ok := err.(awserr.Error); ok && sagemakerErr.Code() == "ValidationException" {
			log.Printf("[INFO] unable to find the sagemaker model resource and therefore it is removed from the state: %s", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("error reading Sagemaker model %s: %s", d.Id(), err)
	}

	if err := d.Set("arn", model.ModelArn); err != nil {
		return fmt.Errorf("unable to set arn for sagemaker model %q: %+v", d.Id(), err)
	}
	if err := d.Set("name", model.ModelName); err != nil {
		return err
	}
	if err := d.Set("execution_role_arn", model.ExecutionRoleArn); err != nil {
		return err
	}
	if err := d.Set("enable_network_isolation", model.EnableNetworkIsolation); err != nil {
		return err
	}
	if err := d.Set("primary_container", flattenContainer(model.PrimaryContainer)); err != nil {
		return err
	}
	if err := d.Set("container", flattenContainers(model.Containers)); err != nil {
		return err
	}
	if err := d.Set("vpc_config", flattenSageMakerVpcConfigResponse(model.VpcConfig)); err != nil {
		return fmt.Errorf("error setting vpc_config: %s", err)
	}

	tagsOutput, err := conn.ListTags(&sagemaker.ListTagsInput{
		ResourceArn: model.ModelArn,
	})
	if err != nil {
		return fmt.Errorf("error listing tags of Sagemaker model %s: %s", d.Id(), err)
	}

	if err := d.Set("tags", tagsToMapSagemaker(tagsOutput.Tags)); err != nil {
		return err
	}
	return nil
}

func flattenSageMakerVpcConfigResponse(vpcConfig *sagemaker.VpcConfig) []map[string]interface{} {
	if vpcConfig == nil {
		return []map[string]interface{}{}
	}

	m := map[string]interface{}{
		"security_group_ids": schema.NewSet(schema.HashString, flattenStringList(vpcConfig.SecurityGroupIds)),
		"subnets":            schema.NewSet(schema.HashString, flattenStringList(vpcConfig.Subnets)),
	}

	return []map[string]interface{}{m}
}

func resourceAwsSagemakerModelUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	d.Partial(true)

	if err := setSagemakerTags(conn, d); err != nil {
		return err
	} else {
		d.SetPartial("tags")
	}

	d.Partial(false)

	return resourceAwsSagemakerModelRead(d, meta)
}

func resourceAwsSagemakerModelDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	deleteOpts := &sagemaker.DeleteModelInput{
		ModelName: aws.String(d.Id()),
	}
	log.Printf("[INFO] Deleting Sagemaker model: %s", d.Id())

	return resource.Retry(5*time.Minute, func() *resource.RetryError {
		_, err := conn.DeleteModel(deleteOpts)
		if err == nil {
			return nil
		}

		sagemakerErr, ok := err.(awserr.Error)
		if !ok {
			return resource.NonRetryableError(err)
		}

		if sagemakerErr.Code() == "ResourceNotFound" {
			return resource.RetryableError(err)
		}

		return resource.NonRetryableError(fmt.Errorf("error deleting Sagemaker model: %s", err))
	})
}

func expandContainer(m map[string]interface{}) *sagemaker.ContainerDefinition {
	container := sagemaker.ContainerDefinition{
		Image: aws.String(m["image"].(string)),
	}

	if v, ok := m["container_hostname"]; ok && v.(string) != "" {
		container.ContainerHostname = aws.String(v.(string))
	}
	if v, ok := m["model_data_url"]; ok && v.(string) != "" {
		container.ModelDataUrl = aws.String(v.(string))
	}
	if v, ok := m["environment"]; ok {
		container.Environment = stringMapToPointers(v.(map[string]interface{}))
	}

	return &container
}

func expandContainers(a []interface{}) []*sagemaker.ContainerDefinition {
	containers := make([]*sagemaker.ContainerDefinition, 0, len(a))

	for _, m := range a {
		containers = append(containers, expandContainer(m.(map[string]interface{})))
	}

	return containers
}

func flattenContainer(container *sagemaker.ContainerDefinition) []interface{} {
	if container == nil {
		return []interface{}{}
	}

	cfg := make(map[string]interface{})

	cfg["image"] = *container.Image

	if container.ContainerHostname != nil {
		cfg["container_hostname"] = *container.ContainerHostname
	}
	if container.ModelDataUrl != nil {
		cfg["model_data_url"] = *container.ModelDataUrl
	}
	if container.Environment != nil {
		cfg["environment"] = flattenEnvironment(container.Environment)
	}

	return []interface{}{cfg}
}

func flattenContainers(containers []*sagemaker.ContainerDefinition) []interface{} {
	fContainers := make([]interface{}, 0, len(containers))
	for _, container := range containers {
		fContainers = append(fContainers, flattenContainer(container)[0].(map[string]interface{}))
	}
	return fContainers
}

func flattenEnvironment(env map[string]*string) map[string]string {
	m := map[string]string{}
	for k, v := range env {
		m[k] = *v
	}
	return m
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/transfer"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsTransferServer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsTransferServerCreate,
		Read:   resourceAwsTransferServerRead,
		Update: resourceAwsTransferServerUpdate,
		Delete: resourceAwsTransferServerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"endpoint": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"endpoint_type": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  transfer.EndpointTypePublic,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.EndpointTypePublic,
					transfer.EndpointTypeVpcEndpoint,
				}, false),
			},

			"endpoint_details": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"vpc_endpoint_id": {
							Type:     schema.TypeString,
							Required: true,
							ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
								value := v.(string)
								validNamePattern := "^vpce-[0-9a-f]{17}$"
								validName, nameMatchErr := regexp.MatchString(validNamePattern, value)
								if !validName || nameMatchErr != nil {
									errors = append(errors, fmt.Errorf(
										"%q must match regex '%v'", k, validNamePattern))
								}
								return
							},
						},
					},
				},
			},

			"invocation_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"url": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"identity_provider_type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  transfer.IdentityProviderTypeServiceManaged,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.IdentityProviderTypeServiceManaged,
					transfer.IdentityProviderTypeApiGateway,
				}, false),
			},

			"logging_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"force_destroy": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsTransferServerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	tags := tagsFromMapTransfer(d.Get("tags").(map[string]interface{}))
	createOpts := &transfer.CreateServerInput{}

	if len(tags) != 0 {
		createOpts.Tags = tags
	}

	identityProviderDetails := &transfer.IdentityProviderDetails{}
	if attr, ok := d.GetOk("invocation_role"); ok {
		identityProviderDetails.InvocationRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("url"); ok {
		identityProviderDetails.Url = aws.String(attr.(string))
	}

	if identityProviderDetails.Url != nil || identityProviderDetails.InvocationRole != nil {
		createOpts.IdentityProviderDetails = identityProviderDetails
	}

	if attr, ok := d.GetOk("identity_provider_type"); ok {
		createOpts.IdentityProviderType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("logging_role"); ok {
		createOpts.LoggingRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("endpoint_type"); ok {
		createOpts.EndpointType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("endpoint_details"); ok {
		createOpts.EndpointDetails = expandTransferServerEndpointDetails(attr.([]interface{}))
	}

	log.Printf("[DEBUG] Create Transfer Server Option: %#v", createOpts)

	resp, err := conn.CreateServer(createOpts)
	if err != nil {
		return fmt.Errorf("Error creating Transfer Server: %s", err)
	}

	d.SetId(*resp.ServerId)

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	descOpts := &transfer.DescribeServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Describe Transfer Server Option: %#v", descOpts)

	resp, err := conn.DescribeServer(descOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	endpoint := fmt.Sprintf("%s.server.transfer.%s.amazonaws.com", d.Id(), meta.(*AWSClient).region)

	d.Set("arn", resp.Server.Arn)
	d.Set("endpoint", endpoint)
	d.Set("invocation_role", "")
	d.Set("url", "")
	if resp.Server.IdentityProviderDetails != nil {
		d.Set("invocation_role", aws.StringValue(resp.Server.IdentityProviderDetails.InvocationRole))
		d.Set("url", aws.StringValue(resp.Server.IdentityProviderDetails.Url))
	}
	d.Set("endpoint_type", resp.Server.EndpointType)
	d.Set("endpoint_details", flattenTransferServerEndpointDetails(resp.Server.EndpointDetails))
	d.Set("identity_provider_type", resp.Server.IdentityProviderType)
	d.Set("logging_role", resp.Server.LoggingRole)

	if err := d.Set("tags", tagsToMapTransfer(resp.Server.Tags)); err != nil {
		return fmt.Errorf("Error setting tags: %s", err)
	}
	return nil
}

func resourceAwsTransferServerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	updateFlag := false
	updateOpts := &transfer.UpdateServerInput{
		ServerId: aws.String(d.Id()),
	}

	if d.HasChange("logging_role") {
		updateFlag = true
		updateOpts.LoggingRole = aws.String(d.Get("logging_role").(string))
	}

	if d.HasChange("invocation_role") || d.HasChange("url") {
		identityProviderDetails := &transfer.IdentityProviderDetails{}
		updateFlag = true
		if attr, ok := d.GetOk("invocation_role"); ok {
			identityProviderDetails.InvocationRole = aws.String(attr.(string))
		}

		if attr, ok := d.GetOk("url"); ok {
			identityProviderDetails.Url = aws.String(attr.(string))
		}
		updateOpts.IdentityProviderDetails = identityProviderDetails
	}

	if d.HasChange("endpoint_type") {
		updateFlag = true
		if attr, ok := d.GetOk("endpoint_type"); ok {
			updateOpts.EndpointType = aws.String(attr.(string))
		}
	}

	if d.HasChange("endpoint_details") {
		updateFlag = true
		if attr, ok := d.GetOk("endpoint_details"); ok {
			updateOpts.EndpointDetails = expandTransferServerEndpointDetails(attr.([]interface{}))
		}
	}

	if updateFlag {
		_, err := conn.UpdateServer(updateOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("error updating Transfer Server (%s): %s", d.Id(), err)
		}
	}

	if err := setTagsTransfer(conn, d); err != nil {
		return fmt.Errorf("Error update tags: %s", err)
	}

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	if d.Get("force_destroy").(bool) {
		log.Printf("[DEBUG] Transfer Server (%s) attempting to forceDestroy", d.Id())
		if err := deleteTransferUsers(conn, d.Id(), nil); err != nil {
			return err
		}
	}

	delOpts := &transfer.DeleteServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Delete Transfer Server Option: %#v", delOpts)

	_, err := conn.DeleteServer(delOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("error deleting Transfer Server (%s): %s", d.Id(), err)
	}

	if err := waitForTransferServerDeletion(conn, d.Id()); err != nil {
		return fmt.Errorf("error waiting for Transfer Server (%s): %s", d.Id(), err)
	}

	return nil
}

func waitForTransferServerDeletion(conn *transfer.Transfer, serverID string) error {
	params := &transfer.DescribeServerInput{
		ServerId: aws.String(serverID),
	}

	return resource.Retry(10*time.Minute, func() *resource.RetryError {
		_, err := conn.DescribeServer(params)

		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return resource.RetryableError(fmt.Errorf("Transfer Server (%s) still exists", serverID))
	})
}

func deleteTransferUsers(conn *transfer.Transfer, serverID string, nextToken *string) error {
	listOpts := &transfer.ListUsersInput{
		ServerId:  aws.String(serverID),
		NextToken: nextToken,
	}

	log.Printf("[DEBUG] List Transfer User Option: %#v", listOpts)

	resp, err := conn.ListUsers(listOpts)
	if err != nil {
		return err
	}

	for _, user := range resp.Users {

		delOpts := &transfer.DeleteUserInput{
			ServerId: aws.String(serverID),
			UserName: user.UserName,
		}

		log.Printf("[DEBUG] Delete Transfer User Option: %#v", delOpts)

		_, err = conn.DeleteUser(delOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				continue
			}
			return fmt.Errorf("error deleting Transfer User (%s) for Server(%s): %s", *user.UserName, serverID, err)
		}
	}

	if resp.NextToken != nil {
		return deleteTransferUsers(conn, serverID, resp.NextToken)
	}

	return nil
}

func expandTransferServerEndpointDetails(l []interface{}) *transfer.EndpointDetails {
	if len(l) == 0 || l[0] == nil {
		return nil
	}
	e := l[0].(map[string]interface{})

	return &transfer.EndpointDetails{
		VpcEndpointId: aws.String(e["vpc_endpoint_id"].(string)),
	}
}

func flattenTransferServerEndpointDetails(endpointDetails *transfer.EndpointDetails) []interface{} {
	if endpointDetails == nil {
		return []interface{}{}
	}

	e := map[string]interface{}{
		"vpc_endpoint_id": aws.StringValue(endpointDetails.VpcEndpointId),
	}

	return []interface{}{e}
}
<commit_msg>Final retry for transfer server<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/transfer"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsTransferServer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsTransferServerCreate,
		Read:   resourceAwsTransferServerRead,
		Update: resourceAwsTransferServerUpdate,
		Delete: resourceAwsTransferServerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"endpoint": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"endpoint_type": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  transfer.EndpointTypePublic,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.EndpointTypePublic,
					transfer.EndpointTypeVpcEndpoint,
				}, false),
			},

			"endpoint_details": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"vpc_endpoint_id": {
							Type:     schema.TypeString,
							Required: true,
							ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
								value := v.(string)
								validNamePattern := "^vpce-[0-9a-f]{17}$"
								validName, nameMatchErr := regexp.MatchString(validNamePattern, value)
								if !validName || nameMatchErr != nil {
									errors = append(errors, fmt.Errorf(
										"%q must match regex '%v'", k, validNamePattern))
								}
								return
							},
						},
					},
				},
			},

			"invocation_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"url": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"identity_provider_type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  transfer.IdentityProviderTypeServiceManaged,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.IdentityProviderTypeServiceManaged,
					transfer.IdentityProviderTypeApiGateway,
				}, false),
			},

			"logging_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"force_destroy": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsTransferServerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	tags := tagsFromMapTransfer(d.Get("tags").(map[string]interface{}))
	createOpts := &transfer.CreateServerInput{}

	if len(tags) != 0 {
		createOpts.Tags = tags
	}

	identityProviderDetails := &transfer.IdentityProviderDetails{}
	if attr, ok := d.GetOk("invocation_role"); ok {
		identityProviderDetails.InvocationRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("url"); ok {
		identityProviderDetails.Url = aws.String(attr.(string))
	}

	if identityProviderDetails.Url != nil || identityProviderDetails.InvocationRole != nil {
		createOpts.IdentityProviderDetails = identityProviderDetails
	}

	if attr, ok := d.GetOk("identity_provider_type"); ok {
		createOpts.IdentityProviderType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("logging_role"); ok {
		createOpts.LoggingRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("endpoint_type"); ok {
		createOpts.EndpointType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("endpoint_details"); ok {
		createOpts.EndpointDetails = expandTransferServerEndpointDetails(attr.([]interface{}))
	}

	log.Printf("[DEBUG] Create Transfer Server Option: %#v", createOpts)

	resp, err := conn.CreateServer(createOpts)
	if err != nil {
		return fmt.Errorf("Error creating Transfer Server: %s", err)
	}

	d.SetId(*resp.ServerId)

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	descOpts := &transfer.DescribeServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Describe Transfer Server Option: %#v", descOpts)

	resp, err := conn.DescribeServer(descOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	endpoint := fmt.Sprintf("%s.server.transfer.%s.amazonaws.com", d.Id(), meta.(*AWSClient).region)

	d.Set("arn", resp.Server.Arn)
	d.Set("endpoint", endpoint)
	d.Set("invocation_role", "")
	d.Set("url", "")
	if resp.Server.IdentityProviderDetails != nil {
		d.Set("invocation_role", aws.StringValue(resp.Server.IdentityProviderDetails.InvocationRole))
		d.Set("url", aws.StringValue(resp.Server.IdentityProviderDetails.Url))
	}
	d.Set("endpoint_type", resp.Server.EndpointType)
	d.Set("endpoint_details", flattenTransferServerEndpointDetails(resp.Server.EndpointDetails))
	d.Set("identity_provider_type", resp.Server.IdentityProviderType)
	d.Set("logging_role", resp.Server.LoggingRole)

	if err := d.Set("tags", tagsToMapTransfer(resp.Server.Tags)); err != nil {
		return fmt.Errorf("Error setting tags: %s", err)
	}
	return nil
}

func resourceAwsTransferServerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	updateFlag := false
	updateOpts := &transfer.UpdateServerInput{
		ServerId: aws.String(d.Id()),
	}

	if d.HasChange("logging_role") {
		updateFlag = true
		updateOpts.LoggingRole = aws.String(d.Get("logging_role").(string))
	}

	if d.HasChange("invocation_role") || d.HasChange("url") {
		identityProviderDetails := &transfer.IdentityProviderDetails{}
		updateFlag = true
		if attr, ok := d.GetOk("invocation_role"); ok {
			identityProviderDetails.InvocationRole = aws.String(attr.(string))
		}

		if attr, ok := d.GetOk("url"); ok {
			identityProviderDetails.Url = aws.String(attr.(string))
		}
		updateOpts.IdentityProviderDetails = identityProviderDetails
	}

	if d.HasChange("endpoint_type") {
		updateFlag = true
		if attr, ok := d.GetOk("endpoint_type"); ok {
			updateOpts.EndpointType = aws.String(attr.(string))
		}
	}

	if d.HasChange("endpoint_details") {
		updateFlag = true
		if attr, ok := d.GetOk("endpoint_details"); ok {
			updateOpts.EndpointDetails = expandTransferServerEndpointDetails(attr.([]interface{}))
		}
	}

	if updateFlag {
		_, err := conn.UpdateServer(updateOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("error updating Transfer Server (%s): %s", d.Id(), err)
		}
	}

	if err := setTagsTransfer(conn, d); err != nil {
		return fmt.Errorf("Error update tags: %s", err)
	}

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	if d.Get("force_destroy").(bool) {
		log.Printf("[DEBUG] Transfer Server (%s) attempting to forceDestroy", d.Id())
		if err := deleteTransferUsers(conn, d.Id(), nil); err != nil {
			return err
		}
	}

	delOpts := &transfer.DeleteServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Delete Transfer Server Option: %#v", delOpts)

	_, err := conn.DeleteServer(delOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("error deleting Transfer Server (%s): %s", d.Id(), err)
	}

	if err := waitForTransferServerDeletion(conn, d.Id()); err != nil {
		return fmt.Errorf("error waiting for Transfer Server (%s): %s", d.Id(), err)
	}

	return nil
}

func waitForTransferServerDeletion(conn *transfer.Transfer, serverID string) error {
	params := &transfer.DescribeServerInput{
		ServerId: aws.String(serverID),
	}

	err := resource.Retry(10*time.Minute, func() *resource.RetryError {
		_, err := conn.DescribeServer(params)

		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return resource.RetryableError(fmt.Errorf("Transfer Server (%s) still exists", serverID))
	})
	if isResourceTimeoutError(err) {
		_, err = conn.DescribeServer(params)
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}
		if err == nil {
			return fmt.Errorf("Transfer server (%s) still exists", serverID)
		}
	}
	if err != nil {
		return fmt.Errorf("Error waiting for transfer server deletion: %s", err)
	}
	return nil
}

func deleteTransferUsers(conn *transfer.Transfer, serverID string, nextToken *string) error {
	listOpts := &transfer.ListUsersInput{
		ServerId:  aws.String(serverID),
		NextToken: nextToken,
	}

	log.Printf("[DEBUG] List Transfer User Option: %#v", listOpts)

	resp, err := conn.ListUsers(listOpts)
	if err != nil {
		return err
	}

	for _, user := range resp.Users {

		delOpts := &transfer.DeleteUserInput{
			ServerId: aws.String(serverID),
			UserName: user.UserName,
		}

		log.Printf("[DEBUG] Delete Transfer User Option: %#v", delOpts)

		_, err = conn.DeleteUser(delOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				continue
			}
			return fmt.Errorf("error deleting Transfer User (%s) for Server(%s): %s", *user.UserName, serverID, err)
		}
	}

	if resp.NextToken != nil {
		return deleteTransferUsers(conn, serverID, resp.NextToken)
	}

	return nil
}

func expandTransferServerEndpointDetails(l []interface{}) *transfer.EndpointDetails {
	if len(l) == 0 || l[0] == nil {
		return nil
	}
	e := l[0].(map[string]interface{})

	return &transfer.EndpointDetails{
		VpcEndpointId: aws.String(e["vpc_endpoint_id"].(string)),
	}
}

func flattenTransferServerEndpointDetails(endpointDetails *transfer.EndpointDetails) []interface{} {
	if endpointDetails == nil {
		return []interface{}{}
	}

	e := map[string]interface{}{
		"vpc_endpoint_id": aws.StringValue(endpointDetails.VpcEndpointId),
	}

	return []interface{}{e}
}
<|endoftext|>