func (c *Client) handleLine(line string) error {
	go func() {
		// Send a message on the `messageReceived` channel, but do not block in case no one is receiving on the other end
		select {
		case c.messageReceived <- true:
		default:
		}
	}()

	message := ParseMessage(line)

	switch msg := message.(type) {
	case *WhisperMessage:
		if c.onWhisperMessage != nil {
			c.onWhisperMessage(*msg)
		}
		return nil

	case *PrivateMessage:
		if c.onPrivateMessage != nil {
			c.onPrivateMessage(*msg)
		}
		return nil

	case *ClearChatMessage:
		if c.onClearChatMessage != nil {
			c.onClearChatMessage(*msg)
		}
		return nil

	case *RoomStateMessage:
		if c.onRoomStateMessage != nil {
			c.onRoomStateMessage(*msg)
		}
		return nil

	case *UserNoticeMessage:
		if c.onUserNoticeMessage != nil {
			c.onUserNoticeMessage(*msg)
		}
		return nil

	case *UserStateMessage:
		if c.onUserStateMessage != nil {
			c.onUserStateMessage(*msg)
		}
		return nil

	case *NoticeMessage:
		if c.onNoticeMessage != nil {
			c.onNoticeMessage(*msg)
		}
		return c.handleNoticeMessage(*msg)

	case *UserJoinMessage:
		if c.handleUserJoinMessage(*msg) {
			if c.onUserJoinMessage != nil {
				c.onUserJoinMessage(*msg)
			}
		}
		return nil

	case *UserPartMessage:
		if c.handleUserPartMessage(*msg) {
			if c.onUserPartMessage != nil {
				c.onUserPartMessage(*msg)
			}
		}
		return nil

	case *ReconnectMessage:
		// https://dev.twitch.tv/docs/irc/commands/#reconnect-twitch-commands
		if c.onReconnectMessage != nil {
			c.onReconnectMessage(*msg)
		}
		return errReconnect

	case *NamesMessage:
		if c.onNamesMessage != nil {
			c.onNamesMessage(*msg)
		}
		c.handleNamesMessage(*msg)
		return nil

	case *PingMessage:
		if c.onPingMessage != nil {
			c.onPingMessage(*msg)
		}
		c.handlePingMessage(*msg)
		return nil

	case *PongMessage:
		if c.onPongMessage != nil {
			c.onPongMessage(*msg)
		}
		c.handlePongMessage(*msg)
		return nil

	case *RawMessage:
		if c.onUnsetMessage != nil {
			c.onUnsetMessage(*msg)
		}
	}

	return nil
}

// Errors returned from handleLine break out of readConnections, which starts a reconnect
// This means that we should only return fatal errors as errors here

Errors returned from handleLine break out of readConnections which starts a reconnect This means that we should only return fatal errors as errors here


func (c *GenerateConcoursePipelineCommand) Execute([]string) error {
	lo.G.Warning("This command has been deprecated use lastest cf-mgmt-config cli")
	const varsFileName = "vars.yml"
	const pipelineFileName = "pipeline.yml"
	const cfMgmtYml = "cf-mgmt.yml"
	const cfMgmtSh = "cf-mgmt.sh"
	var targetFile string
	fmt.Println("Generating pipeline....")
	if err := createFile(pipelineFileName, pipelineFileName); err != nil {
		lo.G.Error("Error creating pipeline.yml", err)
		return err
	}
	if err := createFile(varsFileName, varsFileName); err != nil {
		lo.G.Error("Error creating vars.yml", err)
		return err
	}
	if err := os.MkdirAll("ci/tasks", 0755); err == nil {
		targetFile = filepath.Join("ci", "tasks", cfMgmtYml)
		lo.G.Debug("Creating", targetFile)
		if err = createFile(cfMgmtYml, targetFile); err != nil {
			lo.G.Error("Error creating cf-mgmt.yml", err)
			return err
		}
		targetFile = filepath.Join("ci", "tasks", cfMgmtSh)
		lo.G.Debug("Creating", targetFile)
		if err = createFile(cfMgmtSh, targetFile); err != nil {
			lo.G.Error("Error creating cf-mgmt.sh", err)
			return err
		}
	} else {
		lo.G.Error("Error making directories", err)
		return err
	}
	fmt.Println("1) Update vars.yml with the appropriate values")
	fmt.Println("2) Using following command to set your pipeline in concourse after you have checked all files in to git")
	fmt.Println("fly -t lite set-pipeline -p cf-mgmt -c pipeline.yml --load-vars-from=vars.yml")
	return nil
}

func ( c * GenerateConcoursePipelineCommand ) Execute ( [ ] string ) error { lo . G . Warning ( " " ) const varsFileName = " " const pipelineFileName = " " const cfMgmtYml = " " const cfMgmtSh = " " var targetFile string fmt . Println ( " " ) if err := createFile ( pipelineFileName , pipelineFileName ) ; err != nil { lo . G . Error ( " " , err ) return err } if err := createFile ( varsFileName , varsFileName ) ; err != nil { lo . G . Error ( " " , err ) return err } if err := os . MkdirAll ( " " , 0755 ) ; err == nil { targetFile = filepath . Join ( " " , " " , cfMgmtYml ) lo . G . Debug ( " " , targetFile ) if err = createFile ( cfMgmtYml , targetFile ) ; err != nil { lo . G . Error ( " " , err ) return err } targetFile = filepath . Join ( " " , " " , cfMgmtSh ) lo . G . Debug ( " " , targetFile ) if err = createFile ( cfMgmtSh , targetFile ) ; err != nil { lo . G . Error ( " " , err ) return err } } else { lo . G . Error ( " " , err ) return err } fmt . Println ( " " ) fmt . Println ( " " ) fmt . Println ( " " ) return nil }

//Execute - generates concourse pipeline and tasks


func (c *CleanupOrgUsersCommand) Execute([]string) error {
	if cfMgmt, err := InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		return cfMgmt.UserManager.CleanupOrgUsers()
	}
	return nil
}

func ( c * CleanupOrgUsersCommand ) Execute ( [ ] string ) error { if cfMgmt , err := InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { return cfMgmt . UserManager . CleanupOrgUsers ( ) } return nil }


func classify(desired []cfclient.IsolationSegment, current []cfclient.IsolationSegment) classification {
	currentSegments := make(map[string]*cfclient.IsolationSegment)
	for i := range current {
		currentSegments[current[i].Name] = &current[i]
	}
	desiredSegments := make(map[string]*cfclient.IsolationSegment)
	for i := range desired {
		desiredSegments[desired[i].Name] = &desired[i]
	}

	var missing []cfclient.IsolationSegment
	for name, seg := range desiredSegments {
		if _, ok := currentSegments[name]; !ok {
			missing = append(missing, *seg)
		}
	}

	var extra []cfclient.IsolationSegment
	for name, seg := range currentSegments {
		if _, ok := desiredSegments[name]; !ok {
			extra = append(extra, *seg)
		}
	}

	return classification{missing, extra}
}

func classify ( desired [ ] cfclient . IsolationSegment , current [ ] cfclient . IsolationSegment ) classification { currentSegments := make ( map [ string ] * cfclient . IsolationSegment ) for i := range current { currentSegments [ current [ i ] . Name ] = & current [ i ] } desiredSegments := make ( map [ string ] * cfclient . IsolationSegment ) for i := range desired { desiredSegments [ desired [ i ] . Name ] = & desired [ i ] } var missing [ ] cfclient . IsolationSegment for name , seg := range desiredSegments { if _ , ok := currentSegments [ name ] ; ! ok { missing = append ( missing , * seg ) } } var extra [ ] cfclient . IsolationSegment for name , seg := range currentSegments { if _ , ok := desiredSegments [ name ] ; ! ok { extra = append ( extra , * seg ) } } return classification { missing , extra } }

// classify accepts a list of segments that should meet some property and a list
// of segments that currently do meet that property, and returns a classification.

classify accepts a list of segments that should meet some property and a list of segments that currently do meet that property and returns a classification .


func (c *CreateSpaceSecurityGroupsCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.SecurityGroupManager.CreateApplicationSecurityGroups()
	}
	return err
}

func ( c * CreateSpaceSecurityGroupsCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . SecurityGroupManager . CreateApplicationSecurityGroups ( ) } return err }

//Execute - creates space specific security groups


func (c *UpdateSpacesMetadataCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.SpaceManager.UpdateSpacesMetadata()
	}
	return err
}

func ( c * UpdateSpacesMetadataCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . SpaceManager . UpdateSpacesMetadata ( ) } return err }


func (c *SpaceNamedQuotaConfigurationCommand) Execute(args []string) error {
	c.initConfig()
	spaceQuota, err := c.ConfigManager.GetSpaceQuota(c.Name, c.Org)
	if err != nil {
		return err
	}
	if spaceQuota == nil {
		spaceQuota = &config.SpaceQuota{
			Name:                    c.Name,
			Org:                     c.Org,
			TotalReservedRoutePorts: "unlimited",
			TotalServiceKeys:        "unlimited",
			AppInstanceLimit:        "unlimited",
			AppTaskLimit:            "unlimited",
			InstanceMemoryLimit:     "unlimited",
			TotalRoutes:             "unlimited",
			TotalServices:           "unlimited",
			PaidServicePlansAllowed: true,
		}
	}
	errorString := ""
	updateSpaceNamedQuotaConfig(spaceQuota, c.Quota, &errorString)

	if errorString != "" {
		return errors.New(errorString)
	}
	return c.ConfigManager.SaveSpaceQuota(spaceQuota)
}

func ( c * SpaceNamedQuotaConfigurationCommand ) Execute ( args [ ] string ) error { c . initConfig ( ) spaceQuota , err := c . ConfigManager . GetSpaceQuota ( c . Name , c . Org ) if err != nil { return err } if spaceQuota == nil { spaceQuota = & config . SpaceQuota { Name : c . Name , Org : c . Org , TotalReservedRoutePorts : " " , TotalServiceKeys : " " , AppInstanceLimit : " " , AppTaskLimit : " " , InstanceMemoryLimit : " " , TotalRoutes : " " , TotalServices : " " , PaidServicePlansAllowed : true , } } errorString := " " updateSpaceNamedQuotaConfig ( spaceQuota , c . Quota , & errorString ) if errorString != " " { return errors . New ( errorString ) } return c . ConfigManager . SaveSpaceQuota ( spaceQuota ) }


func (c *AddASGToConfigurationCommand) Execute([]string) error {
	c.initConfig()

	errorString := ""

	if errorString != "" {
		return errors.New(errorString)
	}

	if !c.Override {
		if c.ASGType == "space" {
			asgConfigs, err := c.ConfigManager.GetASGConfigs()
			if err != nil {
				return err
			}
			for _, asgConfig := range asgConfigs {
				if c.ASGName == asgConfig.Name {
					return errors.New(fmt.Sprintf("asg [%s] already exists if wanting to update use --override flag", c.ASGName))
				}
			}
		} else {
			asgConfigs, err := c.ConfigManager.GetDefaultASGConfigs()
			if err != nil {
				return err
			}
			for _, asgConfig := range asgConfigs {
				if c.ASGName == asgConfig.Name {
					return errors.New(fmt.Sprintf("asg [%s] already exists if wanting to update use --override flag", c.ASGName))
				}
			}
		}
	}

	securityGroupsBytes := []byte("[]")
	if c.FilePath != "" {
		bytes, err := config.LoadFileBytes(c.FilePath)
		if err != nil {
			return err
		}
		securityGroupsBytes = bytes
	}
	if c.ASGType == "space" {
		if err := config.NewManager(c.ConfigDirectory).AddSecurityGroup(c.ASGName, securityGroupsBytes); err != nil {
			return err
		}
	} else {
		if err := config.NewManager(c.ConfigDirectory).AddDefaultSecurityGroup(c.ASGName, securityGroupsBytes); err != nil {
			return err
		}
	}
	fmt.Println(fmt.Sprintf("The asg [%s] has been updated", c.ASGName))
	return nil
}

func ( c * AddASGToConfigurationCommand ) Execute ( [ ] string ) error { c . initConfig ( ) errorString := " " if errorString != " " { return errors . New ( errorString ) } if ! c . Override { if c . ASGType == " " { asgConfigs , err := c . ConfigManager . GetASGConfigs ( ) if err != nil { return err } for _ , asgConfig := range asgConfigs { if c . ASGName == asgConfig . Name { return errors . New ( fmt . Sprintf ( " " , c . ASGName ) ) } } } else { asgConfigs , err := c . ConfigManager . GetDefaultASGConfigs ( ) if err != nil { return err } for _ , asgConfig := range asgConfigs { if c . ASGName == asgConfig . Name { return errors . New ( fmt . Sprintf ( " " , c . ASGName ) ) } } } } securityGroupsBytes := [ ] byte ( " " ) if c . FilePath != " " { bytes , err := config . LoadFileBytes ( c . FilePath ) if err != nil { return err } securityGroupsBytes = bytes } if c . ASGType == " " { if err := config . NewManager ( c . ConfigDirectory ) . AddSecurityGroup ( c . ASGName , securityGroupsBytes ) ; err != nil { return err } } else { if err := config . NewManager ( c . ConfigDirectory ) . AddDefaultSecurityGroup ( c . ASGName , securityGroupsBytes ) ; err != nil { return err } } fmt . Println ( fmt . Sprintf ( " " , c . ASGName ) ) return nil }

//Execute - adds a named asg to the configuration


func (c *UpdateSpaceUsersCommand) Execute([]string) error {
	if cfMgmt, err := InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		if err := cfMgmt.UserManager.InitializeLdap(c.LdapUser, c.LdapPassword, c.LdapServer); err != nil {
			return err
		}
		defer cfMgmt.UserManager.DeinitializeLdap()
		return cfMgmt.UserManager.UpdateSpaceUsers()
	}
	return nil
}

