<commit_before>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package platformvm

import (
	"errors"
	"fmt"

	"github.com/ava-labs/gecko/database"
	"github.com/ava-labs/gecko/database/versiondb"
	"github.com/ava-labs/gecko/ids"
	"github.com/ava-labs/gecko/utils/crypto"
	"github.com/ava-labs/gecko/utils/hashing"
	"github.com/ava-labs/gecko/vms/components/verify"
	"github.com/ava-labs/gecko/vms/secp256k1fx"
)

var (
	errSigsNotSorted           = errors.New("control signatures not sorted")
	errWrongNumberOfSignatures = errors.New("wrong number of signatures")
	errDSValidatorSubset       = errors.New("all subnets must be a subset of the default subnet")
)

// UnsignedAddNonDefaultSubnetValidatorTx is an unsigned addNonDefaultSubnetValidatorTx
type UnsignedAddNonDefaultSubnetValidatorTx struct {
	// Metadata, inputs and outputs
	CommonTx `serialize:"true"`
	// IDs of control keys
	controlIDs []ids.ShortID
	// The validator
	SubnetValidator `serialize:"true"`
}

// addNonDefaultSubnetValidatorTx is a transaction that, if it is in a ProposeAddValidator block that
// is accepted and followed by a Commit block, adds a validator to the pending validator set of a subnet
// other than the default subnet.
// (That is, the validator in the tx will validate at some point in the future.)
// The transaction fee will be paid from the account whose ID is [Sigs[0].Address()]
type addNonDefaultSubnetValidatorTx struct {
	UnsignedAddNonDefaultSubnetValidatorTx `serialize:"true"`
	// Credentials that authorize the inputs to spend the corresponding outputs
	Credentials []verify.Verifiable `serialize:"true"`
	// When a subnet is created, it specifies a set of public keys ("control keys") such
	// that in order to add a validator to the subnet, a tx must be signed with
	// a certain threshold of those keys
	// Each element of ControlSigs is the signature of one of those keys
	ControlSigs [][crypto.SECP256K1RSigLen]byte `serialize:"true"`
}

// Creds returns this transactions credentials
func (tx *addNonDefaultSubnetValidatorTx) Creds() []verify.Verifiable {
	return tx.Credentials
}

// initialize [tx]. Sets [tx.vm], [tx.unsignedBytes], [tx.bytes], [tx.id]
func (tx *addNonDefaultSubnetValidatorTx) initialize(vm *VM) error {
	if tx.vm != nil { // already been initialized
		return nil
	}
	tx.vm = vm
	var err error
	tx.unsignedBytes, err = Codec.Marshal(interface{}(tx.UnsignedAddNonDefaultSubnetValidatorTx))
	if err != nil {
		return fmt.Errorf("couldn't marshal UnsignedAddNonDefaultSubnetValidatorTx: %w", err)
	}
	tx.bytes, err = Codec.Marshal(tx) // byte representation of the signed transaction
	if err != nil {
		return fmt.Errorf("couldn't marshal addNonDefaultSubnetValidatorTx: %w", err)
	}
	tx.id = ids.NewID(hashing.ComputeHash256Array(tx.bytes))
	return nil
}

// SyntacticVerify return nil iff [tx] is valid
// If [tx] is valid, sets [tx.accountID]
// TODO: only verify once
func (tx *addNonDefaultSubnetValidatorTx) SyntacticVerify() error {
	switch {
	case tx == nil:
		return tempError{errNilTx}
	case tx.syntacticallyVerified: // already passed syntactic verification
		return nil
	case tx.id.IsZero():
		return tempError{errInvalidID}
	case tx.NetworkID != tx.vm.Ctx.NetworkID:
		return permError{errWrongNetworkID}
	case tx.NodeID.IsZero():
		return tempError{errInvalidID}
	case tx.Subnet.IsZero():
		return tempError{errInvalidID}
	case tx.Wght == 0: // Ensure the validator has some weight
		return permError{errWeightTooSmall}
	case !crypto.IsSortedAndUniqueSECP2561RSigs(tx.ControlSigs):
		return permError{errSigsNotSorted}
	}

	// Ensure staking length is not too short or long
	if stakingDuration := tx.Duration(); stakingDuration < MinimumStakingDuration {
		return permError{errStakeTooShort}
	} else if stakingDuration > MaximumStakingDuration {
		return permError{errStakeTooLong}
	}

	// Verify tx inputs and outputs are valid
	if err := syntacticVerifySpend(tx, tx.vm.txFee, tx.vm.avaxAssetID); err != nil {
		return err
	}

	// recover control signatures
	tx.controlIDs = make([]ids.ShortID, len(tx.ControlSigs))
	unsignedBytesHash := hashing.ComputeHash256(tx.unsignedBytes)
	for i, sig := range tx.ControlSigs {
		key, err := tx.vm.factory.RecoverHashPublicKey(unsignedBytesHash, sig[:])
		if err != nil {
			return permError{err}
		}
		tx.controlIDs[i] = key.Address()
	}
	tx.syntacticallyVerified = true
	return nil
}

// SemanticVerify this transaction is valid.
func (tx *addNonDefaultSubnetValidatorTx) SemanticVerify(db database.Database) (*versiondb.Database, *versiondb.Database, func(), func(), TxError) {
	if err := tx.SyntacticVerify(); err != nil { // Ensure tx is syntactically valid
		return nil, nil, nil, nil, permError{err}
	} else if err := tx.vm.semanticVerifySpend(db, tx); err != nil { // Validate/update UTXOs
		return nil, nil, nil, nil, tempError{fmt.Errorf("couldn't verify tx: %w", err)}
	}

	// Get info about the subnet we're adding a validator to
	subnets, err := tx.vm.getSubnets(db)
	if err != nil {
		return nil, nil, nil, nil, permError{err}
	}
	var subnet *CreateSubnetTx
	for _, sn := range subnets {
		if sn.id.Equals(tx.SubnetID()) {
			subnet = sn
			break
		}
	}

	if subnet == nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("subnet %s does not exist", tx.SubnetID())}
	} else if len(tx.ControlSigs) != int(subnet.Threshold) {
		return nil, nil, nil, nil, permError{fmt.Errorf("expected tx to have %d control sigs but has %d", subnet.Threshold, len(tx.ControlSigs))}
	} else if !crypto.IsSortedAndUniqueSECP2561RSigs(tx.ControlSigs) {
		return nil, nil, nil, nil, permError{errors.New("control signatures aren't sorted")}
	}

	// Ensure the sigs on [tx] are valid
	controlKeys := ids.ShortSet{}
	controlKeys.Add(subnet.ControlKeys...)
	for _, controlID := range tx.controlIDs {
		if !controlKeys.Contains(controlID) {
			return nil, nil, nil, nil, permError{errors.New("tx has control signature from key not in subnet's ControlKeys")}
		}
	}

	// Ensure that the period this validator validates the specified subnet is a subnet of the time they validate the default subnet
	// First, see if they're currently validating the default subnet
	currentDSValidators, err := tx.vm.getCurrentValidators(db, DefaultSubnetID)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current validators of default subnet: %v", err)}
	}
	if dsValidator, err := currentDSValidators.getDefaultSubnetStaker(tx.NodeID); err == nil {
		if !tx.DurationValidator.BoundedBy(dsValidator.StartTime(), dsValidator.EndTime()) {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("time validating subnet [%v, %v] not subset of time validating default subnet [%v, %v]",
					tx.DurationValidator.StartTime(), tx.DurationValidator.EndTime(),
					dsValidator.StartTime(), dsValidator.EndTime())}
		}
	} else {
		// They aren't currently validating the default subnet.
		// See if they will validate the default subnet in the future.
		pendingDSValidators, err := tx.vm.getPendingValidators(db, DefaultSubnetID)
		if err != nil {
			return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get pending validators of default subnet: %v", err)}
		}
		dsValidator, err := pendingDSValidators.getDefaultSubnetStaker(tx.NodeID)
		if err != nil {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("validator would not be validating default subnet while validating non-default subnet")}
		}
		if !tx.DurationValidator.BoundedBy(dsValidator.StartTime(), dsValidator.EndTime()) {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("time validating subnet [%v, %v] not subset of time validating default subnet [%v, %v]",
					tx.DurationValidator.StartTime(), tx.DurationValidator.EndTime(),
					dsValidator.StartTime(), dsValidator.EndTime())}
		}
	}

	// Ensure the proposed validator starts after the current timestamp
	if currentTimestamp, err := tx.vm.getTimestamp(db); err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current timestamp: %v", err)}
	} else if validatorStartTime := tx.StartTime(); !currentTimestamp.Before(validatorStartTime) {
		return nil, nil, nil, nil, permError{fmt.Errorf("validator's start time (%s) is at or after current chain timestamp (%s)",
			currentTimestamp,
			validatorStartTime)}
	}

	// Ensure the proposed validator is not already a validator of the specified subnet
	currentValidatorHeap, err := tx.vm.getCurrentValidators(db, tx.Subnet)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current validators of subnet %s: %v", tx.Subnet, err)}
	}
	for _, currentVdr := range tx.vm.getValidators(currentValidatorHeap) {
		if currentVdr.ID().Equals(tx.NodeID) {
			return nil, nil, nil, nil, permError{fmt.Errorf("validator with ID %s already in the current validator set for subnet with ID %s",
				tx.NodeID,
				tx.Subnet)}
		}
	}

	// Ensure the proposed validator is not already slated to validate for the specified subnet
	pendingValidatorHeap, err := tx.vm.getPendingValidators(db, tx.Subnet)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get pending validators of subnet %s: %v", tx.Subnet, err)}
	}
	for _, pendingVdr := range tx.vm.getValidators(pendingValidatorHeap) {
		if pendingVdr.ID().Equals(tx.NodeID) {
			return nil, nil, nil, nil, permError{fmt.Errorf("validator with ID %s already in the pending validator set for subnet with ID %s",
				tx.NodeID,
				tx.Subnet)}
		}
	}
	pendingValidatorHeap.Add(tx) // add validator to set of pending validators

	// If this proposal is committed, update the pending validator set to include the validator
	onCommitDB := versiondb.New(db)
	if err := tx.vm.putPendingValidators(onCommitDB, pendingValidatorHeap, tx.Subnet); err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't put current validators: %v", err)}
	}

	// If this proposal is aborted, chain state doesn't change
	onAbortDB := versiondb.New(db)
	return onCommitDB, onAbortDB, nil, nil, nil
}

