<commit_before>/*
Copyright 2014 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 persistentvolume

import (
	"fmt"
	"sort"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/client/cache"
	"k8s.io/kubernetes/pkg/labels"
)

// persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes
// indexed by AccessModes and ordered by storage capacity.
type persistentVolumeOrderedIndex struct {
	store cache.Indexer
}

func newPersistentVolumeOrderedIndex() persistentVolumeOrderedIndex {
	return persistentVolumeOrderedIndex{cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"accessmodes": accessModesIndexFunc})}
}

// accessModesIndexFunc is an indexing function that returns a persistent
// volume's AccessModes as a string
func accessModesIndexFunc(obj interface{}) ([]string, error) {
	if pv, ok := obj.(*api.PersistentVolume); ok {
		modes := api.GetAccessModesAsString(pv.Spec.AccessModes)
		return []string{modes}, nil
	}
	return []string{""}, fmt.Errorf("object is not a persistent volume: %v", obj)
}

// listByAccessModes returns all volumes with the given set of
// AccessModeTypes. The list is unsorted!
func (pvIndex *persistentVolumeOrderedIndex) listByAccessModes(modes []api.PersistentVolumeAccessMode) ([]*api.PersistentVolume, error) {
	pv := &api.PersistentVolume{
		Spec: api.PersistentVolumeSpec{
			AccessModes: modes,
		},
	}

	objs, err := pvIndex.store.Index("accessmodes", pv)
	if err != nil {
		return nil, err
	}

	volumes := make([]*api.PersistentVolume, len(objs))
	for i, obj := range objs {
		volumes[i] = obj.(*api.PersistentVolume)
	}

	return volumes, nil
}

// matchPredicate is a function that indicates that a persistent volume matches another
type matchPredicate func(compareThis, toThis *api.PersistentVolume) bool

// find returns the nearest PV from the ordered list or nil if a match is not found
func (pvIndex *persistentVolumeOrderedIndex) findByClaim(claim *api.PersistentVolumeClaim, matchPredicate matchPredicate) (*api.PersistentVolume, error) {
	// PVs are indexed by their access modes to allow easier searching.  Each
	// index is the string representation of a set of access modes. There is a
	// finite number of possible sets and PVs will only be indexed in one of
	// them (whichever index matches the PV's modes).
	//
	// A request for resources will always specify its desired access modes.
	// Any matching PV must have at least that number of access modes, but it
	// can have more.  For example, a user asks for ReadWriteOnce but a GCEPD
	// is available, which is ReadWriteOnce+ReadOnlyMany.
	//
	// Searches are performed against a set of access modes, so we can attempt
	// not only the exact matching modes but also potential matches (the GCEPD
	// example above).
	allPossibleModes := pvIndex.allPossibleMatchingAccessModes(claim.Spec.AccessModes)

	var smallestVolume *api.PersistentVolume
	var smallestVolumeSize int64
	requestedQty := claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)]
	requestedSize := requestedQty.Value()

	var selector labels.Selector
	if claim.Spec.Selector != nil {
		internalSelector, err := unversioned.LabelSelectorAsSelector(claim.Spec.Selector)
		if err != nil {
			// should be unreachable code due to validation
			return nil, fmt.Errorf("error creating internal label selector for claim: %v: %v", claimToClaimKey(claim), err)
		}
		selector = internalSelector
	}

	for _, modes := range allPossibleModes {
		volumes, err := pvIndex.listByAccessModes(modes)
		if err != nil {
			return nil, err
		}

		// Go through all available volumes with two goals:
		// - find a volume that is either pre-bound by user or dynamically
		//   provisioned for this claim. Because of this we need to loop through
		//   all volumes.
		// - find the smallest matching one if there is no volume pre-bound to
		//   the claim.
		for _, volume := range volumes {
			if isVolumeBoundToClaim(volume, claim) {
				// this claim and volume are bound; return it,
				// whether the claim is prebound or for volumes
				// intended for dynamic provisioning v1
				return volume, nil
			}

			// filter out:
			// - volumes bound to another claim
			// - volumes whose labels don't match the claim's selector, if specified
			if volume.Spec.ClaimRef != nil {
				continue
			} else if selector != nil && !selector.Matches(labels.Set(volume.Labels)) {
				continue
			}

			volumeQty := volume.Spec.Capacity[api.ResourceStorage]
			volumeSize := volumeQty.Value()
			if volumeSize >= requestedSize {
				if smallestVolume == nil || smallestVolumeSize > volumeSize {
					smallestVolume = volume
					smallestVolumeSize = volumeSize
				}
			}
		}

		// We want to provision volumes if the annotation is set even if there
		// is matching PV. Therefore, do not look for available PV and let
		// a new volume to be provisioned.
		//
		// When provisioner creates a new PV to this claim, an exact match
		// pre-bound to the claim will be found by the checks above during
		// subsequent claim sync.
		if hasAnnotation(claim.ObjectMeta, annClass) {
			return nil, nil
		}

		if smallestVolume != nil {
			// Found a matching volume
			return smallestVolume, nil
		}
	}
	return nil, nil
}

// findBestMatchForClaim is a convenience method that finds a volume by the claim's AccessModes and requests for Storage
func (pvIndex *persistentVolumeOrderedIndex) findBestMatchForClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolume, error) {
	return pvIndex.findByClaim(claim, matchStorageCapacity)
}

// matchStorageCapacity is a matchPredicate used to sort and find volumes
func matchStorageCapacity(pvA, pvB *api.PersistentVolume) bool {
	aQty := pvA.Spec.Capacity[api.ResourceStorage]
	bQty := pvB.Spec.Capacity[api.ResourceStorage]
	aSize := aQty.Value()
	bSize := bQty.Value()
	return aSize <= bSize
}

// allPossibleMatchingAccessModes returns an array of AccessMode arrays that
// can satisfy a user's requested modes.
//
// see comments in the Find func above regarding indexing.
//
// allPossibleMatchingAccessModes gets all stringified accessmodes from the
// index and returns all those that contain at least all of the requested
// mode.
//
// For example, assume the index contains 2 types of PVs where the stringified
// accessmodes are:
//
// "RWO,ROX" -- some number of GCEPDs
// "RWO,ROX,RWX" -- some number of NFS volumes
//
// A request for RWO could be satisfied by both sets of indexed volumes, so
// allPossibleMatchingAccessModes returns:
//
// [][]api.PersistentVolumeAccessMode {
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany,
//		},
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany,
//		},
// }
//
// A request for RWX can be satisfied by only one set of indexed volumes, so
// the return is:
//
// [][]api.PersistentVolumeAccessMode {
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany,
//		},
// }
//
// This func returns modes with ascending levels of modes to give the user
// what is closest to what they actually asked for.
func (pvIndex *persistentVolumeOrderedIndex) allPossibleMatchingAccessModes(requestedModes []api.PersistentVolumeAccessMode) [][]api.PersistentVolumeAccessMode {
	matchedModes := [][]api.PersistentVolumeAccessMode{}
	keys := pvIndex.store.ListIndexFuncValues("accessmodes")
	for _, key := range keys {
		indexedModes := api.GetAccessModesFromString(key)
		if containedInAll(indexedModes, requestedModes) {
			matchedModes = append(matchedModes, indexedModes)
		}
	}

	// sort by the number of modes in each array with the fewest number of
	// modes coming first. this allows searching for volumes by the minimum
	// number of modes required of the possible matches.
	sort.Sort(byAccessModes{matchedModes})
	return matchedModes
}

func contains(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool {
	for _, m := range modes {
		if m == mode {
			return true
		}
	}
	return false
}

func containedInAll(indexedModes []api.PersistentVolumeAccessMode, requestedModes []api.PersistentVolumeAccessMode) bool {
	for _, mode := range requestedModes {
		if !contains(indexedModes, mode) {
			return false
		}
	}
	return true
}

// byAccessModes is used to order access modes by size, with the fewest modes first
type byAccessModes struct {
	modes [][]api.PersistentVolumeAccessMode
}

func (c byAccessModes) Less(i, j int) bool {
	return len(c.modes[i]) < len(c.modes[j])
}

func (c byAccessModes) Swap(i, j int) {
	c.modes[i], c.modes[j] = c.modes[j], c.modes[i]
}

func (c byAccessModes) Len() int {
	return len(c.modes)
}

func claimToClaimKey(claim *api.PersistentVolumeClaim) string {
	return fmt.Sprintf("%s/%s", claim.Namespace, claim.Name)
}

func claimrefToClaimKey(claimref *api.ObjectReference) string {
	return fmt.Sprintf("%s/%s", claimref.Namespace, claimref.Name)
}
<commit_msg>Don't bind pre-bound pvc & pv if size request not satisfied<commit_after>/*
Copyright 2014 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 persistentvolume

import (
	"fmt"
	"sort"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/client/cache"
	"k8s.io/kubernetes/pkg/labels"
)

// persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes
// indexed by AccessModes and ordered by storage capacity.
type persistentVolumeOrderedIndex struct {
	store cache.Indexer
}

func newPersistentVolumeOrderedIndex() persistentVolumeOrderedIndex {
	return persistentVolumeOrderedIndex{cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"accessmodes": accessModesIndexFunc})}
}

// accessModesIndexFunc is an indexing function that returns a persistent
// volume's AccessModes as a string
func accessModesIndexFunc(obj interface{}) ([]string, error) {
	if pv, ok := obj.(*api.PersistentVolume); ok {
		modes := api.GetAccessModesAsString(pv.Spec.AccessModes)
		return []string{modes}, nil
	}
	return []string{""}, fmt.Errorf("object is not a persistent volume: %v", obj)
}

// listByAccessModes returns all volumes with the given set of
// AccessModeTypes. The list is unsorted!
func (pvIndex *persistentVolumeOrderedIndex) listByAccessModes(modes []api.PersistentVolumeAccessMode) ([]*api.PersistentVolume, error) {
	pv := &api.PersistentVolume{
		Spec: api.PersistentVolumeSpec{
			AccessModes: modes,
		},
	}

	objs, err := pvIndex.store.Index("accessmodes", pv)
	if err != nil {
		return nil, err
	}

	volumes := make([]*api.PersistentVolume, len(objs))
	for i, obj := range objs {
		volumes[i] = obj.(*api.PersistentVolume)
	}

	return volumes, nil
}

// matchPredicate is a function that indicates that a persistent volume matches another
type matchPredicate func(compareThis, toThis *api.PersistentVolume) bool

// find returns the nearest PV from the ordered list or nil if a match is not found
func (pvIndex *persistentVolumeOrderedIndex) findByClaim(claim *api.PersistentVolumeClaim, matchPredicate matchPredicate) (*api.PersistentVolume, error) {
	// PVs are indexed by their access modes to allow easier searching.  Each
	// index is the string representation of a set of access modes. There is a
	// finite number of possible sets and PVs will only be indexed in one of
	// them (whichever index matches the PV's modes).
	//
	// A request for resources will always specify its desired access modes.
	// Any matching PV must have at least that number of access modes, but it
	// can have more.  For example, a user asks for ReadWriteOnce but a GCEPD
	// is available, which is ReadWriteOnce+ReadOnlyMany.
	//
	// Searches are performed against a set of access modes, so we can attempt
	// not only the exact matching modes but also potential matches (the GCEPD
	// example above).
	allPossibleModes := pvIndex.allPossibleMatchingAccessModes(claim.Spec.AccessModes)

	var smallestVolume *api.PersistentVolume
	var smallestVolumeSize int64
	requestedQty := claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)]
	requestedSize := requestedQty.Value()

	var selector labels.Selector
	if claim.Spec.Selector != nil {
		internalSelector, err := unversioned.LabelSelectorAsSelector(claim.Spec.Selector)
		if err != nil {
			// should be unreachable code due to validation
			return nil, fmt.Errorf("error creating internal label selector for claim: %v: %v", claimToClaimKey(claim), err)
		}
		selector = internalSelector
	}

	for _, modes := range allPossibleModes {
		volumes, err := pvIndex.listByAccessModes(modes)
		if err != nil {
			return nil, err
		}

		// Go through all available volumes with two goals:
		// - find a volume that is either pre-bound by user or dynamically
		//   provisioned for this claim. Because of this we need to loop through
		//   all volumes.
		// - find the smallest matching one if there is no volume pre-bound to
		//   the claim.
		for _, volume := range volumes {
			if isVolumeBoundToClaim(volume, claim) {
				// this claim and volume are pre-bound; return
				// the volume if the size request is satisfied,
				// otherwise leave the claim pending
				volumeQty := volume.Spec.Capacity[api.ResourceStorage]
				volumeSize := volumeQty.Value()
				if volumeSize < requestedSize {
					return nil, nil
				}
				return volume, nil
			}

			// filter out:
			// - volumes bound to another claim
			// - volumes whose labels don't match the claim's selector, if specified
			if volume.Spec.ClaimRef != nil {
				continue
			} else if selector != nil && !selector.Matches(labels.Set(volume.Labels)) {
				continue
			}

			volumeQty := volume.Spec.Capacity[api.ResourceStorage]
			volumeSize := volumeQty.Value()
			if volumeSize >= requestedSize {
				if smallestVolume == nil || smallestVolumeSize > volumeSize {
					smallestVolume = volume
					smallestVolumeSize = volumeSize
				}
			}
		}

		// We want to provision volumes if the annotation is set even if there
		// is matching PV. Therefore, do not look for available PV and let
		// a new volume to be provisioned.
		//
		// When provisioner creates a new PV to this claim, an exact match
		// pre-bound to the claim will be found by the checks above during
		// subsequent claim sync.
		if hasAnnotation(claim.ObjectMeta, annClass) {
			return nil, nil
		}

		if smallestVolume != nil {
			// Found a matching volume
			return smallestVolume, nil
		}
	}
	return nil, nil
}

// findBestMatchForClaim is a convenience method that finds a volume by the claim's AccessModes and requests for Storage
func (pvIndex *persistentVolumeOrderedIndex) findBestMatchForClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolume, error) {
	return pvIndex.findByClaim(claim, matchStorageCapacity)
}

// matchStorageCapacity is a matchPredicate used to sort and find volumes
func matchStorageCapacity(pvA, pvB *api.PersistentVolume) bool {
	aQty := pvA.Spec.Capacity[api.ResourceStorage]
	bQty := pvB.Spec.Capacity[api.ResourceStorage]
	aSize := aQty.Value()
	bSize := bQty.Value()
	return aSize <= bSize
}

// allPossibleMatchingAccessModes returns an array of AccessMode arrays that
// can satisfy a user's requested modes.
//
// see comments in the Find func above regarding indexing.
//
// allPossibleMatchingAccessModes gets all stringified accessmodes from the
// index and returns all those that contain at least all of the requested
// mode.
//
// For example, assume the index contains 2 types of PVs where the stringified
// accessmodes are:
//
// "RWO,ROX" -- some number of GCEPDs
// "RWO,ROX,RWX" -- some number of NFS volumes
//
// A request for RWO could be satisfied by both sets of indexed volumes, so
// allPossibleMatchingAccessModes returns:
//
// [][]api.PersistentVolumeAccessMode {
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany,
//		},
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany,
//		},
// }
//
// A request for RWX can be satisfied by only one set of indexed volumes, so
// the return is:
//
// [][]api.PersistentVolumeAccessMode {
//      []api.PersistentVolumeAccessMode {
//			api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany,
//		},
// }
//
// This func returns modes with ascending levels of modes to give the user
// what is closest to what they actually asked for.
func (pvIndex *persistentVolumeOrderedIndex) allPossibleMatchingAccessModes(requestedModes []api.PersistentVolumeAccessMode) [][]api.PersistentVolumeAccessMode {
	matchedModes := [][]api.PersistentVolumeAccessMode{}
	keys := pvIndex.store.ListIndexFuncValues("accessmodes")
	for _, key := range keys {
		indexedModes := api.GetAccessModesFromString(key)
		if containedInAll(indexedModes, requestedModes) {
			matchedModes = append(matchedModes, indexedModes)
		}
	}

	// sort by the number of modes in each array with the fewest number of
	// modes coming first. this allows searching for volumes by the minimum
	// number of modes required of the possible matches.
	sort.Sort(byAccessModes{matchedModes})
	return matchedModes
}

func contains(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool {
	for _, m := range modes {
		if m == mode {
			return true
		}
	}
	return false
}

func containedInAll(indexedModes []api.PersistentVolumeAccessMode, requestedModes []api.PersistentVolumeAccessMode) bool {
	for _, mode := range requestedModes {
		if !contains(indexedModes, mode) {
			return false
		}
	}
	return true
}

// byAccessModes is used to order access modes by size, with the fewest modes first
type byAccessModes struct {
	modes [][]api.PersistentVolumeAccessMode
}

func (c byAccessModes) Less(i, j int) bool {
	return len(c.modes[i]) < len(c.modes[j])
}

func (c byAccessModes) Swap(i, j int) {
	c.modes[i], c.modes[j] = c.modes[j], c.modes[i]
}

func (c byAccessModes) Len() int {
	return len(c.modes)
}

func claimToClaimKey(claim *api.PersistentVolumeClaim) string {
	return fmt.Sprintf("%s/%s", claim.Namespace, claim.Name)
}

func claimrefToClaimKey(claimref *api.ObjectReference) string {
	return fmt.Sprintf("%s/%s", claimref.Namespace, claimref.Name)
}
<|endoftext|>


<commit_before>/*
Copyright 2018 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 nodeauthorizer

import (
	"errors"
	"fmt"
	"os"
	"time"

	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/pkg/model/components"
	"k8s.io/kops/upup/pkg/fi/loader"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// OptionsBuilder fills in the default options for the node-authorizer
type OptionsBuilder struct {
	Context *components.OptionsContext
}

var _ loader.OptionsBuilder = &OptionsBuilder{}

var (
	// DefaultPort is the default port to listen on
	DefaultPort = 10443
	// DefaultTimeout is the max time we are willing to wait before erroring
	DefaultTimeout = &metav1.Duration{Duration: 20 * time.Second}
	// DefaultTokenTTL is the default expiration on a bootstrap token
	DefaultTokenTTL = &metav1.Duration{Duration: 5 * time.Minute}
)

// BuildOptions generates the configurations used to create node authorizer
func (b *OptionsBuilder) BuildOptions(o interface{}) error {
	cs, ok := o.(*kops.ClusterSpec)
	if !ok {
		return errors.New("expected a ClusterSpec object")
	}

	if cs.NodeAuthorization != nil {
		na := cs.NodeAuthorization
		// NodeAuthorizerSpec
		if na.NodeAuthorizer != nil {
			if na.NodeAuthorizer.Authorizer == "" {
				switch kops.CloudProviderID(cs.CloudProvider) {
				case kops.CloudProviderAWS:
					na.NodeAuthorizer.Authorizer = "aws"
				default:
					na.NodeAuthorizer.Authorizer = "alwaysallow"
				}
			}
			if na.NodeAuthorizer.Image == "" {
				na.NodeAuthorizer.Image = GetNodeAuthorizerImage()
			}
			if na.NodeAuthorizer.Port == 0 {
				na.NodeAuthorizer.Port = DefaultPort
			}
			if na.NodeAuthorizer.Timeout == nil {
				na.NodeAuthorizer.Timeout = DefaultTimeout
			}
			if na.NodeAuthorizer.TokenTTL == nil {
				na.NodeAuthorizer.TokenTTL = DefaultTokenTTL
			}
			if na.NodeAuthorizer.NodeURL == "" {
				na.NodeAuthorizer.NodeURL = fmt.Sprintf("https://node-authorizer-internal.%s:%d", b.Context.ClusterName, na.NodeAuthorizer.Port)
			}
			if na.NodeAuthorizer.Features == nil {
				features := []string{"verify-registration", "verify-ip"}

				switch kops.CloudProviderID(cs.CloudProvider) {
				case kops.CloudProviderAWS:
					features = append(features, "verify-signature")
				}
				na.NodeAuthorizer.Features = &features
			}
		}
	}

	return nil
}

// GetNodeAuthorizerImage returns the image to use for the node-authorizer
func GetNodeAuthorizerImage() string {
	if v := os.Getenv("NODE_AUTHORIZER_IMAGE"); v != "" {
		return v
	}

	return "quay.io/gambol99/node-authorizer:v0.0.1@sha256:3ff243f5af76a73b6faaa6a0b0be8e3882dd1e7ffea6bacda9bede2273446059"
}
<commit_msg>- updating to the fix rollout image for node authorizer<commit_after>/*
Copyright 2018 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 nodeauthorizer

import (
	"errors"
	"fmt"
	"os"
	"time"

	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/pkg/model/components"
	"k8s.io/kops/upup/pkg/fi/loader"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// OptionsBuilder fills in the default options for the node-authorizer
type OptionsBuilder struct {
	Context *components.OptionsContext
}

var _ loader.OptionsBuilder = &OptionsBuilder{}

var (
	// DefaultPort is the default port to listen on
	DefaultPort = 10443
	// DefaultTimeout is the max time we are willing to wait before erroring
	DefaultTimeout = &metav1.Duration{Duration: 20 * time.Second}
	// DefaultTokenTTL is the default expiration on a bootstrap token
	DefaultTokenTTL = &metav1.Duration{Duration: 5 * time.Minute}
)

// BuildOptions generates the configurations used to create node authorizer
func (b *OptionsBuilder) BuildOptions(o interface{}) error {
	cs, ok := o.(*kops.ClusterSpec)
	if !ok {
		return errors.New("expected a ClusterSpec object")
	}

	if cs.NodeAuthorization != nil {
		na := cs.NodeAuthorization
		// NodeAuthorizerSpec
		if na.NodeAuthorizer != nil {
			if na.NodeAuthorizer.Authorizer == "" {
				switch kops.CloudProviderID(cs.CloudProvider) {
				case kops.CloudProviderAWS:
					na.NodeAuthorizer.Authorizer = "aws"
				default:
					na.NodeAuthorizer.Authorizer = "alwaysallow"
				}
			}
			if na.NodeAuthorizer.Image == "" {
				na.NodeAuthorizer.Image = GetNodeAuthorizerImage()
			}
			if na.NodeAuthorizer.Port == 0 {
				na.NodeAuthorizer.Port = DefaultPort
			}
			if na.NodeAuthorizer.Timeout == nil {
				na.NodeAuthorizer.Timeout = DefaultTimeout
			}
			if na.NodeAuthorizer.TokenTTL == nil {
				na.NodeAuthorizer.TokenTTL = DefaultTokenTTL
			}
			if na.NodeAuthorizer.NodeURL == "" {
				na.NodeAuthorizer.NodeURL = fmt.Sprintf("https://node-authorizer-internal.%s:%d", b.Context.ClusterName, na.NodeAuthorizer.Port)
			}
			if na.NodeAuthorizer.Features == nil {
				features := []string{"verify-registration", "verify-ip"}

				switch kops.CloudProviderID(cs.CloudProvider) {
				case kops.CloudProviderAWS:
					features = append(features, "verify-signature")
				}
				na.NodeAuthorizer.Features = &features
			}
		}
	}

	return nil
}

// GetNodeAuthorizerImage returns the image to use for the node-authorizer
func GetNodeAuthorizerImage() string {
	if v := os.Getenv("NODE_AUTHORIZER_IMAGE"); v != "" {
		return v
	}

	return "quay.io/gambol99/node-authorizer:v0.0.2@sha256:4a9f17072cb937ccbe3042add3e7da8152a7f35ffbdf8b96ae49306f6b59c080"
}
<|endoftext|>


<commit_before>package helpers

import (
	"taap_project/models"

	"database/sql"
	"github.com/go-gorp/gorp"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
)

var db *sql.DB
var dbmap *gorp.DbMap

func GetDatabase() *sql.DB {
	return db
}

func InitDatabase() {
	db, _ = sql.Open("mysql", "root:#54nFr4nc15c0@/taap")
	dbmap = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{}}

	dbmap.AddTable(models.Drill{}).SetKeys(false, "Title")
	dbmap.AddTable(models.User{}).SetKeys(false, "Number")
	dbmap.AddTable(models.SessionLog{}).SetKeys(false, "LogId")
}

func VerifyMySQLConnection(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	db, _ = sql.Open("mysql", "root:#54nFr4nc15c0@/taap")
	if err := db.Ping(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	next(w, r)
}
<commit_msg>added getter for gorpMap<commit_after>package helpers

import (
	"taap_project/models"

	"database/sql"
	"github.com/go-gorp/gorp"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
)

var db *sql.DB
var dbmap *gorp.DbMap

func GetDatabase() *sql.DB {
	return db
}

func GetGorpMap() *gorp.DbMap {
	return dbmap
}

func InitDatabase() {
	db, _ = sql.Open("mysql", "root:#54nFr4nc15c0@/taap")
	dbmap = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{}}

	dbmap.AddTable(models.Drill{}).SetKeys(false, "Title")
	dbmap.AddTable(models.User{}).SetKeys(false, "Number")
	dbmap.AddTable(models.SessionLog{}).SetKeys(false, "LogId")
}

func VerifyMySQLConnection(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	db, _ = sql.Open("mysql", "root:#54nFr4nc15c0@/taap")
	if err := db.Ping(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	next(w, r)
}
<|endoftext|>


<commit_before>package dev

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/control/app_control_launcher"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/recipe/rc_spec"
	"github.com/watermint/toolbox/infra/ui/app_msg"
	"github.com/watermint/toolbox/infra/ui/app_msg_container"
	"github.com/watermint/toolbox/quality/infra/qt_messages"
	"go.uber.org/zap"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strings"
)

type Preflight struct {
	TestMode bool
}

func (z *Preflight) Preset() {
	z.TestMode = false
}

func (z *Preflight) Test(c app_control.Control) error {
	z.TestMode = true
	return z.Exec(c)
}

func (z *Preflight) sortMessages(c app_control.Control, filename string) error {
	l := c.Log().With(zap.String("filename", filename))
	p := filepath.Join("resources", filename)
	content, err := ioutil.ReadFile(p)
	if err != nil {
		l.Warn("Unable to open resource file", zap.Error(err))
		return err
	}
	messages := make(map[string]string)
	if err = json.Unmarshal(content, &messages); err != nil {
		l.Warn("Unable to unmarshal message file", zap.Error(err))
		return err
	}
	buf := &bytes.Buffer{}
	je := json.NewEncoder(buf)
	je.SetEscapeHTML(false)
	je.SetIndent("", "  ")
	if err = je.Encode(messages); err != nil {
		l.Warn("Unable to create sorted image", zap.Error(err))
		return err
	}
	if err := ioutil.WriteFile(p, buf.Bytes(), 0644); err != nil {
		l.Warn("Unable to update message", zap.Error(err))
		return err
	}
	return nil
}

func (z *Preflight) Exec(c app_control.Control) error {
	l := c.Log()
	{
		l.Info("Generating English documents")
		err := rc_exec.Exec(c, &Doc{}, func(r rc_recipe.Recipe) {
			rr := r.(*Doc)
			rr.TestMode = z.TestMode
			rr.Badge = true
			rr.MarkdownReadme = true
			rr.Lang = "en"
			rr.Filename = "README.md"
			rr.CommandPath = "doc/generated/"
		})
		if err != nil {
			l.Error("Failed to generate documents", zap.Error(err))
			return err
		}
	}
	{
		l.Info("Generating Japanese documents")
		err := rc_exec.Exec(c, &Doc{}, func(r rc_recipe.Recipe) {
			rr := r.(*Doc)
			rr.TestMode = z.TestMode
			rr.Badge = true
			rr.MarkdownReadme = true
			rr.Lang = "ja"
			rr.Filename = "README_ja.md"
			rr.CommandPath = "doc/generated_ja/"
		})
		if err != nil {
			l.Error("Failed to generate documents", zap.Error(err))
			return err
		}
	}

	{
		cl := c.(app_control_launcher.ControlLauncher)
		cat := cl.Catalogue()
		l.Info("Verify recipes")
		for _, r := range cat.Recipes() {
			spec := rc_spec.New(r)
			for _, m := range spec.Messages() {
				l.Debug("message", zap.String("key", m.Key()), zap.String("text", c.UI().Text(m)))
			}
		}

		l.Info("Verify ingredients")
		for _, r := range cat.Ingredients() {
			spec := rc_spec.New(r)
			for _, m := range spec.Messages() {
				l.Debug("message", zap.String("key", m.Key()), zap.String("text", c.UI().Text(m)))
			}
		}

		l.Info("Verify message objects")
		for _, m := range cat.Messages() {
			msgs := app_msg.Messages(m)
			for _, msg := range msgs {
				l.Debug("message", zap.String("key", msg.Key()), zap.String("text", c.UI().Text(msg)))
			}
		}
	}

	l.Info("Sorting message resources")
	if err := z.sortMessages(c, "messages.json"); err != nil {
		return err
	}
	if err := z.sortMessages(c, "messages_ja.json"); err != nil {
		return err
	}

	l.Info("Verify message resources")
	qm := c.Messages().(app_msg_container.Quality)
	missing := qm.MissingKeys()
	if len(missing) > 0 {
		suggested := make([]string, 0)
		for _, k := range missing {
			l.Error("Key missing", zap.String("key", k))
			suggested = append(suggested, "\""+k+"\":\"\",")
		}
		sort.Strings(suggested)
		fmt.Println(strings.Join(suggested, "\n"))
	}

	return qt_messages.VerifyMessages(c)
}
<commit_msg>skip test for preflight<commit_after>package dev

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/control/app_control_launcher"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/recipe/rc_spec"
	"github.com/watermint/toolbox/infra/ui/app_msg"
	"github.com/watermint/toolbox/infra/ui/app_msg_container"
	"github.com/watermint/toolbox/quality/infra/qt_messages"
	"go.uber.org/zap"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strings"
)

type Preflight struct {
	TestMode bool
}

func (z *Preflight) Preset() {
	z.TestMode = false
}

func (z *Preflight) Test(c app_control.Control) error {
	z.TestMode = true
	return z.Exec(c)
}

func (z *Preflight) sortMessages(c app_control.Control, filename string) error {
	l := c.Log().With(zap.String("filename", filename))
	p := filepath.Join("resources", filename)
	content, err := ioutil.ReadFile(p)
	if err != nil {
		l.Info("SKIP: Unable to open resource file", zap.Error(err))
		return nil
	}
	messages := make(map[string]string)
	if err = json.Unmarshal(content, &messages); err != nil {
		l.Warn("Unable to unmarshal message file", zap.Error(err))
		return err
	}
	buf := &bytes.Buffer{}
	je := json.NewEncoder(buf)
	je.SetEscapeHTML(false)
	je.SetIndent("", "  ")
	if err = je.Encode(messages); err != nil {
		l.Warn("Unable to create sorted image", zap.Error(err))
		return err
	}
	if err := ioutil.WriteFile(p, buf.Bytes(), 0644); err != nil {
		l.Warn("Unable to update message", zap.Error(err))
		return err
	}
	return nil
}

func (z *Preflight) Exec(c app_control.Control) error {
	l := c.Log()
	{
		l.Info("Generating English documents")
		err := rc_exec.Exec(c, &Doc{}, func(r rc_recipe.Recipe) {
			rr := r.(*Doc)
			rr.TestMode = z.TestMode
			rr.Badge = true
			rr.MarkdownReadme = true
			rr.Lang = "en"
			rr.Filename = "README.md"
			rr.CommandPath = "doc/generated/"
		})
		if err != nil {
			l.Error("Failed to generate documents", zap.Error(err))
			return err
		}
	}
	{
		l.Info("Generating Japanese documents")
		err := rc_exec.Exec(c, &Doc{}, func(r rc_recipe.Recipe) {
			rr := r.(*Doc)
			rr.TestMode = z.TestMode
			rr.Badge = true
			rr.MarkdownReadme = true
			rr.Lang = "ja"
			rr.Filename = "README_ja.md"
			rr.CommandPath = "doc/generated_ja/"
		})
		if err != nil {
			l.Error("Failed to generate documents", zap.Error(err))
			return err
		}
	}

	{
		cl := c.(app_control_launcher.ControlLauncher)
		cat := cl.Catalogue()
		l.Info("Verify recipes")
		for _, r := range cat.Recipes() {
			spec := rc_spec.New(r)
			for _, m := range spec.Messages() {
				l.Debug("message", zap.String("key", m.Key()), zap.String("text", c.UI().Text(m)))
			}
		}

		l.Info("Verify ingredients")
		for _, r := range cat.Ingredients() {
			spec := rc_spec.New(r)
			for _, m := range spec.Messages() {
				l.Debug("message", zap.String("key", m.Key()), zap.String("text", c.UI().Text(m)))
			}
		}

		l.Info("Verify message objects")
		for _, m := range cat.Messages() {
			msgs := app_msg.Messages(m)
			for _, msg := range msgs {
				l.Debug("message", zap.String("key", msg.Key()), zap.String("text", c.UI().Text(msg)))
			}
		}
	}

	l.Info("Sorting message resources")
	if err := z.sortMessages(c, "messages.json"); err != nil {
		return err
	}
	if err := z.sortMessages(c, "messages_ja.json"); err != nil {
		return err
	}

	l.Info("Verify message resources")
	qm := c.Messages().(app_msg_container.Quality)
	missing := qm.MissingKeys()
	if len(missing) > 0 {
		suggested := make([]string, 0)
		for _, k := range missing {
			l.Error("Key missing", zap.String("key", k))
			suggested = append(suggested, "\""+k+"\":\"\",")
		}
		sort.Strings(suggested)
		fmt.Println(strings.Join(suggested, "\n"))
	}

	return qt_messages.VerifyMessages(c)
}
<|endoftext|>


<commit_before>// main.go
package main

func main() {
	start("192.168.1.1")
}
<commit_msg>add args<commit_after>// main.go
package main

import "os"

func main() {
	ipAddr := "*"
	if len(os.Args) >= 2 {
		ipAddr = os.Args[1]
	}
	start(ipAddr)
}
<|endoftext|>


<commit_before>package adler32_test

import (
	"hash"
	"hash/adler32"
	"strings"
	"testing"

	rollsum "gopkg.in/chmduquesne/rollinghash.v1/adler32"
)

// Stolen from hash/adler32
var golden = []struct {
	out uint32
	in  string
}{
	{0x00000001, ""},
	{0x00620062, "a"},
	{0x012600c4, "ab"},
	{0x024d0127, "abc"},
	{0x03d8018b, "abcd"},
	{0x05c801f0, "abcde"},
	{0x081e0256, "abcdef"},
	{0x0adb02bd, "abcdefg"},
	{0x0e000325, "abcdefgh"},
	{0x118e038e, "abcdefghi"},
	{0x158603f8, "abcdefghij"},
	{0x3f090f02, "Discard medicine more than two years old."},
	{0x46d81477, "He who has a shady past knows that nice guys finish last."},
	{0x40ee0ee1, "I wouldn't marry him with a ten foot pole."},
	{0x16661315, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
	{0x5b2e1480, "The days of the digital watch are numbered.  -Tom Stoppard"},
	{0x8c3c09ea, "Nepal premier won't resign."},
	{0x45ac18fd, "For every action there is an equal and opposite government program."},
	{0x53c61462, "His money is twice tainted: 'taint yours and 'taint mine."},
	{0x7e511e63, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
	{0xe4801a6a, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
	{0x61b507df, "size:  a.out:  bad magic"},
	{0xb8631171, "The major problem is with sendmail.  -Mark Horton"},
	{0x8b5e1904, "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
	{0x7cc6102b, "If the enemy is within range, then so are you."},
	{0x700318e7, "It's well we cannot hear the screams/That we create in others' dreams."},
	{0x1e601747, "You remind me of a TV show, but that's all right: I watch it anyway."},
	{0xb55b0b09, "C is as portable as Stonehedge!!"},
	{0x39111dd0, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
	{0x91dd304f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
	{0x2e5d1316, "How can you write a big system without C++?  -Paul Glick"},
	{0xd0201df6, "'Invariant assertions' is the most elegant programming technique!  -Tom Szymanski"},
	{0x211297c8, strings.Repeat("\xff", 5548) + "8"},
	{0xbaa198c8, strings.Repeat("\xff", 5549) + "9"},
	{0x553499be, strings.Repeat("\xff", 5550) + "0"},
	{0xf0c19abe, strings.Repeat("\xff", 5551) + "1"},
	{0x8d5c9bbe, strings.Repeat("\xff", 5552) + "2"},
	{0x2af69cbe, strings.Repeat("\xff", 5553) + "3"},
	{0xc9809dbe, strings.Repeat("\xff", 5554) + "4"},
	{0x69189ebe, strings.Repeat("\xff", 5555) + "5"},
	{0x86af0001, strings.Repeat("\x00", 1e5)},
	{0x79660b4d, strings.Repeat("a", 1e5)},
	{0x110588ee, strings.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1e4)},
}

// This is a no-op to prove that rollsum.Hash32 implements hash.Hash32
var _ = hash.Hash32(rollsum.New())

func TestGolden(t *testing.T) {
	for _, g := range golden {
		in := g.in

		// We test the vanilla implementation
		p := []byte(g.in)
		vanilla := adler32.New()
		vanilla.Write(p)
		if got := vanilla.Sum32(); got != g.out {
			t.Errorf("vanilla implentation: for %q, expected 0x%x, got 0x%x", in, g.out, got)
			continue
		}

		// We test the rolling implementation by prefixing the slice by a
		// space, writing it to our rolling hash, and then rolling once
		q := []byte(" ")
		q = append(q, p...)
		rolling := rollsum.New()
		rolling.Write(q[:len(q)-1])
		rolling.Roll(q[len(q)-1])
		if got := rolling.Sum32(); got != g.out {
			t.Errorf("rolling implentation: for %q, expected 0x%x, got 0x%x", in, g.out, got)
			continue
		}
	}
}

func TestUninitialized(t *testing.T) {
	s := []byte(data)
	hash := rollsum.New()
	err := hash.Roll(s[0])

	if err == nil {
		t.Fatal("Rolling with an uninitialized window should trigger an error")
	}
}

// Modified from hash/adler32
func BenchmarkVanillaKB(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 1024)
	for i := range window {
		window[i] = byte(i)
	}
	h := adler32.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Reset()
		h.Write(window)
		h.Sum(in)
	}
}

func BenchmarkRollingKB(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 1024)
	for i := range window {
		window[i] = byte(i)
	}

	h := rollsum.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	h.Write(window)
	for i := 0; i < b.N; i++ {
		h.Roll(byte(1024 + i))
		h.Sum(in)
	}
}

// A common use is to roll over a 128 bytes window
func BenchmarkVanilla128B(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 128)
	for i := range window {
		window[i] = byte(i)
	}
	h := adler32.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Reset()
		h.Write(window)
		h.Sum(in)
	}
}

func BenchmarkRolling128B(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 128)
	for i := range window {
		window[i] = byte(i)
	}

	h := rollsum.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	h.Write(window)
	for i := 0; i < b.N; i++ {
		h.Roll(byte(128 + i))
		h.Sum(in)
	}
}
<commit_msg>adding blackbox testing<commit_after>package adler32_test

import (
	"hash"
	"hash/adler32"
	"math/rand"
	"strings"
	"testing"

	rollsum "gopkg.in/chmduquesne/rollinghash.v1/adler32"
)

// Stolen from hash/adler32
var golden = []struct {
	out uint32
	in  string
}{
	{0x00000001, ""},
	{0x00620062, "a"},
	{0x012600c4, "ab"},
	{0x024d0127, "abc"},
	{0x03d8018b, "abcd"},
	{0x05c801f0, "abcde"},
	{0x081e0256, "abcdef"},
	{0x0adb02bd, "abcdefg"},
	{0x0e000325, "abcdefgh"},
	{0x118e038e, "abcdefghi"},
	{0x158603f8, "abcdefghij"},
	{0x3f090f02, "Discard medicine more than two years old."},
	{0x46d81477, "He who has a shady past knows that nice guys finish last."},
	{0x40ee0ee1, "I wouldn't marry him with a ten foot pole."},
	{0x16661315, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
	{0x5b2e1480, "The days of the digital watch are numbered.  -Tom Stoppard"},
	{0x8c3c09ea, "Nepal premier won't resign."},
	{0x45ac18fd, "For every action there is an equal and opposite government program."},
	{0x53c61462, "His money is twice tainted: 'taint yours and 'taint mine."},
	{0x7e511e63, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
	{0xe4801a6a, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
	{0x61b507df, "size:  a.out:  bad magic"},
	{0xb8631171, "The major problem is with sendmail.  -Mark Horton"},
	{0x8b5e1904, "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
	{0x7cc6102b, "If the enemy is within range, then so are you."},
	{0x700318e7, "It's well we cannot hear the screams/That we create in others' dreams."},
	{0x1e601747, "You remind me of a TV show, but that's all right: I watch it anyway."},
	{0xb55b0b09, "C is as portable as Stonehedge!!"},
	{0x39111dd0, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
	{0x91dd304f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
	{0x2e5d1316, "How can you write a big system without C++?  -Paul Glick"},
	{0xd0201df6, "'Invariant assertions' is the most elegant programming technique!  -Tom Szymanski"},
	{0x211297c8, strings.Repeat("\xff", 5548) + "8"},
	{0xbaa198c8, strings.Repeat("\xff", 5549) + "9"},
	{0x553499be, strings.Repeat("\xff", 5550) + "0"},
	{0xf0c19abe, strings.Repeat("\xff", 5551) + "1"},
	{0x8d5c9bbe, strings.Repeat("\xff", 5552) + "2"},
	{0x2af69cbe, strings.Repeat("\xff", 5553) + "3"},
	{0xc9809dbe, strings.Repeat("\xff", 5554) + "4"},
	{0x69189ebe, strings.Repeat("\xff", 5555) + "5"},
	{0x86af0001, strings.Repeat("\x00", 1e5)},
	{0x79660b4d, strings.Repeat("a", 1e5)},
	{0x110588ee, strings.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1e4)},
}

// This is a no-op to prove that rollsum.Hash32 implements hash.Hash32
var _ = hash.Hash32(rollsum.New())

func TestGolden(t *testing.T) {
	for _, g := range golden {
		in := g.in

		// We test the vanilla implementation
		p := []byte(g.in)
		vanilla := adler32.New()
		vanilla.Write(p)
		if got := vanilla.Sum32(); got != g.out {
			t.Errorf("vanilla implentation: for %q, expected 0x%x, got 0x%x", in, g.out, got)
			continue
		}

		// We test the rolling implementation by prefixing the slice by a
		// space, writing it to our rolling hash, and then rolling once
		q := []byte(" ")
		q = append(q, p...)
		rolling := rollsum.New()
		rolling.Write(q[:len(q)-1])
		rolling.Roll(q[len(q)-1])
		if got := rolling.Sum32(); got != g.out {
			t.Errorf("rolling implentation: for %q, expected 0x%x, got 0x%x", in, g.out, got)
			continue
		}
	}
}

func RandomBytes() (res []byte) {
	n := rand.Intn(8192)
	res = make([]byte, n)
	rand.Read(res)
	return res
}

func TestBlackBox(t *testing.T) {
	for i := 0; i < 100; i++ {
		in := RandomBytes()
		if len(in) > 0 {
			vanilla := adler32.New()
			vanilla.Write(in)
			q := []byte(" ")
			q = append(q, in...)
			roll := rollsum.New()
			roll.Write(q[:len(q)-1])
			roll.Roll(q[len(q)-1])
			if vanilla.Sum32() != roll.Sum32() {
				t.Errorf("Iteration %d: Different checksums between rolling and vanilla %d", i, len(in))
			}
		}
	}
}

func TestUninitialized(t *testing.T) {
	s := []byte(data)
	hash := rollsum.New()
	err := hash.Roll(s[0])

	if err == nil {
		t.Fatal("Rolling with an uninitialized window should trigger an error")
	}
}

// Modified from hash/adler32
func BenchmarkVanillaKB(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 1024)
	for i := range window {
		window[i] = byte(i)
	}
	h := adler32.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Reset()
		h.Write(window)
		h.Sum(in)
	}
}

func BenchmarkRollingKB(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 1024)
	for i := range window {
		window[i] = byte(i)
	}

	h := rollsum.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	h.Write(window)
	for i := 0; i < b.N; i++ {
		h.Roll(byte(1024 + i))
		h.Sum(in)
	}
}

// A common use is to roll over a 128 bytes window
func BenchmarkVanilla128B(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 128)
	for i := range window {
		window[i] = byte(i)
	}
	h := adler32.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Reset()
		h.Write(window)
		h.Sum(in)
	}
}

func BenchmarkRolling128B(b *testing.B) {
	b.SetBytes(1024)
	window := make([]byte, 128)
	for i := range window {
		window[i] = byte(i)
	}

	h := rollsum.New()
	in := make([]byte, 0, h.Size())

	b.ResetTimer()
	h.Write(window)
	for i := 0; i < b.N; i++ {
		h.Roll(byte(128 + i))
		h.Sum(in)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"golang.org/x/crypto/ssh"
)

type httpParams struct {
	bastionIP   string
	bastionUser string
	cmd         string
	key         string
	remoteUser  string
	userIP      string
}

func webHandler(w http.ResponseWriter, r *http.Request, conf *config) {
	// Do basic auth with the reverse proxy to prevent side-stepping it
	user, pass, ok := r.BasicAuth()
	if !ok {
		http.Error(w, "Authorization Failure", http.StatusUnauthorized)
		return
	}
	if user != conf.ProxyUser || pass != conf.ProxyPass {
		log.Printf("Invalid proxy credentials")
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Load our form parameters into a struct
	p := httpParams{
		bastionIP:   r.PostFormValue("bastionIP"),
		bastionUser: r.Header.Get(conf.UserHeader),
		cmd:         r.PostFormValue("cmd"),
		key:         r.PostFormValue("key"),
		remoteUser:  r.PostFormValue("remoteUser"), // FIXME this should be re-evaluated as a daemon config option
		userIP:      r.PostFormValue("userIP"),
	}

	// Set our certificate validity times
	va := time.Now()
	vb := time.Now().Add(conf.dur)

	// Generate a fingerprint of the received public key for our key_id string
	fp := ""
	pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(p.key))
	if err != nil {
		log.Printf("Unable to parse authorized key")
		http.Error(w, "Unable to parse authorized key", http.StatusUnprocessableEntity)
		return
	}
	fp = ssh.FingerprintLegacyMD5(pk)

	// Generate our key_id for the certificate
	//keyID := fmt.Sprintf("user[%s] from[%s] command[%s] sshKey[%s] ca[%s] valid to[%s]",
	keyID := fmt.Sprintf("user[%s] from[%s] command[%s] sshKey[%s] valid to[%s]",
		p.bastionUser, p.userIP, p.cmd, fp, vb.Format(time.RFC3339))

	// Log the request
	log.Printf("Request: |%s|", keyID)

	// Make sure we have everything we need from our parameters
	err = validateHTTPParams(p, conf)
	if err != nil {
		errMsg := fmt.Sprintf("Param validation failure: %v", err)
		log.Printf(errMsg)
		http.Error(w, errMsg, http.StatusUnprocessableEntity)
		return
	}

	// Check if we've seen this pubkey before and if it's too old
	expired, err := checkPubKeyAge(conf, fp)
	if expired {
		http.Error(w, "Submitted pubkey is too old. Please generate new key.", http.StatusForbidden)
		return
	}

	// Set all of our certificate options
	cc := certConfig{
		certType:    ssh.UserCert,
		command:     p.cmd,
		extensions:  conf.exts,
		keyID:       keyID,
		principals:  []string{p.remoteUser},
		srcAddr:     p.bastionIP,
		validAfter:  va,
		validBefore: vb,
	}

	// Sign the public key
	key, err := signPubKey(conf.caSigner, []byte(p.key), cc)
	if err != nil {
		log.Printf("%v", err)
		http.Error(w, "Server error", http.StatusInternalServerError)
		return
	}

	w.Write(ssh.MarshalAuthorizedKey(key))
}

func validateHTTPParams(p httpParams, conf *config) error {
	if conf.ForceCmd && p.cmd == "" {
		err := fmt.Errorf("cmd missing from request")
		return err
	}
	if p.bastionIP == "" || !validIP(p.bastionIP) {
		err := fmt.Errorf("bastionIP is invalid")
		return err
	}
	if p.bastionUser == "" {
		err := fmt.Errorf("%s missing from request", conf.UserHeader)
		return err
	} else if len(p.bastionUser) > 32 || !conf.userRegex.MatchString(p.bastionUser) {
		err := fmt.Errorf("username is invalid")
		return err
	}
	if p.key == "" {
		err := fmt.Errorf("key missing from request")
		return err
	}
	if p.remoteUser == "" {
		err := fmt.Errorf("remoteUser missing from request")
		return err
	}
	if conf.RequireClientIP && !validIP(p.userIP) {
		err := fmt.Errorf("invalid userIP")
		log.Printf("invalid userIP: |%s|", p.userIP) // FIXME This should be re-evaluated in the logging refactor
		return err
	}

	return nil
}
<commit_msg>Reworked HTTP response codes<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"golang.org/x/crypto/ssh"
)

type httpParams struct {
	bastionIP   string
	bastionUser string
	cmd         string
	key         string
	remoteUser  string
	userIP      string
}

func webHandler(w http.ResponseWriter, r *http.Request, conf *config) {
	// Do basic auth with the reverse proxy to prevent side-stepping it
	user, pass, ok := r.BasicAuth()
	if !ok {
		http.Error(w, "Authorization Failure", http.StatusUnauthorized)
		return
	}
	if user != conf.ProxyUser || pass != conf.ProxyPass {
		log.Printf("Invalid proxy credentials")
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Load our form parameters into a struct
	p := httpParams{
		bastionIP:   r.PostFormValue("bastionIP"),
		bastionUser: r.Header.Get(conf.UserHeader),
		cmd:         r.PostFormValue("cmd"),
		key:         r.PostFormValue("key"),
		remoteUser:  r.PostFormValue("remoteUser"), // FIXME this should be re-evaluated as a daemon config option
		userIP:      r.PostFormValue("userIP"),
	}

	// Set our certificate validity times
	va := time.Now()
	vb := time.Now().Add(conf.dur)

	// Generate a fingerprint of the received public key for our key_id string
	fp := ""
	pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(p.key))
	if err != nil {
		log.Printf("Unable to parse authorized key")
		http.Error(w, "Unable to parse authorized key", http.StatusBadRequest)
		return
	}
	fp = ssh.FingerprintLegacyMD5(pk)

	// Generate our key_id for the certificate
	//keyID := fmt.Sprintf("user[%s] from[%s] command[%s] sshKey[%s] ca[%s] valid to[%s]",
	keyID := fmt.Sprintf("user[%s] from[%s] command[%s] sshKey[%s] valid to[%s]",
		p.bastionUser, p.userIP, p.cmd, fp, vb.Format(time.RFC3339))

	// Log the request
	log.Printf("Request: |%s|", keyID)

	// Make sure we have everything we need from our parameters
	err = validateHTTPParams(p, conf)
	if err != nil {
		errMsg := fmt.Sprintf("Param validation failure: %v", err)
		log.Printf(errMsg)
		http.Error(w, errMsg, http.StatusBadRequest)
		return
	}

	// Check if we've seen this pubkey before and if it's too old
	expired, err := checkPubKeyAge(conf, fp)
	if expired {
		http.Error(w, "Submitted pubkey is too old. Please generate new key.", http.StatusUnprocessableEntity)
		return
	}

	// Set all of our certificate options
	cc := certConfig{
		certType:    ssh.UserCert,
		command:     p.cmd,
		extensions:  conf.exts,
		keyID:       keyID,
		principals:  []string{p.remoteUser},
		srcAddr:     p.bastionIP,
		validAfter:  va,
		validBefore: vb,
	}

	// Sign the public key
	key, err := signPubKey(conf.caSigner, []byte(p.key), cc)
	if err != nil {
		log.Printf("%v", err)
		http.Error(w, "Server error", http.StatusInternalServerError)
		return
	}

	w.Write(ssh.MarshalAuthorizedKey(key))
}

func validateHTTPParams(p httpParams, conf *config) error {
	if conf.ForceCmd && p.cmd == "" {
		err := fmt.Errorf("cmd missing from request")
		return err
	}
	if p.bastionIP == "" || !validIP(p.bastionIP) {
		err := fmt.Errorf("bastionIP is invalid")
		return err
	}
	if p.bastionUser == "" {
		err := fmt.Errorf("%s missing from request", conf.UserHeader)
		return err
	} else if len(p.bastionUser) > 32 || !conf.userRegex.MatchString(p.bastionUser) {
		err := fmt.Errorf("username is invalid")
		return err
	}
	if p.key == "" {
		err := fmt.Errorf("key missing from request")
		return err
	}
	if p.remoteUser == "" {
		err := fmt.Errorf("remoteUser missing from request")
		return err
	}
	if conf.RequireClientIP && !validIP(p.userIP) {
		err := fmt.Errorf("invalid userIP")
		log.Printf("invalid userIP: |%s|", p.userIP) // FIXME This should be re-evaluated in the logging refactor
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package httpd

/*
A Controller maps a REST endpoint to an
endpoint handler (processor)

handlers take the form

  handlerXXX(req httpd.RestAPI, params httpd.ParamMap) httpd.APIResponse

*/
import (
	"fmt"

	"regexp"
	"strings"
)