func ( c * UpdateSpaceUsersCommand ) Execute ( [ ] string ) error { if cfMgmt , err := InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { if err := cfMgmt . UserManager . InitializeLdap ( c . LdapUser , c . LdapPassword , c . LdapServer ) ; err != nil { return err } defer cfMgmt . UserManager . DeinitializeLdap ( ) return cfMgmt . UserManager . UpdateSpaceUsers ( ) } return nil }


func (c *DeleteOrgsCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.OrgManager.DeleteOrgs()
	}
	return err
}

func ( c * DeleteOrgsCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . OrgManager . DeleteOrgs ( ) } return err }


func (c *OrgNamedQuotaConfigurationCommand) Execute(args []string) error {
	c.initConfig()
	orgQuota, err := c.ConfigManager.GetOrgQuota(c.Name)
	if err != nil {
		return err
	}
	if orgQuota == nil {
		orgQuota = &config.OrgQuota{
			Name:                    c.Name,
			TotalPrivateDomains:     "unlimited",
			TotalReservedRoutePorts: "unlimited",
			TotalServiceKeys:        "unlimited",
			AppInstanceLimit:        "unlimited",
			AppTaskLimit:            "unlimited",
			InstanceMemoryLimit:     "unlimited",
			TotalRoutes:             "unlimited",
			TotalServices:           "unlimited",
			PaidServicePlansAllowed: true,
		}
	}
	errorString := ""
	updateOrgNamedQuotaConfig(orgQuota, c.Quota, &errorString)

	if errorString != "" {
		return errors.New(errorString)
	}
	return c.ConfigManager.SaveOrgQuota(orgQuota)
}

func ( c * OrgNamedQuotaConfigurationCommand ) Execute ( args [ ] string ) error { c . initConfig ( ) orgQuota , err := c . ConfigManager . GetOrgQuota ( c . Name ) if err != nil { return err } if orgQuota == nil { orgQuota = & config . OrgQuota { Name : c . Name , TotalPrivateDomains : " " , TotalReservedRoutePorts : " " , TotalServiceKeys : " " , AppInstanceLimit : " " , AppTaskLimit : " " , InstanceMemoryLimit : " " , TotalRoutes : " " , TotalServices : " " , PaidServicePlansAllowed : true , } } errorString := " " updateOrgNamedQuotaConfig ( orgQuota , c . Quota , & errorString ) if errorString != " " { return errors . New ( errorString ) } return c . ConfigManager . SaveOrgQuota ( orgQuota ) }


func (s *Spaces) Contains(spaceName string) bool {
	spaceNameToUpper := strings.ToUpper(spaceName)
	for _, v := range s.Spaces {
		if strings.ToUpper(v) == spaceNameToUpper {
			return true
		}
	}
	return false
}

func ( s * Spaces ) Contains ( spaceName string ) bool { spaceNameToUpper := strings . ToUpper ( spaceName ) for _ , v := range s . Spaces { if strings . ToUpper ( v ) == spaceNameToUpper { return true } } return false }

// Contains determines whether a space is present in a list of spaces.

Contains determines whether a space is present in a list of spaces .


func (c *UpdateOrgQuotasCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.QuotaManager.CreateOrgQuotas()
	}
	return err
}

func ( c * UpdateOrgQuotasCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . QuotaManager . CreateOrgQuotas ( ) } return err }


func (c *UpdateSpaceQuotasCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.QuotaManager.CreateSpaceQuotas()
	}
	return err
}

func ( c * UpdateSpaceQuotasCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . QuotaManager . CreateSpaceQuotas ( ) } return err }


func (m *yamlManager) Orgs() (*Orgs, error) {
	configFile := filepath.Join(m.ConfigDir, "orgs.yml")
	lo.G.Debug("Processing org file", configFile)
	input := &Orgs{}
	if err := LoadFile(configFile, &input); err != nil {
		return nil, err
	}
	return input, nil
}

func ( m * yamlManager ) Orgs ( ) ( * Orgs , error ) { configFile := filepath . Join ( m . ConfigDir , " " ) lo . G . Debug ( " " , configFile ) input := & Orgs { } if err := LoadFile ( configFile , & input ) ; err != nil { return nil , err } return input , nil }


func (m *yamlManager) GetGlobalConfig() (*GlobalConfig, error) {
	globalConfig := &GlobalConfig{}
	LoadFile(path.Join(m.ConfigDir, "cf-mgmt.yml"), globalConfig)
	if len(globalConfig.MetadataPrefix) == 0 {
		globalConfig.MetadataPrefix = "cf-mgmt.pivotal.io"
	}
	return globalConfig, nil
}

func ( m * yamlManager ) GetGlobalConfig ( ) ( * GlobalConfig , error ) { globalConfig := & GlobalConfig { } LoadFile ( path . Join ( m . ConfigDir , " " ) , globalConfig ) if len ( globalConfig . MetadataPrefix ) == 0 { globalConfig . MetadataPrefix = " " } return globalConfig , nil }

// GetIsolationSegmentConfig reads isolation segment config


func (m *yamlManager) GetOrgConfigs() ([]OrgConfig, error) {
	files, err := FindFiles(m.ConfigDir, "orgConfig.yml")
	if err != nil {
		return nil, err
	}
	result := make([]OrgConfig, len(files))
	for i, f := range files {
		result[i].AppTaskLimit = unlimited
		result[i].AppInstanceLimit = unlimited
		result[i].TotalReservedRoutePorts = "0"
		result[i].TotalPrivateDomains = unlimited
		result[i].TotalServiceKeys = unlimited
		result[i].InstanceMemoryLimit = unlimited

		if err = LoadFile(f, &result[i]); err != nil {
			lo.G.Error(err)
			return nil, err
		}
	}
	return result, nil
}

func ( m * yamlManager ) GetOrgConfigs ( ) ( [ ] OrgConfig , error ) { files , err := FindFiles ( m . ConfigDir , " " ) if err != nil { return nil , err } result := make ( [ ] OrgConfig , len ( files ) ) for i , f := range files { result [ i ] . AppTaskLimit = unlimited result [ i ] . AppInstanceLimit = unlimited result [ i ] . TotalReservedRoutePorts = " " result [ i ] . TotalPrivateDomains = unlimited result [ i ] . TotalServiceKeys = unlimited result [ i ] . InstanceMemoryLimit = unlimited if err = LoadFile ( f , & result [ i ] ) ; err != nil { lo . G . Error ( err ) return nil , err } } return result , nil }

// GetOrgConfigs reads all orgs from the cf-mgmt configuration.

GetOrgConfigs reads all orgs from the cf - mgmt configuration .


func (m *yamlManager) GetSpaceDefaults() (*SpaceConfig, error) {
	fp := filepath.Join(m.ConfigDir, "spaceDefaults.yml")

	if !FileOrDirectoryExists(fp) {
		return nil, nil
	}
	result := SpaceConfig{}
	err := LoadFile(fp, &result)
	return &result, err
}

func ( m * yamlManager ) GetSpaceDefaults ( ) ( * SpaceConfig , error ) { fp := filepath . Join ( m . ConfigDir , " " ) if ! FileOrDirectoryExists ( fp ) { return nil , nil } result := SpaceConfig { } err := LoadFile ( fp , & result ) return & result , err }

// GetSpaceDefaults returns the default space configuration, if one was provided.
// If no space defaults were configured, a nil config and a nil error are returned.

GetSpaceDefaults returns the default space configuration if one was provided . If no space defaults were configured a nil config and a nil error are returned .


func (m *yamlManager) AddOrgToConfig(orgConfig *OrgConfig, spaces *Spaces) error {
	orgList, err := m.Orgs()
	if err != nil {
		return err
	}
	orgName := orgConfig.Org
	if orgName == "" {
		return errors.New("cannot have an empty org name")
	}

	if orgList.Contains(orgName) {
		return fmt.Errorf("org [%s] already added to config -> %v", orgName, orgList.Orgs)
	}
	lo.G.Infof("Adding org: %s ", orgName)
	orgList.Orgs = append(orgList.Orgs, orgName)
	if err = m.SaveOrgs(orgList); err != nil {
		return err
	}
	m.SaveOrgConfig(orgConfig)
	return m.SaveOrgSpaces(spaces)
}

func ( m * yamlManager ) AddOrgToConfig ( orgConfig * OrgConfig , spaces * Spaces ) error { orgList , err := m . Orgs ( ) if err != nil { return err } orgName := orgConfig . Org if orgName == " " { return errors . New ( " " ) } if orgList . Contains ( orgName ) { return fmt . Errorf ( " " , orgName , orgList . Orgs ) } lo . G . Infof ( " " , orgName ) orgList . Orgs = append ( orgList . Orgs , orgName ) if err = m . SaveOrgs ( orgList ) ; err != nil { return err } m . SaveOrgConfig ( orgConfig ) return m . SaveOrgSpaces ( spaces ) }

// AddOrgToConfig adds an organization to the cf-mgmt configuration.

AddOrgToConfig adds an organization to the cf - mgmt configuration .


func (m *yamlManager) AddSpaceToConfig(spaceConfig *SpaceConfig) error {
	orgName := spaceConfig.Org
	spaceFileName := filepath.Join(m.ConfigDir, orgName, "spaces.yml")
	spaceList := &Spaces{}
	spaceName := spaceConfig.Space

	if err := LoadFile(spaceFileName, spaceList); err != nil {
		return err
	}
	if spaceList.Contains(spaceName) {
		return fmt.Errorf("space [%s] already added to config -> [%v]", spaceName, spaceList.Spaces)
	}
	lo.G.Infof("Adding space: %s ", spaceName)
	spaceList.Spaces = append(spaceList.Spaces, spaceName)
	if err := WriteFile(spaceFileName, spaceList); err != nil {
		return err
	}

	if err := m.SaveSpaceConfig(spaceConfig); err != nil {
		return err
	}
	if err := WriteFileBytes(fmt.Sprintf("%s/%s/%s/security-group.json", m.ConfigDir, orgName, spaceName), []byte("[]")); err != nil {
		return err
	}
	return nil
}

func ( m * yamlManager ) AddSpaceToConfig ( spaceConfig * SpaceConfig ) error { orgName := spaceConfig . Org spaceFileName := filepath . Join ( m . ConfigDir , orgName , " " ) spaceList := & Spaces { } spaceName := spaceConfig . Space if err := LoadFile ( spaceFileName , spaceList ) ; err != nil { return err } if spaceList . Contains ( spaceName ) { return fmt . Errorf ( " " , spaceName , spaceList . Spaces ) } lo . G . Infof ( " " , spaceName ) spaceList . Spaces = append ( spaceList . Spaces , spaceName ) if err := WriteFile ( spaceFileName , spaceList ) ; err != nil { return err } if err := m . SaveSpaceConfig ( spaceConfig ) ; err != nil { return err } if err := WriteFileBytes ( fmt . Sprintf ( " " , m . ConfigDir , orgName , spaceName ) , [ ] byte ( " " ) ) ; err != nil { return err } return nil }

// AddSpaceToConfig adds a space to the cf-mgmt configuration, so long as a
// space with the specified name doesn't already exist.

AddSpaceToConfig adds a space to the cf - mgmt configuration so long as a space with the specified name doesn t already exist .


func (m *yamlManager) CreateConfigIfNotExists(uaaOrigin string) error {
	if FileOrDirectoryExists(m.ConfigDir) {
		lo.G.Infof("Config directory %s already exists, skipping creation", m.ConfigDir)
		return nil
	}
	if err := os.MkdirAll(m.ConfigDir, 0755); err != nil {
		lo.G.Errorf("Error creating config directory %s. Error : %s", m.ConfigDir, err)
		return fmt.Errorf("cannot create directory %s: %v", m.ConfigDir, err)
	}
	lo.G.Infof("Config directory %s created", m.ConfigDir)

	asgDir := path.Join(m.ConfigDir, "asgs")
	if err := os.MkdirAll(asgDir, 0755); err != nil {
		lo.G.Errorf("Error creating config directory %s. Error : %s", asgDir, err)
		return fmt.Errorf("cannot create directory %s: %v", asgDir, err)
	}
	lo.G.Infof("ASG directory %s created", asgDir)

	asgDir = path.Join(m.ConfigDir, "default_asgs")
	if err := os.MkdirAll(asgDir, 0755); err != nil {
		lo.G.Errorf("Error creating config directory %s. Error : %s", asgDir, err)
		return fmt.Errorf("cannot create directory %s: %v", asgDir, err)
	}
	lo.G.Infof("ASG directory %s created", asgDir)

	orgQuotasDir := path.Join(m.ConfigDir, "org_quotas")
	if err := os.MkdirAll(orgQuotasDir, 0755); err != nil {
		lo.G.Errorf("Error creating config directory %s. Error : %s", orgQuotasDir, err)
		return fmt.Errorf("cannot create directory %s: %v", orgQuotasDir, err)
	}
	lo.G.Infof("OrgQuotas directory %s created", orgQuotasDir)

	if err := m.SaveGlobalConfig(&GlobalConfig{}); err != nil {
		return err
	}
	if err := WriteFile(fmt.Sprintf("%s/ldap.yml", m.ConfigDir), &LdapConfig{TLS: false, Origin: uaaOrigin}); err != nil {
		return err
	}

	if err := WriteFile(fmt.Sprintf("%s/orgs.yml", m.ConfigDir), &Orgs{
		EnableDeleteOrgs: true,
		ProtectedOrgs:    DefaultProtectedOrgs,
	}); err != nil {
		return err
	}
	if err := WriteFile(fmt.Sprintf("%s/spaceDefaults.yml", m.ConfigDir), struct {
		Developer UserMgmt `yaml:"space-developer"`
		Manager   UserMgmt `yaml:"space-manager"`
		Auditor   UserMgmt `yaml:"space-auditor"`
	}{}); err != nil {
		return err
	}
	return nil
}