// InitiallyPrefersCommit returns true if the proposed validators start time is
// after the current wall clock time,
func (tx *addNonDefaultSubnetValidatorTx) InitiallyPrefersCommit() bool {
	return tx.StartTime().After(tx.vm.clock.Time())
}

// Create a new transaction
func (vm *VM) newAddNonDefaultSubnetValidatorTx(
	weight, // Sampling weight of the new validator
	startTime, // Unix time they start delegating
	endTime uint64, // Unix time they top delegating
	nodeID ids.ShortID, // ID of the node validating
	subnetID ids.ID, // ID of the subnet the validator will validate
	controlKeys []*crypto.PrivateKeySECP256K1R, // Control keys for the subnet ID
	keys []*crypto.PrivateKeySECP256K1R, // Pay the fee
) (*addNonDefaultSubnetValidatorTx, error) {

	// Calculate inputs, outputs, and keys used to sign this tx
	inputs, outputs, credKeys, err := vm.spend(vm.DB, vm.txFee, keys)
	if err != nil {
		return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err)
	}

	// Create the tx
	tx := &addNonDefaultSubnetValidatorTx{
		UnsignedAddNonDefaultSubnetValidatorTx: UnsignedAddNonDefaultSubnetValidatorTx{
			CommonTx: CommonTx{
				NetworkID: vm.Ctx.NetworkID,
				Inputs:    inputs,
				Outputs:   outputs,
			},
			SubnetValidator: SubnetValidator{
				DurationValidator: DurationValidator{
					Validator: Validator{
						NodeID: nodeID,
						Wght:   weight,
					},
					Start: startTime,
					End:   endTime,
				},
				Subnet: subnetID,
			},
		},
	}
	tx.unsignedBytes, err = Codec.Marshal(interface{}(tx.UnsignedAddNonDefaultSubnetValidatorTx))
	if err != nil {
		return nil, fmt.Errorf("couldn't marshal UnsignedAddNonDefaultSubnetValidatorTx: %w", err)
	}
	hash := hashing.ComputeHash256(tx.unsignedBytes)

	// Attach credentials
	for _, inputKeys := range credKeys { // [inputKeys] are the keys used to authorize spend of an input
		cred := &secp256k1fx.Credential{}
		for _, key := range inputKeys {
			sig, err := key.SignHash(hash) // Sign hash(tx.unsignedBytes)
			if err != nil {
				return nil, fmt.Errorf("problem generating credential: %w", err)
			}
			sigArr := [crypto.SECP256K1RSigLen]byte{}
			copy(sigArr[:], sig)
			cred.Sigs = append(cred.Sigs, sigArr)
		}
		tx.Credentials = append(tx.Credentials, cred) // Attach credntial to tx
	}

	return tx, tx.initialize(vm)
}
<commit_msg>sign new addNonDefaultSubnetValidatorTx with controlKeys<commit_after>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package platformvm

import (
	"errors"
	"fmt"

	"github.com/ava-labs/gecko/database"
	"github.com/ava-labs/gecko/database/versiondb"
	"github.com/ava-labs/gecko/ids"
	"github.com/ava-labs/gecko/utils/crypto"
	"github.com/ava-labs/gecko/utils/hashing"
	"github.com/ava-labs/gecko/vms/components/verify"
	"github.com/ava-labs/gecko/vms/secp256k1fx"
)

var (
	errSigsNotSorted           = errors.New("control signatures not sorted")
	errWrongNumberOfSignatures = errors.New("wrong number of signatures")
	errDSValidatorSubset       = errors.New("all subnets must be a subset of the default subnet")
)

// UnsignedAddNonDefaultSubnetValidatorTx is an unsigned addNonDefaultSubnetValidatorTx
type UnsignedAddNonDefaultSubnetValidatorTx struct {
	// Metadata, inputs and outputs
	CommonTx `serialize:"true"`
	// IDs of control keys
	controlIDs []ids.ShortID
	// The validator
	SubnetValidator `serialize:"true"`
}

// addNonDefaultSubnetValidatorTx is a transaction that, if it is in a ProposeAddValidator block that
// is accepted and followed by a Commit block, adds a validator to the pending validator set of a subnet
// other than the default subnet.
// (That is, the validator in the tx will validate at some point in the future.)
// The transaction fee will be paid from the account whose ID is [Sigs[0].Address()]
type addNonDefaultSubnetValidatorTx struct {
	UnsignedAddNonDefaultSubnetValidatorTx `serialize:"true"`
	// Credentials that authorize the inputs to spend the corresponding outputs
	Credentials []verify.Verifiable `serialize:"true"`
	// When a subnet is created, it specifies a set of public keys ("control keys") such
	// that in order to add a validator to the subnet, a tx must be signed with
	// a certain threshold of those keys
	// Each element of ControlSigs is the signature of one of those keys
	ControlSigs [][crypto.SECP256K1RSigLen]byte `serialize:"true"`
}

// Creds returns this transactions credentials
func (tx *addNonDefaultSubnetValidatorTx) Creds() []verify.Verifiable {
	return tx.Credentials
}

// initialize [tx]. Sets [tx.vm], [tx.unsignedBytes], [tx.bytes], [tx.id]
func (tx *addNonDefaultSubnetValidatorTx) initialize(vm *VM) error {
	if tx.vm != nil { // already been initialized
		return nil
	}
	tx.vm = vm
	var err error
	tx.unsignedBytes, err = Codec.Marshal(interface{}(tx.UnsignedAddNonDefaultSubnetValidatorTx))
	if err != nil {
		return fmt.Errorf("couldn't marshal UnsignedAddNonDefaultSubnetValidatorTx: %w", err)
	}
	tx.bytes, err = Codec.Marshal(tx) // byte representation of the signed transaction
	if err != nil {
		return fmt.Errorf("couldn't marshal addNonDefaultSubnetValidatorTx: %w", err)
	}
	tx.id = ids.NewID(hashing.ComputeHash256Array(tx.bytes))
	return nil
}

// SyntacticVerify return nil iff [tx] is valid
// If [tx] is valid, sets [tx.accountID]
func (tx *addNonDefaultSubnetValidatorTx) SyntacticVerify() error {
	switch {
	case tx == nil:
		return tempError{errNilTx}
	case tx.syntacticallyVerified: // already passed syntactic verification
		return nil
	case tx.id.IsZero():
		return tempError{errInvalidID}
	case tx.NetworkID != tx.vm.Ctx.NetworkID:
		return permError{errWrongNetworkID}
	case tx.NodeID.IsZero():
		return tempError{errInvalidID}
	case tx.Subnet.IsZero():
		return tempError{errInvalidID}
	case tx.Wght == 0: // Ensure the validator has some weight
		return permError{errWeightTooSmall}
	case !crypto.IsSortedAndUniqueSECP2561RSigs(tx.ControlSigs):
		return permError{errSigsNotSorted}
	}

	// Ensure staking length is not too short or long
	if stakingDuration := tx.Duration(); stakingDuration < MinimumStakingDuration {
		return permError{errStakeTooShort}
	} else if stakingDuration > MaximumStakingDuration {
		return permError{errStakeTooLong}
	}

	// Verify tx inputs and outputs are valid
	if err := syntacticVerifySpend(tx, tx.vm.txFee, tx.vm.avaxAssetID); err != nil {
		return err
	}

	// recover control signatures
	tx.controlIDs = make([]ids.ShortID, len(tx.ControlSigs))
	unsignedBytesHash := hashing.ComputeHash256(tx.unsignedBytes)
	for i, sig := range tx.ControlSigs {
		key, err := tx.vm.factory.RecoverHashPublicKey(unsignedBytesHash, sig[:])
		if err != nil {
			return permError{err}
		}
		tx.controlIDs[i] = key.Address()
	}
	tx.syntacticallyVerified = true
	return nil
}