var (
	parmPtrn = regexp.MustCompile(`^\{(.+)\}$`)
)

const (
	pathSep = "/"
)

// ParamMap URI Path Parameter Map
type ParamMap map[string]string

// RestEndpoint function signature for API handlers
type RestEndpoint func(req RestAPI, params ParamMap) (resp APIResponse)

// EndpointSpec method and path for endpoint
type EndpointSpec struct {
	Method string
	Path   []string
}

// EndpointMap maps endpoint URI to handler
type EndpointMap struct {
	Endpoint  EndpointSpec
	Processor RestEndpoint
}

/*
NewEndpointMap is a convenience constructor for mapping endpoints
*/
func NewEndpointMap(path string, method string, proc RestEndpoint) *EndpointMap {
	em := EndpointMap{Endpoint: EndpointSpec{Method: method, Path: strings.Split(path, "/")}, Processor: proc}

	return &em
}

// IController The Controller interface spec
type IController interface {
	Route(params RestAPI) APIResponse
	SetupRouting(endpoints []EndpointMap) error
	Routes() []EndpointMap
}

/*
A Controller maps one or more REST endpoints to their assigned
endpoint handlers (processors)

handlers take the form

  handlerXXX(req httpd.RestAPI, params httpd.ParamMap) httpd.APIResponse

*/
type Controller struct {

	// the map of endpoints to methods
	// common to all controllers
	emp []EndpointMap
}