func ( m * yamlManager ) CreateConfigIfNotExists ( uaaOrigin string ) error { if FileOrDirectoryExists ( m . ConfigDir ) { lo . G . Infof ( " " , m . ConfigDir ) return nil } if err := os . MkdirAll ( m . ConfigDir , 0755 ) ; err != nil { lo . G . Errorf ( " " , m . ConfigDir , err ) return fmt . Errorf ( " " , m . ConfigDir , err ) } lo . G . Infof ( " " , m . ConfigDir ) asgDir := path . Join ( m . ConfigDir , " " ) if err := os . MkdirAll ( asgDir , 0755 ) ; err != nil { lo . G . Errorf ( " " , asgDir , err ) return fmt . Errorf ( " " , asgDir , err ) } lo . G . Infof ( " " , asgDir ) asgDir = path . Join ( m . ConfigDir , " " ) if err := os . MkdirAll ( asgDir , 0755 ) ; err != nil { lo . G . Errorf ( " " , asgDir , err ) return fmt . Errorf ( " " , asgDir , err ) } lo . G . Infof ( " " , asgDir ) orgQuotasDir := path . Join ( m . ConfigDir , " " ) if err := os . MkdirAll ( orgQuotasDir , 0755 ) ; err != nil { lo . G . Errorf ( " " , orgQuotasDir , err ) return fmt . Errorf ( " " , orgQuotasDir , err ) } lo . G . Infof ( " " , orgQuotasDir ) if err := m . SaveGlobalConfig ( & GlobalConfig { } ) ; err != nil { return err } if err := WriteFile ( fmt . Sprintf ( " " , m . ConfigDir ) , & LdapConfig { TLS : false , Origin : uaaOrigin } ) ; err != nil { return err } if err := WriteFile ( fmt . Sprintf ( " " , m . ConfigDir ) , & Orgs { EnableDeleteOrgs : true , ProtectedOrgs : DefaultProtectedOrgs , } ) ; err != nil { return err } if err := WriteFile ( fmt . Sprintf ( " " , m . ConfigDir ) , struct { Developer UserMgmt `yaml:"space-developer"` Manager UserMgmt `yaml:"space-manager"` Auditor UserMgmt `yaml:"space-auditor"` } { } ) ; err != nil { return err } return nil }

// CreateConfigIfNotExists initializes a new configuration directory.
// If the specified configuration directory already exists, it is left unmodified.

CreateConfigIfNotExists initializes a new configuration directory . If the specified configuration directory already exists it is left unmodified .


func (m *yamlManager) DeleteConfigIfExists() error {
	if !FileOrDirectoryExists(m.ConfigDir) {
		lo.G.Infof("%s doesn't exists, nothing to delete", m.ConfigDir)
		return nil
	}
	if err := os.RemoveAll(m.ConfigDir); err != nil {
		lo.G.Errorf("Error deleting config folder. Error: %s", err)
		return fmt.Errorf("cannot delete %s: %v", m.ConfigDir, err)
	}
	lo.G.Info("Config directory deleted")
	return nil
}

func ( m * yamlManager ) DeleteConfigIfExists ( ) error { if ! FileOrDirectoryExists ( m . ConfigDir ) { lo . G . Infof ( " " , m . ConfigDir ) return nil } if err := os . RemoveAll ( m . ConfigDir ) ; err != nil { lo . G . Errorf ( " " , err ) return fmt . Errorf ( " " , m . ConfigDir , err ) } lo . G . Info ( " " ) return nil }

// DeleteConfigIfExists deletes config directory if it exists.

DeleteConfigIfExists deletes config directory if it exists .


func (c *RenameSpaceConfigurationCommand) Execute(args []string) error {
	c.initConfig()
	spaceConfig, err := c.ConfigManager.GetSpaceConfig(c.OrgName, c.SpaceName)
	if err != nil {
		return err
	}

	spaces, err := c.ConfigManager.OrgSpaces(c.OrgName)
	if err != nil {
		return err
	}
	spaceConfig.Space = c.NewSpaceName
	spaceConfig.OriginalSpace = c.SpaceName

	err = c.ConfigManager.RenameSpaceConfig(spaceConfig)
	if err != nil {
		return err
	}
	spaces.Replace(c.SpaceName, c.NewSpaceName)
	err = c.ConfigManager.SaveOrgSpaces(spaces)
	if err != nil {
		return err
	}
	fmt.Println(fmt.Sprintf("The org/space [%s/%s] has been renamed to [%s/%s]", c.OrgName, c.SpaceName, c.OrgName, c.NewSpaceName))
	return nil
}

func ( c * RenameSpaceConfigurationCommand ) Execute ( args [ ] string ) error { c . initConfig ( ) spaceConfig , err := c . ConfigManager . GetSpaceConfig ( c . OrgName , c . SpaceName ) if err != nil { return err } spaces , err := c . ConfigManager . OrgSpaces ( c . OrgName ) if err != nil { return err } spaceConfig . Space = c . NewSpaceName spaceConfig . OriginalSpace = c . SpaceName err = c . ConfigManager . RenameSpaceConfig ( spaceConfig ) if err != nil { return err } spaces . Replace ( c . SpaceName , c . NewSpaceName ) err = c . ConfigManager . SaveOrgSpaces ( spaces ) if err != nil { return err } fmt . Println ( fmt . Sprintf ( " " , c . OrgName , c . SpaceName , c . OrgName , c . NewSpaceName ) ) return nil }


func (c *CreateSpacesCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.SpaceManager.CreateSpaces()
	}
	return err
}

func ( c * CreateSpacesCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . SpaceManager . CreateSpaces ( ) } return err }


func (m *DefaultManager) DeleteSpace(space cfclient.Space, orgName string) error {
	if m.Peek {
		lo.G.Infof("[dry-run]: delete space with %s from org %s", space.Name, orgName)
		return nil
	}
	lo.G.Infof("delete space with %s from org %s", space.Name, orgName)
	return m.Client.DeleteSpace(space.Guid, true, false)
}

func ( m * DefaultManager ) DeleteSpace ( space cfclient . Space , orgName string ) error { if m . Peek { lo . G . Infof ( " " , space . Name , orgName ) return nil } lo . G . Infof ( " " , space . Name , orgName ) return m . Client . DeleteSpace ( space . Guid , true , false ) }

//DeleteSpace - deletes a space based on GUID


func NewExportManager(
	configDir string,
	uaaMgr uaa.Manager,
	spaceManager space.Manager,
	userManager user.Manager,
	orgManager organization.Manager,
	securityGroupManager securitygroup.Manager,
	isoSegmentMgr isosegment.Manager,
	privateDomainMgr privatedomain.Manager,
	sharedDomainMgr *shareddomain.Manager,
	serviceAccessMgr *serviceaccess.Manager,
	quotaMgr *quota.Manager) Manager {
	return &DefaultImportManager{
		ConfigDir:            configDir,
		UAAMgr:               uaaMgr,
		SpaceManager:         spaceManager,
		UserManager:          userManager,
		OrgManager:           orgManager,
		SecurityGroupManager: securityGroupManager,
		IsoSegmentManager:    isoSegmentMgr,
		PrivateDomainManager: privateDomainMgr,
		SharedDomainManager:  sharedDomainMgr,
		ServiceAccessManager: serviceAccessMgr,
		QuotaManager:         quotaMgr,
	}
}

func NewExportManager ( configDir string , uaaMgr uaa . Manager , spaceManager space . Manager , userManager user . Manager , orgManager organization . Manager , securityGroupManager securitygroup . Manager , isoSegmentMgr isosegment . Manager , privateDomainMgr privatedomain . Manager , sharedDomainMgr * shareddomain . Manager , serviceAccessMgr * serviceaccess . Manager , quotaMgr * quota . Manager ) Manager { return & DefaultImportManager { ConfigDir : configDir , UAAMgr : uaaMgr , SpaceManager : spaceManager , UserManager : userManager , OrgManager : orgManager , SecurityGroupManager : securityGroupManager , IsoSegmentManager : isoSegmentMgr , PrivateDomainManager : privateDomainMgr , SharedDomainManager : sharedDomainMgr , ServiceAccessManager : serviceAccessMgr , QuotaManager : quotaMgr , } }

//NewExportManager Creates a new instance of the ImportConfig manager


func (o *Orgs) Contains(orgName string) bool {
	orgNameUpper := strings.ToUpper(orgName)
	for _, org := range o.Orgs {
		if strings.ToUpper(org) == orgNameUpper {
			return true
		}
	}
	return false
}

func ( o * Orgs ) Contains ( orgName string ) bool { orgNameUpper := strings . ToUpper ( orgName ) for _ , org := range o . Orgs { if strings . ToUpper ( org ) == orgNameUpper { return true } } return false }

// Contains determines whether an org is present in a list of orgs.

Contains determines whether an org is present in a list of orgs .


func (u *Updater) UpdateOrgs() error {
	ocs, err := u.Cfg.GetOrgConfigs()
	if err != nil {
		return err
	}
	for _, oc := range ocs {
		org, err := u.OrgManager.FindOrg(oc.Org)
		if err != nil {
			return errors.Wrap(err, "finding org for org configs in update orgs")
		}
		isolationSegmentMap, err := u.isolationSegmentMap()
		if err != nil {
			return err
		}

		isolationSegmentGUID, err := u.getIsolationSegmentGUID(oc.DefaultIsoSegment, isolationSegmentMap)
		if err != nil {
			return err
		}

		if org.DefaultIsolationSegmentGuid != isolationSegmentGUID {
			if u.Peek {
				if isolationSegmentGUID != "" {
					lo.G.Infof("[dry-run]: set default isolation segment for org %s to %s", oc.Org, oc.DefaultIsoSegment)
				} else {
					lo.G.Infof("[dry-run]: reset default isolation segment for org %s", oc.Org)
				}
				continue
			}

			if isolationSegmentGUID != "" {
				lo.G.Infof("set default isolation segment for org %s to %s", oc.Org, oc.DefaultIsoSegment)
				err = u.Client.DefaultIsolationSegmentForOrg(org.Guid, isolationSegmentGUID)
				if err != nil {
					return err
				}
			} else {
				lo.G.Infof("reset default isolation segment for org %s", oc.Org)
				err = u.Client.ResetDefaultIsolationSegmentForOrg(org.Guid)
				if err != nil {
					return err
				}
			}

		}
	}
	return nil
}

func ( u * Updater ) UpdateOrgs ( ) error { ocs , err := u . Cfg . GetOrgConfigs ( ) if err != nil { return err } for _ , oc := range ocs { org , err := u . OrgManager . FindOrg ( oc . Org ) if err != nil { return errors . Wrap ( err , " " ) } isolationSegmentMap , err := u . isolationSegmentMap ( ) if err != nil { return err } isolationSegmentGUID , err := u . getIsolationSegmentGUID ( oc . DefaultIsoSegment , isolationSegmentMap ) if err != nil { return err } if org . DefaultIsolationSegmentGuid != isolationSegmentGUID { if u . Peek { if isolationSegmentGUID != " " { lo . G . Infof ( " " , oc . Org , oc . DefaultIsoSegment ) } else { lo . G . Infof ( " " , oc . Org ) } continue } if isolationSegmentGUID != " " { lo . G . Infof ( " " , oc . Org , oc . DefaultIsoSegment ) err = u . Client . DefaultIsolationSegmentForOrg ( org . Guid , isolationSegmentGUID ) if err != nil { return err } } else { lo . G . Infof ( " " , oc . Org ) err = u . Client . ResetDefaultIsolationSegmentForOrg ( org . Guid ) if err != nil { return err } } } } return nil }

// UpdateOrgs sets the default isolation segment for each org,
// as specified in the cf-mgmt config.

UpdateOrgs sets the default isolation segment for each org as specified in the cf - mgmt config .


func (u *Updater) UpdateSpaces() error {
	scs, err := u.Cfg.GetSpaceConfigs()
	if err != nil {
		return err
	}

	isolationSegmentMap, err := u.isolationSegmentMap()
	if err != nil {
		return err
	}
	for _, sc := range scs {
		space, err := u.SpaceManager.FindSpace(sc.Org, sc.Space)
		if err != nil {
			return err
		}
		isolationSegmentGUID, err := u.getIsolationSegmentGUID(sc.IsoSegment, isolationSegmentMap)
		if err != nil {
			return err
		}
		if space.IsolationSegmentGuid != isolationSegmentGUID {
			if u.Peek {
				if sc.IsoSegment != "" {
					lo.G.Infof("[dry-run]: set isolation segment for space %s to %s (org %s)", sc.Space, sc.IsoSegment, sc.Org)
				} else {
					lo.G.Infof("[dry-run]: reset isolation segment for space %s (org %s)", sc.Space, sc.Org)
				}
				continue
			}
			if sc.IsoSegment != "" {
				lo.G.Infof("set isolation segment for space %s to %s (org %s)", sc.Space, sc.IsoSegment, sc.Org)
				err = u.Client.IsolationSegmentForSpace(space.Guid, isolationSegmentGUID)
				if err != nil {
					return err
				}
			} else {
				lo.G.Infof("reset isolation segment for space %s (org %s)", sc.Space, sc.Org)
				err = u.Client.ResetIsolationSegmentForSpace(space.Guid)
				if err != nil {
					return err
				}
			}
		}

	}
	return nil
}

func ( u * Updater ) UpdateSpaces ( ) error { scs , err := u . Cfg . GetSpaceConfigs ( ) if err != nil { return err } isolationSegmentMap , err := u . isolationSegmentMap ( ) if err != nil { return err } for _ , sc := range scs { space , err := u . SpaceManager . FindSpace ( sc . Org , sc . Space ) if err != nil { return err } isolationSegmentGUID , err := u . getIsolationSegmentGUID ( sc . IsoSegment , isolationSegmentMap ) if err != nil { return err } if space . IsolationSegmentGuid != isolationSegmentGUID { if u . Peek { if sc . IsoSegment != " " { lo . G . Infof ( " " , sc . Space , sc . IsoSegment , sc . Org ) } else { lo . G . Infof ( " " , sc . Space , sc . Org ) } continue } if sc . IsoSegment != " " { lo . G . Infof ( " " , sc . Space , sc . IsoSegment , sc . Org ) err = u . Client . IsolationSegmentForSpace ( space . Guid , isolationSegmentGUID ) if err != nil { return err } } else { lo . G . Infof ( " " , sc . Space , sc . Org ) err = u . Client . ResetIsolationSegmentForSpace ( space . Guid ) if err != nil { return err } } } } return nil }