// SemanticVerify this transaction is valid.
func (tx *addNonDefaultSubnetValidatorTx) SemanticVerify(db database.Database) (*versiondb.Database, *versiondb.Database, func(), func(), TxError) {
	if err := tx.SyntacticVerify(); err != nil { // Ensure tx is syntactically valid
		return nil, nil, nil, nil, permError{err}
	} else if err := tx.vm.semanticVerifySpend(db, tx); err != nil { // Validate/update UTXOs
		return nil, nil, nil, nil, tempError{fmt.Errorf("couldn't verify tx: %w", err)}
	}

	// Get info about the subnet we're adding a validator to
	subnets, err := tx.vm.getSubnets(db)
	if err != nil {
		return nil, nil, nil, nil, permError{err}
	}
	var subnet *CreateSubnetTx
	for _, sn := range subnets {
		if sn.id.Equals(tx.SubnetID()) {
			subnet = sn
			break
		}
	}

	if subnet == nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("subnet %s does not exist", tx.SubnetID())}
	} else if len(tx.ControlSigs) != int(subnet.Threshold) {
		return nil, nil, nil, nil, permError{fmt.Errorf("expected tx to have %d control sigs but has %d", subnet.Threshold, len(tx.ControlSigs))}
	} else if !crypto.IsSortedAndUniqueSECP2561RSigs(tx.ControlSigs) {
		return nil, nil, nil, nil, permError{errors.New("control signatures aren't sorted")}
	}

	// Ensure the sigs on [tx] are valid
	controlKeys := ids.ShortSet{}
	controlKeys.Add(subnet.ControlKeys...)
	for _, controlID := range tx.controlIDs {
		if !controlKeys.Contains(controlID) {
			return nil, nil, nil, nil, permError{errors.New("tx has control signature from key not in subnet's ControlKeys")}
		}
	}

	// Ensure that the period this validator validates the specified subnet is a subnet of the time they validate the default subnet
	// First, see if they're currently validating the default subnet
	currentDSValidators, err := tx.vm.getCurrentValidators(db, DefaultSubnetID)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current validators of default subnet: %v", err)}
	}
	if dsValidator, err := currentDSValidators.getDefaultSubnetStaker(tx.NodeID); err == nil {
		if !tx.DurationValidator.BoundedBy(dsValidator.StartTime(), dsValidator.EndTime()) {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("time validating subnet [%v, %v] not subset of time validating default subnet [%v, %v]",
					tx.DurationValidator.StartTime(), tx.DurationValidator.EndTime(),
					dsValidator.StartTime(), dsValidator.EndTime())}
		}
	} else {
		// They aren't currently validating the default subnet.
		// See if they will validate the default subnet in the future.
		pendingDSValidators, err := tx.vm.getPendingValidators(db, DefaultSubnetID)
		if err != nil {
			return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get pending validators of default subnet: %v", err)}
		}
		dsValidator, err := pendingDSValidators.getDefaultSubnetStaker(tx.NodeID)
		if err != nil {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("validator would not be validating default subnet while validating non-default subnet")}
		}
		if !tx.DurationValidator.BoundedBy(dsValidator.StartTime(), dsValidator.EndTime()) {
			return nil, nil, nil, nil,
				permError{fmt.Errorf("time validating subnet [%v, %v] not subset of time validating default subnet [%v, %v]",
					tx.DurationValidator.StartTime(), tx.DurationValidator.EndTime(),
					dsValidator.StartTime(), dsValidator.EndTime())}
		}
	}

	// Ensure the proposed validator starts after the current timestamp
	if currentTimestamp, err := tx.vm.getTimestamp(db); err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current timestamp: %v", err)}
	} else if validatorStartTime := tx.StartTime(); !currentTimestamp.Before(validatorStartTime) {
		return nil, nil, nil, nil, permError{fmt.Errorf("validator's start time (%s) is at or after current chain timestamp (%s)",
			currentTimestamp,
			validatorStartTime)}
	}

	// Ensure the proposed validator is not already a validator of the specified subnet
	currentValidatorHeap, err := tx.vm.getCurrentValidators(db, tx.Subnet)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get current validators of subnet %s: %v", tx.Subnet, err)}
	}
	for _, currentVdr := range tx.vm.getValidators(currentValidatorHeap) {
		if currentVdr.ID().Equals(tx.NodeID) {
			return nil, nil, nil, nil, permError{fmt.Errorf("validator with ID %s already in the current validator set for subnet with ID %s",
				tx.NodeID,
				tx.Subnet)}
		}
	}

	// Ensure the proposed validator is not already slated to validate for the specified subnet
	pendingValidatorHeap, err := tx.vm.getPendingValidators(db, tx.Subnet)
	if err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't get pending validators of subnet %s: %v", tx.Subnet, err)}
	}
	for _, pendingVdr := range tx.vm.getValidators(pendingValidatorHeap) {
		if pendingVdr.ID().Equals(tx.NodeID) {
			return nil, nil, nil, nil, permError{fmt.Errorf("validator with ID %s already in the pending validator set for subnet with ID %s",
				tx.NodeID,
				tx.Subnet)}
		}
	}
	pendingValidatorHeap.Add(tx) // add validator to set of pending validators

	// If this proposal is committed, update the pending validator set to include the validator
	onCommitDB := versiondb.New(db)
	if err := tx.vm.putPendingValidators(onCommitDB, pendingValidatorHeap, tx.Subnet); err != nil {
		return nil, nil, nil, nil, permError{fmt.Errorf("couldn't put current validators: %v", err)}
	}

	// If this proposal is aborted, chain state doesn't change
	onAbortDB := versiondb.New(db)
	return onCommitDB, onAbortDB, nil, nil, nil
}

// InitiallyPrefersCommit returns true if the proposed validators start time is
// after the current wall clock time,
func (tx *addNonDefaultSubnetValidatorTx) InitiallyPrefersCommit() bool {
	return tx.StartTime().After(tx.vm.clock.Time())
}

// Create a new transaction
func (vm *VM) newAddNonDefaultSubnetValidatorTx(
	weight, // Sampling weight of the new validator
	startTime, // Unix time they start delegating
	endTime uint64, // Unix time they top delegating
	nodeID ids.ShortID, // ID of the node validating
	subnetID ids.ID, // ID of the subnet the validator will validate
	controlKeys []*crypto.PrivateKeySECP256K1R, // Control keys for the subnet ID
	keys []*crypto.PrivateKeySECP256K1R, // Pay the fee
) (*addNonDefaultSubnetValidatorTx, error) {

	// Calculate inputs, outputs, and keys used to sign this tx
	inputs, outputs, credKeys, err := vm.spend(vm.DB, vm.txFee, keys)
	if err != nil {
		return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err)
	}

	// Create the tx
	tx := &addNonDefaultSubnetValidatorTx{
		UnsignedAddNonDefaultSubnetValidatorTx: UnsignedAddNonDefaultSubnetValidatorTx{
			CommonTx: CommonTx{
				NetworkID: vm.Ctx.NetworkID,
				Inputs:    inputs,
				Outputs:   outputs,
			},
			SubnetValidator: SubnetValidator{
				DurationValidator: DurationValidator{
					Validator: Validator{
						NodeID: nodeID,
						Wght:   weight,
					},
					Start: startTime,
					End:   endTime,
				},
				Subnet: subnetID,
			},
		},
	}
	tx.unsignedBytes, err = Codec.Marshal(interface{}(tx.UnsignedAddNonDefaultSubnetValidatorTx))
	if err != nil {
		return nil, fmt.Errorf("couldn't marshal UnsignedAddNonDefaultSubnetValidatorTx: %w", err)
	}
	hash := hashing.ComputeHash256(tx.unsignedBytes)

	// Attach credentials
	for _, inputKeys := range credKeys { // [inputKeys] are the keys used to authorize spend of an input
		cred := &secp256k1fx.Credential{}
		for _, key := range inputKeys {
			sig, err := key.SignHash(hash) // Sign hash(tx.unsignedBytes)
			if err != nil {
				return nil, fmt.Errorf("problem generating credential: %w", err)
			}
			sigArr := [crypto.SECP256K1RSigLen]byte{}
			copy(sigArr[:], sig)
			cred.Sigs = append(cred.Sigs, sigArr)
		}
		tx.Credentials = append(tx.Credentials, cred) // Attach credntial to tx
	}
	// Attach control key signatures
	tx.ControlSigs = make([][crypto.SECP256K1RSigLen]byte, len(controlKeys))
	for i, key := range controlKeys {
		sig, err := key.SignHash(hash)
		if err != nil {
			return nil, err
		}
		// tx.ControlSigs[i] is type [65]byte but sig is type []byte do the below
		copy(tx.ControlSigs[i][:], sig)
	}
	crypto.SortSECP2561RSigs(tx.ControlSigs)

	return tx, tx.initialize(vm)
}
<|endoftext|>


<commit_before>// +build e2e

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"fmt"
	"os"
	"strings"
	"testing"

	"knative.dev/pkg/test/logstream"
)

var packages = []string{
	"github.com/google/knative-gcp/test/cmd/target",
	"github.com/google/knative-gcp/test/cmd/storage_target",
}

var packageToImageConfig = map[string]string{}
var packageToImageConfigDone bool

func TestMain(m *testing.M) {
	for _, pack := range packages {
		image, err := KoPublish(pack)
		if err != nil {
			fmt.Printf("error attempting to ko publish: %s\n", err)
			panic(err)
		}
		i := strings.Split(pack, "/")
		packageToImageConfig[i[len(i)-1]+"Image"] = image
	}
	packageToImageConfigDone = true

	os.Exit(m.Run())
}

// This test is more for debugging the ko publish process.
func TestKoPublish(t *testing.T) {
	for k, v := range packageToImageConfig {
		t.Log(k, "-->", v)
	}
}

// Rest of e2e tests go below:

// TestSmoke makes sure we can run tests.
func TestSmokeChannel(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	SmokeTestChannelImpl(t)
}

// TestSmokePullSubscription makes sure we can run tests on PullSubscriptions.
func TestSmokePullSubscription(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	SmokePullSubscriptionTestImpl(t)
}

// TestPullSubscriptionWithTarget tests we can knock down a target.
func TestPullSubscriptionWithTarget(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	PullSubscriptionWithTargetTestImpl(t, packageToImageConfig)
}

// TestStorage tests we can knock down a target fot storage
func TestStorage(t *testing.T) {
	t.Skip("currently doesn't work in PROW, needs investigation")
	cancel := logstream.Start(t)
	defer cancel()
	StorageWithTestImpl(t, packageToImageConfig)
}
<commit_msg>remove skip<commit_after>// +build e2e

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"fmt"
	"os"
	"strings"
	"testing"

	"knative.dev/pkg/test/logstream"
)