// Route direct request to correct processor
func (ctlr *Controller) Route(apiParams RestAPI) (resp APIResponse) {

	// test for match
	if params, proc := ctlr.URIMatch(apiParams.URI, apiParams.Method); proc != nil {
		// found one, call it...
		resp = proc(apiParams, params)

	} else {
		// not found...
		resp = APIResponse{}
		resp.Code = 404

		resp.Message = fmt.Sprintf("Path not found %s", apiParams.URL)
		resp.Body = "{\"Error\": \"No endpoint found\"}"
	}

	// return results
	return resp
}

// SetupRouting isntall controllers enpoint route mappings
func (ctlr *Controller) SetupRouting(endpoints []EndpointMap) (err error) {
	// save to internal map
	ctlr.emp = endpoints

	return err
}

// Routes reflect routing maps
func (ctlr Controller) Routes() (emp []EndpointMap) {
	// return mappings
	return emp
}

// URIMatch tries to identify a processor given an array of URI nodes
func (ctlr Controller) URIMatch(uri []string, method string) (params map[string]string, processor RestEndpoint) {

	// check all endpoints for matching
	for tst := range ctlr.emp {
		var match bool

		ep := ctlr.emp[tst].Endpoint

		// method testing first...
		if !strings.EqualFold(method, ep.Method) {
			continue
		}
		// create a fresh param map
		pps := make(map[string]string)

		// fetch the stored path segments
		tendpt := ctlr.emp[tst].Endpoint

		// size match first
		if match = (len(tendpt.Path) == len(uri)); match {
			// segment by segment testing
			for seg := range uri {
				// check for param delimiters in endpts
				ptst := parmPtrn.FindStringSubmatch(tendpt.Path[seg])
				if len(ptst) > 0 {
					// found, create path param (implied match)
					pps[ptst[len(ptst)-1]] = uri[seg]
				} else {
					// not found, test path walk
					if !strings.EqualFold(uri[seg], tendpt.Path[seg]) {
						// not a match
						match = false
						break
					}
				}
			}
		}

		// check results
		if match {
			// winner winner chicken dinner!
			params = pps
			processor = ctlr.emp[tst].Processor
			break
		}
	}

	// and the results are....
	return params, processor
}