// UpdateSpaces sets the isolation segment for each space,
// as specified in the cf-mgmt config.

UpdateSpaces sets the isolation segment for each space as specified in the cf - mgmt config .


func (u *Updater) allDesiredSegments() ([]cfclient.IsolationSegment, error) {
	orgs, err := u.Cfg.GetOrgConfigs()
	if err != nil {
		return nil, err
	}
	spaces, err := u.Cfg.GetSpaceConfigs()
	if err != nil {
		return nil, err
	}

	segments := make(map[string]struct{})
	for _, org := range orgs {
		if org.DefaultIsoSegment != "" {
			segments[org.DefaultIsoSegment] = struct{}{}
		}
	}
	for _, space := range spaces {
		if space.IsoSegment != "" {
			segments[space.IsoSegment] = struct{}{}
		}
	}

	result := make([]cfclient.IsolationSegment, 0, len(segments))
	for k := range segments {
		result = append(result, cfclient.IsolationSegment{Name: k})
	}
	return result, nil
}

func ( u * Updater ) allDesiredSegments ( ) ( [ ] cfclient . IsolationSegment , error ) { orgs , err := u . Cfg . GetOrgConfigs ( ) if err != nil { return nil , err } spaces , err := u . Cfg . GetSpaceConfigs ( ) if err != nil { return nil , err } segments := make ( map [ string ] struct { } ) for _ , org := range orgs { if org . DefaultIsoSegment != " " { segments [ org . DefaultIsoSegment ] = struct { } { } } } for _ , space := range spaces { if space . IsoSegment != " " { segments [ space . IsoSegment ] = struct { } { } } } result := make ( [ ] cfclient . IsolationSegment , 0 , len ( segments ) ) for k := range segments { result = append ( result , cfclient . IsolationSegment { Name : k } ) } return result , nil }

// allDesiredSegments iterates through the cf-mgmt configuration for all
// orgs and spaces and builds the complete set of isolation segments that
// should exist

allDesiredSegments iterates through the cf - mgmt configuration for all orgs and spaces and builds the complete set of isolation segments that should exist


func (m *DefaultUAAManager) ListUsers() (*Users, error) {
	users := &Users{}
	lo.G.Debug("Getting users from Cloud Foundry")
	userList, err := m.Client.ListAllUsers("", "", "userName,id,externalId,emails,origin", "")
	if err != nil {
		return nil, err
	}

	lo.G.Debugf("Found %d users in the CF instance", len(userList))
	for _, user := range userList {
		lo.G.Debugf("Adding to users userID [%s], externalID [%s], origin [%s], email [%s], GUID [%s]", user.Username, user.ExternalID, user.Origin, Email(user), user.ID)
		users.Add(User{
			Username:   user.Username,
			ExternalID: user.ExternalID,
			Email:      Email(user),
			Origin:     user.Origin,
			GUID:       user.ID,
		})
	}
	return users, nil
}

func ( m * DefaultUAAManager ) ListUsers ( ) ( * Users , error ) { users := & Users { } lo . G . Debug ( " " ) userList , err := m . Client . ListAllUsers ( " " , " " , " " , " " ) if err != nil { return nil , err } lo . G . Debugf ( " " , len ( userList ) ) for _ , user := range userList { lo . G . Debugf ( " " , user . Username , user . ExternalID , user . Origin , Email ( user ) , user . ID ) users . Add ( User { Username : user . Username , ExternalID : user . ExternalID , Email : Email ( user ) , Origin : user . Origin , GUID : user . ID , } ) } return users , nil }


func (c *UpdateSpaceConfigurationCommand) Execute(args []string) error {
	c.initConfig()
	spaceConfig, err := c.ConfigManager.GetSpaceConfig(c.OrgName, c.SpaceName)
	if err != nil {
		return err
	}
	asgConfigs, err := c.ConfigManager.GetASGConfigs()
	if err != nil {
		return err
	}

	if c.Quota.EnableSpaceQuota == "true" && c.NamedQuota != "" {
		return fmt.Errorf("cannot enable space quota and use named quotas")
	}

	errorString := ""

	convertToBool("enable-remove-users", &spaceConfig.RemoveUsers, c.EnableRemoveUsers, &errorString)
	convertToBool("enable-security-group", &spaceConfig.EnableSecurityGroup, c.EnableSecurityGroup, &errorString)
	convertToBool("enable-unassign-security-group", &spaceConfig.EnableUnassignSecurityGroup, c.EnableUnassignSecurityGroup, &errorString)
	if c.IsoSegment != "" {
		spaceConfig.IsoSegment = c.IsoSegment
	}
	if c.ClearIsolationSegment {
		spaceConfig.IsoSegment = ""
	}

	spaceConfig.ASGs = removeFromSlice(addToSlice(spaceConfig.ASGs, c.ASGs, &errorString), c.ASGsToRemove)
	validateASGsExist(asgConfigs, spaceConfig.ASGs, &errorString)
	updateSpaceQuotaConfig(spaceConfig, c.Quota, &errorString)

	if c.NamedQuota != "" {
		spaceConfig.NamedQuota = c.NamedQuota
	}
	if c.ClearNamedQuota {
		spaceConfig.NamedQuota = ""
	}

	c.updateUsers(spaceConfig, &errorString)
	c.sshConfig(spaceConfig, &errorString)

	if errorString != "" {
		return errors.New(errorString)
	}

	if err := c.ConfigManager.SaveSpaceConfig(spaceConfig); err != nil {
		return err
	}
	fmt.Println(fmt.Sprintf("The org/space [%s/%s] has been updated", c.OrgName, c.SpaceName))
	return nil
}

func ( c * UpdateSpaceConfigurationCommand ) Execute ( args [ ] string ) error { c . initConfig ( ) spaceConfig , err := c . ConfigManager . GetSpaceConfig ( c . OrgName , c . SpaceName ) if err != nil { return err } asgConfigs , err := c . ConfigManager . GetASGConfigs ( ) if err != nil { return err } if c . Quota . EnableSpaceQuota == " " && c . NamedQuota != " " { return fmt . Errorf ( " " ) } errorString := " " convertToBool ( " " , & spaceConfig . RemoveUsers , c . EnableRemoveUsers , & errorString ) convertToBool ( " " , & spaceConfig . EnableSecurityGroup , c . EnableSecurityGroup , & errorString ) convertToBool ( " " , & spaceConfig . EnableUnassignSecurityGroup , c . EnableUnassignSecurityGroup , & errorString ) if c . IsoSegment != " " { spaceConfig . IsoSegment = c . IsoSegment } if c . ClearIsolationSegment { spaceConfig . IsoSegment = " " } spaceConfig . ASGs = removeFromSlice ( addToSlice ( spaceConfig . ASGs , c . ASGs , & errorString ) , c . ASGsToRemove ) validateASGsExist ( asgConfigs , spaceConfig . ASGs , & errorString ) updateSpaceQuotaConfig ( spaceConfig , c . Quota , & errorString ) if c . NamedQuota != " " { spaceConfig . NamedQuota = c . NamedQuota } if c . ClearNamedQuota { spaceConfig . NamedQuota = " " } c . updateUsers ( spaceConfig , & errorString ) c . sshConfig ( spaceConfig , & errorString ) if errorString != " " { return errors . New ( errorString ) } if err := c . ConfigManager . SaveSpaceConfig ( spaceConfig ) ; err != nil { return err } fmt . Println ( fmt . Sprintf ( " " , c . OrgName , c . SpaceName ) ) return nil }

//Execute - updates space configuration`