var packages = []string{
	"github.com/google/knative-gcp/test/cmd/target",
	"github.com/google/knative-gcp/test/cmd/storage_target",
}

var packageToImageConfig = map[string]string{}
var packageToImageConfigDone bool

func TestMain(m *testing.M) {
	for _, pack := range packages {
		image, err := KoPublish(pack)
		if err != nil {
			fmt.Printf("error attempting to ko publish: %s\n", err)
			panic(err)
		}
		i := strings.Split(pack, "/")
		packageToImageConfig[i[len(i)-1]+"Image"] = image
	}
	packageToImageConfigDone = true

	os.Exit(m.Run())
}

// This test is more for debugging the ko publish process.
func TestKoPublish(t *testing.T) {
	for k, v := range packageToImageConfig {
		t.Log(k, "-->", v)
	}
}

// Rest of e2e tests go below:

// TestSmoke makes sure we can run tests.
func TestSmokeChannel(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	SmokeTestChannelImpl(t)
}

// TestSmokePullSubscription makes sure we can run tests on PullSubscriptions.
func TestSmokePullSubscription(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	SmokePullSubscriptionTestImpl(t)
}

// TestPullSubscriptionWithTarget tests we can knock down a target.
func TestPullSubscriptionWithTarget(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()

	PullSubscriptionWithTargetTestImpl(t, packageToImageConfig)
}