// Response conveniece response enerator
func (ctlr Controller) Response(code int, message string, body string) (resp APIResponse) {
	resp.Code = code
	resp.Message = message
	resp.Body = body

	return resp
}

// APIError conveniece error enerator
func (ctlr Controller) APIError(code int, err error) APIResponse {
	return ctlr.Response(code, err.Error(), "")
}
<commit_msg>fixing it up<commit_after>package httpd

/*
A Controller maps a REST endpoint to an
endpoint handler (processor)

handlers take the form

  handlerXXX(req httpd.RestAPI, params httpd.ParamMap) httpd.APIResponse

*/
import (
	"fmt"

	"regexp"
	"strings"
)

var (
	parmPtrn = regexp.MustCompile(`^\{(.+)\}$`)
)

const (
	pathSep = "/"
)

// ParamMap URI Path Parameter Map
type ParamMap map[string]string

// RestEndpoint function signature for API handlers
type RestEndpoint func(req RestAPI, params ParamMap) (resp APIResponse)

// EndpointSpec method and path for endpoint
type EndpointSpec struct {
	Method string
	Path   []string
}

// EndpointMap maps endpoint URI to handler
type EndpointMap struct {
	Endpoint  EndpointSpec
	Processor RestEndpoint
}

/*
NewEndpointMap is a convenience constructor for mapping endpoints
*/
func NewEndpointMap(path string, method string, proc RestEndpoint) *EndpointMap {
	em := EndpointMap{Endpoint: EndpointSpec{Method: method, Path: strings.Split(path, "/")}, Processor: proc}

	return &em
}