func (m *Manager) RemoveUnknownVisibilites(serviceInfo *ServiceInfo) error {
	for servicePlanName, servicePlan := range serviceInfo.AllPlans() {
		for _, plan := range servicePlan {
			for _, visibility := range plan.ListVisibilities() {
				if m.Peek {
					lo.G.Infof("[dry-run]: removing plan %s for service %s to org with guid %s", plan.Name, servicePlanName, visibility.OrganizationGuid)
					continue
				}
				lo.G.Infof("removing plan %s for service %s to org with guid %s", plan.Name, servicePlanName, visibility.OrganizationGuid)
				err := m.Client.DeleteServicePlanVisibilityByPlanAndOrg(visibility.ServicePlanGuid, visibility.OrganizationGuid, false)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}

func ( m * Manager ) RemoveUnknownVisibilites ( serviceInfo * ServiceInfo ) error { for servicePlanName , servicePlan := range serviceInfo . AllPlans ( ) { for _ , plan := range servicePlan { for _ , visibility := range plan . ListVisibilities ( ) { if m . Peek { lo . G . Infof ( " " , plan . Name , servicePlanName , visibility . OrganizationGuid ) continue } lo . G . Infof ( " " , plan . Name , servicePlanName , visibility . OrganizationGuid ) err := m . Client . DeleteServicePlanVisibilityByPlanAndOrg ( visibility . ServicePlanGuid , visibility . OrganizationGuid , false ) if err != nil { return err } } } } return nil }

//RemoveUnknownVisibilites - will remove any service plan visiblities that are not known by cf-mgmt

RemoveUnknownVisibilites - will remove any service plan visiblities that are not known by cf - mgmt


func (m *Manager) DisablePublicServiceAccess(serviceInfo *ServiceInfo) error {
	for _, servicePlan := range serviceInfo.AllPlans() {
		for _, plan := range servicePlan {
			if plan.Public {
				err := m.Client.MakeServicePlanPrivate(plan.GUID)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}

func ( m * Manager ) DisablePublicServiceAccess ( serviceInfo * ServiceInfo ) error { for _ , servicePlan := range serviceInfo . AllPlans ( ) { for _ , plan := range servicePlan { if plan . Public { err := m . Client . MakeServicePlanPrivate ( plan . GUID ) if err != nil { return err } } } } return nil }

//DisablePublicServiceAccess - will ensure any public plan is made private


func (m *Manager) ListServiceInfo() (*ServiceInfo, error) {
	serviceInfo := &ServiceInfo{}
	services, err := m.Client.ListServices()
	if err != nil {
		return nil, err
	}
	for _, service := range services {
		plans, err := m.Client.ListServicePlansByQuery(url.Values{
			"q": []string{fmt.Sprintf("%s:%s", "service_guid", service.Guid)},
		})
		if err != nil {
			return nil, err
		}
		for _, plan := range plans {
			servicePlanInfo := serviceInfo.AddPlan(service.Label, plan)
			visibilities, err := m.Client.ListServicePlanVisibilitiesByQuery(url.Values{
				"q": []string{fmt.Sprintf("%s:%s", "service_plan_guid", plan.Guid)},
			})
			if err != nil {
				return nil, err
			}
			for _, visibility := range visibilities {
				servicePlanInfo.AddOrg(visibility.OrganizationGuid, visibility)
			}
		}
	}
	return serviceInfo, nil
}

func ( m * Manager ) ListServiceInfo ( ) ( * ServiceInfo , error ) { serviceInfo := & ServiceInfo { } services , err := m . Client . ListServices ( ) if err != nil { return nil , err } for _ , service := range services { plans , err := m . Client . ListServicePlansByQuery ( url . Values { " " : [ ] string { fmt . Sprintf ( " " , " " , service . Guid ) } , } ) if err != nil { return nil , err } for _ , plan := range plans { servicePlanInfo := serviceInfo . AddPlan ( service . Label , plan ) visibilities , err := m . Client . ListServicePlanVisibilitiesByQuery ( url . Values { " " : [ ] string { fmt . Sprintf ( " " , " " , plan . Guid ) } , } ) if err != nil { return nil , err } for _ , visibility := range visibilities { servicePlanInfo . AddOrg ( visibility . OrganizationGuid , visibility ) } } } return serviceInfo , nil }

//ListServiceInfo - returns services and their cooresponding plans


func (c *CreateOrgsCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.OrgManager.CreateOrgs()
	}
	return err
}

func ( c * CreateOrgsCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . OrgManager . CreateOrgs ( ) } return err }


func (c *UpdateOrgsMetadataCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.OrgManager.UpdateOrgsMetadata()
	}
	return err
}

func ( c * UpdateOrgsMetadataCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . OrgManager . UpdateOrgsMetadata ( ) } return err }

//Execute - updates organizations metadata


func (c *DeleteOrgConfigurationCommand) Execute([]string) error {
	if err := config.NewManager(c.ConfigDirectory).DeleteOrgConfig(c.OrgName); err != nil {
		return err
	}

	fmt.Printf("The org %s was successfully deleted", c.OrgName)
	return nil
}

func ( c * DeleteOrgConfigurationCommand ) Execute ( [ ] string ) error { if err := config . NewManager ( c . ConfigDirectory ) . DeleteOrgConfig ( c . OrgName ) ; err != nil { return err } fmt . Printf ( " " , c . OrgName ) return nil }


func (c *DeleteSpaceConfigurationCommand) Execute([]string) error {
	if err := config.NewManager(c.ConfigDirectory).DeleteSpaceConfig(c.OrgName, c.SpaceName); err != nil {
		return err
	}

	fmt.Printf("The org/space %s/%s was successfully deleted", c.OrgName, c.SpaceName)
	return nil
}

func ( c * DeleteSpaceConfigurationCommand ) Execute ( [ ] string ) error { if err := config . NewManager ( c . ConfigDirectory ) . DeleteSpaceConfig ( c . OrgName , c . SpaceName ) ; err != nil { return err } fmt . Printf ( " " , c . OrgName , c . SpaceName ) return nil }


func (c *DeleteSpacesCommand) Execute([]string) error {
	var cfMgmt *CFMgmt
	var err error
	if cfMgmt, err = InitializePeekManagers(c.BaseCFConfigCommand, c.Peek); err == nil {
		err = cfMgmt.SpaceManager.DeleteSpaces()
	}
	return err
}

func ( c * DeleteSpacesCommand ) Execute ( [ ] string ) error { var cfMgmt * CFMgmt var err error if cfMgmt , err = InitializePeekManagers ( c . BaseCFConfigCommand , c . Peek ) ; err == nil { err = cfMgmt . SpaceManager . DeleteSpaces ( ) } return err }


func NewKeyProvider(key interface{}) SecretProvider {
	return SecretProviderFunc(func(_ *http.Request) (interface{}, error) {
		return key, nil
	})
}

func NewKeyProvider ( key interface { } ) SecretProvider { return SecretProviderFunc ( func ( _ * http . Request ) ( interface { } , error ) { return key , nil } ) }

// NewKeyProvider provide a simple passphrase key provider.

NewKeyProvider provide a simple passphrase key provider .


func NewConfiguration(provider SecretProvider, audience []string, issuer string, method jose.SignatureAlgorithm) Configuration {
	return Configuration{
		secretProvider: provider,
		expectedClaims: jwt.Expected{Issuer: issuer, Audience: audience},
		signIn:         method,
	}
}

func NewConfiguration ( provider SecretProvider , audience [ ] string , issuer string , method jose . SignatureAlgorithm ) Configuration { return Configuration { secretProvider : provider , expectedClaims : jwt . Expected { Issuer : issuer , Audience : audience } , signIn : method , } }

// NewConfiguration creates a configuration for server


func NewConfigurationTrustProvider(provider SecretProvider, audience []string, issuer string) Configuration {
	return Configuration{
		secretProvider: provider,
		expectedClaims: jwt.Expected{Issuer: issuer, Audience: audience},
	}
}

func NewConfigurationTrustProvider ( provider SecretProvider , audience [ ] string , issuer string ) Configuration { return Configuration { secretProvider : provider , expectedClaims : jwt . Expected { Issuer : issuer , Audience : audience } , } }

// NewConfigurationTrustProvider creates a configuration for server with no enforcement for token sig alg type, instead trust provider

NewConfigurationTrustProvider creates a configuration for server with no enforcement for token sig alg type instead trust provider


func NewValidator(config Configuration, extractor RequestTokenExtractor) *JWTValidator {
	if extractor == nil {
		extractor = RequestTokenExtractorFunc(FromHeader)
	}
	return &JWTValidator{config, extractor}
}

func NewValidator ( config Configuration , extractor RequestTokenExtractor ) * JWTValidator { if extractor == nil { extractor = RequestTokenExtractorFunc ( FromHeader ) } return & JWTValidator { config , extractor } }

// NewValidator creates a new
// validator with the provided configuration.

NewValidator creates a new validator with the provided configuration .


func (v *JWTValidator) ValidateRequest(r *http.Request) (*jwt.JSONWebToken, error) {
	return v.validateRequestWithLeeway(r, jwt.DefaultLeeway)
}

func ( v * JWTValidator ) ValidateRequest ( r * http . Request ) ( * jwt . JSONWebToken , error ) { return v . validateRequestWithLeeway ( r , jwt . DefaultLeeway ) }

// ValidateRequest validates the token within
// the http request.
// A default leeway value of one minute is used to compare time values.

ValidateRequest validates the token within the http request . A default leeway value of one minute is used to compare time values .


func (v *JWTValidator) ValidateRequestWithLeeway(r *http.Request, leeway time.Duration) (*jwt.JSONWebToken, error) {
	return v.validateRequestWithLeeway(r, leeway)
}

func ( v * JWTValidator ) ValidateRequestWithLeeway ( r * http . Request , leeway time . Duration ) ( * jwt . JSONWebToken , error ) { return v . validateRequestWithLeeway ( r , leeway ) }

// ValidateRequestWithLeeway validates the token within
// the http request.
// The provided leeway value is used to compare time values.

ValidateRequestWithLeeway validates the token within the http request . The provided leeway value is used to compare time values .


func (v *JWTValidator) Claims(r *http.Request, token *jwt.JSONWebToken, values ...interface{}) error {
	key, err := v.config.secretProvider.GetSecret(r)
	if err != nil {
		return err
	}
	return token.Claims(key, values...)
}

func ( v * JWTValidator ) Claims ( r * http . Request , token * jwt . JSONWebToken , values ... interface { } ) error { key , err := v . config . secretProvider . GetSecret ( r ) if err != nil { return err } return token . Claims ( key , values ... ) }

// Claims unmarshall the claims of the provided token


func NewJWKClient(options JWKClientOptions, extractor RequestTokenExtractor) *JWKClient {
	return NewJWKClientWithCache(options, extractor, nil)
}

func NewJWKClient ( options JWKClientOptions , extractor RequestTokenExtractor ) * JWKClient { return NewJWKClientWithCache ( options , extractor , nil ) }

// NewJWKClient creates a new JWKClient instance from the
// provided options.

NewJWKClient creates a new JWKClient instance from the provided options .


func NewJWKClientWithCache(options JWKClientOptions, extractor RequestTokenExtractor, keyCacher KeyCacher) *JWKClient {
	if extractor == nil {
		extractor = RequestTokenExtractorFunc(FromHeader)
	}
	if keyCacher == nil {
		keyCacher = newMemoryPersistentKeyCacher()
	}
	if options.Client == nil {
		options.Client = http.DefaultClient
	}

	return &JWKClient{
		keyCacher: keyCacher,
		options:   options,
		extractor: extractor,
	}
}

func NewJWKClientWithCache ( options JWKClientOptions , extractor RequestTokenExtractor , keyCacher KeyCacher ) * JWKClient { if extractor == nil { extractor = RequestTokenExtractorFunc ( FromHeader ) } if keyCacher == nil { keyCacher = newMemoryPersistentKeyCacher ( ) } if options . Client == nil { options . Client = http . DefaultClient } return & JWKClient { keyCacher : keyCacher , options : options , extractor : extractor , } }

// NewJWKClientWithCache creates a new JWKClient instance from the
// provided options and a custom keycacher interface.
// Passing nil to keyCacher will create a persistent key cacher

NewJWKClientWithCache creates a new JWKClient instance from the provided options and a custom keycacher interface . Passing nil to keyCacher will create a persistent key cacher


func (j *JWKClient) GetKey(ID string) (jose.JSONWebKey, error) {
	j.mu.Lock()
	defer j.mu.Unlock()

	searchedKey, err := j.keyCacher.Get(ID)
	if err != nil {
		keys, err := j.downloadKeys()
		if err != nil {
			return jose.JSONWebKey{}, err
		}
		addedKey, err := j.keyCacher.Add(ID, keys)
		if err != nil {
			return jose.JSONWebKey{}, err
		}
		return *addedKey, nil
	}

	return *searchedKey, nil
}

func ( j * JWKClient ) GetKey ( ID string ) ( jose . JSONWebKey , error ) { j . mu . Lock ( ) defer j . mu . Unlock ( ) searchedKey , err := j . keyCacher . Get ( ID ) if err != nil { keys , err := j . downloadKeys ( ) if err != nil { return jose . JSONWebKey { } , err } addedKey , err := j . keyCacher . Add ( ID , keys ) if err != nil { return jose . JSONWebKey { } , err } return * addedKey , nil } return * searchedKey , nil }

// GetKey returns the key associated with the provided ID.

GetKey returns the key associated with the provided ID .


func (j *JWKClient) GetSecret(r *http.Request) (interface{}, error) {
	token, err := j.extractor.Extract(r)
	if err != nil {
		return nil, err
	}

	if len(token.Headers) < 1 {
		return nil, ErrNoJWTHeaders
	}

	header := token.Headers[0]

	return j.GetKey(header.KeyID)
}

func ( j * JWKClient ) GetSecret ( r * http . Request ) ( interface { } , error ) { token , err := j . extractor . Extract ( r ) if err != nil { return nil , err } if len ( token . Headers ) < 1 { return nil , ErrNoJWTHeaders } header := token . Headers [ 0 ] return j . GetKey ( header . KeyID ) }

// GetSecret implements the GetSecret method of the SecretProvider interface.

GetSecret implements the GetSecret method of the SecretProvider interface .


func FromMultiple(extractors ...RequestTokenExtractor) RequestTokenExtractor {
	return RequestTokenExtractorFunc(func(r *http.Request) (*jwt.JSONWebToken, error) {
		for _, e := range extractors {
			token, err := e.Extract(r)
			if err == ErrTokenNotFound {
				continue
			} else if err != nil {
				return nil, err
			}
			return token, nil
		}
		return nil, ErrTokenNotFound
	})
}

func FromMultiple ( extractors ... RequestTokenExtractor ) RequestTokenExtractor { return RequestTokenExtractorFunc ( func ( r * http . Request ) ( * jwt . JSONWebToken , error ) { for _ , e := range extractors { token , err := e . Extract ( r ) if err == ErrTokenNotFound { continue } else if err != nil { return nil , err } return token , nil } return nil , ErrTokenNotFound } ) }

// FromMultiple combines multiple extractors by chaining.

FromMultiple combines multiple extractors by chaining .


func FromParams(r *http.Request) (*jwt.JSONWebToken, error) {
	if r == nil {
		return nil, ErrNilRequest
	}
	raw := r.URL.Query().Get("token")
	if raw == "" {
		return nil, ErrTokenNotFound
	}
	return jwt.ParseSigned(raw)
}

func FromParams ( r * http . Request ) ( * jwt . JSONWebToken , error ) { if r == nil { return nil , ErrNilRequest } raw := r . URL . Query ( ) . Get ( " " ) if raw == " " { return nil , ErrTokenNotFound } return jwt . ParseSigned ( raw ) }

// FromParams returns the JWT when passed as the URL query param "token".

FromParams returns the JWT when passed as the URL query param token .


func NewMemoryKeyCacher(maxKeyAge time.Duration, maxCacheSize int) KeyCacher {
	return &memoryKeyCacher{
		entries:      map[string]keyCacherEntry{},
		maxKeyAge:    maxKeyAge,
		maxCacheSize: maxCacheSize,
	}
}

func NewMemoryKeyCacher ( maxKeyAge time . Duration , maxCacheSize int ) KeyCacher { return & memoryKeyCacher { entries : map [ string ] keyCacherEntry { } , maxKeyAge : maxKeyAge , maxCacheSize : maxCacheSize , } }

// NewMemoryKeyCacher creates a new Keycacher interface with option
// to set max age of cached keys and max size of the cache.

NewMemoryKeyCacher creates a new Keycacher interface with option to set max age of cached keys and max size of the cache .


func (mkc *memoryKeyCacher) Get(keyID string) (*jose.JSONWebKey, error) {
	searchKey, ok := mkc.entries[keyID]
	if ok {
		if mkc.maxKeyAge == MaxKeyAgeNoCheck || !mkc.keyIsExpired(keyID) {
			return &searchKey.JSONWebKey, nil
		}
		return nil, ErrKeyExpired
	}
	return nil, ErrNoKeyFound
}

func ( mkc * memoryKeyCacher ) Get ( keyID string ) ( * jose . JSONWebKey , error ) { searchKey , ok := mkc . entries [ keyID ] if ok { if mkc . maxKeyAge == MaxKeyAgeNoCheck || ! mkc . keyIsExpired ( keyID ) { return & searchKey . JSONWebKey , nil } return nil , ErrKeyExpired } return nil , ErrNoKeyFound }

// Get obtains a key from the cache, and checks if the key is expired

Get obtains a key from the cache and checks if the key is expired


func (mkc *memoryKeyCacher) Add(keyID string, downloadedKeys []jose.JSONWebKey) (*jose.JSONWebKey, error) {
	var addingKey jose.JSONWebKey

	for _, key := range downloadedKeys {
		if key.KeyID == keyID {
			addingKey = key
		}
		if mkc.maxCacheSize == -1 {
			mkc.entries[key.KeyID] = keyCacherEntry{
				addedAt:    time.Now(),
				JSONWebKey: key,
			}
		}
	}
	if addingKey.Key != nil {
		if mkc.maxCacheSize != -1 {
			mkc.entries[addingKey.KeyID] = keyCacherEntry{
				addedAt:    time.Now(),
				JSONWebKey: addingKey,
			}
			mkc.handleOverflow()
		}
		return &addingKey, nil
	}
	return nil, ErrNoKeyFound
}

func ( mkc * memoryKeyCacher ) Add ( keyID string , downloadedKeys [ ] jose . JSONWebKey ) ( * jose . JSONWebKey , error ) { var addingKey jose . JSONWebKey for _ , key := range downloadedKeys { if key . KeyID == keyID { addingKey = key } if mkc . maxCacheSize == - 1 { mkc . entries [ key . KeyID ] = keyCacherEntry { addedAt : time . Now ( ) , JSONWebKey : key , } } } if addingKey . Key != nil { if mkc . maxCacheSize != - 1 { mkc . entries [ addingKey . KeyID ] = keyCacherEntry { addedAt : time . Now ( ) , JSONWebKey : addingKey , } mkc . handleOverflow ( ) } return & addingKey , nil } return nil , ErrNoKeyFound }

// Add adds a key into the cache and handles overflow


func (mkc *memoryKeyCacher) keyIsExpired(keyID string) bool {
	if time.Now().After(mkc.entries[keyID].addedAt.Add(mkc.maxKeyAge)) {
		delete(mkc.entries, keyID)
		return true
	}
	return false
}

func ( mkc * memoryKeyCacher ) keyIsExpired ( keyID string ) bool { if time . Now ( ) . After ( mkc . entries [ keyID ] . addedAt . Add ( mkc . maxKeyAge ) ) { delete ( mkc . entries , keyID ) return true } return false }

// keyIsExpired deletes the key from cache if it is expired


func (mkc *memoryKeyCacher) handleOverflow() {
	if mkc.maxCacheSize < len(mkc.entries) {
		var oldestEntryKeyID string
		var latestAddedTime = time.Now()
		for entryKeyID, entry := range mkc.entries {
			if entry.addedAt.Before(latestAddedTime) {
				latestAddedTime = entry.addedAt
				oldestEntryKeyID = entryKeyID
			}
		}
		delete(mkc.entries, oldestEntryKeyID)
	}
}

func ( mkc * memoryKeyCacher ) handleOverflow ( ) { if mkc . maxCacheSize < len ( mkc . entries ) { var oldestEntryKeyID string var latestAddedTime = time . Now ( ) for entryKeyID , entry := range mkc . entries { if entry . addedAt . Before ( latestAddedTime ) { latestAddedTime = entry . addedAt oldestEntryKeyID = entryKeyID } } delete ( mkc . entries , oldestEntryKeyID ) } }

// handleOverflow deletes the oldest key from the cache if overflowed


func Patch(old io.Reader, new io.Writer, patch io.Reader) error {
	var hdr header
	err := binary.Read(patch, signMagLittleEndian{}, &hdr)
	if err != nil {
		return err
	}
	if hdr.Magic != magic {
		return ErrCorrupt
	}
	if hdr.CtrlLen < 0 || hdr.DiffLen < 0 || hdr.NewSize < 0 {
		return ErrCorrupt
	}

	ctrlbuf := make([]byte, hdr.CtrlLen)
	_, err = io.ReadFull(patch, ctrlbuf)
	if err != nil {
		return err
	}
	cpfbz2 := bzip2.NewReader(bytes.NewReader(ctrlbuf))

	diffbuf := make([]byte, hdr.DiffLen)
	_, err = io.ReadFull(patch, diffbuf)
	if err != nil {
		return err
	}
	dpfbz2 := bzip2.NewReader(bytes.NewReader(diffbuf))

	// The entire rest of the file is the extra block.
	epfbz2 := bzip2.NewReader(patch)

	obuf, err := ioutil.ReadAll(old)
	if err != nil {
		return err
	}

	nbuf := make([]byte, hdr.NewSize)

	var oldpos, newpos int64
	for newpos < hdr.NewSize {
		var ctrl struct{ Add, Copy, Seek int64 }
		err = binary.Read(cpfbz2, signMagLittleEndian{}, &ctrl)
		if err != nil {
			return err
		}

		// Sanity-check
		if newpos+ctrl.Add > hdr.NewSize {
			return ErrCorrupt
		}

		// Read diff string
		_, err = io.ReadFull(dpfbz2, nbuf[newpos:newpos+ctrl.Add])
		if err != nil {
			return ErrCorrupt
		}

		// Add old data to diff string
		for i := int64(0); i < ctrl.Add; i++ {
			if oldpos+i >= 0 && oldpos+i < int64(len(obuf)) {
				nbuf[newpos+i] += obuf[oldpos+i]
			}
		}

		// Adjust pointers
		newpos += ctrl.Add
		oldpos += ctrl.Add

		// Sanity-check
		if newpos+ctrl.Copy > hdr.NewSize {
			return ErrCorrupt
		}

		// Read extra string
		_, err = io.ReadFull(epfbz2, nbuf[newpos:newpos+ctrl.Copy])
		if err != nil {
			return ErrCorrupt
		}

		// Adjust pointers
		newpos += ctrl.Copy
		oldpos += ctrl.Seek
	}

	// Write the new file
	for len(nbuf) > 0 {
		n, err := new.Write(nbuf)
		if err != nil {
			return err
		}
		nbuf = nbuf[n:]
	}

	return nil
}

// Patch applies patch to old, according to the bspatch algorithm,
// and writes the result to new.

Patch applies patch to old according to the bspatch algorithm and writes the result to new .


func Diff(old, new io.Reader, patch io.Writer) error {
	obuf, err := ioutil.ReadAll(old)
	if err != nil {
		return err
	}

	nbuf, err := ioutil.ReadAll(new)
	if err != nil {
		return err
	}

	pbuf, err := diffBytes(obuf, nbuf)
	if err != nil {
		return err
	}

	_, err = patch.Write(pbuf)
	return err
}

func Diff ( old , new io . Reader , patch io . Writer ) error { obuf , err := ioutil . ReadAll ( old ) if err != nil { return err } nbuf , err := ioutil . ReadAll ( new ) if err != nil { return err } pbuf , err := diffBytes ( obuf , nbuf ) if err != nil { return err } _ , err = patch . Write ( pbuf ) return err }

// Diff computes the difference between old and new, according to the bsdiff
// algorithm, and writes the result to patch.

Diff computes the difference between old and new according to the bsdiff algorithm and writes the result to patch .


func validColor(c string) bool {
	valid := false
	if validColors[c] {
		valid = true
	}
	return valid
}

func validColor ( c string ) bool { valid := false if validColors [ c ] { valid = true } return valid }

// validColor will make sure the given color is actually allowed


func New(cs []string, d time.Duration, options ...Option) *Spinner {
	s := &Spinner{
		Delay:    d,
		chars:    cs,
		color:    color.New(color.FgWhite).SprintFunc(),
		lock:     &sync.RWMutex{},
		Writer:   color.Output,
		active:   false,
		stopChan: make(chan struct{}, 1),
	}

	for _, option := range options {
		option(s)
	}
	return s
}

func New ( cs [ ] string , d time . Duration , options ... Option ) * Spinner { s := & Spinner { Delay : d , chars : cs , color : color . New ( color . FgWhite ) . SprintFunc ( ) , lock : & sync . RWMutex { } , Writer : color . Output , active : false , stopChan : make ( chan struct { } , 1 ) , } for _ , option := range options { option ( s ) } return s }

// New provides a pointer to an instance of Spinner with the supplied options


func (s *Spinner) Start() {
	s.lock.Lock()
	if s.active {
		s.lock.Unlock()
		return
	}
	if s.HideCursor && runtime.GOOS != "windows" {
		// hides the cursor
		fmt.Print("\033[?25l")
	}
	s.active = true
	s.lock.Unlock()

	go func() {
		for {
			for i := 0; i < len(s.chars); i++ {
				select {
				case <-s.stopChan:
					return
				default:
					s.lock.Lock()
					s.erase()
					var outColor string
					if runtime.GOOS == "windows" {
						if s.Writer == os.Stderr {
							outColor = fmt.Sprintf("\r%s%s%s ", s.Prefix, s.chars[i], s.Suffix)
						} else {
							outColor = fmt.Sprintf("\r%s%s%s ", s.Prefix, s.color(s.chars[i]), s.Suffix)
						}
					} else {
						outColor = fmt.Sprintf("%s%s%s ", s.Prefix, s.color(s.chars[i]), s.Suffix)
					}
					outPlain := fmt.Sprintf("%s%s%s ", s.Prefix, s.chars[i], s.Suffix)
					fmt.Fprint(s.Writer, outColor)
					s.lastOutput = outPlain
					delay := s.Delay
					s.lock.Unlock()

					time.Sleep(delay)
				}
			}
		}
	}()
}

func
(
s
*
Spinner
)
Start
(
)
{
s
.
lock
.
Lock
(
)
if
s
.
active
{
s
.
lock
.
Unlock
(
)
return
}
if
s
.
HideCursor
&&
runtime
.
GOOS
!=
"
"
{
// hides the cursor
fmt
.
Print
(
"
\033
"
)
}
s
.
active
=
true
s
.
lock
.
Unlock
(
)
go
func
(
)
{
for
{
for
i
:=
0
;
i
<
len
(
s
.
chars
)
;
i
++
{
select
{
case
<-
s
.
stopChan
:
return
default
:
s
.
lock
.
Lock
(
)
s
.
erase
(
)
var
outColor
string
if
runtime
.
GOOS
==
"
"
{
if
s
.
Writer
==
os
.
Stderr
{
outColor
=
fmt
.
Sprintf
(
"
\r
"
,
s
.
Prefix
,
s
.
chars
[
i
]
,
s
.
Suffix
)
}
else
{
outColor
=
fmt
.
Sprintf
(
"
\r
"
,
s
.
Prefix
,
s
.
color
(
s
.
chars
[
i
]
)
,
s
.
Suffix
)
}
}
else
{
outColor
=
fmt
.
Sprintf
(
"
"
,
s
.
Prefix
,
s
.
color
(
s
.
chars
[
i
]
)
,
s
.
Suffix
)
}
outPlain
:=
fmt
.
Sprintf
(
"
"
,
s
.
Prefix
,
s
.
chars
[
i
]
,
s
.
Suffix
)
fmt
.
Fprint
(
s
.
Writer
,
outColor
)
s
.
lastOutput
=
outPlain
delay
:=
s
.
Delay
s
.
lock
.
Unlock
(
)
time
.
Sleep
(
delay
)
}
}
}
}
(
)
}


func (s *Spinner) Stop() {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.active {
		s.active = false
		if s.HideCursor && runtime.GOOS != "windows" {
			// makes the cursor visible
			fmt.Print("\033[?25h")
		}
		s.erase()
		if s.FinalMSG != "" {
			fmt.Fprintf(s.Writer, s.FinalMSG)
		}
		s.stopChan <- struct{}{}
	}
}

func
(
s
*
Spinner
)
Stop
(
)
{
s
.
lock
.
Lock
(
)
defer
s
.
lock
.
Unlock
(
)
if
s
.
active
{
s
.
active
=
false
if
s
.
HideCursor
&&
runtime
.
GOOS
!=
"
"
{
// makes the cursor visible
fmt
.
Print
(
"
\033
"
)
}
s
.
erase
(
)
if
s
.
FinalMSG
!=
"
"
{
fmt
.
Fprintf
(
s
.
Writer
,
s
.
FinalMSG
)
}
s
.
stopChan
<-
struct
{
}
{
}
}
}


func (s *Spinner) Reverse() {
	s.lock.Lock()
	defer s.lock.Unlock()
	for i, j := 0, len(s.chars)-1; i < j; i, j = i+1, j-1 {
		s.chars[i], s.chars[j] = s.chars[j], s.chars[i]
	}
}

func ( s * Spinner ) Reverse ( ) { s . lock . Lock ( ) defer s . lock . Unlock ( ) for i , j := 0 , len ( s . chars ) - 1 ; i < j ; i , j = i + 1 , j - 1 { s . chars [ i ] , s . chars [ j ] = s . chars [ j ] , s . chars [ i ] } }

// Reverse will reverse the order of the slice assigned to the indicator


func (s *Spinner) Color(colors ...string) error {

	colorAttributes := make([]color.Attribute, len(colors))

	// Verify colours are valid and place the appropriate attribute in the array
	for index, c := range colors {
		if !validColor(c) {
			return errInvalidColor
		}

		colorAttributes[index] = colorAttributeMap[c]
	}

	s.lock.Lock()
	s.color = color.New(colorAttributes...).SprintFunc()
	s.lock.Unlock()
	s.Restart()
	return nil
}

// Color will set the struct field for the given color to be used


func (s *Spinner) UpdateSpeed(d time.Duration) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.Delay = d
}

func ( s * Spinner ) UpdateSpeed ( d time . Duration ) { s . lock . Lock ( ) defer s . lock . Unlock ( ) s . Delay = d }

// UpdateSpeed will set the indicator delay to the given value


func (s *Spinner) UpdateCharSet(cs []string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.chars = cs
}

func ( s * Spinner ) UpdateCharSet ( cs [ ] string ) { s . lock . Lock ( ) defer s . lock . Unlock ( ) s . chars = cs }

// UpdateCharSet will change the current character set to the given one


func (s *Spinner) erase() {
	n := utf8.RuneCountInString(s.lastOutput)
	if runtime.GOOS == "windows" {
		clearString := "\r"
		for i := 0; i < n; i++ {
			clearString += " "
		}
		fmt.Fprintf(s.Writer, clearString)
		return
	}
	del, _ := hex.DecodeString("7f")
	for _, c := range []string{
		"\b",
		string(del),
		"\b",
		"\033[K", // for macOS Terminal
	} {
		for i := 0; i < n; i++ {
			fmt.Fprintf(s.Writer, c)
		}
	}
	s.lastOutput = ""
}

func
(
s
*
Spinner
)
erase
(
)
{
n
:=
utf8
.
RuneCountInString
(
s
.
lastOutput
)
if
runtime
.
GOOS
==
"
"
{
clearString
:=
"
\r
"
for
i
:=
0
;
i
<
n
;
i
++
{
clearString
+=
"
"
}
fmt
.
Fprintf
(
s
.
Writer
,
clearString
)
return
}
del
,
_
:=
hex
.
DecodeString
(
"
"
)
for
_
,
c
:=
range
[
]
string
{
"
\b
"
,
string
(
del
)
,
"
\b
"
,
"
\033
"
,
// for macOS Terminal
}
{
for
i
:=
0
;
i
<
n
;
i
++
{
fmt
.
Fprintf
(
s
.
Writer
,
c
)
}
}
s
.
lastOutput
=
"
"
}

// erase deletes written characters
//
// Caller must already hold s.lock.

erase deletes written characters Caller must already hold s . lock .


func GenerateNumberSequence(length int) []string {
	numSeq := make([]string, length)
	for i := 0; i < length; i++ {
		numSeq[i] = strconv.Itoa(i)
	}
	return numSeq
}

func GenerateNumberSequence ( length int ) [ ] string { numSeq := make ( [ ] string , length ) for i := 0 ; i < length ; i ++ { numSeq [ i ] = strconv . Itoa ( i ) } return numSeq }

// GenerateNumberSequence will generate a slice of integers at the
// provided length and convert them each to a string

GenerateNumberSequence will generate a slice of integers at the provided length and convert them each to a string


func (id *streamID) header(tag uint64) uint64 {
	header := id.id<<3 | tag
	if !id.initiator {
		header--
	}
	return header
}

func ( id * streamID ) header ( tag uint64 ) uint64 { header := id . id << 3 | tag if ! id . initiator { header -- } return header }

// header computes the header for the given tag


func NewMultiplex(con net.Conn, initiator bool) *Multiplex {
	mp := &Multiplex{
		con:       con,
		initiator: initiator,
		buf:       bufio.NewReader(con),
		channels:  make(map[streamID]*Stream),
		closed:    make(chan struct{}),
		shutdown:  make(chan struct{}),
		wrTkn:     make(chan struct{}, 1),
		nstreams:  make(chan *Stream, 16),
	}

	go mp.handleIncoming()

	mp.wrTkn <- struct{}{}

	return mp
}

func NewMultiplex ( con net . Conn , initiator bool ) * Multiplex { mp := & Multiplex { con : con , initiator : initiator , buf : bufio . NewReader ( con ) , channels : make ( map [ streamID ] * Stream ) , closed : make ( chan struct { } ) , shutdown : make ( chan struct { } ) , wrTkn : make ( chan struct { } , 1 ) , nstreams : make ( chan * Stream , 16 ) , } go mp . handleIncoming ( ) mp . wrTkn <- struct { } { } return mp }

// NewMultiplex creates a new multiplexer session.

NewMultiplex creates a new multiplexer session .


func (m *Multiplex) Accept() (*Stream, error) {
	select {
	case s, ok := <-m.nstreams:
		if !ok {
			return nil, errors.New("multiplex closed")
		}
		return s, nil
	case <-m.closed:
		return nil, m.shutdownErr
	}
}

func ( m * Multiplex ) Accept ( ) ( * Stream , error ) { select { case s , ok := <- m . nstreams : if ! ok { return nil , errors . New ( " " ) } return s , nil case <- m . closed : return nil , m . shutdownErr } }

// Accept accepts the next stream from the connection.

Accept accepts the next stream from the connection .


func (mp *Multiplex) NewNamedStream(name string) (*Stream, error) {
	mp.chLock.Lock()

	// We could call IsClosed but this is faster (given that we already have
	// the lock).
	if mp.channels == nil {
		mp.chLock.Unlock()
		return nil, ErrShutdown
	}

	sid := mp.nextChanID()
	header := (sid << 3) | newStreamTag

	if name == "" {
		name = fmt.Sprint(sid)
	}
	s := mp.newStream(streamID{
		id:        sid,
		initiator: true,
	}, name)
	mp.channels[s.id] = s
	mp.chLock.Unlock()

	err := mp.sendMsg(context.Background(), header, []byte(name))
	if err != nil {
		return nil, err
	}

	return s, nil
}

// NewNamedStream creates a new named stream.

NewNamedStream creates a new named stream .


func encodeInt(lat, lng float64) uint64 {
	latInt := encodeRange(lat, 90)
	lngInt := encodeRange(lng, 180)
	return interleave(latInt, lngInt)
}

func encodeInt ( lat , lng float64 ) uint64 { latInt := encodeRange ( lat , 90 ) lngInt := encodeRange ( lng , 180 ) return interleave ( latInt , lngInt ) }

// encodeInt provides a Go implementation of integer geohash. This is the
// default implementation of EncodeInt, but optimized versions are provided
// for certain architectures.

encodeInt provides a Go implementation of integer geohash . This is the default implementation of EncodeInt but optimized versions are provided for certain architectures .


func (b Box) Center() (lat, lng float64) {
	lat = (b.MinLat + b.MaxLat) / 2.0
	lng = (b.MinLng + b.MaxLng) / 2.0
	return
}

func ( b Box ) Center ( ) ( lat , lng float64 ) { lat = ( b . MinLat + b . MaxLat ) / 2.0 lng = ( b . MinLng + b . MaxLng ) / 2.0 return }

// Center returns the center of the box.


func (b Box) Round() (lat, lng float64) {
	x := maxDecimalPower(b.MaxLat - b.MinLat)
	lat = math.Ceil(b.MinLat/x) * x
	x = maxDecimalPower(b.MaxLng - b.MinLng)
	lng = math.Ceil(b.MinLng/x) * x
	return
}

func ( b Box ) Round ( ) ( lat , lng float64 ) { x := maxDecimalPower ( b . MaxLat - b . MinLat ) lat = math . Ceil ( b . MinLat / x ) * x x = maxDecimalPower ( b . MaxLng - b . MinLng ) lng = math . Ceil ( b . MinLng / x ) * x return }

// Round returns a point inside the box, making an effort to round to minimal
// precision.

Round returns a point inside the box making an effort to round to minimal precision .


func BoundingBox(hash string) Box {
	bits := uint(5 * len(hash))
	inthash := base32encoding.Decode(hash)
	return BoundingBoxIntWithPrecision(inthash, bits)
}

func BoundingBox ( hash string ) Box { bits := uint ( 5 * len ( hash ) ) inthash := base32encoding . Decode ( hash ) return BoundingBoxIntWithPrecision ( inthash , bits ) }

// BoundingBox returns the region encoded by the given string geohash.

BoundingBox returns the region encoded by the given string geohash .


func BoundingBoxIntWithPrecision(hash uint64, bits uint) Box {
	fullHash := hash << (64 - bits)
	latInt, lngInt := deinterleave(fullHash)
	lat := decodeRange(latInt, 90)
	lng := decodeRange(lngInt, 180)
	latErr, lngErr := errorWithPrecision(bits)
	return Box{
		MinLat: lat,
		MaxLat: lat + latErr,
		MinLng: lng,
		MaxLng: lng + lngErr,
	}
}

func BoundingBoxIntWithPrecision ( hash uint64 , bits uint ) Box { fullHash := hash << ( 64 - bits ) latInt , lngInt := deinterleave ( fullHash ) lat := decodeRange ( latInt , 90 ) lng := decodeRange ( lngInt , 180 ) latErr , lngErr := errorWithPrecision ( bits ) return Box { MinLat : lat , MaxLat : lat + latErr , MinLng : lng , MaxLng : lng + lngErr , } }

// BoundingBoxIntWithPrecision returns the region encoded by the integer
// geohash with the specified precision.

BoundingBoxIntWithPrecision returns the region encoded by the integer geohash with the specified precision .


func DecodeCenter(hash string) (lat, lng float64) {
	box := BoundingBox(hash)
	return box.Center()
}

func DecodeCenter ( hash string ) ( lat , lng float64 ) { box := BoundingBox ( hash ) return box . Center ( ) }

// DecodeCenter decodes the string geohash to the central point of the bounding box.

DecodeCenter decodes the string geohash to the central point of the bounding box .


func Neighbors(hash string) []string {
	box := BoundingBox(hash)
	lat, lng := box.Center()
	latDelta := box.MaxLat - box.MinLat
	lngDelta := box.MaxLng - box.MinLng
	precision := uint(len(hash))
	return []string{
		// N
		EncodeWithPrecision(lat+latDelta, lng, precision),
		// NE,
		EncodeWithPrecision(lat+latDelta, lng+lngDelta, precision),
		// E,
		EncodeWithPrecision(lat, lng+lngDelta, precision),
		// SE,
		EncodeWithPrecision(lat-latDelta, lng+lngDelta, precision),
		// S,
		EncodeWithPrecision(lat-latDelta, lng, precision),
		// SW,
		EncodeWithPrecision(lat-latDelta, lng-lngDelta, precision),
		// W,
		EncodeWithPrecision(lat, lng-lngDelta, precision),
		// NW
		EncodeWithPrecision(lat+latDelta, lng-lngDelta, precision),
	}
}

func
Neighbors
(
hash
string
)
[
]
string
{
box
:=
BoundingBox
(
hash
)
lat
,
lng
:=
box
.
Center
(
)
latDelta
:=
box
.
MaxLat
box
.
MinLat
lngDelta
:=
box
.
MaxLng
box
.
MinLng
precision
:=
uint
(
len
(
hash
)
)
return
[
]
string
{
// N
EncodeWithPrecision
(
lat
+
latDelta
,
lng
,
precision
)
,
// NE,
EncodeWithPrecision
(
lat
+
latDelta
,
lng
+
lngDelta
,
precision
)
,
// E,
EncodeWithPrecision
(
lat
,
lng
+
lngDelta
,
precision
)
,
// SE,
EncodeWithPrecision
(
lat
latDelta
,
lng
+
lngDelta
,
precision
)
,
// S,
EncodeWithPrecision
(
lat
latDelta
,
lng
,
precision
)
,
// SW,
EncodeWithPrecision
(
lat
latDelta
,
lng
lngDelta
,
precision
)
,
// W,
EncodeWithPrecision
(
lat
,
lng
lngDelta
,
precision
)
,
// NW
EncodeWithPrecision
(
lat
+
latDelta
,
lng
lngDelta
,
precision
)
,
}
}

// Neighbors returns a slice of geohash strings that correspond to the provided
// geohash's neighbors.

Neighbors returns a slice of geohash strings that correspond to the provided geohash s neighbors .


func NeighborsIntWithPrecision(hash uint64, bits uint) []uint64 {
	box := BoundingBoxIntWithPrecision(hash, bits)
	lat, lng := box.Center()
	latDelta := box.MaxLat - box.MinLat
	lngDelta := box.MaxLng - box.MinLng
	return []uint64{
		// N
		EncodeIntWithPrecision(lat+latDelta, lng, bits),
		// NE,
		EncodeIntWithPrecision(lat+latDelta, lng+lngDelta, bits),
		// E,
		EncodeIntWithPrecision(lat, lng+lngDelta, bits),
		// SE,
		EncodeIntWithPrecision(lat-latDelta, lng+lngDelta, bits),
		// S,
		EncodeIntWithPrecision(lat-latDelta, lng, bits),
		// SW,
		EncodeIntWithPrecision(lat-latDelta, lng-lngDelta, bits),
		// W,
		EncodeIntWithPrecision(lat, lng-lngDelta, bits),
		// NW
		EncodeIntWithPrecision(lat+latDelta, lng-lngDelta, bits),
	}
}

func
NeighborsIntWithPrecision
(
hash
uint64
,
bits
uint
)
[
]
uint64
{
box
:=
BoundingBoxIntWithPrecision
(
hash
,
bits
)
lat
,
lng
:=
box
.
Center
(
)
latDelta
:=
box
.
MaxLat
box
.
MinLat
lngDelta
:=
box
.
MaxLng
box
.
MinLng
return
[
]
uint64
{
// N
EncodeIntWithPrecision
(
lat
+
latDelta
,
lng
,
bits
)
,
// NE,
EncodeIntWithPrecision
(
lat
+
latDelta
,
lng
+
lngDelta
,
bits
)
,
// E,
EncodeIntWithPrecision
(
lat
,
lng
+
lngDelta
,
bits
)
,
// SE,
EncodeIntWithPrecision
(
lat
latDelta
,
lng
+
lngDelta
,
bits
)
,
// S,
EncodeIntWithPrecision
(
lat
latDelta
,
lng
,
bits
)
,
// SW,
EncodeIntWithPrecision
(
lat
latDelta
,
lng
lngDelta
,
bits
)
,
// W,
EncodeIntWithPrecision
(
lat
,
lng
lngDelta
,
bits
)
,
// NW
EncodeIntWithPrecision
(
lat
+
latDelta
,
lng
lngDelta
,
bits
)
,
}
}

// NeighborsIntWithPrecision returns a slice of uint64s that correspond to the
// provided hash's neighbors at the given precision.

NeighborsIntWithPrecision returns a slice of uint64s that correspond to the provided hash s neighbors at the given precision .


func NeighborIntWithPrecision(hash uint64, bits uint, direction Direction) uint64 {
	return NeighborsIntWithPrecision(hash, bits)[direction]
}

func NeighborIntWithPrecision ( hash uint64 , bits uint , direction Direction ) uint64 { return NeighborsIntWithPrecision ( hash , bits ) [ direction ] }

// NeighborIntWithPrecision returns a uint64s that corresponds to the
// provided hash's neighbor in the provided direction at the given precision.

NeighborIntWithPrecision returns a uint64s that corresponds to the provided hash s neighbor in the provided direction at the given precision .


// Spread out the 32 bits of x into 64 bits, where the bits of x occupy even
// bit positions.

Spread out the 32 bits of x into 64 bits where the bits of x occupy even bit positions .


func newEncoding(encoder string) *encoding {
	e := new(encoding)
	e.encode = encoder
	for i := 0; i < len(e.decode); i++ {
		e.decode[i] = 0xff
	}
	for i := 0; i < len(encoder); i++ {
		e.decode[encoder[i]] = byte(i)
	}
	return e
}

func newEncoding ( encoder string ) * encoding { e := new ( encoding ) e . encode = encoder for i := 0 ; i < len ( e . decode ) ; i ++ { e . decode [ i ] = 0xff } for i := 0 ; i < len ( encoder ) ; i ++ { e . decode [ encoder [ i ] ] = byte ( i ) } return e }

// newEncoding constructs a new encoding defined by the given alphabet,
// which must be a 32-byte string.

newEncoding constructs a new encoding defined by the given alphabet which must be a 32 - byte string .


func (e *encoding) Encode(x uint64) string {
	b := [12]byte{}
	for i := 0; i < 12; i++ {
		b[11-i] = e.encode[x&0x1f]
		x >>= 5
	}
	return string(b[:])
}

func ( e * encoding ) Encode ( x uint64 ) string { b := [ 12 ] byte { } for i := 0 ; i < 12 ; i ++ { b [ 11 - i ] = e . encode [ x & 0x1f ] x >>= 5 } return string ( b [ : ] ) }

// Encode bits of 64-bit word into a string.

Encode bits of 64 - bit word into a string .


func InitArgs(args ...string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		name := args[0]
		if filepath.Base(name) == name {
			if lp, err := exec.LookPath(name); err == nil {
				name = lp
			}
		}
		l.InitPath = name
		l.InitArgs = append([]string{name}, args[1:]...)
		return nil
	}
}