// TestStorage tests we can knock down a target fot storage
func TestStorage(t *testing.T) {
	cancel := logstream.Start(t)
	defer cancel()
	StorageWithTestImpl(t, packageToImageConfig)
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package node

import (
	"fmt"
	"strings"

	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
)

const maxNodes = 100

var _ = SIGDescribe("SSH", func() {

	f := framework.NewDefaultFramework("ssh")

	BeforeEach(func() {
		// When adding more providers here, also implement their functionality in util.go's framework.GetSigner(...).
		framework.SkipUnlessProviderIs(framework.ProvidersWithSSH...)

		// This test SSH's into the node for which it needs the $HOME/.ssh/id_rsa key to be present. So
		// we should skip if the environment does not have the key (not all CI systems support this use case)
		framework.SkipUnlessSSHKeyPresent()
	})

	It("should SSH to all nodes and run commands", func() {
		// Get all nodes' external IPs.
		By("Getting all nodes' SSH-able IP addresses")
		hosts, err := framework.NodeSSHHosts(f.ClientSet)
		if err != nil {
			framework.Failf("Error getting node hostnames: %v", err)
		}

		testCases := []struct {
			cmd            string
			checkStdout    bool
			expectedStdout string
			expectedStderr string
			expectedCode   int
			expectedError  error
		}{
			// Keep this test first - this variant runs on all nodes.
			{`echo "Hello from $(whoami)@$(hostname)"`, false, "", "", 0, nil},
			{`echo "foo" | grep "bar"`, true, "", "", 1, nil},
			{`echo "Out" && echo "Error" >&2 && exit 7`, true, "Out", "Error", 7, nil},
		}

		for i, testCase := range testCases {
			// Only run the first testcase against max 100 nodes. Run
			// the rest against the first node we find only, since
			// they're basically testing SSH semantics (and we don't
			// need to do that against each host in the cluster).
			nodes := len(hosts)
			if i > 0 {
				nodes = 1
			} else if nodes > maxNodes {
				nodes = maxNodes
			}
			testhosts := hosts[:nodes]
			By(fmt.Sprintf("SSH'ing to %d nodes and running %s", len(testhosts), testCase.cmd))

			for _, host := range testhosts {
				result, err := framework.SSH(testCase.cmd, host, framework.TestContext.Provider)
				stdout, stderr := strings.TrimSpace(result.Stdout), strings.TrimSpace(result.Stderr)
				if err != testCase.expectedError {
					framework.Failf("Ran %s on %s, got error %v, expected %v", testCase.cmd, host, err, testCase.expectedError)
				}
				if testCase.checkStdout && stdout != testCase.expectedStdout {
					framework.Failf("Ran %s on %s, got stdout '%s', expected '%s'", testCase.cmd, host, stdout, testCase.expectedStdout)
				}
				if stderr != testCase.expectedStderr {
					framework.Failf("Ran %s on %s, got stderr '%s', expected '%s'", testCase.cmd, host, stderr, testCase.expectedStderr)
				}
				if result.Code != testCase.expectedCode {
					framework.Failf("Ran %s on %s, got exit code %d, expected %d", testCase.cmd, host, result.Code, testCase.expectedCode)
				}
				// Show stdout, stderr for logging purposes.
				if len(stdout) > 0 {
					framework.Logf("Got stdout from %s: %s", host, strings.TrimSpace(stdout))
				}
				if len(stderr) > 0 {
					framework.Logf("Got stderr from %s: %s", host, strings.TrimSpace(stderr))
				}
			}
		}

		// Quickly test that SSH itself errors correctly.
		By("SSH'ing to a nonexistent host")
		if _, err = framework.SSH(`echo "hello"`, "i.do.not.exist", framework.TestContext.Provider); err == nil {
			framework.Failf("Expected error trying to SSH to nonexistent host.")
		}
	})
})
<commit_msg>e2e: change test strings to avoid error highlighting<commit_after>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package node

import (
	"fmt"
	"strings"

	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
)

const maxNodes = 100

var _ = SIGDescribe("SSH", func() {

	f := framework.NewDefaultFramework("ssh")

	BeforeEach(func() {
		// When adding more providers here, also implement their functionality in util.go's framework.GetSigner(...).
		framework.SkipUnlessProviderIs(framework.ProvidersWithSSH...)

		// This test SSH's into the node for which it needs the $HOME/.ssh/id_rsa key to be present. So
		// we should skip if the environment does not have the key (not all CI systems support this use case)
		framework.SkipUnlessSSHKeyPresent()
	})

	It("should SSH to all nodes and run commands", func() {
		// Get all nodes' external IPs.
		By("Getting all nodes' SSH-able IP addresses")
		hosts, err := framework.NodeSSHHosts(f.ClientSet)
		if err != nil {
			framework.Failf("Error getting node hostnames: %v", err)
		}

		testCases := []struct {
			cmd            string
			checkStdout    bool
			expectedStdout string
			expectedStderr string
			expectedCode   int
			expectedError  error
		}{
			// Keep this test first - this variant runs on all nodes.
			{`echo "Hello from $(whoami)@$(hostname)"`, false, "", "", 0, nil},
			{`echo "foo" | grep "bar"`, true, "", "", 1, nil},
			{`echo "stdout" && echo "stderr" >&2 && exit 7`, true, "stdout", "stderr", 7, nil},
		}

		for i, testCase := range testCases {
			// Only run the first testcase against max 100 nodes. Run
			// the rest against the first node we find only, since
			// they're basically testing SSH semantics (and we don't
			// need to do that against each host in the cluster).
			nodes := len(hosts)
			if i > 0 {
				nodes = 1
			} else if nodes > maxNodes {
				nodes = maxNodes
			}
			testhosts := hosts[:nodes]
			By(fmt.Sprintf("SSH'ing to %d nodes and running %s", len(testhosts), testCase.cmd))

			for _, host := range testhosts {
				result, err := framework.SSH(testCase.cmd, host, framework.TestContext.Provider)
				stdout, stderr := strings.TrimSpace(result.Stdout), strings.TrimSpace(result.Stderr)
				if err != testCase.expectedError {
					framework.Failf("Ran %s on %s, got error %v, expected %v", testCase.cmd, host, err, testCase.expectedError)
				}
				if testCase.checkStdout && stdout != testCase.expectedStdout {
					framework.Failf("Ran %s on %s, got stdout '%s', expected '%s'", testCase.cmd, host, stdout, testCase.expectedStdout)
				}
				if stderr != testCase.expectedStderr {
					framework.Failf("Ran %s on %s, got stderr '%s', expected '%s'", testCase.cmd, host, stderr, testCase.expectedStderr)
				}
				if result.Code != testCase.expectedCode {
					framework.Failf("Ran %s on %s, got exit code %d, expected %d", testCase.cmd, host, result.Code, testCase.expectedCode)
				}
				// Show stdout, stderr for logging purposes.
				if len(stdout) > 0 {
					framework.Logf("Got stdout from %s: %s", host, strings.TrimSpace(stdout))
				}
				if len(stderr) > 0 {
					framework.Logf("Got stderr from %s: %s", host, strings.TrimSpace(stderr))
				}
			}
		}

		// Quickly test that SSH itself errors correctly.
		By("SSH'ing to a nonexistent host")
		if _, err = framework.SSH(`echo "hello"`, "i.do.not.exist", framework.TestContext.Provider); err == nil {
			framework.Failf("Expected error trying to SSH to nonexistent host.")
		}
	})
})
<|endoftext|>


<commit_before>package integration

import (
	"runtime"
	"testing"

	"github.com/buildkite/bintest/v3"
)

func TestMultilineCommandRunUnderBatch(t *testing.T) {
	t.Parallel()

	if runtime.GOOS != "windows" {
		t.Skip("batch test only applies to Windows")
	}

	tester, err := NewBootstrapTester()
	if err != nil {
		t.Fatal(err)
	}
	defer tester.Close()

	setup := tester.MustMock(t, "Setup.cmd")
	build := tester.MustMock(t, "BuildProject.cmd")

	setup.Expect().Once()
	build.Expect().Once().AndCallFunc(func(c *bintest.Call) {
		llamas := c.GetEnv(`LLAMAS`)
		if llamas != "COOL" {
			t.Errorf("Expected LLAMAS=COOL, got %s", llamas)
			c.Exit(1)
		} else {
			c.Exit(0)
		}
	})

	tester.RunAndCheck(t, "BUILDKITE_COMMAND=Setup.cmd\nset LLAMAS=COOL\nBuildProject.cmd")
}

func TestPreExitHooksRunsAfterCommandFails(t *testing.T) {
	tester, err := NewBootstrapTester()
	if err != nil {
		t.Fatal(err)
	}
	defer tester.Close()

	// Mock out the meta-data calls to the agent after checkout
	agent := tester.MustMock(t, "buildkite-agent")
	agent.
		Expect("meta-data", "exists", "buildkite:git:commit").
		AndExitWith(0)

	preExitFunc := func(c *bintest.Call) {
		cmdExitStatus := c.GetEnv(`BUILDKITE_COMMAND_EXIT_STATUS`)
		if cmdExitStatus != "1" {
			t.Errorf("Expected an exit status of 1, got %v", cmdExitStatus)
		}
		c.Exit(0)
	}

	tester.ExpectGlobalHook("pre-exit").Once().AndCallFunc(preExitFunc)
	tester.ExpectLocalHook("pre-exit").Once().AndCallFunc(preExitFunc)

	if err = tester.Run(t, "BUILDKITE_COMMAND=false"); err == nil {
		t.Fatal("Expected the bootstrap to fail")
	}

	tester.CheckMocks(t)
}
<commit_msg>Ensure we are using the batch shell for this test<commit_after>package integration

import (
	"runtime"
	"testing"

	"github.com/buildkite/bintest/v3"
)

func TestMultilineCommandRunUnderBatch(t *testing.T) {
	t.Parallel()

	if runtime.GOOS != "windows" {
		t.Skip("batch test only applies to Windows")
	}

	tester, err := NewBootstrapTester()
	if err != nil {
		t.Fatal(err)
	}
	defer tester.Close()

	setup := tester.MustMock(t, "Setup.cmd")
	build := tester.MustMock(t, "BuildProject.cmd")

	setup.Expect().Once()
	build.Expect().Once().AndCallFunc(func(c *bintest.Call) {
		llamas := c.GetEnv(`LLAMAS`)
		if llamas != "COOL" {
			t.Errorf("Expected LLAMAS=COOL, got %s", llamas)
			c.Exit(1)
		} else {
			c.Exit(0)
		}
	})

	env := []string{
		"BUILDKITE_COMMAND=Setup.cmd\nset LLAMAS=COOL\nBuildProject.cmd",
		`BUILDKITE_SHELL=C:\Windows\System32\CMD.exe /S /C`,
	}

	tester.RunAndCheck(t, env...)
}

func TestPreExitHooksRunsAfterCommandFails(t *testing.T) {
	tester, err := NewBootstrapTester()
	if err != nil {
		t.Fatal(err)
	}
	defer tester.Close()

	// Mock out the meta-data calls to the agent after checkout
	agent := tester.MustMock(t, "buildkite-agent")
	agent.
		Expect("meta-data", "exists", "buildkite:git:commit").
		AndExitWith(0)

	preExitFunc := func(c *bintest.Call) {
		cmdExitStatus := c.GetEnv(`BUILDKITE_COMMAND_EXIT_STATUS`)
		if cmdExitStatus != "1" {
			t.Errorf("Expected an exit status of 1, got %v", cmdExitStatus)
		}
		c.Exit(0)
	}

	tester.ExpectGlobalHook("pre-exit").Once().AndCallFunc(preExitFunc)
	tester.ExpectLocalHook("pre-exit").Once().AndCallFunc(preExitFunc)

	if err = tester.Run(t, "BUILDKITE_COMMAND=false"); err == nil {
		t.Fatal("Expected the bootstrap to fail")
	}

	tester.CheckMocks(t)
}
<|endoftext|>


<commit_before>package privileged

import (
	"github.com/Shopify/kubeaudit"
	"github.com/Shopify/kubeaudit/internal/k8s"
	"github.com/Shopify/kubeaudit/internal/override"
	"github.com/Shopify/kubeaudit/k8stypes"
)

const Name = "privileged"

const (
	// PrivilegedTrue occurs when privileged is set to true in the container SecurityContext
	PrivilegedTrue = "PrivilegedTrue"
	// PrivilegedNil occurs when privileged is not set in the container SecurityContext.
	// Prvivileged defaults to false so this is ok
	PrivilegedNil = "PrivilegedNil"
)

const OverrideLabel = "allow-privileged"

// Privileged implements Auditable
type Privileged struct{}

func New() *Privileged {
	return &Privileged{}
}

// Audit checks that privileged is set to false in every container's security context
func (a *Privileged) Audit(resource k8stypes.Resource, _ []k8stypes.Resource) ([]*kubeaudit.AuditResult, error) {
	var auditResults []*kubeaudit.AuditResult

	for _, container := range k8s.GetContainers(resource) {
		auditResult := auditContainer(container, resource)
		auditResult = override.ApplyOverride(auditResult, container.Name, resource, OverrideLabel)
		if auditResult != nil {
			auditResults = append(auditResults, auditResult)
		}
	}

	return auditResults, nil
}

func auditContainer(container *k8stypes.ContainerV1, resource k8stypes.Resource) *kubeaudit.AuditResult {
	if isPrivilegedNil(container) {
		return &kubeaudit.AuditResult{
			Name:     PrivilegedNil,
			Severity: kubeaudit.Warn,
			Message:  "privileged is not set in container SecurityContext. Privileged defaults to 'false' but it should be explicitly set to 'false'.",
			PendingFix: &fixPrivileged{
				container: container,
			},
			Metadata: kubeaudit.Metadata{
				"Container": container.Name,
			},
		}
	}

	if isPrivilegedTrue(container) {
		return &kubeaudit.AuditResult{
			Name:     PrivilegedTrue,
			Severity: kubeaudit.Error,
			Message:  "privileged is set to 'true' in container SecurityContext. It should be set to 'false'.",
			PendingFix: &fixPrivileged{
				container: container,
			},
			Metadata: kubeaudit.Metadata{
				"Container": container.Name,
			},
		}
	}

	return nil
}

func isPrivilegedTrue(container *k8stypes.ContainerV1) bool {
	if isPrivilegedNil(container) {
		return false
	}

	return *container.SecurityContext.Privileged
}

func isPrivilegedNil(container *k8stypes.ContainerV1) bool {
	return container.SecurityContext == nil || container.SecurityContext.Privileged == nil
}
<commit_msg>fix: typo in privileged auditor (#308)<commit_after>package privileged

import (
	"github.com/Shopify/kubeaudit"
	"github.com/Shopify/kubeaudit/internal/k8s"
	"github.com/Shopify/kubeaudit/internal/override"
	"github.com/Shopify/kubeaudit/k8stypes"
)

const Name = "privileged"

const (
	// PrivilegedTrue occurs when privileged is set to true in the container SecurityContext
	PrivilegedTrue = "PrivilegedTrue"
	// PrivilegedNil occurs when privileged is not set in the container SecurityContext.
	// Privileged defaults to false so this is ok
	PrivilegedNil = "PrivilegedNil"
)

const OverrideLabel = "allow-privileged"

// Privileged implements Auditable
type Privileged struct{}

func New() *Privileged {
	return &Privileged{}
}

// Audit checks that privileged is set to false in every container's security context
func (a *Privileged) Audit(resource k8stypes.Resource, _ []k8stypes.Resource) ([]*kubeaudit.AuditResult, error) {
	var auditResults []*kubeaudit.AuditResult

	for _, container := range k8s.GetContainers(resource) {
		auditResult := auditContainer(container, resource)
		auditResult = override.ApplyOverride(auditResult, container.Name, resource, OverrideLabel)
		if auditResult != nil {
			auditResults = append(auditResults, auditResult)
		}
	}

	return auditResults, nil
}

func auditContainer(container *k8stypes.ContainerV1, resource k8stypes.Resource) *kubeaudit.AuditResult {
	if isPrivilegedNil(container) {
		return &kubeaudit.AuditResult{
			Name:     PrivilegedNil,
			Severity: kubeaudit.Warn,
			Message:  "privileged is not set in container SecurityContext. Privileged defaults to 'false' but it should be explicitly set to 'false'.",
			PendingFix: &fixPrivileged{
				container: container,
			},
			Metadata: kubeaudit.Metadata{
				"Container": container.Name,
			},
		}
	}

	if isPrivilegedTrue(container) {
		return &kubeaudit.AuditResult{
			Name:     PrivilegedTrue,
			Severity: kubeaudit.Error,
			Message:  "privileged is set to 'true' in container SecurityContext. It should be set to 'false'.",
			PendingFix: &fixPrivileged{
				container: container,
			},
			Metadata: kubeaudit.Metadata{
				"Container": container.Name,
			},
		}
	}

	return nil
}

func isPrivilegedTrue(container *k8stypes.ContainerV1) bool {
	if isPrivilegedNil(container) {
		return false
	}

	return *container.SecurityContext.Privileged
}

func isPrivilegedNil(container *k8stypes.ContainerV1) bool {
	return container.SecurityContext == nil || container.SecurityContext.Privileged == nil
}
<|endoftext|>


<commit_before>package main

import(
        "github.com/spf13/cobra"
        "fmt"
        "path"
        "./profile"
        "./iwscanner"
        "github.com/rakyll/globalconf"
        "./proflocker"
)

var wifi_device string
var profiles_dir string
var flag_profiles_dir string

func OverrideProfileDir() {
        if flag_profiles_dir != "" {
                profiles_dir = flag_profiles_dir
        }
}

func main() {

        conf, err := globalconf.New("proflock")
        if err != nil {
                panic(err)
        }

        profiles_dir = path.Dir(conf.Filename) + "/profiles"

        var cmdScan = &cobra.Command{
                Use:   "scan",
                Short: "Scan current location for APs",
                Long:  `Turns on WiFi and scans for AP around.`,
                Run: func(cmd *cobra.Command, args []string) {
                        fmt.Printf("Turning %s on\n", wifi_device)

                        if e := iwscanner.TurnWifi(wifi_device, "on"); e != nil {
                                panic(e)
                        }

                        fmt.Println("Scanning")
                        aps, err := iwscanner.GetAPs(wifi_device)
                        if err != nil {
                                panic(err);
                        } else {
                                fmt.Println(aps)
                        }
                },
        }

        var cmdTurnWifi = &cobra.Command{
                Use:   "turn-wifi [on|off]",
                Short: "Turns Wifi On or Off",
                Long:  `Turns Wifi On or Off.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) == 0 {
                                if e := iwscanner.TurnWifi(wifi_device, "on"); e != nil {
                                        panic(e)
                                }
                        } else {
                                if e := iwscanner.TurnWifi(wifi_device, args[0]); e != nil {
                                        panic(e)
                                }
                        }
                },
        }

        var cmdProfiles = &cobra.Command{
                Use:   "profiles",
                Short: "Show profiles",
                Long:  `Show profiles.`,
                Run: func(cmd *cobra.Command, args []string) {
                        OverrideProfileDir()
                        profiles, err := proflocker.ParseLocationsDir(profiles_dir)
                        if err != nil {
                                panic(err);
                        }

                        if len(profiles) == 0 {
                                fmt.Println("fatal: no profile found")
                        } else {
                                fmt.Printf("The following profiles were found in %s:\n", profiles_dir)
                                for _, profile := range profiles {
                                        fmt.Println(profile.Name)
                                }
                        }

                },
        }

        var cmdRecord = &cobra.Command{
                Use:   "record [location]",
                Short: "Record location to use it as a profile afterwards.",
                Long:  `Record location to use it as a profile afterwards.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) < 1 {
                                fmt.Println("Location name is required.")
                                return
                        }

                        OverrideProfileDir()
                        err := proflocker.RecordLocation(args[0], profiles_dir, wifi_device)
                        if err != nil {
                                panic(err)
                        }
                },
        }

        var cmdShow = &cobra.Command{
                Use:   "show [location]",
                Short: "Shows location's data.",
                Long:  `Shows location's data.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) < 1 {
                                fmt.Println("Location name is required.")
                                return
                        }

                        name := args[0]

                        OverrideProfileDir()
                        location, err := proflocker.ParseLocation(profiles_dir + "/" + name + "/data", name)
                        if err != nil {
                                panic(err)
                        }

                        fmt.Println(location)
                },
        }

        var cmdLocate = &cobra.Command{
                Use:   "locate",
                Short: "Locate using prerecorded locations.",
                Long:  `Locate using prerecorded locations.`,
                Run: func(cmd *cobra.Command, args []string) {
                        OverrideProfileDir()
                        profiles, err := proflocker.ParseLocationsDir(profiles_dir)
                        if err != nil {
                                panic(err);
                        }

                        var probabs = make(map[string]float64)
                        aps, err := iwscanner.GetAPsAsHash(wifi_device)

                        for _, profile := range profiles {
                                score := profile.Aps_score
                                frequencies := proflocker.BuildFrequecyScores(profile)

                                if err != nil {
                                        panic(err)
                                }

                                for _, ap := range aps {
                                        prob := proflocker.ApproximateScore(ap, frequencies)/10

                                        // fmt.Printf("%s\t%f\n", ap.Essid, prob)

                                        if prob == 0.0 {
                                                prob = 0.1
                                        }

                                        score = score * prob
                                }

                                probabs[profile.Name] = score
                        }

                        max_profile := "no_profile"
                        max_probab := 0.0
                        for profile, probab := range probabs {
                                fmt.Printf("%s\t\t%f\n", profile, probab)
                                if probab > max_probab {
                                        max_profile = profile
                                        max_probab = probab
                                }
                        }

                        if max_probab > 1.0 {
                                fmt.Printf("Seems like you are located at '%s'.\n", max_profile)
                        } else {
                                fmt.Println("It is not possible to say where you are located.")
                        }

                },
        }

        var rootCmd = &cobra.Command{Use: "proflock"}
        rootCmd.PersistentFlags().StringVarP(&wifi_device, "device", "", "wlp4s0",
                                                "wifi-enabled device to be used")
        rootCmd.PersistentFlags().StringVarP(&flag_profiles_dir, "profiledir", "P", "",
                                                "the directory with profiles in it")

        rootCmd.AddCommand(cmdScan, profile.CmdProfile, cmdTurnWifi, cmdProfiles, cmdRecord, cmdShow,
                                cmdLocate)
        rootCmd.Execute()
}

<commit_msg>update: Added IsWifiOne command<commit_after>package main

import(
        "github.com/spf13/cobra"
        "fmt"
        "path"
        "./profile"
        "./iwscanner"
        "github.com/rakyll/globalconf"
        "./proflocker"
)

var wifi_device string
var profiles_dir string
var flag_profiles_dir string

func OverrideProfileDir() {
        if flag_profiles_dir != "" {
                profiles_dir = flag_profiles_dir
        }
}

func main() {

        conf, err := globalconf.New("proflock")
        if err != nil {
                panic(err)
        }

        profiles_dir = path.Dir(conf.Filename) + "/profiles"

        var cmdScan = &cobra.Command{
                Use:   "scan",
                Short: "Scan current location for APs",
                Long:  `Turns on WiFi and scans for AP around.`,
                Run: func(cmd *cobra.Command, args []string) {
                        fmt.Printf("Turning %s on\n", wifi_device)

                        if e := iwscanner.TurnWifi(wifi_device, "on"); e != nil {
                                panic(e)
                        }

                        fmt.Println("Scanning")
                        aps, err := iwscanner.GetAPs(wifi_device)
                        if err != nil {
                                panic(err);
                        } else {
                                fmt.Println(aps)
                        }
                },
        }

        var cmdTurnWifi = &cobra.Command{
                Use:   "turn-wifi [on|off]",
                Short: "Turns Wifi On or Off",
                Long:  `Turns Wifi On or Off.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) == 0 {
                                if e := iwscanner.TurnWifi(wifi_device, "on"); e != nil {
                                        panic(e)
                                }
                        } else {
                                if e := iwscanner.TurnWifi(wifi_device, args[0]); e != nil {
                                        panic(e)
                                }
                        }
                },
        }

         var cmdIsWifi= &cobra.Command{
                Use:   "is-wifi [on|off]",
                Short: "Is Wifi On or Off",
                Long:  `Is Wifi On or Off?`,
                Run: func(cmd *cobra.Command, args []string) {
                        on, e := iwscanner.IsWifiOn(wifi_device)
                        if e != nil {
                                panic(e);
                        }

                        fmt.Println(on)

                },
        }

        var cmdProfiles = &cobra.Command{
                Use:   "profiles",
                Short: "Show profiles",
                Long:  `Show profiles.`,
                Run: func(cmd *cobra.Command, args []string) {
                        OverrideProfileDir()
                        profiles, err := proflocker.ParseLocationsDir(profiles_dir)
                        if err != nil {
                                panic(err);
                        }

                        if len(profiles) == 0 {
                                fmt.Println("fatal: no profile found")
                        } else {
                                fmt.Printf("The following profiles were found in %s:\n", profiles_dir)
                                for _, profile := range profiles {
                                        fmt.Println(profile.Name)
                                }
                        }

                },
        }

        var cmdRecord = &cobra.Command{
                Use:   "record [location]",
                Short: "Record location to use it as a profile afterwards.",
                Long:  `Record location to use it as a profile afterwards.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) < 1 {
                                fmt.Println("Location name is required.")
                                return
                        }

                        OverrideProfileDir()
                        err := proflocker.RecordLocation(args[0], profiles_dir, wifi_device)
                        if err != nil {
                                panic(err)
                        }
                },
        }

        var cmdShow = &cobra.Command{
                Use:   "show [location]",
                Short: "Shows location's data.",
                Long:  `Shows location's data.`,
                Run: func(cmd *cobra.Command, args []string) {
                        if len(args) < 1 {
                                fmt.Println("Location name is required.")
                                return
                        }

                        name := args[0]

                        OverrideProfileDir()
                        location, err := proflocker.ParseLocation(profiles_dir + "/" + name + "/data", name)
                        if err != nil {
                                panic(err)
                        }

                        fmt.Println(location)
                },
        }

        var cmdLocate = &cobra.Command{
                Use:   "locate",
                Short: "Locate using prerecorded locations.",
                Long:  `Locate using prerecorded locations.`,
                Run: func(cmd *cobra.Command, args []string) {
                        OverrideProfileDir()
                        profiles, err := proflocker.ParseLocationsDir(profiles_dir)
                        if err != nil {
                                panic(err);
                        }

                        var probabs = make(map[string]float64)
                        aps, err := iwscanner.GetAPsAsHash(wifi_device)

                        for _, profile := range profiles {
                                score := profile.Aps_score
                                frequencies := proflocker.BuildFrequecyScores(profile)

                                if err != nil {
                                        panic(err)
                                }

                                for _, ap := range aps {
                                        prob := proflocker.ApproximateScore(ap, frequencies)/10

                                        // fmt.Printf("%s\t%f\n", ap.Essid, prob)

                                        if prob == 0.0 {
                                                prob = 0.1
                                        }

                                        score = score * prob
                                }

                                probabs[profile.Name] = score
                        }

                        max_profile := "no_profile"
                        max_probab := 0.0
                        for profile, probab := range probabs {
                                fmt.Printf("%s\t\t%f\n", profile, probab)
                                if probab > max_probab {
                                        max_profile = profile
                                        max_probab = probab
                                }
                        }

                        if max_probab > 1.0 {
                                fmt.Printf("Seems like you are located at '%s'.\n", max_profile)
                        } else {
                                fmt.Println("It is not possible to say where you are located.")
                        }

                },
        }

        var rootCmd = &cobra.Command{Use: "proflock"}
        rootCmd.PersistentFlags().StringVarP(&wifi_device, "device", "", "wlp4s0",
                                                "wifi-enabled device to be used")
        rootCmd.PersistentFlags().StringVarP(&flag_profiles_dir, "profiledir", "P", "",
                                                "the directory with profiles in it")

        rootCmd.AddCommand(cmdScan, profile.CmdProfile, cmdTurnWifi, cmdProfiles, cmdRecord, cmdShow,
                                cmdLocate, cmdIsWifi)
        rootCmd.Execute()
}