// IController The Controller interface spec
type IController interface {
	Route(params RestAPI) APIResponse
	SetupRouting(endpoints []EndpointMap) error
	Routes() []EndpointMap
}

/*
A Controller maps one or more REST endpoints to their assigned
endpoint handlers (processors)

handlers take the form

  handlerXXX(req httpd.RestAPI, params httpd.ParamMap) httpd.APIResponse

*/
type Controller struct {

	// the map of endpoints to methods
	// common to all controllers
	emp []EndpointMap
}

// Route direct request to correct processor
func (ctlr *Controller) Route(apiParams RestAPI) (resp APIResponse) {
	fmt.Println(apiParams)
	// test for match
	if params, proc := ctlr.URIMatch(apiParams.URI, apiParams.Method); proc != nil {
		// found one, call it...
		resp = proc(apiParams, params)

	} else {
		// not found...
		resp = APIResponse{}
		resp.Code = 404

		resp.Message = fmt.Sprintf("Path not found %s", apiParams.URL)
		resp.Body = "{\"Error\": \"No endpoint found\"}"
	}

	// return results
	return resp
}

// SetupRouting isntall controllers enpoint route mappings
func (ctlr *Controller) SetupRouting(endpoints []EndpointMap) (err error) {
	// save to internal map
	ctlr.emp = endpoints

	return err
}