func InitArgs ( args ... string ) func ( * LinuxFactory ) error { return func ( l * LinuxFactory ) error { name := args [ 0 ] if filepath . Base ( name ) == name { if lp , err := exec . LookPath ( name ) ; err == nil { name = lp } } l . InitPath = name l . InitArgs = append ( [ ] string { name } , args [ 1 : ] ... ) return nil } }

// InitArgs returns an options func to configure a LinuxFactory with the
// provided init arguments.

InitArgs returns an options func to configure a LinuxFactory with the provided init arguments .


func InitPath(path string, args ...string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.InitPath = path
		l.InitArgs = args
		return nil
	}
}

func InitPath ( path string , args ... string ) func ( * LinuxFactory ) error { return func ( l * LinuxFactory ) error { l . InitPath = path l . InitArgs = args return nil } }

// InitPath returns an options func to configure a LinuxFactory with the
// provided absolute path to the init binary and arguements.

InitPath returns an options func to configure a LinuxFactory with the provided absolute path to the init binary and arguements .


func (l *LinuxFactory) StartInitialization() (err error) {
	pipefd, err := strconv.Atoi(os.Getenv("_LIBCONTAINER_INITPIPE"))
	if err != nil {
		return err
	}
	var (
		pipe = os.NewFile(uintptr(pipefd), "pipe")
		it   = initType(os.Getenv("_LIBCONTAINER_INITTYPE"))
	)
	// clear the current process's environment to clean any libcontainer
	// specific env vars.
	os.Clearenv()
	defer func() {
		// if we have an error during the initialization of the container's init then send it back to the
		// parent process in the form of an initError.
		if err != nil {
			// ensure that any data sent from the parent is consumed so it doesn't
			// receive ECONNRESET when the child writes to the pipe.
			ioutil.ReadAll(pipe)
			if err := json.NewEncoder(pipe).Encode(newSystemError(err)); err != nil {
				panic(err)
			}
		}
		// ensure that this pipe is always closed
		pipe.Close()
	}()
	i, err := newContainerInit(it, pipe)
	if err != nil {
		return err
	}
	return i.Init()
}

// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
// This is a low level implementation detail of the reexec and should not be consumed externally

StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state This is a low level implementation detail of the reexec and should not be consumed externally


func newConsole(uid, gid int) (Console, error) {
	master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
	if err != nil {
		return nil, err
	}
	console, err := ptsname(master)
	if err != nil {
		return nil, err
	}
	if err := unlockpt(master); err != nil {
		return nil, err
	}
	if err := os.Chmod(console, 0600); err != nil {
		return nil, err
	}
	if err := os.Chown(console, uid, gid); err != nil {
		return nil, err
	}
	return &linuxConsole{
		slavePath: console,
		master:    master,
	}, nil
}

func newConsole ( uid , gid int ) ( Console , error ) { master , err := os . OpenFile ( " " , syscall . O_RDWR | syscall . O_NOCTTY | syscall . O_CLOEXEC , 0 ) if err != nil { return nil , err } console , err := ptsname ( master ) if err != nil { return nil , err } if err := unlockpt ( master ) ; err != nil { return nil , err } if err := os . Chmod ( console , 0600 ) ; err != nil { return nil , err } if err := os . Chown ( console , uid , gid ) ; err != nil { return nil , err } return & linuxConsole { slavePath : console , master : master , } , nil }

// newConsole returns an initalized console that can be used within a container by copying bytes
// from the master side to the slave that is attached as the tty for the container's init process.