<|endoftext|>


<commit_before>//package WatWeatherBot

package main

import (
    "encoding/json"
    "log"
    "fmt"
    "net"
    ipinfo "github.com/syohex/go-ipinfo"
    "strings"
    "regexp"
    "net/http"
    "io/ioutil"
)

//Auto generated struct from: https://mholt.github.io/json-to-go/
type WeatherMap struct {
    Cod string `json:"cod"`
    Message float64 `json:"message"`
    Cnt int `json:"cnt"`
    List []struct {
        Dt int `json:"dt"`
        Main struct {
            Temp float64 `json:"temp"`
            TempMin float64 `json:"temp_min"`
            TempMax float64 `json:"temp_max"`
            Pressure float64 `json:"pressure"`
            SeaLevel float64 `json:"sea_level"`
            GrndLevel float64 `json:"grnd_level"`
            Humidity int `json:"humidity"`
            TempKf float64 `json:"temp_kf"`
        } `json:"main"`
        Weather []struct {
            ID int `json:"id"`
            Main string `json:"main"`
            Description string `json:"description"`
            Icon string `json:"icon"`
        } `json:"weather"`
        Clouds struct {
            All int `json:"all"`
        } `json:"clouds"`
        Wind struct {
            Speed float64 `json:"speed"`
            Deg float64 `json:"deg"` } `json:"wind"`
        Rain struct { ThreeH float64 `json:"3h"`
        } `json:"rain"`
        Sys struct {
            Pod string `json:"pod"`
        } `json:"sys"`
        DtTxt string `json:"dt_txt"`
        Snow struct {
            ThreeH float64 `json:"3h"`
        } `json:"snow,omitempty"`
    } `json:"list"`
    City struct {
        ID int `json:"id"`
        Name string `json:"name"`
        Coord struct {
            Lat float64 `json:"lat"`
            Lon float64 `json:"lon"`
        } `json:"coord"`
        Country string `json:"country"`
    } `json:"city"`
}