// Routes reflect routing maps
func (ctlr Controller) Routes() (emp []EndpointMap) {
	// return mappings
	return ctlr.emp
}

// URIMatch tries to identify a processor given an array of URI nodes
func (ctlr Controller) URIMatch(uri []string, method string) (params map[string]string, processor RestEndpoint) {

	// check all endpoints for matching
	for tst := range ctlr.emp {
		var match bool

		ep := ctlr.emp[tst].Endpoint

		// method testing first...
		if !strings.EqualFold(method, ep.Method) {
			continue
		}
		// create a fresh param map
		pps := make(map[string]string)

		// fetch the stored path segments
		tendpt := ctlr.emp[tst].Endpoint

		// size match first
		if match = (len(tendpt.Path) == len(uri)); match {
			// segment by segment testing
			for seg := range uri {
				// check for param delimiters in endpts
				ptst := parmPtrn.FindStringSubmatch(tendpt.Path[seg])
				if len(ptst) > 0 {
					// found, create path param (implied match)
					pps[ptst[len(ptst)-1]] = uri[seg]
				} else {
					// not found, test path walk
					if !strings.EqualFold(uri[seg], tendpt.Path[seg]) {
						// not a match
						match = false
						break
					}
				}
			}
		}

		// check results
		if match {
			// winner winner chicken dinner!
			params = pps
			processor = ctlr.emp[tst].Processor
			break
		}
	}

	// and the results are....
	return params, processor
}

// Response conveniece response enerator
func (ctlr Controller) Response(code int, message string, body string) (resp APIResponse) {
	resp.Code = code
	resp.Message = message
	resp.Body = body

	return resp
}

// APIError conveniece error enerator
func (ctlr Controller) APIError(code int, err error) APIResponse {
	return ctlr.Response(code, err.Error(), "")
}
<|endoftext|>


<commit_before>/*
Copyright 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.
*/

// Code generated by informer-gen. DO NOT EDIT.

package v1alpha1

import (
	time "time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	watch "k8s.io/apimachinery/pkg/watch"
	cache "k8s.io/client-go/tools/cache"
	samplecontroller_v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
	versioned "k8s.io/sample-controller/pkg/client/clientset/versioned"
	internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
	v1alpha1 "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1"
)

// FooInformer provides access to a shared informer and lister for
// Foos.
type FooInformer interface {
	Informer() cache.SharedIndexInformer
	Lister() v1alpha1.FooLister
}

type fooInformer struct {
	factory          internalinterfaces.SharedInformerFactory
	tweakListOptions internalinterfaces.TweakListOptionsFunc
	namespace        string
}

// NewFooInformer constructs a new informer for Foo type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFooInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
	return NewFilteredFooInformer(client, namespace, resyncPeriod, indexers, nil)
}

// NewFilteredFooInformer constructs a new informer for Foo type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredFooInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
	return cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
				if tweakListOptions != nil {
					tweakListOptions(&options)
				}
				return client.SamplecontrollerV1alpha1().Foos(namespace).List(options)
			},
			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
				if tweakListOptions != nil {
					tweakListOptions(&options)
				}
				return client.SamplecontrollerV1alpha1().Foos(namespace).Watch(options)
			},
		},
		&samplecontroller_v1alpha1.Foo{},
		resyncPeriod,
		indexers,
	)
}

func (f *fooInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
	return NewFilteredFooInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}

func (f *fooInformer) Informer() cache.SharedIndexInformer {
	return f.factory.InformerFor(&samplecontroller_v1alpha1.Foo{}, f.defaultInformer)
}

func (f *fooInformer) Lister() v1alpha1.FooLister {
	return v1alpha1.NewFooLister(f.Informer().GetIndexer())
}
<commit_msg>Update generated files<commit_after>/*
Copyright 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.
*/

// Code generated by informer-gen. DO NOT EDIT.

package v1alpha1

import (
	time "time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	watch "k8s.io/apimachinery/pkg/watch"
	cache "k8s.io/client-go/tools/cache"
	samplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
	versioned "k8s.io/sample-controller/pkg/client/clientset/versioned"
	internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
	v1alpha1 "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1"
)

// FooInformer provides access to a shared informer and lister for
// Foos.
type FooInformer interface {
	Informer() cache.SharedIndexInformer
	Lister() v1alpha1.FooLister
}

type fooInformer struct {
	factory          internalinterfaces.SharedInformerFactory
	tweakListOptions internalinterfaces.TweakListOptionsFunc
	namespace        string
}

// NewFooInformer constructs a new informer for Foo type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFooInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
	return NewFilteredFooInformer(client, namespace, resyncPeriod, indexers, nil)
}

// NewFilteredFooInformer constructs a new informer for Foo type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredFooInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
	return cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
				if tweakListOptions != nil {
					tweakListOptions(&options)
				}
				return client.SamplecontrollerV1alpha1().Foos(namespace).List(options)
			},
			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
				if tweakListOptions != nil {
					tweakListOptions(&options)
				}
				return client.SamplecontrollerV1alpha1().Foos(namespace).Watch(options)
			},
		},
		&samplecontrollerv1alpha1.Foo{},
		resyncPeriod,
		indexers,
	)
}

func (f *fooInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
	return NewFilteredFooInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}

func (f *fooInformer) Informer() cache.SharedIndexInformer {
	return f.factory.InformerFor(&samplecontrollerv1alpha1.Foo{}, f.defaultInformer)
}

func (f *fooInformer) Lister() v1alpha1.FooLister {
	return v1alpha1.NewFooLister(f.Informer().GetIndexer())
}
<|endoftext|>