newConsole returns an initalized console that can be used within a container by copying bytes from the master side to the slave that is attached as the tty for the container s init process .


func (c *linuxConsole) mount(rootfs, mountLabel string, uid, gid int) error {
	oldMask := syscall.Umask(0000)
	defer syscall.Umask(oldMask)
	if err := label.SetFileLabel(c.slavePath, mountLabel); err != nil {
		return err
	}
	dest := filepath.Join(rootfs, "/dev/console")
	f, err := os.Create(dest)
	if err != nil && !os.IsExist(err) {
		return err
	}
	if f != nil {
		f.Close()
	}
	return syscall.Mount(c.slavePath, dest, "bind", syscall.MS_BIND, "")
}

func ( c * linuxConsole ) mount ( rootfs , mountLabel string , uid , gid int ) error { oldMask := syscall . Umask ( 0000 ) defer syscall . Umask ( oldMask ) if err := label . SetFileLabel ( c . slavePath , mountLabel ) ; err != nil { return err } dest := filepath . Join ( rootfs , " " ) f , err := os . Create ( dest ) if err != nil && ! os . IsExist ( err ) { return err } if f != nil { f . Close ( ) } return syscall . Mount ( c . slavePath , dest , " " , syscall . MS_BIND , " " ) }

// mount initializes the console inside the rootfs mounting with the specified mount label
// and applying the correct ownership of the console.

mount initializes the console inside the rootfs mounting with the specified mount label and applying the correct ownership of the console .


func (c *linuxConsole) dupStdio() error {
	slave, err := c.open(syscall.O_RDWR)
	if err != nil {
		return err
	}
	fd := int(slave.Fd())
	for _, i := range []int{0, 1, 2} {
		if err := syscall.Dup3(fd, i, 0); err != nil {
			return err
		}
	}
	return nil
}

func ( c * linuxConsole ) dupStdio ( ) error { slave , err := c . open ( syscall . O_RDWR ) if err != nil { return err } fd := int ( slave . Fd ( ) ) for _ , i := range [ ] int { 0 , 1 , 2 } { if err := syscall . Dup3 ( fd , i , 0 ) ; err != nil { return err } } return nil }

// dupStdio opens the slavePath for the console and dups the fds to the current
// processes stdio, fd 0,1,2.

dupStdio opens the slavePath for the console and dups the fds to the current processes stdio fd 0 1 2 .


func (c *linuxConsole) open(flag int) (*os.File, error) {
	r, e := syscall.Open(c.slavePath, flag, 0)
	if e != nil {
		return nil, &os.PathError{
			Op:   "open",
			Path: c.slavePath,
			Err:  e,
		}
	}
	return os.NewFile(uintptr(r), c.slavePath), nil
}

func ( c * linuxConsole ) open ( flag int ) ( * os . File , error ) { r , e := syscall . Open ( c . slavePath , flag , 0 ) if e != nil { return nil , & os . PathError { Op : " " , Path : c . slavePath , Err : e , } } return os . NewFile ( uintptr ( r ) , c . slavePath ) , nil }

// open is a clone of os.OpenFile without the O_CLOEXEC used to open the pty slave.

open is a clone of os . OpenFile without the O_CLOEXEC used to open the pty slave .


func ptsname(f *os.File) (string, error) {
	var n int32
	if err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
		return "", err
	}
	return fmt.Sprintf("/dev/pts/%d", n), nil
}

func ptsname ( f * os . File ) ( string , error ) { var n int32 if err := ioctl ( f . Fd ( ) , syscall . TIOCGPTN , uintptr ( unsafe . Pointer ( & n ) ) ) ; err != nil { return " " , err } return fmt . Sprintf ( " " , n ) , nil }

// ptsname retrieves the name of the first available pts for the given master.

ptsname retrieves the name of the first available pts for the given master .


func finalizeNamespace(config *initConfig) error {
	// Ensure that all unwanted fds we may have accidentally
	// inherited are marked close-on-exec so they stay out of the
	// container
	if err := utils.CloseExecFrom(config.PassedFilesCount + 3); err != nil {
		return err
	}

	capabilities := config.Config.Capabilities
	if config.Capabilities != nil {
		capabilities = config.Capabilities
	}
	w, err := newCapWhitelist(capabilities)
	if err != nil {
		return err
	}
	// drop capabilities in bounding set before changing user
	if err := w.dropBoundingSet(); err != nil {
		return err
	}
	// preserve existing capabilities while we change users
	if err := system.SetKeepCaps(); err != nil {
		return err
	}
	if err := setupUser(config); err != nil {
		return err
	}
	if err := system.ClearKeepCaps(); err != nil {
		return err
	}
	// drop all other capabilities
	if err := w.drop(); err != nil {
		return err
	}
	if config.Cwd != "" {
		if err := syscall.Chdir(config.Cwd); err != nil {
			return err
		}
	}
	return nil
}

// finalizeNamespace drops the caps, sets the correct user
// and working dir, and closes any leaked file descriptors
// before executing the command inside the namespace

finalizeNamespace drops the caps sets the correct user and working dir and closes any leaked file descriptors before executing the command inside the namespace


func joinExistingNamespaces(namespaces []configs.Namespace) error {
	for _, ns := range namespaces {
		if ns.Path != "" {
			f, err := os.OpenFile(ns.Path, os.O_RDONLY, 0)
			if err != nil {
				return err
			}
			err = system.Setns(f.Fd(), uintptr(ns.Syscall()))
			f.Close()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func joinExistingNamespaces ( namespaces [ ] configs . Namespace ) error { for _ , ns := range namespaces { if ns . Path != " " { f , err := os . OpenFile ( ns . Path , os . O_RDONLY , 0 ) if err != nil { return err } err = system . Setns ( f . Fd ( ) , uintptr ( ns . Syscall ( ) ) ) f . Close ( ) if err != nil { return err } } } return nil }

// joinExistingNamespaces gets all the namespace paths specified for the container and
// does a setns on the namespace fd so that the current process joins the namespace.

joinExistingNamespaces gets all the namespace paths specified for the container and does a setns on the namespace fd so that the current process joins the namespace .


func setupUser(config *initConfig) error {
	// Set up defaults.
	defaultExecUser := user.ExecUser{
		Uid:  syscall.Getuid(),
		Gid:  syscall.Getgid(),
		Home: "/",
	}
	passwdPath, err := user.GetPasswdPath()
	if err != nil {
		return err
	}
	groupPath, err := user.GetGroupPath()
	if err != nil {
		return err
	}
	execUser, err := user.GetExecUserPath(config.User, &defaultExecUser, passwdPath, groupPath)
	if err != nil {
		return err
	}

	var addGroups []int
	if len(config.Config.AdditionalGroups) > 0 {
		addGroups, err = user.GetAdditionalGroupsPath(config.Config.AdditionalGroups, groupPath)
		if err != nil {
			return err
		}
	}

	suppGroups := append(execUser.Sgids, addGroups...)
	if err := syscall.Setgroups(suppGroups); err != nil {
		return err
	}

	if err := system.Setgid(execUser.Gid); err != nil {
		return err
	}
	if err := system.Setuid(execUser.Uid); err != nil {
		return err
	}
	// if we didn't get HOME already, set it based on the user's HOME
	if envHome := os.Getenv("HOME"); envHome == "" {
		if err := os.Setenv("HOME", execUser.Home); err != nil {
			return err
		}
	}
	return nil
}

// setupUser changes the groups, gid, and uid for the user inside the container

setupUser changes the groups gid and uid for the user inside the container


func killCgroupProcesses(m cgroups.Manager) error {
	var procs []*os.Process
	if err := m.Freeze(configs.Frozen); err != nil {
		logrus.Warn(err)
	}
	pids, err := m.GetPids()
	if err != nil {
		m.Freeze(configs.Thawed)
		return err
	}
	for _, pid := range pids {
		if p, err := os.FindProcess(pid); err == nil {
			procs = append(procs, p)
			if err := p.Kill(); err != nil {
				logrus.Warn(err)
			}
		}
	}
	if err := m.Freeze(configs.Thawed); err != nil {
		logrus.Warn(err)
	}
	for _, p := range procs {
		if _, err := p.Wait(); err != nil {
			logrus.Warn(err)
		}
	}
	return nil
}

func killCgroupProcesses ( m cgroups . Manager ) error { var procs [ ] * os . Process if err := m . Freeze ( configs . Frozen ) ; err != nil { logrus . Warn ( err ) } pids , err := m . GetPids ( ) if err != nil { m . Freeze ( configs . Thawed ) return err } for _ , pid := range pids { if p , err := os . FindProcess ( pid ) ; err == nil { procs = append ( procs , p ) if err := p . Kill ( ) ; err != nil { logrus . Warn ( err ) } } } if err := m . Freeze ( configs . Thawed ) ; err != nil { logrus . Warn ( err ) } for _ , p := range procs { if _ , err := p . Wait ( ) ; err != nil { logrus . Warn ( err ) } } return nil }

// killCgroupProcesses freezes then iterates over all the processes inside the
// manager's cgroups sending a SIGKILL to each process then waiting for them to
// exit.

killCgroupProcesses freezes then iterates over all the processes inside the manager s cgroups sending a SIGKILL to each process then waiting for them to exit .


func (c *linuxContainer) addUidGidMappings(sys *syscall.SysProcAttr) error {
	if c.config.UidMappings != nil {
		sys.UidMappings = make([]syscall.SysProcIDMap, len(c.config.UidMappings))
		for i, um := range c.config.UidMappings {
			sys.UidMappings[i].ContainerID = um.ContainerID
			sys.UidMappings[i].HostID = um.HostID
			sys.UidMappings[i].Size = um.Size
		}
	}
	if c.config.GidMappings != nil {
		sys.GidMappings = make([]syscall.SysProcIDMap, len(c.config.GidMappings))
		for i, gm := range c.config.GidMappings {
			sys.GidMappings[i].ContainerID = gm.ContainerID
			sys.GidMappings[i].HostID = gm.HostID
			sys.GidMappings[i].Size = gm.Size
		}
	}
	return nil
}

func ( c * linuxContainer ) addUidGidMappings ( sys * syscall . SysProcAttr ) error { if c . config . UidMappings != nil { sys . UidMappings = make ( [ ] syscall . SysProcIDMap , len ( c . config . UidMappings ) ) for i , um := range c . config . UidMappings { sys . UidMappings [ i ] . ContainerID = um . ContainerID sys . UidMappings [ i ] . HostID = um . HostID sys . UidMappings [ i ] . Size = um . Size } } if c . config . GidMappings != nil { sys . GidMappings = make ( [ ] syscall . SysProcIDMap , len ( c . config . GidMappings ) ) for i , gm := range c . config . GidMappings { sys . GidMappings [ i ] . ContainerID = gm . ContainerID sys . GidMappings [ i ] . HostID = gm . HostID sys . GidMappings [ i ] . Size = gm . Size } } return nil }

// Converts IDMap to SysProcIDMap array and adds it to SysProcAttr.

Converts IDMap to SysProcIDMap array and adds it to SysProcAttr .