func getStations(body []byte) (*WeatherMap, error) {
    var s = new(WeatherMap)
    err := json.Unmarshal(body, &s)
    if(err != nil){
        fmt.Println("failed to marshal json:", err)
    }
    return s, err
}

func GetCurrentWeather(ip string) (string, string) {
    wd := GetWeatherMap(ip)
    weather := wd.List[0].Weather[0]
    return weather.Main, weather.Description
}

func GetWeatherMap(ip string)(wd WeatherMap) {
    info := ipinfo.IPInfo(net.ParseIP(ip))
    var validID = regexp.MustCompile(`([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)`)
    coords := []string{"0", "0"}
    if validID.MatchString(info.Location) {
        coords = strings.SplitN(info.Location, ",", -1)
    }
    url := fmt.Sprintf("http://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=2d744698c24036564a733d5c1ad358ca", coords[0], coords[1])
    log.Println(url)
    res, err := http.Get(url)//"http://api.openweathermap.org/data/2.5/forecast?id=524901&APPID=2d744698c24036564a733d5c1ad358ca")
    if err != nil {
        panic(err.Error())
    }
    fmt.Println("", res.StatusCode)
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        panic(err.Error())
    }

    s, err := getStations([]byte(body))
    return *s
}

<commit_msg>Fix typos<commit_after>package WatWeatherBot

import (
    "encoding/json"
    "log"
    "fmt"
    "net"
    ipinfo "github.com/syohex/go-ipinfo"
    "strings"
    "regexp"
    "net/http"
    "io/ioutil"
)

//Auto generated struct from: https://mholt.github.io/json-to-go/
type WeatherMap struct {
    Cod string `json:"cod"`
    Message float64 `json:"message"`
    Cnt int `json:"cnt"`
    List []struct {
        Dt int `json:"dt"`
        Main struct {
            Temp float64 `json:"temp"`
            TempMin float64 `json:"temp_min"`
            TempMax float64 `json:"temp_max"`
            Pressure float64 `json:"pressure"`
            SeaLevel float64 `json:"sea_level"`
            GrndLevel float64 `json:"grnd_level"`
            Humidity int `json:"humidity"`
            TempKf float64 `json:"temp_kf"`
        } `json:"main"`
        Weather []struct {
            ID int `json:"id"`
            Main string `json:"main"`
            Description string `json:"description"`
            Icon string `json:"icon"`
        } `json:"weather"`
        Clouds struct {
            All int `json:"all"`
        } `json:"clouds"`
        Wind struct {
            Speed float64 `json:"speed"`
            Deg float64 `json:"deg"` } `json:"wind"`
        Rain struct { ThreeH float64 `json:"3h"`
        } `json:"rain"`
        Sys struct {
            Pod string `json:"pod"`
        } `json:"sys"`
        DtTxt string `json:"dt_txt"`
        Snow struct {
            ThreeH float64 `json:"3h"`
        } `json:"snow,omitempty"`
    } `json:"list"`
    City struct {
        ID int `json:"id"`
        Name string `json:"name"`
        Coord struct {
            Lat float64 `json:"lat"`
            Lon float64 `json:"lon"`
        } `json:"coord"`
        Country string `json:"country"`
    } `json:"city"`
}

func initWeatherMap(body []byte) (*WeatherMap, error) {
    var s = new(WeatherMap)
    err := json.Unmarshal(body, &s)
    if(err != nil){
        fmt.Println("failed to marshal json:", err)
    }
    return s, err
}

func GetCurrentWeather(ip string) (string, string) {
    wd := GetWeatherMap(ip)
    weather := wd.List[0].Weather[0]
    return weather.Main, weather.Description
}

func GetWeatherMap(ip string)(wd WeatherMap) {
    info := ipinfo.IPInfo(net.ParseIP(ip))
    var validID = regexp.MustCompile(`([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)`)
    coords := []string{"0", "0"}
    if validID.MatchString(info.Location) {
        coords = strings.SplitN(info.Location, ",", -1)
    }
    url := fmt.Sprintf("http://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=2d744698c24036564a733d5c1ad358ca", coords[0], coords[1])
    log.Println(url)
    res, err := http.Get(url)//"http://api.openweathermap.org/data/2.5/forecast?id=524901&APPID=2d744698c24036564a733d5c1ad358ca")
    if err != nil {
        panic(err.Error())
    }
    fmt.Println("", res.StatusCode)
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        panic(err.Error())
    }

    s, err := initWeatherMap([]byte(body))
    return *s
}