<commit_before>/*
 * Minimalist Object Storage, (C) 2015 Minio, Inc.
 *
 * 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 memory

import (
	"sync"
	"time"
)

var zeroExpiration = time.Duration(0)

// Intelligent holds the required variables to compose an in memory cache system
// which also provides expiring key mechanism and also maxSize
type Intelligent struct {
	// Mutex is used for handling the concurrent
	// read/write requests for cache
	sync.Mutex

	// items hold the cached objects
	items map[string]interface{}

	// createdAt holds the time that related item's created At
	createdAt map[string]time.Time

	// expiration is a duration for a cache key to expire
	expiration time.Duration

	// gcInterval is a duration for garbage collection
	gcInterval time.Duration

	// maxSize is a total size for overall cache
	maxSize uint64

	// currentSize is a current size in memory
	currentSize uint64

	// OnEvicted - callback function for eviction
	OnEvicted func(a ...interface{})

	// totalEvicted counter to keep track of total evictions
	totalEvicted uint64
}

// Stats current cache statistics
type Stats struct {
	Bytes     uint64
	Items     uint64
	Evictions uint64
}

// NewIntelligent creates an inmemory cache
//
// maxSize is used for expiring objects before we run out of memory
// expiration is used for expiration of a key from cache
func NewIntelligent(maxSize uint64, expiration time.Duration) *Intelligent {
	return &Intelligent{
		items:      map[string]interface{}{},
		createdAt:  map[string]time.Time{},
		expiration: expiration,
		maxSize:    maxSize,
	}
}

// Stats get current cache statistics
func (r *Intelligent) Stats() Stats {
	return Stats{
		Bytes:     r.currentSize,
		Items:     uint64(len(r.items)),
		Evictions: r.totalEvicted,
	}
}

// ExpireObjects expire objects in go routine
func (r *Intelligent) ExpireObjects(gcInterval time.Duration) {
	r.gcInterval = gcInterval
	go func() {
		for range time.Tick(gcInterval) {
			for key := range r.items {
				r.Lock()
				if !r.isValid(key) {
					r.Delete(key)
				}
				r.Unlock()
			}
		}
	}()
}

// Get returns a value of a given key if it exists
func (r *Intelligent) Get(key string) (interface{}, bool) {
	r.Lock()
	defer r.Unlock()
	value, ok := r.items[key]
	return value, ok
}

// Set will persist a value to the cache
func (r *Intelligent) Set(key string, value interface{}) {
	r.Lock()
	// remove random key if only we reach the maxSize threshold,
	// if not assume infinite memory
	if r.maxSize > 0 {
		for key := range r.items {
			for (r.currentSize + uint64(len(value.([]byte)))) > r.maxSize {
				r.Delete(key)
			}
			break
		}
	}
	r.items[key] = value
	r.currentSize += uint64(len(value.([]byte)))
	r.createdAt[key] = time.Now()
	r.Unlock()
	return
}

// Delete deletes a given key if exists
func (r *Intelligent) Delete(key string) {
	r.currentSize -= uint64(len(r.items[key].([]byte)))
	delete(r.items, key)
	delete(r.createdAt, key)
	r.totalEvicted++
	if r.OnEvicted != nil {
		r.OnEvicted(key)
	}
}

func (r *Intelligent) isValid(key string) bool {
	createdAt, ok := r.createdAt[key]
	if !ok {
		return false
	}
	if r.expiration == zeroExpiration {
		return true
	}
	return createdAt.Add(r.expiration).After(time.Now())
}
<commit_msg>Fix a potential race between ExpireObjects() and Set() over items map<commit_after>/*
 * Minimalist Object Storage, (C) 2015 Minio, Inc.
 *
 * 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 memory

import (
	"sync"
	"time"
)

var zeroExpiration = time.Duration(0)

// Intelligent holds the required variables to compose an in memory cache system
// which also provides expiring key mechanism and also maxSize
type Intelligent struct {
	// Mutex is used for handling the concurrent
	// read/write requests for cache
	sync.Mutex

	// items hold the cached objects
	items map[string]interface{}

	// createdAt holds the time that related item's created At
	createdAt map[string]time.Time

	// expiration is a duration for a cache key to expire
	expiration time.Duration

	// gcInterval is a duration for garbage collection
	gcInterval time.Duration

	// maxSize is a total size for overall cache
	maxSize uint64

	// currentSize is a current size in memory
	currentSize uint64

	// OnEvicted - callback function for eviction
	OnEvicted func(a ...interface{})

	// totalEvicted counter to keep track of total evictions
	totalEvicted uint64
}

// Stats current cache statistics
type Stats struct {
	Bytes     uint64
	Items     uint64
	Evictions uint64
}

// NewIntelligent creates an inmemory cache
//
// maxSize is used for expiring objects before we run out of memory
// expiration is used for expiration of a key from cache
func NewIntelligent(maxSize uint64, expiration time.Duration) *Intelligent {
	return &Intelligent{
		items:      map[string]interface{}{},
		createdAt:  map[string]time.Time{},
		expiration: expiration,
		maxSize:    maxSize,
	}
}

// Stats get current cache statistics
func (r *Intelligent) Stats() Stats {
	return Stats{
		Bytes:     r.currentSize,
		Items:     uint64(len(r.items)),
		Evictions: r.totalEvicted,
	}
}

// ExpireObjects expire objects in go routine
func (r *Intelligent) ExpireObjects(gcInterval time.Duration) {
	r.gcInterval = gcInterval
	go func() {
		for range time.Tick(gcInterval) {
			r.Lock()
			for key := range r.items {

				if !r.isValid(key) {
					r.Delete(key)
				}
			}
			r.Unlock()
		}
	}()
}

// Get returns a value of a given key if it exists
func (r *Intelligent) Get(key string) (interface{}, bool) {
	r.Lock()
	defer r.Unlock()
	value, ok := r.items[key]
	return value, ok
}

// Set will persist a value to the cache
func (r *Intelligent) Set(key string, value interface{}) {
	r.Lock()
	// remove random key if only we reach the maxSize threshold,
	// if not assume infinite memory
	if r.maxSize > 0 {
		for key := range r.items {
			for (r.currentSize + uint64(len(value.([]byte)))) > r.maxSize {
				r.Delete(key)
			}
			break
		}
	}
	r.items[key] = value
	r.currentSize += uint64(len(value.([]byte)))
	r.createdAt[key] = time.Now()
	r.Unlock()
	return
}

// Delete deletes a given key if exists
func (r *Intelligent) Delete(key string) {
	r.currentSize -= uint64(len(r.items[key].([]byte)))
	delete(r.items, key)
	delete(r.createdAt, key)
	r.totalEvicted++
	if r.OnEvicted != nil {
		r.OnEvicted(key)
	}
}

func (r *Intelligent) isValid(key string) bool {
	createdAt, ok := r.createdAt[key]
	if !ok {
		return false
	}
	if r.expiration == zeroExpiration {
		return true
	}
	return createdAt.Add(r.expiration).After(time.Now())
}
<|endoftext|>


<commit_before>package download

import (
	"errors"
	"log"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/vcs"
)

// Download takes a user-provided string that represents a remote
// Go repository, and attempts to download it in a way similar to go get.
// It is forgiving in terms of the exact path given: the path may have
// a scheme or username, which will be trimmed.
func Download(path, dest string) (root *vcs.RepoRoot, err error) {
	return download(path, dest, true)
}

func download(path, dest string, firstAttempt bool) (root *vcs.RepoRoot, err error) {
	vcs.ShowCmd = true

	path, err = Clean(path)
	if err != nil {
		return root, err
	}

	root, err = vcs.RepoRootForImportPath(path, true)
	if err != nil {
		return root, err
	}

	localDirPath := filepath.Join(dest, root.Root, "..")

	err = os.MkdirAll(localDirPath, 0777)
	if err != nil {
		return root, err
	}

	fullLocalPath := filepath.Join(dest, root.Root)
	ex, err := exists(fullLocalPath)
	if err != nil {
		return root, err
	}
	if ex {
		log.Println("Update", root.Repo)
		err = root.VCS.Download(fullLocalPath)
		if err != nil && firstAttempt {
			// may have been rebased; we delete the directory, then try one more time:
			log.Printf("Failed to download %q (%v), trying again...", root.Repo, err.Error())
			err = os.Remove(fullLocalPath)
			return download(path, dest, false)
		} else if err != nil {
			return root, err
		}
	} else {
		log.Println("Create", root.Repo)

		err = root.VCS.Create(fullLocalPath, root.Repo)
		if err != nil {
			return root, err
		}
	}
	err = root.VCS.TagSync(fullLocalPath, "")
	if err != nil && firstAttempt {
		// may have been rebased; we delete the directory, then try one more time:
		log.Printf("Failed to update %q (%v), trying again...", root.Repo, err.Error())
		err = os.Remove(fullLocalPath)
		return download(path, dest, false)
	}
	return root, err
}

// Clean trims any URL parts, like the scheme or username, that might be present
// in a user-submitted URL
func Clean(path string) (string, error) {
	importPath := trimUsername(trimScheme(path))
	root, err := vcs.RepoRootForImportPath(importPath, true)
	if err != nil {
		return "", err
	}
	if root != nil && (root.Root == "" || root.Repo == "") {
		return root.Root, errors.New("empty repo root")
	}
	return root.Root, err
}

// trimScheme removes a scheme (e.g. https://) from the URL for more
// convenient pasting from browsers.
func trimScheme(repo string) string {
	schemeSep := "://"
	schemeSepIdx := strings.Index(repo, schemeSep)
	if schemeSepIdx > -1 {
		return repo[schemeSepIdx+len(schemeSep):]
	}

	return repo
}

// trimUsername removes the username for a URL, if it is present
func trimUsername(repo string) string {
	usernameSep := "@"
	usernameSepIdx := strings.Index(repo, usernameSep)
	if usernameSepIdx > -1 {
		return repo[usernameSepIdx+len(usernameSep):]
	}

	return repo
}

// exists returns whether the given file or directory exists or not
// from http://stackoverflow.com/a/10510783
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}
<commit_msg>Closes #151. Use RemoveAll instead of Remove<commit_after>package download

import (
	"errors"
	"log"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/vcs"
)

// Download takes a user-provided string that represents a remote
// Go repository, and attempts to download it in a way similar to go get.
// It is forgiving in terms of the exact path given: the path may have
// a scheme or username, which will be trimmed.
func Download(path, dest string) (root *vcs.RepoRoot, err error) {
	return download(path, dest, true)
}

func download(path, dest string, firstAttempt bool) (root *vcs.RepoRoot, err error) {
	vcs.ShowCmd = true

	path, err = Clean(path)
	if err != nil {
		return root, err
	}

	root, err = vcs.RepoRootForImportPath(path, true)
	if err != nil {
		return root, err
	}

	localDirPath := filepath.Join(dest, root.Root, "..")

	err = os.MkdirAll(localDirPath, 0777)
	if err != nil {
		return root, err
	}

	fullLocalPath := filepath.Join(dest, root.Root)
	ex, err := exists(fullLocalPath)
	if err != nil {
		return root, err
	}
	if ex {
		log.Println("Update", root.Repo)
		err = root.VCS.Download(fullLocalPath)
		if err != nil && firstAttempt {
			// may have been rebased; we delete the directory, then try one more time:
			log.Printf("Failed to download %q (%v), trying again...", root.Repo, err.Error())
			err = os.RemoveAll(fullLocalPath)
			if err != nil {
				log.Println("Failed to delete path:", fullLocalPath, err)
			}
			return download(path, dest, false)
		} else if err != nil {
			return root, err
		}
	} else {
		log.Println("Create", root.Repo)

		err = root.VCS.Create(fullLocalPath, root.Repo)
		if err != nil {
			return root, err
		}
	}
	err = root.VCS.TagSync(fullLocalPath, "")
	if err != nil && firstAttempt {
		// may have been rebased; we delete the directory, then try one more time:
		log.Printf("Failed to update %q (%v), trying again...", root.Repo, err.Error())
		err = os.RemoveAll(fullLocalPath)
		return download(path, dest, false)
	}
	return root, err
}

// Clean trims any URL parts, like the scheme or username, that might be present
// in a user-submitted URL
func Clean(path string) (string, error) {
	importPath := trimUsername(trimScheme(path))
	root, err := vcs.RepoRootForImportPath(importPath, true)
	if err != nil {
		return "", err
	}
	if root != nil && (root.Root == "" || root.Repo == "") {
		return root.Root, errors.New("empty repo root")
	}
	return root.Root, err
}

// trimScheme removes a scheme (e.g. https://) from the URL for more
// convenient pasting from browsers.
func trimScheme(repo string) string {
	schemeSep := "://"
	schemeSepIdx := strings.Index(repo, schemeSep)
	if schemeSepIdx > -1 {
		return repo[schemeSepIdx+len(schemeSep):]
	}

	return repo
}

// trimUsername removes the username for a URL, if it is present
func trimUsername(repo string) string {
	usernameSep := "@"
	usernameSepIdx := strings.Index(repo, usernameSep)
	if usernameSepIdx > -1 {
		return repo[usernameSepIdx+len(usernameSep):]
	}

	return repo
}

// exists returns whether the given file or directory exists or not
// from http://stackoverflow.com/a/10510783
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}
<|endoftext|>


<commit_before>package filters

import (
	"encoding/json"
	"encoding/xml"
	"github.com/gophergala/yaag/middleware"
	"github.com/revel/revel"
	"log"
	"net/http/httptest"
	"strings"
	"yaag/yaag"
)

func FilterForApiDoc(c *revel.Controller, fc []revel.Filter) {
	if record, _ := revel.Config.Bool("yaag.record"); !record {
		log.Printf("record %v ", record)
		fc[0](c, fc[1:])
		return
	}

	w := httptest.NewRecorder()
	c.Response = revel.NewResponse(w)
	httpVerb := c.Request.Method
	customParams := make(map[string]interface{})
	headers := make(map[string]string)
	hasJson := false
	hasXml := false

	body := middleware.ReadBody(c.Request.Request)
	log.Println(*body)

	if c.Request.ContentType == "application/json" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := json.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		} else {
			err := json.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		}

	} else if c.Request.ContentType == "application/xml" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := xml.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Xml Error ! ", err)
			} else {
				hasXml = true
			}
		} else {
			err := xml.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasXml = true
			}
		}
	}
	log.Println(hasXml, hasJson)
	// call remaiing filters
	fc[0](c, fc[1:])

	c.Result.Apply(c.Request, c.Response)
	htmlValues := yaag.APICall{}
	htmlValues.CommonRequestHeaders = make(map[string]string)
	// get headers
	for k, v := range c.Request.Header {
		isCommon := false
		for _, hk := range yaag.CommonHeaders {
			if k == hk {
				isCommon = true
				htmlValues.CommonRequestHeaders[k] = strings.Join(v, " ")
				break
			}
		}
		if !isCommon {
			headers[k] = strings.Join(v, " ")
		}
	}

	htmlValues.MethodType = httpVerb
	htmlValues.CurrentPath = c.Request.URL.Path
	htmlValues.PostForm = make(map[string]string)
	for k, v := range c.Params.Form {
		htmlValues.PostForm[k] = strings.Join(v, " ")
	}
	htmlValues.RequestBody = *body
	htmlValues.RequestHeader = headers
	htmlValues.RequestUrlParams = make(map[string]string)
	for k, v := range c.Request.URL.Query() {
		htmlValues.RequestUrlParams[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseHeader = make(map[string]string)
	htmlValues.ResponseBody = w.Body.String()
	for k, v := range w.Header() {
		htmlValues.ResponseHeader[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseCode = w.Code

	yaag.ApiCallValueInstance.BaseLink = c.Request.Host

	go yaag.GenerateHtml(&htmlValues)
}
<commit_msg>set proper import paths<commit_after>package filters

import (
	"encoding/json"
	"encoding/xml"
	"github.com/gophergala/yaag/middleware"
	"github.com/gophergala/yaag/yaag"
	"github.com/revel/revel"
	"log"
	"net/http/httptest"
	"strings"
)

func FilterForApiDoc(c *revel.Controller, fc []revel.Filter) {
	if record, _ := revel.Config.Bool("yaag.record"); !record {
		log.Printf("record %v ", record)
		fc[0](c, fc[1:])
		return
	}

	w := httptest.NewRecorder()
	c.Response = revel.NewResponse(w)
	httpVerb := c.Request.Method
	customParams := make(map[string]interface{})
	headers := make(map[string]string)
	hasJson := false
	hasXml := false

	body := middleware.ReadBody(c.Request.Request)
	log.Println(*body)

	if c.Request.ContentType == "application/json" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := json.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		} else {
			err := json.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		}

	} else if c.Request.ContentType == "application/xml" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := xml.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Xml Error ! ", err)
			} else {
				hasXml = true
			}
		} else {
			err := xml.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasXml = true
			}
		}
	}
	log.Println(hasXml, hasJson)
	// call remaiing filters
	fc[0](c, fc[1:])

	c.Result.Apply(c.Request, c.Response)
	htmlValues := yaag.APICall{}
	htmlValues.CommonRequestHeaders = make(map[string]string)
	// get headers
	for k, v := range c.Request.Header {
		isCommon := false
		for _, hk := range yaag.CommonHeaders {
			if k == hk {
				isCommon = true
				htmlValues.CommonRequestHeaders[k] = strings.Join(v, " ")
				break
			}
		}
		if !isCommon {
			headers[k] = strings.Join(v, " ")
		}
	}

	htmlValues.MethodType = httpVerb
	htmlValues.CurrentPath = c.Request.URL.Path
	htmlValues.PostForm = make(map[string]string)
	for k, v := range c.Params.Form {
		htmlValues.PostForm[k] = strings.Join(v, " ")
	}
	htmlValues.RequestBody = *body
	htmlValues.RequestHeader = headers
	htmlValues.RequestUrlParams = make(map[string]string)
	for k, v := range c.Request.URL.Query() {
		htmlValues.RequestUrlParams[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseHeader = make(map[string]string)
	htmlValues.ResponseBody = w.Body.String()
	for k, v := range w.Header() {
		htmlValues.ResponseHeader[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseCode = w.Code

	yaag.ApiCallValueInstance.BaseLink = c.Request.Host

	go yaag.GenerateHtml(&htmlValues)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/rglog/level"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type parameters struct {
	// 画面表示ログ。
	consLv level.Level

	// 追加ログ種別。
	logType string
	// 追加ログ表示重要度。
	logLv level.Level
	// ログファイルパス。
	logPath string
	// fluentd アドレス。
	fluAddr string
	// fluentd 用タグ。
	fluTag string

	// 秘密鍵置き場。
	priKeyContType string
	// ファイルベース秘密鍵置き場。
	priKeyContPath string

	// ソケット種別。
	socType string
	// UNIX ソケット。
	socPath string
	// TCP ソケット。
	socPort int

	// プロトコル種別。
	protType string

	// キャッシュを最新とみなす期間。
	caStaleDur time.Duration
	// キャッシュを廃棄するまでの期間。
	caExpiDur time.Duration

	// 称する TA の ID。
	taId string

	// 署名に使うハッシュ関数。
	hashName string

	// 有効期限ギリギリのセッションを避けるための遊び。
	sessMargin time.Duration

	// 同一ホスト用の http.Client の保持期間。
	cliExpiDur time.Duration

	// セッションを事前に検査するボディサイズの下限。
	threSize int

	// SSL 証明書を検証しない。
	noVerify bool
}

func parseParameters(args ...string) (param *parameters, err error) {

	const label = "edo-access-proxy"

	flags := util.NewFlagSet(label+" parameters", flag.ExitOnError)
	flags.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage:")
		fmt.Fprintln(os.Stderr, "  "+args[0]+" [{FLAG}...]")
		fmt.Fprintln(os.Stderr, "FLAG:")
		flags.PrintDefaults()
	}

	param = &parameters{}

	flags.Var(level.Var(&param.consLv, level.INFO), "consLv", "Console log level.")
	flags.StringVar(&param.logType, "logType", "", "Extra log type.")
	flags.Var(level.Var(&param.logLv, level.ALL), "logLv", "Extra log level.")
	flags.StringVar(&param.logPath, "logPath", filepath.Join(filepath.Dir(os.Args[0]), "log", label+".log"), "File log path.")
	flags.StringVar(&param.fluAddr, "fluAddr", "localhost:24224", "fluentd address.")
	flags.StringVar(&param.fluTag, "fluTag", "edo."+label, "fluentd tag.")

	flags.StringVar(&param.priKeyContType, "priKeyContType", "file", "Private key container type.")
	flags.StringVar(&param.priKeyContPath, "priKeyContPath", filepath.Join(filepath.Dir(os.Args[0]), "private_keys"), "Private key container directory.")

	flags.StringVar(&param.socType, "socType", "tcp", "Socket type.")
	flags.StringVar(&param.socPath, "socPath", filepath.Join(filepath.Dir(os.Args[0]), "run", label+".soc"), "UNIX socket path.")
	flags.IntVar(&param.socPort, "socPort", 16051, "TCP socket port.")
	flags.StringVar(&param.protType, "protType", "http", "Protocol type.")

	flags.DurationVar(&param.caStaleDur, "caStaleDur", 5*time.Minute, "Cache fresh duration.")
	flags.DurationVar(&param.caExpiDur, "caExpiDur", 30*time.Minute, "Cache expiration duration.")

	flags.StringVar(&param.taId, "taId", "", "Default TA ID.")
	flags.StringVar(&param.hashName, "hashName", "sha256", "Sign hash type.")

	flags.DurationVar(&param.sessMargin, "sessMargin", time.Minute, "Margin for session expiration duration.")
	flags.DurationVar(&param.cliExpiDur, "cliExpiDur", 10*time.Minute, "Client expiration duration.")
	flags.IntVar(&param.threSize, "threSize", 8192, "Maximum byte size of request body for skipping session check.")
	flags.BoolVar(&param.noVerify, "noVerify", false, "Skipping SSL verification.")

	var config string
	flags.StringVar(&config, "f", "", "Config file path.")

	// 実行引数を読んで、設定ファイルを指定させてから、
	// 設定ファイルを読んで、また実行引数を読む。
	flags.Parse(args[1:])
	if config != "" {
		if buff, err := ioutil.ReadFile(config); err != nil {
			if !os.IsNotExist(err) {
				return nil, erro.Wrap(err)
			}
			log.Warn("Config file " + config + " is not exist.")
		} else {
			flags.CompleteParse(strings.Fields(string(buff)))
		}
	}
	flags.Parse(args[1:])

	if l := len(flags.Args()); l > 0 {
		log.Warn("Ignore extra parameters ", flags.Args(), ".")
	}

	return param, nil
}
<commit_msg>デフォルトポートを変更<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/rglog/level"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type parameters struct {
	// 画面表示ログ。
	consLv level.Level

	// 追加ログ種別。
	logType string
	// 追加ログ表示重要度。
	logLv level.Level
	// ログファイルパス。
	logPath string
	// fluentd アドレス。
	fluAddr string
	// fluentd 用タグ。
	fluTag string

	// 秘密鍵置き場。
	priKeyContType string
	// ファイルベース秘密鍵置き場。
	priKeyContPath string

	// ソケット種別。
	socType string
	// UNIX ソケット。
	socPath string
	// TCP ソケット。
	socPort int

	// プロトコル種別。
	protType string

	// キャッシュを最新とみなす期間。
	caStaleDur time.Duration
	// キャッシュを廃棄するまでの期間。
	caExpiDur time.Duration

	// 称する TA の ID。
	taId string

	// 署名に使うハッシュ関数。
	hashName string

	// 有効期限ギリギリのセッションを避けるための遊び。
	sessMargin time.Duration

	// 同一ホスト用の http.Client の保持期間。
	cliExpiDur time.Duration

	// セッションを事前に検査するボディサイズの下限。
	threSize int

	// SSL 証明書を検証しない。
	noVerify bool
}

func parseParameters(args ...string) (param *parameters, err error) {

	const label = "edo-access-proxy"

	flags := util.NewFlagSet(label+" parameters", flag.ExitOnError)
	flags.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage:")
		fmt.Fprintln(os.Stderr, "  "+args[0]+" [{FLAG}...]")
		fmt.Fprintln(os.Stderr, "FLAG:")
		flags.PrintDefaults()
	}

	param = &parameters{}

	flags.Var(level.Var(&param.consLv, level.INFO), "consLv", "Console log level.")
	flags.StringVar(&param.logType, "logType", "", "Extra log type.")
	flags.Var(level.Var(&param.logLv, level.ALL), "logLv", "Extra log level.")
	flags.StringVar(&param.logPath, "logPath", filepath.Join(filepath.Dir(os.Args[0]), "log", label+".log"), "File log path.")
	flags.StringVar(&param.fluAddr, "fluAddr", "localhost:24224", "fluentd address.")
	flags.StringVar(&param.fluTag, "fluTag", "edo."+label, "fluentd tag.")

	flags.StringVar(&param.priKeyContType, "priKeyContType", "file", "Private key container type.")
	flags.StringVar(&param.priKeyContPath, "priKeyContPath", filepath.Join(filepath.Dir(os.Args[0]), "private_keys"), "Private key container directory.")

	flags.StringVar(&param.socType, "socType", "tcp", "Socket type.")
	flags.StringVar(&param.socPath, "socPath", filepath.Join(filepath.Dir(os.Args[0]), "run", label+".soc"), "UNIX socket path.")
	flags.IntVar(&param.socPort, "socPort", 16050, "TCP socket port.")
	flags.StringVar(&param.protType, "protType", "http", "Protocol type.")

	flags.DurationVar(&param.caStaleDur, "caStaleDur", 5*time.Minute, "Cache fresh duration.")
	flags.DurationVar(&param.caExpiDur, "caExpiDur", 30*time.Minute, "Cache expiration duration.")

	flags.StringVar(&param.taId, "taId", "", "Default TA ID.")
	flags.StringVar(&param.hashName, "hashName", "sha256", "Sign hash type.")

	flags.DurationVar(&param.sessMargin, "sessMargin", time.Minute, "Margin for session expiration duration.")
	flags.DurationVar(&param.cliExpiDur, "cliExpiDur", 10*time.Minute, "Client expiration duration.")
	flags.IntVar(&param.threSize, "threSize", 8192, "Maximum byte size of request body for skipping session check.")
	flags.BoolVar(&param.noVerify, "noVerify", false, "Skipping SSL verification.")

	var config string
	flags.StringVar(&config, "f", "", "Config file path.")

	// 実行引数を読んで、設定ファイルを指定させてから、
	// 設定ファイルを読んで、また実行引数を読む。
	flags.Parse(args[1:])
	if config != "" {
		if buff, err := ioutil.ReadFile(config); err != nil {
			if !os.IsNotExist(err) {
				return nil, erro.Wrap(err)
			}
			log.Warn("Config file " + config + " is not exist.")
		} else {
			flags.CompleteParse(strings.Fields(string(buff)))
		}
	}
	flags.Parse(args[1:])

	if l := len(flags.Args()); l > 0 {
		log.Warn("Ignore extra parameters ", flags.Args(), ".")
	}

	return param, nil
}
<|endoftext|>