<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"time"

	"github.com/drone/drone/router"
	"github.com/drone/drone/router/middleware"
	"github.com/gin-gonic/contrib/ginrus"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var serverCmd = cli.Command{
	Name:  "server",
	Usage: "starts the drone server daemon",
	Action: func(c *cli.Context) {
		if err := server(c); err != nil {
			logrus.Fatal(err)
		}
	},
	Flags: []cli.Flag{
		cli.BoolFlag{
			EnvVar: "DRONE_DEBUG",
			Name:   "debug",
			Usage:  "start the server in debug mode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_ADDR",
			Name:   "server-addr",
			Usage:  "server address",
			Value:  ":8000",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_CERT",
			Name:   "server-cert",
			Usage:  "server ssl cert",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_KEY",
			Name:   "server-key",
			Usage:  "server ssl key",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ADMIN",
			Name:   "admin",
			Usage:  "list of admin users",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ORGS",
			Name:   "orgs",
			Usage:  "list of approved organizations",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_OPEN",
			Name:   "open",
			Usage:  "open user registration",
		},
		cli.StringFlag{
			EnvVar: "DRONE_YAML",
			Name:   "yaml",
			Usage:  "build configuraton file name",
			Value:  ".drone.yml",
		},
		cli.DurationFlag{
			EnvVar: "DRONE_CACHE_TTY",
			Name:   "cache-tty",
			Usage:  "cache duration",
			Value:  time.Minute * 15,
		},
		cli.StringFlag{
			EnvVar: "DRONE_AGENT_SECRET,DRONE_SECRET",
			Name:   "agent-secret",
			Usage:  "agent secret passcode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DRIVER,DATABASE_DRIVER",
			Name:   "driver",
			Usage:  "database driver",
			Value:  "sqlite3",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DATASOURCE,DATABASE_CONFIG",
			Name:   "datasource",
			Usage:  "database driver configuration string",
			Value:  "drone.sqlite",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB",
			Name:   "github",
			Usage:  "github driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_URL",
			Name:   "github-server",
			Usage:  "github server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CONTEXT",
			Name:   "github-context",
			Usage:  "github status context",
			Value:  "continuous-integration/drone",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CLIENT",
			Name:   "github-client",
			Usage:  "github oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_SECRET",
			Name:   "github-secret",
			Usage:  "github oauth2 client secret",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_GITHUB_SCOPE",
			Name:   "github-scope",
			Usage:  "github oauth scope",
			Value: &cli.StringSlice{
				"repo",
				"repo:status",
				"user:email",
				"read:org",
			},
		},
		cli.BoolTFlag{
			EnvVar: "DRONE_GITHUB_MERGE_REF",
			Name:   "github-merge-ref",
			Usage:  "github pull requests use merge ref",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_PRIVATE_MODE",
			Name:   "github-private-mode",
			Usage:  "github is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_SKIP_VERIFY",
			Name:   "github-skip-verify",
			Usage:  "github skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS",
			Name:   "gogs",
			Usage:  "gogs driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_URL",
			Name:   "gogs-server",
			Usage:  "gogs server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_USERNAME",
			Name:   "gogs-git-username",
			Usage:  "gogs service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_PASSWORD",
			Name:   "gogs-git-password",
			Usage:  "gogs service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_PRIVATE_MODE",
			Name:   "gogs-private-mode",
			Usage:  "gogs private mode enabled",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_SKIP_VERIFY",
			Name:   "gogs-skip-verify",
			Usage:  "gogs skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BITBUCKET",
			Name:   "bitbucket",
			Usage:  "bitbucket driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_CLIENT",
			Name:   "bitbucket-client",
			Usage:  "bitbucket oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_SECRET",
			Name:   "bitbucket-secret",
			Usage:  "bitbucket oauth2 client secret",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB",
			Name:   "gitlab",
			Usage:  "gitlab driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_URL",
			Name:   "gitlab-server",
			Usage:  "gitlab server address",
			Value:  "https://gitlab.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_CLIENT",
			Name:   "gitlab-client",
			Usage:  "gitlab oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_SECRET",
			Name:   "gitlab-secret",
			Usage:  "gitlab oauth2 client secret",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_USERNAME",
			Name:   "gitlab-git-username",
			Usage:  "gitlab service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_PASSWORD",
			Name:   "gitlab-git-password",
			Usage:  "gitlab service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_SKIP_VERIFY",
			Name:   "gitlab-skip-verify",
			Usage:  "gitlab skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_PRIVATE_MODE",
			Name:   "gitlab-private-mode",
			Usage:  "gitlab is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH",
			Name:   "stash",
			Usage:  "stash driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_URL",
			Name:   "stash-server",
			Usage:  "stash server address",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_KEY",
			Name:   "stash-consumer-key",
			Usage:  "stash oauth1 consumer key",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_RSA",
			Name:   "stash-consumer-rsa",
			Usage:  "stash oauth1 private key file",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_USERNAME",
			Name:   "stash-git-username",
			Usage:  "stash service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_PASSWORD",
			Name:   "stash-git-password",
			Usage:  "stash service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH_SKIP_VERIFY",
			Name:   "stash-skip-verify",
			Usage:  "stash skip ssl verification",
		},
	},
}

func server(c *cli.Context) error {

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	// setup the server and start the listener
	handler := router.Load(
		ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
		middleware.Version,
		middleware.Config(c),
		middleware.Queue(c),
		middleware.Stream(c),
		middleware.Bus(c),
		middleware.Cache(c),
		middleware.Store(c),
		middleware.Remote(c),
		middleware.Agents(c),
	)

	// start the server with tls enabled
	if c.String("server-cert") != "" {
		return http.ListenAndServeTLS(
			c.String("server-addr"),
			c.String("server-cert"),
			c.String("server-key"),
			handler,
		)
	}

	// start the server without tls enabled
	return http.ListenAndServe(
		c.String("server-addr"),
		handler,
	)
}
<commit_msg>Expose GitHub machine user options.<commit_after>package main

import (
	"net/http"
	"time"

	"github.com/drone/drone/router"
	"github.com/drone/drone/router/middleware"
	"github.com/gin-gonic/contrib/ginrus"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var serverCmd = cli.Command{
	Name:  "server",
	Usage: "starts the drone server daemon",
	Action: func(c *cli.Context) {
		if err := server(c); err != nil {
			logrus.Fatal(err)
		}
	},
	Flags: []cli.Flag{
		cli.BoolFlag{
			EnvVar: "DRONE_DEBUG",
			Name:   "debug",
			Usage:  "start the server in debug mode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_ADDR",
			Name:   "server-addr",
			Usage:  "server address",
			Value:  ":8000",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_CERT",
			Name:   "server-cert",
			Usage:  "server ssl cert",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_KEY",
			Name:   "server-key",
			Usage:  "server ssl key",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ADMIN",
			Name:   "admin",
			Usage:  "list of admin users",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ORGS",
			Name:   "orgs",
			Usage:  "list of approved organizations",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_OPEN",
			Name:   "open",
			Usage:  "open user registration",
		},
		cli.StringFlag{
			EnvVar: "DRONE_YAML",
			Name:   "yaml",
			Usage:  "build configuraton file name",
			Value:  ".drone.yml",
		},
		cli.DurationFlag{
			EnvVar: "DRONE_CACHE_TTY",
			Name:   "cache-tty",
			Usage:  "cache duration",
			Value:  time.Minute * 15,
		},
		cli.StringFlag{
			EnvVar: "DRONE_AGENT_SECRET,DRONE_SECRET",
			Name:   "agent-secret",
			Usage:  "agent secret passcode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DRIVER,DATABASE_DRIVER",
			Name:   "driver",
			Usage:  "database driver",
			Value:  "sqlite3",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DATASOURCE,DATABASE_CONFIG",
			Name:   "datasource",
			Usage:  "database driver configuration string",
			Value:  "drone.sqlite",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB",
			Name:   "github",
			Usage:  "github driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_URL",
			Name:   "github-server",
			Usage:  "github server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CONTEXT",
			Name:   "github-context",
			Usage:  "github status context",
			Value:  "continuous-integration/drone",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CLIENT",
			Name:   "github-client",
			Usage:  "github oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_SECRET",
			Name:   "github-secret",
			Usage:  "github oauth2 client secret",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_GITHUB_SCOPE",
			Name:   "github-scope",
			Usage:  "github oauth scope",
			Value: &cli.StringSlice{
				"repo",
				"repo:status",
				"user:email",
				"read:org",
			},
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_USERNAME",
			Name:   "github-git-username",
			Usage:  "github machine user username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_PASSWORD",
			Name:   "github-git-password",
			Usage:  "github machine user password",
		},
		cli.BoolTFlag{
			EnvVar: "DRONE_GITHUB_MERGE_REF",
			Name:   "github-merge-ref",
			Usage:  "github pull requests use merge ref",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_PRIVATE_MODE",
			Name:   "github-private-mode",
			Usage:  "github is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_SKIP_VERIFY",
			Name:   "github-skip-verify",
			Usage:  "github skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS",
			Name:   "gogs",
			Usage:  "gogs driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_URL",
			Name:   "gogs-server",
			Usage:  "gogs server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_USERNAME",
			Name:   "gogs-git-username",
			Usage:  "gogs service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_PASSWORD",
			Name:   "gogs-git-password",
			Usage:  "gogs service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_PRIVATE_MODE",
			Name:   "gogs-private-mode",
			Usage:  "gogs private mode enabled",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_SKIP_VERIFY",
			Name:   "gogs-skip-verify",
			Usage:  "gogs skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BITBUCKET",
			Name:   "bitbucket",
			Usage:  "bitbucket driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_CLIENT",
			Name:   "bitbucket-client",
			Usage:  "bitbucket oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_SECRET",
			Name:   "bitbucket-secret",
			Usage:  "bitbucket oauth2 client secret",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB",
			Name:   "gitlab",
			Usage:  "gitlab driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_URL",
			Name:   "gitlab-server",
			Usage:  "gitlab server address",
			Value:  "https://gitlab.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_CLIENT",
			Name:   "gitlab-client",
			Usage:  "gitlab oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_SECRET",
			Name:   "gitlab-secret",
			Usage:  "gitlab oauth2 client secret",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_USERNAME",
			Name:   "gitlab-git-username",
			Usage:  "gitlab service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_PASSWORD",
			Name:   "gitlab-git-password",
			Usage:  "gitlab service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_SKIP_VERIFY",
			Name:   "gitlab-skip-verify",
			Usage:  "gitlab skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_PRIVATE_MODE",
			Name:   "gitlab-private-mode",
			Usage:  "gitlab is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH",
			Name:   "stash",
			Usage:  "stash driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_URL",
			Name:   "stash-server",
			Usage:  "stash server address",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_KEY",
			Name:   "stash-consumer-key",
			Usage:  "stash oauth1 consumer key",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_RSA",
			Name:   "stash-consumer-rsa",
			Usage:  "stash oauth1 private key file",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_USERNAME",
			Name:   "stash-git-username",
			Usage:  "stash service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_PASSWORD",
			Name:   "stash-git-password",
			Usage:  "stash service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH_SKIP_VERIFY",
			Name:   "stash-skip-verify",
			Usage:  "stash skip ssl verification",
		},
	},
}

func server(c *cli.Context) error {

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	// setup the server and start the listener
	handler := router.Load(
		ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
		middleware.Version,
		middleware.Config(c),
		middleware.Queue(c),
		middleware.Stream(c),
		middleware.Bus(c),
		middleware.Cache(c),
		middleware.Store(c),
		middleware.Remote(c),
		middleware.Agents(c),
	)

	// start the server with tls enabled
	if c.String("server-cert") != "" {
		return http.ListenAndServeTLS(
			c.String("server-addr"),
			c.String("server-cert"),
			c.String("server-key"),
			handler,
		)
	}

	// start the server without tls enabled
	return http.ListenAndServe(
		c.String("server-addr"),
		handler,
	)
}
<|endoftext|>