<commit_before>package oauth

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

type Consumer struct {
	Key              string
	Secret           string
	Service          string
	RequestTokenURL  string
	AccessTokenURL   string
	AuthorizationURL string
	CallbackURL      string
}

func (c *Consumer) defaultParameters() url.Values {
	values := make(url.Values)
	values.Add("oauth_version", "1.0")
	values.Add("oauth_timestamp", strconv.FormatInt(time.Now().Unix(), 10))
	values.Add("oauth_consumer_key", c.Key)
	values.Add("oauth_nonce", strconv.FormatInt(rand.Int63(), 10))
	values.Add("oauth_signature_method", "HMAC-SHA1")
	return values
}

func (c *Consumer) sign(method string, url string, values url.Values, secret string) string {
	base := fmt.Sprintf("%s&%s&%s", method, encode(url), encodePlusEncoded(values.Encode()))
	key := encode(c.Secret) + "&" + encode(secret)
	return c.digest(key, base)
}

// digest generates a HMAC-SHA1 signature with the given key and data.
func (c *Consumer) digest(key string, data string) string {
	h := hmac.New(sha1.New, []byte(key))
	// TODO: Check for errors here?
	io.WriteString(h, data)
	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func (c *Consumer) headers(method string, url string, values url.Values, secret string) map[string]string {
	signature := c.sign(method, url, values, secret)
	var headers []string
	for k, v := range values {
		if strings.HasPrefix(k, "oauth") {
			headers = append(headers, encodeQuoted(k, v[0]))
			values.Del(k)
		}
	}
	headers = append(headers, encodeQuoted("oauth_signature", signature))
	sort.Strings(headers)
	return map[string]string{
		"Authorization": "OAuth " + strings.Join(headers, ", "),
	}
}

// Authorization requests a Request Token and returns the URL the user should
// visit to authorize it as well as the token, which needs to be used later
// for exchanging it for an Access Token.
func (c *Consumer) Authorization() (string, *Token, error) {
	values := c.defaultParameters()
	values.Add("oauth_callback", c.CallbackURL)
	headers := c.headers("POST", c.RequestTokenURL, values, "")
	fmt.Println(headers, c.RequestTokenURL)
	resp, err := sendReq("POST", c.RequestTokenURL, headers, values)
	if err != nil {
		return "", nil, err
	}
	token, err := parseToken(resp)
	if err != nil {
		return "", nil, err
	}
	return c.AuthorizationURL + "?oauth_token=" + token.Key, token, nil
}

// Exchange exchanges a Request Token for an Access Token using the given
// verifier. The verifier is sent by the provider to the consumer at the
// callback URL. If the provider you're using doesn't require a verifier, just
// pass an empty string.
func (c *Consumer) Exchange(token *Token, verifier string) (*Token, error) {
	p := c.defaultParameters()
	p.Add("oauth_token", token.Key)
	if verifier != "" {
		p.Add("oauth_verifier", verifier)
	}
	headers := c.headers("POST", c.AccessTokenURL, p, token.Secret)
	resp, err := sendReq("POST", c.AccessTokenURL, headers, nil)
	if err != nil {
		return nil, err
	}
	return parseToken(resp)
}

// Get performs a GET request to the given URL with the given values and
// signed with the consumer and the given token (if any). The url parameter
// can't contain a query string. All url parameters should be passed using
// the values parameter.
func (c *Consumer) Get(url string, values url.Values, token *Token) (*http.Response, error) {
	return c.SendRequest("GET", url, values, token)
}

// Post performs a POST request to the given URL with the given values and
// signed with the given token (if any).
func (c *Consumer) Post(url string, values url.Values, token *Token) (*http.Response, error) {
	return c.SendRequest("POST", url, values, token)
}

// Request returns a *http.Request with the given method, url and values, which is already
// signed using the given token (if any).
func (c *Consumer) Request(method string, url string, values url.Values, token *Token) (*http.Request, error) {
	vals := c.defaultParameters()
	for k, v := range values {
		vals[k] = append(vals[k], v...)
	}
	vals.Add("oauth_token", token.Key)
	var secret string
	if token != nil {
		secret = token.Secret
	}
	headers := c.headers(method, url, vals, secret)
	return req(method, url, headers, vals)
}

// SendRequest works like Requests, but it also sends the request and
// returns an *http.Response.
func (c *Consumer) SendRequest(method string, url string, values url.Values, token *Token) (*http.Response, error) {
	r, err := c.Request(method, url, values, token)
	if err != nil {
		return nil, err
	}
	return client.Do(r)
}
<commit_msg>Remove debug print stmt<commit_after>package oauth

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

type Consumer struct {
	Key              string
	Secret           string
	Service          string
	RequestTokenURL  string
	AccessTokenURL   string
	AuthorizationURL string
	CallbackURL      string
}

func (c *Consumer) defaultParameters() url.Values {
	values := make(url.Values)
	values.Add("oauth_version", "1.0")
	values.Add("oauth_timestamp", strconv.FormatInt(time.Now().Unix(), 10))
	values.Add("oauth_consumer_key", c.Key)
	values.Add("oauth_nonce", strconv.FormatInt(rand.Int63(), 10))
	values.Add("oauth_signature_method", "HMAC-SHA1")
	return values
}

func (c *Consumer) sign(method string, url string, values url.Values, secret string) string {
	base := fmt.Sprintf("%s&%s&%s", method, encode(url), encodePlusEncoded(values.Encode()))
	key := encode(c.Secret) + "&" + encode(secret)
	return c.digest(key, base)
}

// digest generates a HMAC-SHA1 signature with the given key and data.
func (c *Consumer) digest(key string, data string) string {
	h := hmac.New(sha1.New, []byte(key))
	// TODO: Check for errors here?
	io.WriteString(h, data)
	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func (c *Consumer) headers(method string, url string, values url.Values, secret string) map[string]string {
	signature := c.sign(method, url, values, secret)
	var headers []string
	for k, v := range values {
		if strings.HasPrefix(k, "oauth") {
			headers = append(headers, encodeQuoted(k, v[0]))
			values.Del(k)
		}
	}
	headers = append(headers, encodeQuoted("oauth_signature", signature))
	sort.Strings(headers)
	return map[string]string{
		"Authorization": "OAuth " + strings.Join(headers, ", "),
	}
}

// Authorization requests a Request Token and returns the URL the user should
// visit to authorize it as well as the token, which needs to be used later
// for exchanging it for an Access Token.
func (c *Consumer) Authorization() (string, *Token, error) {
	values := c.defaultParameters()
	values.Add("oauth_callback", c.CallbackURL)
	headers := c.headers("POST", c.RequestTokenURL, values, "")
	resp, err := sendReq("POST", c.RequestTokenURL, headers, values)
	if err != nil {
		return "", nil, err
	}
	token, err := parseToken(resp)
	if err != nil {
		return "", nil, err
	}
	return c.AuthorizationURL + "?oauth_token=" + token.Key, token, nil
}

// Exchange exchanges a Request Token for an Access Token using the given
// verifier. The verifier is sent by the provider to the consumer at the
// callback URL. If the provider you're using doesn't require a verifier, just
// pass an empty string.
func (c *Consumer) Exchange(token *Token, verifier string) (*Token, error) {
	p := c.defaultParameters()
	p.Add("oauth_token", token.Key)
	if verifier != "" {
		p.Add("oauth_verifier", verifier)
	}
	headers := c.headers("POST", c.AccessTokenURL, p, token.Secret)
	resp, err := sendReq("POST", c.AccessTokenURL, headers, nil)
	if err != nil {
		return nil, err
	}
	return parseToken(resp)
}

// Get performs a GET request to the given URL with the given values and
// signed with the consumer and the given token (if any). The url parameter
// can't contain a query string. All url parameters should be passed using
// the values parameter.
func (c *Consumer) Get(url string, values url.Values, token *Token) (*http.Response, error) {
	return c.SendRequest("GET", url, values, token)
}

// Post performs a POST request to the given URL with the given values and
// signed with the given token (if any).
func (c *Consumer) Post(url string, values url.Values, token *Token) (*http.Response, error) {
	return c.SendRequest("POST", url, values, token)
}

// Request returns a *http.Request with the given method, url and values, which is already
// signed using the given token (if any).
func (c *Consumer) Request(method string, url string, values url.Values, token *Token) (*http.Request, error) {
	vals := c.defaultParameters()
	for k, v := range values {
		vals[k] = append(vals[k], v...)
	}
	vals.Add("oauth_token", token.Key)
	var secret string
	if token != nil {
		secret = token.Secret
	}
	headers := c.headers(method, url, vals, secret)
	return req(method, url, headers, vals)
}

// SendRequest works like Requests, but it also sends the request and
// returns an *http.Response.
func (c *Consumer) SendRequest(method string, url string, values url.Values, token *Token) (*http.Response, error) {
	r, err := c.Request(method, url, values, token)
	if err != nil {
		return nil, err
	}
	return client.Do(r)
}
<|endoftext|>


<commit_before>package providers

import (
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/kolo/xmlrpc"
)

func init() {
	db := GetSubtitleDB()
	db.addSource(openSubtitlesProvider{
		UserAgent: "periscope",
		Server:    "http://api.opensubtitles.org/xml-rpc",
	})
}

type openSubtitlesProvider struct {
	UserAgent string
	Server    string
}

func (s openSubtitlesProvider) login(client *xmlrpc.Client, username, password, language, useragent string) (string, error) {
	request := []interface{}{username, password, language, useragent}
	var response struct {
		Token   string  `xmlrpc:"token"`
		Status  string  `xmlrpc:"status"`
		Seconds float32 `xmlrpc:"seconds"`
	}

	err := client.Call("LogIn", request, &response)
	if err != nil {
		return "", err
	}

	if response.Status != "200 OK" {
		return "", fmt.Errorf("Bad rc from login call to opensubtitles: %s", response.Status)
	}

	return response.Token, nil
}

func (s openSubtitlesProvider) searchSubtitles(client *xmlrpc.Client, token, hash, language string, size int64) ([]Subtitle, error) {
	request := []interface{}{
		token,
		[]struct {
			MovieByteSize string `xmlrpc:"moviebytesize"`
			MovieHash     string `xmlrpc:"moviehash"`
			Language      string `xmlrpc:"sublanguageid"`
		}{{fmt.Sprintf("%d", size), hash, language}}}

	var response struct {
		Status    string `xmlrpc:"status"`
		Subtitles []struct {
			FileName  string `xmlrpc:"SubFileName"`
			Hash      string `xmlrpc:"SubHash"`
			Format    string `xmlrpc:"SubFormat"`
			MovieName string `xmlrpc:"MovieName"`
			Downloads string `xmlrpc:"SubDownloadsCnt"`
			URL       string `xmlrpc:"SubDownloadLink"`
			Page      string `xmlrpc:"SubtitlesLink"`
		} `xmlrpc:"data"`
	}

	err := client.Call("SearchSubtitles", request, &response)
	if err != nil {
		return nil, err
	}

	var subs []Subtitle
	for _, sub := range response.Subtitles {
		downloadsInt, err := strconv.Atoi(sub.Downloads)
		if err != nil {
			downloadsInt = -1
		}

		subs = append(subs, Subtitle{
			FileName:  sub.FileName,
			Hash:      sub.Hash,
			Format:    sub.Format,
			Downloads: downloadsInt,
			URL:       sub.URL,
			Source:    s,
		})
	}

	return subs, nil
}

func (s openSubtitlesProvider) Name() string {
	return "OpenSubtitles.org"
}

func (s openSubtitlesProvider) GetSubtitle(file, language string) ([]Subtitle, error) {
	client, err := xmlrpc.NewClient(s.Server, nil)
	if err != nil {
		return nil, err
	}

	token, err := s.login(client, "", "", language, s.UserAgent)
	if err != nil {
		return nil, err
	}

	hash, size, err := movieHashFile(file)
	if err != nil {
		return nil, err
	}

	subs, err := s.searchSubtitles(client, token, hash, language, size)
	if err != nil {
		return nil, err
	}

	err = client.Call("LogOut", token, nil)
	if err != nil {
		log.Printf("LogOut from opensubtitles failed. Reason: %s\n", err)
	}

	return subs, nil
}

func (s openSubtitlesProvider) Download(subtitle Subtitle, filePath string) (string, error) {
	resp, err := http.Get(subtitle.URL)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	// Substrings the extension out, and adds in the new one
	subtitlePath := createSubtitlePath(filePath, subtitle.Format)
	reader, err := gzip.NewReader(resp.Body)
	if err != nil {
		return "", err
	}

	// All these flags mean: open for write only, create it if it doesnt exists but if it does - empty it
	file, err := os.OpenFile(subtitlePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		return "", err
	}

	defer file.Close()

	_, err = io.Copy(file, reader)
	if err != nil {
		return "", err
	}

	return subtitlePath, nil
}
<commit_msg>Added language map to opensubtitles provider<commit_after>package providers

import (
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	"github.com/kolo/xmlrpc"
)

func init() {
	db := GetSubtitleDB()
	db.addSource(openSubtitlesProvider{
		UserAgent: "periscope",
		Server:    "http://api.opensubtitles.org/xml-rpc",
		LanguageMap: map[string]string{
			"en": "eng", "fr": "fre", "hu": "hun", "cs": "cze",
			"pl": "pol", "sk": "slo", "pt": "por", "pt-br": "pob",
			"es": "spa", "el": "ell", "ar": "ara", "sq": "alb",
			"hy": "arm", "ay": "ass", "bs": "bos", "bg": "bul",
			"ca": "cat", "zh": "chi", "hr": "hrv", "da": "dan",
			"nl": "dut", "eo": "epo", "et": "est", "fi": "fin",
			"gl": "glg", "ka": "geo", "de": "ger", "he": "heb",
			"hi": "hin", "is": "ice", "id": "ind", "it": "ita",
			"ja": "jpn", "kk": "kaz", "ko": "kor", "lv": "lav",
			"lt": "lit", "lb": "ltz", "mk": "mac", "ms": "may",
			"no": "nor", "oc": "oci", "fa": "per", "ro": "rum",
			"ru": "rus", "sr": "scc", "sl": "slv", "sv": "swe",
			"th": "tha", "tr": "tur", "uk": "ukr", "vi": "vie",
		},
	})
}

type openSubtitlesProvider struct {
	UserAgent   string
	Server      string
	LanguageMap map[string]string
}

func (s openSubtitlesProvider) login(client *xmlrpc.Client, username, password, language, useragent string) (string, error) {
	request := []interface{}{username, password, s.LanguageMap[language], useragent}
	var response struct {
		Token   string  `xmlrpc:"token"`
		Status  string  `xmlrpc:"status"`
		Seconds float32 `xmlrpc:"seconds"`
	}

	err := client.Call("LogIn", request, &response)
	if err != nil {
		return "", err
	}

	if response.Status != "200 OK" {
		return "", fmt.Errorf("Bad rc from login call to opensubtitles: %s", response.Status)
	}

	return response.Token, nil
}

func (s openSubtitlesProvider) searchSubtitles(client *xmlrpc.Client, token, hash, language string, size int64) ([]Subtitle, error) {
	request := []interface{}{
		token,
		[]struct {
			MovieByteSize string `xmlrpc:"moviebytesize"`
			MovieHash     string `xmlrpc:"moviehash"`
			Language      string `xmlrpc:"sublanguageid"`
		}{{fmt.Sprintf("%d", size), hash, s.LanguageMap[language]}}}

	var response struct {
		Status    string `xmlrpc:"status"`
		Subtitles []struct {
			FileName  string `xmlrpc:"SubFileName"`
			Hash      string `xmlrpc:"SubHash"`
			Format    string `xmlrpc:"SubFormat"`
			MovieName string `xmlrpc:"MovieName"`
			Downloads string `xmlrpc:"SubDownloadsCnt"`
			URL       string `xmlrpc:"SubDownloadLink"`
			Page      string `xmlrpc:"SubtitlesLink"`
		} `xmlrpc:"data"`
	}

	err := client.Call("SearchSubtitles", request, &response)
	if err != nil {
		return nil, err
	}

	var subs []Subtitle
	for _, sub := range response.Subtitles {
		/*downloadsInt, err := strconv.Atoi(sub.Downloads)
		if err != nil {
			downloadsInt = -1
		}*/

		subs = append(subs, Subtitle{
			FileName: sub.FileName,
			Hash:     sub.Hash,
			Format:   sub.Format,
			//Downloads: downloadsInt,
			URL:    sub.URL,
			Source: s,
		})
	}

	return subs, nil
}

func (s openSubtitlesProvider) Name() string {
	return "OpenSubtitles.org"
}

func (s openSubtitlesProvider) GetSubtitle(file, language string) ([]Subtitle, error) {
	client, err := xmlrpc.NewClient(s.Server, nil)
	if err != nil {
		return nil, err
	}

	token, err := s.login(client, "", "", language, s.UserAgent)
	if err != nil {
		return nil, err
	}

	hash, size, err := movieHashFile(file)
	if err != nil {
		return nil, err
	}

	subs, err := s.searchSubtitles(client, token, hash, language, size)
	if err != nil {
		return nil, err
	}

	err = client.Call("LogOut", token, nil)
	if err != nil {
		log.Printf("LogOut from opensubtitles failed. Reason: %s\n", err)
	}

	return subs, nil
}

func (s openSubtitlesProvider) Download(subtitle Subtitle, filePath string) (string, error) {
	resp, err := http.Get(subtitle.URL)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	// Substrings the extension out, and adds in the new one
	subtitlePath := createSubtitlePath(filePath, subtitle.Format)
	reader, err := gzip.NewReader(resp.Body)
	if err != nil {
		return "", err
	}

	// All these flags mean: open for write only, create it if it doesnt exists but if it does - empty it
	file, err := os.OpenFile(subtitlePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		return "", err
	}

	defer file.Close()

	_, err = io.Copy(file, reader)
	if err != nil {
		return "", err
	}

	return subtitlePath, nil
}
<|endoftext|>


<commit_before>package dokodemo

import (
	"io"
	"sync"

	"github.com/v2ray/v2ray-core/app/dispatcher"
	"github.com/v2ray/v2ray-core/common/alloc"
	v2io "github.com/v2ray/v2ray-core/common/io"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/proxy"
	"github.com/v2ray/v2ray-core/transport/hub"
)

type DokodemoDoor struct {
	tcpMutex         sync.RWMutex
	udpMutex         sync.RWMutex
	config           *Config
	accepting        bool
	address          v2net.Address
	port             v2net.Port
	packetDispatcher dispatcher.PacketDispatcher
	tcpListener      *hub.TCPHub
	udpHub           *hub.UDPHub
	udpServer        *hub.UDPServer
	listeningPort    v2net.Port
}

func NewDokodemoDoor(config *Config, packetDispatcher dispatcher.PacketDispatcher) *DokodemoDoor {
	return &DokodemoDoor{
		config:           config,
		packetDispatcher: packetDispatcher,
		address:          config.Address,
		port:             config.Port,
	}
}

func (this *DokodemoDoor) Port() v2net.Port {
	return this.listeningPort
}

func (this *DokodemoDoor) Close() {
	this.accepting = false
	if this.tcpListener != nil {
		this.tcpMutex.Lock()
		this.tcpListener.Close()
		this.tcpListener = nil
		this.tcpMutex.Unlock()
	}
	if this.udpHub != nil {
		this.udpMutex.Lock()
		this.udpHub.Close()
		this.udpHub = nil
		this.udpMutex.Unlock()
	}
}

func (this *DokodemoDoor) Listen(port v2net.Port) error {
	if this.accepting {
		if this.listeningPort == port {
			return nil
		} else {
			return proxy.ErrorAlreadyListening
		}
	}
	this.listeningPort = port
	this.accepting = true

	if this.config.Network.HasNetwork(v2net.TCPNetwork) {
		err := this.ListenTCP(port)
		if err != nil {
			return err
		}
	}
	if this.config.Network.HasNetwork(v2net.UDPNetwork) {
		err := this.ListenUDP(port)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *DokodemoDoor) ListenUDP(port v2net.Port) error {
	udpHub, err := hub.ListenUDP(port, this.handleUDPPackets)
	if err != nil {
		log.Error("Dokodemo failed to listen on port ", port, ": ", err)
		return err
	}
	this.udpMutex.Lock()
	this.udpHub = udpHub
	this.udpServer = hub.NewUDPServer(this.packetDispatcher)
	this.udpMutex.Unlock()
	return nil
}

func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
	packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false)
	this.udpServer.Dispatch(dest, packet, func(packet v2net.Packet) {
		defer packet.Chunk().Release()
		this.udpMutex.RLock()
		if !this.accepting {
			this.udpMutex.RUnlock()
			return
		}
		this.udpHub.WriteTo(packet.Chunk().Value, packet.Destination())
		this.udpMutex.RUnlock()
	})
}

func (this *DokodemoDoor) ListenTCP(port v2net.Port) error {
	tcpListener, err := hub.ListenTCP(port, this.HandleTCPConnection)
	if err != nil {
		log.Error("Dokodemo: Failed to listen on port ", port, ": ", err)
		return err
	}
	this.tcpMutex.Lock()
	this.tcpListener = tcpListener
	this.tcpMutex.Unlock()
	return nil
}

func (this *DokodemoDoor) HandleTCPConnection(conn *hub.TCPConn) {
	defer conn.Close()

	packet := v2net.NewPacket(v2net.TCPDestination(this.address, this.port), nil, true)
	ray := this.packetDispatcher.DispatchToOutbound(packet)

	var inputFinish, outputFinish sync.Mutex
	inputFinish.Lock()
	outputFinish.Lock()

	reader := v2net.NewTimeOutReader(this.config.Timeout, conn)
	go dumpInput(reader, ray.InboundInput(), &inputFinish)
	go dumpOutput(conn, ray.InboundOutput(), &outputFinish)

	outputFinish.Lock()
}

func dumpInput(reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	v2io.RawReaderToChan(input, reader)
	finish.Unlock()
	close(input)
}

func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
	v2io.ChanToRawWriter(writer, output)
	finish.Unlock()
}
<commit_msg>fix race condition in dokodemo<commit_after>package dokodemo

import (
	"io"
	"sync"

	"github.com/v2ray/v2ray-core/app/dispatcher"
	"github.com/v2ray/v2ray-core/common/alloc"
	v2io "github.com/v2ray/v2ray-core/common/io"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/proxy"
	"github.com/v2ray/v2ray-core/transport/hub"
)

type DokodemoDoor struct {
	tcpMutex         sync.RWMutex
	udpMutex         sync.RWMutex
	config           *Config
	accepting        bool
	address          v2net.Address
	port             v2net.Port
	packetDispatcher dispatcher.PacketDispatcher
	tcpListener      *hub.TCPHub
	udpHub           *hub.UDPHub
	udpServer        *hub.UDPServer
	listeningPort    v2net.Port
}

func NewDokodemoDoor(config *Config, packetDispatcher dispatcher.PacketDispatcher) *DokodemoDoor {
	return &DokodemoDoor{
		config:           config,
		packetDispatcher: packetDispatcher,
		address:          config.Address,
		port:             config.Port,
	}
}

func (this *DokodemoDoor) Port() v2net.Port {
	return this.listeningPort
}

func (this *DokodemoDoor) Close() {
	this.accepting = false
	if this.tcpListener != nil {
		this.tcpMutex.Lock()
		this.tcpListener.Close()
		this.tcpListener = nil
		this.tcpMutex.Unlock()
	}
	if this.udpHub != nil {
		this.udpMutex.Lock()
		this.udpHub.Close()
		this.udpHub = nil
		this.udpMutex.Unlock()
	}
}

func (this *DokodemoDoor) Listen(port v2net.Port) error {
	if this.accepting {
		if this.listeningPort == port {
			return nil
		} else {
			return proxy.ErrorAlreadyListening
		}
	}
	this.listeningPort = port
	this.accepting = true

	if this.config.Network.HasNetwork(v2net.TCPNetwork) {
		err := this.ListenTCP(port)
		if err != nil {
			return err
		}
	}
	if this.config.Network.HasNetwork(v2net.UDPNetwork) {
		err := this.ListenUDP(port)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *DokodemoDoor) ListenUDP(port v2net.Port) error {
	this.udpServer = hub.NewUDPServer(this.packetDispatcher)
	udpHub, err := hub.ListenUDP(port, this.handleUDPPackets)
	if err != nil {
		log.Error("Dokodemo failed to listen on port ", port, ": ", err)
		return err
	}
	this.udpMutex.Lock()
	this.udpHub = udpHub
	this.udpMutex.Unlock()
	return nil
}

func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
	packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false)
	this.udpServer.Dispatch(dest, packet, func(packet v2net.Packet) {
		defer packet.Chunk().Release()
		this.udpMutex.RLock()
		if !this.accepting {
			this.udpMutex.RUnlock()
			return
		}
		this.udpHub.WriteTo(packet.Chunk().Value, packet.Destination())
		this.udpMutex.RUnlock()
	})
}

func (this *DokodemoDoor) ListenTCP(port v2net.Port) error {
	tcpListener, err := hub.ListenTCP(port, this.HandleTCPConnection)
	if err != nil {
		log.Error("Dokodemo: Failed to listen on port ", port, ": ", err)
		return err
	}
	this.tcpMutex.Lock()
	this.tcpListener = tcpListener
	this.tcpMutex.Unlock()
	return nil
}

func (this *DokodemoDoor) HandleTCPConnection(conn *hub.TCPConn) {
	defer conn.Close()

	packet := v2net.NewPacket(v2net.TCPDestination(this.address, this.port), nil, true)
	ray := this.packetDispatcher.DispatchToOutbound(packet)

	var inputFinish, outputFinish sync.Mutex
	inputFinish.Lock()
	outputFinish.Lock()

	reader := v2net.NewTimeOutReader(this.config.Timeout, conn)
	go dumpInput(reader, ray.InboundInput(), &inputFinish)
	go dumpOutput(conn, ray.InboundOutput(), &outputFinish)

	outputFinish.Lock()
}

func dumpInput(reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	v2io.RawReaderToChan(input, reader)
	finish.Unlock()
	close(input)
}

func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
	v2io.ChanToRawWriter(writer, output)
	finish.Unlock()
}
<|endoftext|>


<commit_before>// Copied with small adaptations from the reflect package in the
// Go source tree.

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The deepdiff package implements a version of reflect.DeepEquals that
// also returns an error message describing the first difference found.
package deepdiff

import (
	"reflect"
	"fmt"
	"unsafe"
)

// During deepValueEqual, must keep track of checks that are
// in progress.  The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
	a1  uintptr
	a2  uintptr
	typ reflect.Type
}

type MismatchError struct {
	v1, v2 reflect.Value
	Path string
	How string
}

func (err *MismatchError) Error() string {
	return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", err.Path, err.How, interfaceOf(err.v1), interfaceOf(err.v2))
}

// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) {
	errorf := func(f string, a ...interface{}) error {
		return &MismatchError{
			v1: v1,
			v2: v2,
			Path: path,
			How: fmt.Sprintf(f, a...),
		}
	}
	if !v1.IsValid() || !v2.IsValid() {
		if v1.IsValid() == v2.IsValid() {
			return true, nil
		}
		return false, errorf("validity mismatch")
	}
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}

	// if depth > 10 { panic("deepValueEqual") }	// for debugging
	hard := func(k reflect.Kind) bool {
		switch k {
		case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
			return true
		}
		return false
	}

	if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
		addr1 := v1.UnsafeAddr()
		addr2 := v2.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return true, nil
		}

		// ... or already seen
		typ := v1.Type()
		v := visit{addr1, addr2, typ}
		if visited[v] {
			return true, nil
		}

		// Remember for later.
		visited[v] = true
	}

	switch v1.Kind() {
	case reflect.Array:
		if v1.Len() != v2.Len() {
			// can't happen!
			return false, errorf("length mismatch, %d vs %d", v1.Len, v2.Len())
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Slice:
		// We treat a nil slice the same as an empty slice.
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len, v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Interface:
		if v1.IsNil() || v2.IsNil() {
			if v1.IsNil() != v2.IsNil() {
				return false, fmt.Errorf("nil vs non-nil interface mismatch")
			}
			return true, nil
		}
		return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Ptr:
		return deepValueEqual("(*" + path + ")", v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Struct:
		for i, n := 0, v1.NumField(); i < n; i++ {
			path := path + "." + v1.Type().Field(i).Name
			if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Map:
		if v1.IsNil() != v2.IsNil() {
			return false, errorf("nil vs non-nil mismatch")
		}
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len, v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for _, k := range v1.MapKeys() {
			var p string
			if k.CanInterface() {
				p = path + "[" + fmt.Sprintf("%#v", k.Interface())+ "]"
			} else {
				p = path + "[someKey]"
			}
			if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Func:
		if v1.IsNil() && v2.IsNil() {
			return true, nil
		}
		// Can't do better than this:
		return false, errorf("non-nil functions")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if v1.Int() != v2.Int() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v1.Uint() != v2.Uint() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Float32, reflect.Float64:
		if v1.Float() != v2.Float() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Complex64, reflect.Complex128:
		if v1.Complex() != v2.Complex() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Bool:
		if v1.Bool() != v2.Bool() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.String:
		if v1.String() != v2.String() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Chan, reflect.UnsafePointer:
		if v1.Pointer() != v2.Pointer() {
			return false, errorf("unequal")
		}
		return true, nil
	default:
		panic("unexpected type " + v1.Type().String())
	}
}

func DeepEqual(a1, a2 interface{}) bool {
	ok, _ := DeepDiff(a1, a2)
	return ok
}

// DeepDiff tests for deep equality. It uses normal == equality where
// possible but will scan elements of arrays, slices, maps, and fields of
// structs. In maps, keys are compared with == but elements use deep
// equality. DeepEqual correctly handles recursive types. Functions are equal
// only if they are both nil.
// DeepEqual differs from reflect.DeepEqual in that an empty
// slice is equal to a nil slice, and an empty map is equal to a nil map.
// If the two values compare unequal, the resulting error
// holds the first difference encountered.
func DeepDiff(a1, a2 interface{}) (bool, error) {
	errorf := func(f string, a ...interface{}) error {
		return &MismatchError{
			v1: reflect.ValueOf(a1),
			v2: reflect.ValueOf(a2),
			Path: "$",
			How: fmt.Sprintf(f, a...),
		}
	}
	if a1 == nil || a2 == nil {
		return a1 == a2, errorf("nil vs non-nil mismatch")
	}
	v1 := reflect.ValueOf(a1)
	v2 := reflect.ValueOf(a2)
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}
	return deepValueEqual("$", v1, v2, make(map[visit]bool), 0)
}

type flag uintptr

// copied from reflect/value.go
const (
	flagRO flag = 1 << iota
)

// interfaceOf returns v.Interface() even if v.CanInterface() == false.
// This enables us to call fmt.Printf on a value even if it's
// derived from inside an unexported field.
func interfaceOf(v reflect.Value) interface{} {
	if !v.IsValid() {
		return nil
	}
	return bypass(v).Interface()
}

var flagValOffset = func() uintptr {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	return field.Offset
}()

// Sanity checks against future reflect package changes.
func init() {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
		panic("reflect.Value flag field has changed kind")
	}
	var t struct {
		a int
		A int
	}
	vA := reflect.ValueOf(t).FieldByName("A")
	va := reflect.ValueOf(t).FieldByName("a")
	flagA := *flagField(&vA)
	flaga := *flagField(&va)
	if flagA & flagRO != 0 || flaga & flagRO == 0 {
		panic("reflect.Value read-only flag has changed value")
	}
}

func flagField(v *reflect.Value) *flag {
	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
}

func bypass(v reflect.Value) reflect.Value {
	if !v.IsValid() || v.CanInterface() {
		return v
	}
	*flagField(&v) &^= flagRO
	return v
}
<commit_msg>deepdiff: fix error message<commit_after>// Copied with small adaptations from the reflect package in the
// Go source tree.

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The deepdiff package implements a version of reflect.DeepEquals that
// also returns an error message describing the first difference found.
package deepdiff

import (
	"reflect"
	"fmt"
	"unsafe"
)

// During deepValueEqual, must keep track of checks that are
// in progress.  The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
	a1  uintptr
	a2  uintptr
	typ reflect.Type
}

type MismatchError struct {
	v1, v2 reflect.Value
	Path string
	How string
}

func (err *MismatchError) Error() string {
	return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", err.Path, err.How, interfaceOf(err.v1), interfaceOf(err.v2))
}

// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) {
	errorf := func(f string, a ...interface{}) error {
		return &MismatchError{
			v1: v1,
			v2: v2,
			Path: path,
			How: fmt.Sprintf(f, a...),
		}
	}
	if !v1.IsValid() || !v2.IsValid() {
		if v1.IsValid() == v2.IsValid() {
			return true, nil
		}
		return false, errorf("validity mismatch")
	}
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}

	// if depth > 10 { panic("deepValueEqual") }	// for debugging
	hard := func(k reflect.Kind) bool {
		switch k {
		case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
			return true
		}
		return false
	}

	if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
		addr1 := v1.UnsafeAddr()
		addr2 := v2.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return true, nil
		}

		// ... or already seen
		typ := v1.Type()
		v := visit{addr1, addr2, typ}
		if visited[v] {
			return true, nil
		}

		// Remember for later.
		visited[v] = true
	}

	switch v1.Kind() {
	case reflect.Array:
		if v1.Len() != v2.Len() {
			// can't happen!
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Slice:
		// We treat a nil slice the same as an empty slice.
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Interface:
		if v1.IsNil() || v2.IsNil() {
			if v1.IsNil() != v2.IsNil() {
				return false, fmt.Errorf("nil vs non-nil interface mismatch")
			}
			return true, nil
		}
		return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Ptr:
		return deepValueEqual("(*" + path + ")", v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Struct:
		for i, n := 0, v1.NumField(); i < n; i++ {
			path := path + "." + v1.Type().Field(i).Name
			if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Map:
		if v1.IsNil() != v2.IsNil() {
			return false, errorf("nil vs non-nil mismatch")
		}
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for _, k := range v1.MapKeys() {
			var p string
			if k.CanInterface() {
				p = path + "[" + fmt.Sprintf("%#v", k.Interface())+ "]"
			} else {
				p = path + "[someKey]"
			}
			if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Func:
		if v1.IsNil() && v2.IsNil() {
			return true, nil
		}
		// Can't do better than this:
		return false, errorf("non-nil functions")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if v1.Int() != v2.Int() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v1.Uint() != v2.Uint() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Float32, reflect.Float64:
		if v1.Float() != v2.Float() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Complex64, reflect.Complex128:
		if v1.Complex() != v2.Complex() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Bool:
		if v1.Bool() != v2.Bool() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.String:
		if v1.String() != v2.String() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Chan, reflect.UnsafePointer:
		if v1.Pointer() != v2.Pointer() {
			return false, errorf("unequal")
		}
		return true, nil
	default:
		panic("unexpected type " + v1.Type().String())
	}
}

func DeepEqual(a1, a2 interface{}) bool {
	ok, _ := DeepDiff(a1, a2)
	return ok
}

// DeepDiff tests for deep equality. It uses normal == equality where
// possible but will scan elements of arrays, slices, maps, and fields of
// structs. In maps, keys are compared with == but elements use deep
// equality. DeepEqual correctly handles recursive types. Functions are equal
// only if they are both nil.
// DeepEqual differs from reflect.DeepEqual in that an empty
// slice is equal to a nil slice, and an empty map is equal to a nil map.
// If the two values compare unequal, the resulting error
// holds the first difference encountered.
func DeepDiff(a1, a2 interface{}) (bool, error) {
	errorf := func(f string, a ...interface{}) error {
		return &MismatchError{
			v1: reflect.ValueOf(a1),
			v2: reflect.ValueOf(a2),
			Path: "$",
			How: fmt.Sprintf(f, a...),
		}
	}
	if a1 == nil || a2 == nil {
		return a1 == a2, errorf("nil vs non-nil mismatch")
	}
	v1 := reflect.ValueOf(a1)
	v2 := reflect.ValueOf(a2)
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}
	return deepValueEqual("$", v1, v2, make(map[visit]bool), 0)
}

type flag uintptr

// copied from reflect/value.go
const (
	flagRO flag = 1 << iota
)

// interfaceOf returns v.Interface() even if v.CanInterface() == false.
// This enables us to call fmt.Printf on a value even if it's
// derived from inside an unexported field.
func interfaceOf(v reflect.Value) interface{} {
	if !v.IsValid() {
		return nil
	}
	return bypass(v).Interface()
}

var flagValOffset = func() uintptr {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	return field.Offset
}()

// Sanity checks against future reflect package changes.
func init() {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
		panic("reflect.Value flag field has changed kind")
	}
	var t struct {
		a int
		A int
	}
	vA := reflect.ValueOf(t).FieldByName("A")
	va := reflect.ValueOf(t).FieldByName("a")
	flagA := *flagField(&vA)
	flaga := *flagField(&va)
	if flagA & flagRO != 0 || flaga & flagRO == 0 {
		panic("reflect.Value read-only flag has changed value")
	}
}

func flagField(v *reflect.Value) *flag {
	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
}

func bypass(v reflect.Value) reflect.Value {
	if !v.IsValid() || v.CanInterface() {
		return v
	}
	*flagField(&v) &^= flagRO
	return v
}
<|endoftext|>


<commit_before>package delete

import (
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/flexiant/kdeploy/delete/strategies"
	"github.com/flexiant/kdeploy/models"
	"github.com/flexiant/kdeploy/template"
	"github.com/flexiant/kdeploy/utils"
	"github.com/flexiant/kdeploy/webservice"
)

// CmdDelete implements 'delete' command
func CmdDelete(c *cli.Context) {
	localKubePath, err := webservice.FetchKubeFromURL(os.Getenv("KDEPLOY_KUBEWARE"))
	utils.CheckError(err)

	log.Debugf("Going to parse kubeware in %s", localKubePath)

	md := template.ParseMetadata(localKubePath)
	utils.CheckError(err)

	kubernetes, err := webservice.NewKubeClient()
	utils.CheckError(err)

	namespace := os.Getenv("KDEPLOY_NAMESPACE")
	labelSelector := fmt.Sprintf("kubeware=%s,kubeware-version=%s", utils.NormalizeName(md.Name), md.Version)

	// get services which are currently deployed as part of the kube
	serviceList, err := kubernetes.GetServicesForNamespace(namespace, labelSelector)
	utils.CheckError(err)
	log.Debugf("Services: %v", serviceList)

	// get controllers which are currently deployed as part of the kube
	controllerList, err := kubernetes.GetControllersForNamespace(namespace, labelSelector)
	utils.CheckError(err)
	log.Debugf("Controllers: %v", controllerList)

	// If no resources found that means it's not deployed
	if len(*serviceList) == 0 || len(*controllerList) == 0 {
		log.Warnf("Could not delete kubeware '%s %s' since it is not currently deployed", md.Name, md.Version)
		return
	}

	// delete them
	ds := deletionStrategies.WaitZeroReplicasDeletionStrategy(kubernetes)
	err = ds.Delete(namespace, svcNames(serviceList), rcNames(controllerList))
	utils.CheckError(err)

	log.Infof("Kubeware '%s %s' has been deleted", md.Name, md.Version)
}

func rcNames(rcl *[]models.ReplicaController) []string {
	names := []string{}
	for _, rc := range *rcl {
		names = append(names, rc.Metadata.Name)
	}
	return names
}

func svcNames(sl *[]models.Service) []string {
	names := []string{}
	for _, s := range *sl {
		names = append(names, s.Metadata.Name)
	}
	return names
}
<commit_msg>Support kubeware deletion by specifying only its name. closes #32<commit_after>package delete

import (
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/asaskevich/govalidator"
	"github.com/codegangsta/cli"
	"github.com/flexiant/kdeploy/delete/strategies"
	"github.com/flexiant/kdeploy/models"
	"github.com/flexiant/kdeploy/template"
	"github.com/flexiant/kdeploy/utils"
	"github.com/flexiant/kdeploy/webservice"
)

// CmdDelete implements 'delete' command
func CmdDelete(c *cli.Context) {
	log.Debugf("deleting : %s", os.Getenv("KDEPLOY_KUBEWARE"))
	var kubewareName string
	var kubewareVersion string
	var kubewareURL string
	var labelSelector string

	namespace := os.Getenv("KDEPLOY_NAMESPACE")

	if govalidator.IsURL(os.Getenv("KDEPLOY_KUBEWARE")) {
		kubewareURL = os.Getenv("KDEPLOY_KUBEWARE")
		labelSelector, kubewareName, kubewareVersion = labelSelectorFromURL(kubewareURL)
	} else {
		// not URL so we will interpret it as a name
		kubewareName = utils.NormalizeName(os.Getenv("KDEPLOY_KUBEWARE"))
		labelSelector = labelSelectorFromName(kubewareName)
	}

	kubernetes, err := webservice.NewKubeClient()
	utils.CheckError(err)

	// get services which are currently deployed as part of the kube
	serviceList, err := kubernetes.GetServicesForNamespace(namespace, labelSelector)
	utils.CheckError(err)
	log.Debugf("Services: %v", serviceList)

	// get controllers which are currently deployed as part of the kube
	controllerList, err := kubernetes.GetControllersForNamespace(namespace, labelSelector)
	utils.CheckError(err)
	log.Debugf("Controllers: %v", controllerList)

	// If no resources found that means it's not deployed
	if len(*serviceList) == 0 || len(*controllerList) == 0 {
		var version string
		if kubewareVersion != "" {
			version = fmt.Sprintf(" (%s)", kubewareVersion)
		}
		log.Warnf("Could not delete kubeware '%s'%s since it is not currently deployed", kubewareName, version)
		return
	}

	// delete them
	ds := deletionStrategies.WaitZeroReplicasDeletionStrategy(kubernetes)
	err = ds.Delete(namespace, svcNames(serviceList), rcNames(controllerList))
	utils.CheckError(err)

	log.Infof("Kubeware '%s.%s' has been deleted", namespace, kubewareName)
}

func rcNames(rcl *[]models.ReplicaController) []string {
	names := []string{}
	for _, rc := range *rcl {
		names = append(names, rc.Metadata.Name)
	}
	return names
}

func svcNames(sl *[]models.Service) []string {
	names := []string{}
	for _, s := range *sl {
		names = append(names, s.Metadata.Name)
	}
	return names
}

func labelSelectorFromName(name string) string {
	return fmt.Sprintf("kubeware=%s", name)
}

func labelSelectorFromURL(kubewareURL string) (string, string, string) {
	localKubePath, err := webservice.FetchKubeFromURL(kubewareURL)
	utils.CheckError(err)

	log.Debugf("Going to parse kubeware in %s", localKubePath)

	md := template.ParseMetadata(localKubePath)
	utils.CheckError(err)

	labelSelector := fmt.Sprintf("kubeware=%s,kubeware-version=%s", utils.NormalizeName(md.Name), md.Version)

	return labelSelector, md.Name, md.Version
}
<|endoftext|>


<commit_before>package jpconv

import (
	"strings"
	"unicode"
)

var numMap = map[string]string{
	"0": "０", "1": "１", "2": "２", "3": "３", "4": "４",
	"5": "５", "6": "６", "7": "７", "8": "８", "9": "９",
}
var dakuMap = map[string]string{
	"ｶﾞ": "ガ", "ｷﾞ": "ギ", "ｸﾞ": "グ", "ｹﾞ": "ゲ", "ｺﾞ": "ゴ",
	"ｻﾞ": "ザ", "ｼﾞ": "ジ", "ｽﾞ": "ズ", "ｾﾞ": "ゼ", "ｿﾞ": "ゾ",
	"ﾀﾞ": "ダ", "ﾁﾞ": "ヂ", "ﾂﾞ": "ヅ", "ﾃﾞ": "デ", "ﾄﾞ": "ド",
	"ﾊﾞ": "バ", "ﾋﾞ": "ビ", "ﾌﾞ": "ブ", "ﾍﾞ": "ベ", "ﾎﾞ": "ボ",
	"ﾊﾟ": "パ", "ﾋﾟ": "ピ", "ﾌﾟ": "プ", "ﾍﾟ": "ペ", "ﾎﾟ": "ポ",
	"ｳﾞ": "ヴ", "ﾜﾞ": "ヷ", "ｦﾞ": "ヺ",
}

var kataMap = map[string]string{
	"ｱ": "ア", "ｲ": "イ", "ｳ": "ウ", "ｴ": "エ", "ｵ": "オ",
	"ｶ": "カ", "ｷ": "キ", "ｸ": "ク", "ｹ": "ケ", "ｺ": "コ",
	"ｻ": "サ", "ｼ": "シ", "ｽ": "ス", "ｾ": "セ", "ｿ": "ソ",
	"ﾀ": "タ", "ﾁ": "チ", "ﾂ": "ツ", "ﾃ": "テ", "ﾄ": "ト",
	"ﾅ": "ナ", "ﾆ": "ニ", "ﾇ": "ヌ", "ﾈ": "ネ", "ﾉ": "ノ",
	"ﾊ": "ハ", "ﾋ": "ヒ", "ﾌ": "フ", "ﾍ": "ヘ", "ﾎ": "ホ",
	"ﾏ": "マ", "ﾐ": "ミ", "ﾑ": "ム", "ﾒ": "メ", "ﾓ": "モ",
	"ﾔ": "ヤ", "ﾕ": "ユ", "ﾖ": "ヨ",
	"ﾗ": "ラ", "ﾘ": "リ", "ﾙ": "ル", "ﾚ": "レ", "ﾛ": "ロ",
	"ﾜ": "ワ", "ｦ": "ヲ", "ﾝ": "ン",
	"ｧ": "ァ", "ｨ": "ィ", "ｩ": "ゥ", "ｪ": "ェ", "ｫ": "ォ",
	"ｯ": "ッ", "ｬ": "ャ", "ｭ": "ュ", "ｮ": "ョ",
}

var symbolMap = map[string]string{
	"｡": "。", "､": "、", "ｰ": "ー", "｢": "「", "｣": "」", "･": "・",
}

var kanaCase = unicode.SpecialCase{
	// ァ-ヴ
	unicode.CaseRange{
		0x3040,
		0x3094,
		[unicode.MaxCase]rune{
			0x30a1 - 0x3041,
			0,
			0,
		},
	},
	// ぁ-ゔ
	unicode.CaseRange{
		0x30a0,
		0x30f4,
		[unicode.MaxCase]rune{
			0,
			0x3041 - 0x30a1,
			0,
		},
	},
}

var zenhanCase = unicode.SpecialCase{
	// 0-9
	unicode.CaseRange{
		0x0030,
		0x0039,
		[unicode.MaxCase]rune{
			0xff10 - 0x0030,
			0,
			0,
		},
	},
	// ０-９
	unicode.CaseRange{
		0xff10,
		0xff19,
		[unicode.MaxCase]rune{
			0,
			0x0030 - 0xff10,
			0,
		},
	},
	// ｧ-ﾝ
	unicode.CaseRange{
		0xff67,
		0xff9D,
		[unicode.MaxCase]rune{
			0x30a1 - 0xff67,
			0,
			0,
		},
	},
	// ァ-ン
	unicode.CaseRange{
		0x30a1,
		0x30f3,
		[unicode.MaxCase]rune{
			0,
			0xff67 - 0x30a1,
			0,
		},
	},
}

func HiraganaToKatakana(s string) string {
	return strings.ToUpperSpecial(kanaCase, s)
}

// KatakanaToHiragana はカタカナをひらがなに変換する
func KatakanaToHiragana(s string) string {
	return strings.ToLowerSpecial(kanaCase, s)
}

// ZenkakuToHankaku は全角カタカナを半角に変換する
func ZenkakuToHankaku(s string) string {
	for k, v := range dakuMap {
		s = strings.Replace(s, v, k, -1)
	}
	for k, v := range kataMap {
		s = strings.Replace(s, v, k, -1)
	}
	for k, v := range symbolMap {
		s = strings.Replace(s, v, k, -1)
	}
	return strings.ToLowerSpecial(zenhanCase, s)
}

// HankakuToZenkaku は半角カタカナを全角に変換する
func HankakuToZenkaku(s string) string {
	for k, v := range dakuMap {
		s = strings.Replace(s, k, v, -1)
	}
	for k, v := range kataMap {
		s = strings.Replace(s, k, v, -1)
	}
	for k, v := range symbolMap {
		s = strings.Replace(s, k, v, -1)
	}
	return strings.ToUpperSpecial(zenhanCase, s)
}
<commit_msg>fixes #1<commit_after>package jpconv

import (
	"strings"
	"unicode"
)

var hankaku2zenkaku = strings.NewReplacer(
	"0", "０", "1", "１", "2", "２", "3", "３", "4", "４",
	"5", "５", "6", "６", "7", "７", "8", "８", "9", "９",
	"ｶﾞ", "ガ", "ｷﾞ", "ギ", "ｸﾞ", "グ", "ｹﾞ", "ゲ", "ｺﾞ", "ゴ",
	"ｻﾞ", "ザ", "ｼﾞ", "ジ", "ｽﾞ", "ズ", "ｾﾞ", "ゼ", "ｿﾞ", "ゾ",
	"ﾀﾞ", "ダ", "ﾁﾞ", "ヂ", "ﾂﾞ", "ヅ", "ﾃﾞ", "デ", "ﾄﾞ", "ド",
	"ﾊﾞ", "バ", "ﾋﾞ", "ビ", "ﾌﾞ", "ブ", "ﾍﾞ", "ベ", "ﾎﾞ", "ボ",
	"ﾊﾟ", "パ", "ﾋﾟ", "ピ", "ﾌﾟ", "プ", "ﾍﾟ", "ペ", "ﾎﾟ", "ポ",
	"ｳﾞ", "ヴ", "ﾜﾞ", "ヷ", "ｦﾞ", "ヺ",
	"ｱ", "ア", "ｲ", "イ", "ｳ", "ウ", "ｴ", "エ", "ｵ", "オ",
	"ｶ", "カ", "ｷ", "キ", "ｸ", "ク", "ｹ", "ケ", "ｺ", "コ",
	"ｻ", "サ", "ｼ", "シ", "ｽ", "ス", "ｾ", "セ", "ｿ", "ソ",
	"ﾀ", "タ", "ﾁ", "チ", "ﾂ", "ツ", "ﾃ", "テ", "ﾄ", "ト",
	"ﾅ", "ナ", "ﾆ", "ニ", "ﾇ", "ヌ", "ﾈ", "ネ", "ﾉ", "ノ",
	"ﾊ", "ハ", "ﾋ", "ヒ", "ﾌ", "フ", "ﾍ", "ヘ", "ﾎ", "ホ",
	"ﾏ", "マ", "ﾐ", "ミ", "ﾑ", "ム", "ﾒ", "メ", "ﾓ", "モ",
	"ﾔ", "ヤ", "ﾕ", "ユ", "ﾖ", "ヨ",
	"ﾗ", "ラ", "ﾘ", "リ", "ﾙ", "ル", "ﾚ", "レ", "ﾛ", "ロ",
	"ﾜ", "ワ", "ｦ", "ヲ", "ﾝ", "ン",
	"ｧ", "ァ", "ｨ", "ィ", "ｩ", "ゥ", "ｪ", "ェ", "ｫ", "ォ",
	"ｯ", "ッ", "ｬ", "ャ", "ｭ", "ュ", "ｮ", "ョ",
	"｡", "。", "､", "、", "ｰ", "ー", "｢", "「", "｣", "」", "･", "・",
)

var zenkaku2hankaku = strings.NewReplacer(
	"０", "0", "１", "1", "２", "2", "３", "3", "４", "4",
	"５", "5", "６", "6", "７", "7", "８", "8", "９", "9",
	"ガ", "ｶﾞ", "ギ", "ｷﾞ", "グ", "ｸﾞ", "ゲ", "ｹﾞ", "ゴ", "ｺﾞ",
	"ザ", "ｻﾞ", "ジ", "ｼﾞ", "ズ", "ｽﾞ", "ゼ", "ｾﾞ", "ゾ", "ｿﾞ",
	"ダ", "ﾀﾞ", "ヂ", "ﾁﾞ", "ヅ", "ﾂﾞ", "デ", "ﾃﾞ", "ド", "ﾄﾞ",
	"バ", "ﾊﾞ", "ビ", "ﾋﾞ", "ブ", "ﾌﾞ", "ベ", "ﾍﾞ", "ボ", "ﾎﾞ",
	"パ", "ﾊﾟ", "ピ", "ﾋﾟ", "プ", "ﾌﾟ", "ペ", "ﾍﾟ", "ポ", "ﾎﾟ",
	"ヴ", "ｳﾞ", "ヷ", "ﾜﾞ", "ヺ", "ｦﾞ",
	"ア", "ｱ", "イ", "ｲ", "ウ", "ｳ", "エ", "ｴ", "オ", "ｵ",
	"カ", "ｶ", "キ", "ｷ", "ク", "ｸ", "ケ", "ｹ", "コ", "ｺ",
	"サ", "ｻ", "シ", "ｼ", "ス", "ｽ", "セ", "ｾ", "ソ", "ｿ",
	"タ", "ﾀ", "チ", "ﾁ", "ツ", "ﾂ", "テ", "ﾃ", "ト", "ﾄ",
	"ナ", "ﾅ", "ニ", "ﾆ", "ヌ", "ﾇ", "ネ", "ﾈ", "ノ", "ﾉ",
	"ハ", "ﾊ", "ヒ", "ﾋ", "フ", "ﾌ", "ヘ", "ﾍ", "ホ", "ﾎ",
	"マ", "ﾏ", "ミ", "ﾐ", "ム", "ﾑ", "メ", "ﾒ", "モ", "ﾓ",
	"ヤ", "ﾔ", "ユ", "ﾕ", "ヨ", "ﾖ",
	"ラ", "ﾗ", "リ", "ﾘ", "ル", "ﾙ", "レ", "ﾚ", "ロ", "ﾛ",
	"ワ", "ﾜ", "ヲ", "ｦ", "ン", "ﾝ",
	"ァ", "ｧ", "ィ", "ｨ", "ゥ", "ｩ", "ェ", "ｪ", "ォ", "ｫ",
	"ッ", "ｯ", "ャ", "ｬ", "ュ", "ｭ", "ョ", "ｮ",
	"。", "｡", "、", "､", "ー", "ｰ", "「", "｢", "」", "｣", "・", "･",
)

var kanaCase = unicode.SpecialCase{
	// ァ-ヴ
	unicode.CaseRange{
		0x3040,
		0x3094,
		[unicode.MaxCase]rune{
			0x30a1 - 0x3041,
			0,
			0,
		},
	},
	// ぁ-ゔ
	unicode.CaseRange{
		0x30a0,
		0x30f4,
		[unicode.MaxCase]rune{
			0,
			0x3041 - 0x30a1,
			0,
		},
	},
}

var zenhanCase = unicode.SpecialCase{
	// 0-9
	unicode.CaseRange{
		0x0030,
		0x0039,
		[unicode.MaxCase]rune{
			0xff10 - 0x0030,
			0,
			0,
		},
	},
	// ０-９
	unicode.CaseRange{
		0xff10,
		0xff19,
		[unicode.MaxCase]rune{
			0,
			0x0030 - 0xff10,
			0,
		},
	},
	// ｧ-ﾝ
	unicode.CaseRange{
		0xff67,
		0xff9D,
		[unicode.MaxCase]rune{
			0x30a1 - 0xff67,
			0,
			0,
		},
	},
	// ァ-ン
	unicode.CaseRange{
		0x30a1,
		0x30f3,
		[unicode.MaxCase]rune{
			0,
			0xff67 - 0x30a1,
			0,
		},
	},
}

func HiraganaToKatakana(s string) string {
	return strings.ToUpperSpecial(kanaCase, s)
}

// KatakanaToHiragana はカタカナをひらがなに変換する
func KatakanaToHiragana(s string) string {
	return strings.ToLowerSpecial(kanaCase, s)
}

// ZenkakuToHankaku は全角カタカナを半角に変換する
func ZenkakuToHankaku(s string) string {
	return zenkaku2hankaku.Replace(s)
}

// HankakuToZenkaku は半角カタカナを全角に変換する
func HankakuToZenkaku(s string) string {
	return hankaku2zenkaku.Replace(s)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"
)

var cookiesPerMinute = 2.0

func main() {
	var _ = time.Sleep
	scanner := bufio.NewScanner(os.Stdin)
	var testCases int
	scanner.Scan()
	fmt.Fscanf(strings.NewReader(scanner.Text()), "%d", &testCases)
	for i := 0; i < testCases; i++ {
		fmt.Printf("Case #%v: %.7f\n", i+1, solve(parseTestCase(scanner)))
	}
}

func solve(f, p, g float64) float64 {
	cpm := cookiesPerMinute
	t := 0.0
	c := 0.0
	for c < g {
		// time.Sleep(100 * time.Millisecond)
		no_f_t := (g - c) / cpm
		next_f_t := (f - c) / cpm
		//fmt.Printf("\tAt %v we have %v with cpm %v, %v until goal %v until next factory\n", t, c, cpm, no_f_t, next_f_t)
		if no_f_t < 0.000001 {
			return t
		}
		if no_f_t < next_f_t {
			t += no_f_t
			c += cpm * no_f_t
		} else {
			t += next_f_t
			c += cpm * next_f_t
		}
		if next_f_t == 0 {
			t_with_f := (g - c + f) / (cpm + p)
			t_without_f := (g - c) / (cpm)

			// fmt.Printf("\t\tWithout f %v, with f %v", t_without_f, t_with_f)
			if t_with_f < t_without_f {
				// fmt.Print(" Buy\n")
				c -= f
				cpm += p
			} else {
				// fmt.Print(" Not buy\n")
				t += t_without_f
				c += cpm * t_without_f
			}
		}
	}
	return t
}

func parseTestCase(scanner *bufio.Scanner) (float64, float64, float64) {
	scanner.Scan()
	vars := strings.Split(scanner.Text(), " ")

	f, _ := strconv.ParseFloat(vars[0], 64)
	p, _ := strconv.ParseFloat(vars[1], 64)
	g, _ := strconv.ParseFloat(vars[2], 64)

	return f, p, g
}
<commit_msg>Codejam man<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var errors []string = []string{"Bad magician!", "Volunteer cheated!"}

func main() {
	var _ = time.Sleep
	scanner := bufio.NewScanner(os.Stdin)
	var testCases int
	scanner.Scan()
	fmt.Fscanf(strings.NewReader(scanner.Text()), "%d", &testCases)
	for i := 0; i < testCases; i++ {
		res := solve(parseTestCase(scanner))
		if res < 0 {
			fmt.Printf("Case #%v: %v\n", i+1, errors[-res])
		} else {
			fmt.Printf("Case #%v: %v\n", i+1, res)
		}
	}
}

func solve(a, b []string) int {
	fmt.Println(a, b)
}

func parseTestCase(scanner *bufio.Scanner) ([]string, []string) {
	linea := getSelectedLine(scanner)
	lineb := getSelectedLine(scanner)
	return linea, lineb
}

func getSelectedLine(scanner) []string {
	scanner.Scan()
	lineNo := strconv.Atoi(scanner.Text())
	for i := 0; i < lineNo; i++ {
		scanner.Scan()
	}
	scanner.Scan()
	for _, symbol := range scanner.Text() {
		linea = append(linea, string(symbol))
	}
	for i := 0; i < 4-lineNo; i++ {
		scanner.Scan()
	}
}
<|endoftext|>


<commit_before>package classfile

import (
	"fmt"
	"unicode/utf16"

	"github.com/zxh0/jvm.go/jvmgo/jutil/bigendian"
)

type ClassReader struct {
	data []byte
}

func newClassReader(data []byte) *ClassReader {
	return &ClassReader{data}
}

func (self *ClassReader) readUint8() uint8 {
	val := self.data[0]
	self.data = self.data[1:]
	return val
}

func (self *ClassReader) readUint16() uint16 {
	val := bigendian.Uint16(self.data)
	self.data = self.data[2:]
	return val
}

func (self *ClassReader) readUint16s() []uint16 {
	n := self.readUint16()
	s := make([]uint16, n)
	for i := range s {
		s[i] = self.readUint16()
	}
	return s
}

func (self *ClassReader) readUint32() uint32 {
	val := bigendian.Int32(self.data)
	self.data = self.data[4:]
	return uint32(val)
}
func (self *ClassReader) readInt32() int32 {
	val := bigendian.Int32(self.data)
	self.data = self.data[4:]
	return val
}

func (self *ClassReader) readInt64() int64 {
	val := bigendian.Int64(self.data)
	self.data = self.data[8:]
	return val
}

func (self *ClassReader) readFloat32() float32 {
	val := bigendian.Float32(self.data)
	self.data = self.data[4:]
	return val
}

func (self *ClassReader) readFloat64() float64 {
	val := bigendian.Float64(self.data)
	self.data = self.data[8:]
	return val
}

func (self *ClassReader) readBytes(length uint32) []byte {
	bytes := self.data[:length]
	self.data = self.data[length:]
	return bytes
}

// todo
// func (self *ClassReader) readString() string {
// 	length := uint32(self.readUint16())
// 	bytes := self.readBytes(length)
// 	return string(bytes)
// }

// mutf8 -> utf16 -> utf32 -> string
// see java.io.DataInputStream.readUTF(DataInput)
func (self *ClassReader) readMUTF8() string {
	utflen := uint32(self.readUint16())
	bytearr := self.readBytes(utflen)
	chararr := make([]uint16, utflen)

	var c, char2, char3 uint16
	var count uint32 = 0
	var chararr_count uint32 = 0

	for count < utflen {
		c = uint16(bytearr[count])
		if c > 127 {
			break
		}
		count++
		chararr[chararr_count] = c
		chararr_count++
	}

	for count < utflen {
		c = uint16(bytearr[count])
		switch c >> 4 {
		case 0, 1, 2, 3, 4, 5, 6, 7:
			/* 0xxxxxxx*/
			count++
			chararr[chararr_count] = c
			chararr_count++
		case 12, 13:
			/* 110x xxxx   10xx xxxx*/
			count += 2
			if count > utflen {
				panic("malformed input: partial character at end")
			}
			char2 = uint16(bytearr[count-1])
			if char2&0xC0 != 0x80 {
				panic(fmt.Sprintf("malformed input around byte %v", count))
			}
			chararr[chararr_count] = c&0x1F<<6 | char2&0x3F
			chararr_count++
		case 14:
			/* 1110 xxxx  10xx xxxx  10xx xxxx*/
			count += 3
			if count > utflen {
				panic("malformed input: partial character at end")
			}
			char2 = uint16(bytearr[count-2])
			char3 = uint16(bytearr[count-1])
			if char2&0xC0 != 0x80 || char3&0xC0 != 0x80 {
				panic(fmt.Sprintf("malformed input around byte %v", (count - 1)))
			}
			chararr[chararr_count] = c&0x0F<<12 | char2&0x3F<<6 | char3&0x3F<<0
			chararr_count++
		default:
			/* 10xx xxxx,  1111 xxxx */
			panic(fmt.Sprintf("malformed input around byte %v", count))
		}
	}
	// The number of chars produced may be less than utflen
	chararr = chararr[0:chararr_count]
	runes := utf16.Decode(chararr)
	return string(runes)
}
<commit_msg>reorder methods<commit_after>package classfile

import (
	"fmt"
	"unicode/utf16"

	"github.com/zxh0/jvm.go/jvmgo/jutil/bigendian"
)

type ClassReader struct {
	data []byte
}

func newClassReader(data []byte) *ClassReader {
	return &ClassReader{data}
}

func (self *ClassReader) readUint8() uint8 {
	val := self.data[0]
	self.data = self.data[1:]
	return val
}

func (self *ClassReader) readUint16() uint16 {
	val := bigendian.Uint16(self.data)
	self.data = self.data[2:]
	return val
}

func (self *ClassReader) readUint32() uint32 {
	val := bigendian.Int32(self.data)
	self.data = self.data[4:]
	return uint32(val)
}
func (self *ClassReader) readInt32() int32 {
	val := bigendian.Int32(self.data)
	self.data = self.data[4:]
	return val
}

func (self *ClassReader) readInt64() int64 {
	val := bigendian.Int64(self.data)
	self.data = self.data[8:]
	return val
}

func (self *ClassReader) readFloat32() float32 {
	val := bigendian.Float32(self.data)
	self.data = self.data[4:]
	return val
}

func (self *ClassReader) readFloat64() float64 {
	val := bigendian.Float64(self.data)
	self.data = self.data[8:]
	return val
}

func (self *ClassReader) readUint16s() []uint16 {
	n := self.readUint16()
	s := make([]uint16, n)
	for i := range s {
		s[i] = self.readUint16()
	}
	return s
}

func (self *ClassReader) readBytes(length uint32) []byte {
	bytes := self.data[:length]
	self.data = self.data[length:]
	return bytes
}

// mutf8 -> utf16 -> utf32 -> string
// see java.io.DataInputStream.readUTF(DataInput)
func (self *ClassReader) readMUTF8() string {
	utflen := uint32(self.readUint16())
	bytearr := self.readBytes(utflen)
	chararr := make([]uint16, utflen)

	var c, char2, char3 uint16
	var count uint32 = 0
	var chararr_count uint32 = 0

	for count < utflen {
		c = uint16(bytearr[count])
		if c > 127 {
			break
		}
		count++
		chararr[chararr_count] = c
		chararr_count++
	}

	for count < utflen {
		c = uint16(bytearr[count])
		switch c >> 4 {
		case 0, 1, 2, 3, 4, 5, 6, 7:
			/* 0xxxxxxx*/
			count++
			chararr[chararr_count] = c
			chararr_count++
		case 12, 13:
			/* 110x xxxx   10xx xxxx*/
			count += 2
			if count > utflen {
				panic("malformed input: partial character at end")
			}
			char2 = uint16(bytearr[count-1])
			if char2&0xC0 != 0x80 {
				panic(fmt.Sprintf("malformed input around byte %v", count))
			}
			chararr[chararr_count] = c&0x1F<<6 | char2&0x3F
			chararr_count++
		case 14:
			/* 1110 xxxx  10xx xxxx  10xx xxxx*/
			count += 3
			if count > utflen {
				panic("malformed input: partial character at end")
			}
			char2 = uint16(bytearr[count-2])
			char3 = uint16(bytearr[count-1])
			if char2&0xC0 != 0x80 || char3&0xC0 != 0x80 {
				panic(fmt.Sprintf("malformed input around byte %v", (count - 1)))
			}
			chararr[chararr_count] = c&0x0F<<12 | char2&0x3F<<6 | char3&0x3F<<0
			chararr_count++
		default:
			/* 10xx xxxx,  1111 xxxx */
			panic(fmt.Sprintf("malformed input around byte %v", count))
		}
	}
	// The number of chars produced may be less than utflen
	chararr = chararr[0:chararr_count]
	runes := utf16.Decode(chararr)
	return string(runes)
}
<|endoftext|>


<commit_before>package authkit

import (
	"html/template"
	"strings"
)

var funcMap = template.FuncMap{
	"join": strings.Join,
}

var loginTemplate = template.Must(template.New("login").Funcs(funcMap).Parse(loginJS))
var loginJS = `
var __authkit__state__ = {
  authCallback : "__authkit__"+parseInt(Math.random()*1e12,10).toString(36),
  providers : {}
};

{{ $base := .Base }}
{{ range $key, $value := .Providers }}
__authkit__state__.providers["{{ $value.Network }}"] = {
  network : "{{ $value.Network }}",
  authurl : "{{ $value.AuthURL }}",
  client_id : "{{ $value.ClientID }}",
  scopes : "{{ join $value.Scopes " " }}",
  redirect: "{{ $base }}redirect"
};
{{ end }}

var authkit = {
  providers : function () {
    return __authkit__state__.providers;
  },
  provider : function (p) {
    return __authkit__state__.providers[p];
  },
  login : function (provider,base) {
    var p = authkit.provider(provider);
    if (!p) return;
    if (!base) base = window.location.origin;
    var scopes = encodeURIComponent(p.scopes);
    var redir = encodeURIComponent(base+p.redirect);
    var state = encodeURIComponent(JSON.stringify({network:p.network,redirect_uri:redir,cbid:__authkit__state__.authCallback}));
    var authU = p.authurl+"?redirect_uri="+redir+"&response_type=code&client_id="+p.client_id+"&state="+state;
    if (p.scopes) {
      authU = authU + "&scope="+scopes;
    }
    var self = this;
    self.user = function (cb) { this.authCB = cb; };
    window[__authkit__state__.authCallback] = function (token, usr) {
      console.log(usr);
      self.authCB(usr, token)
    }
    popup(authU, 500, 600);
    return self;
  }
};

function popup (u, w, h) {
  var documentElement = document.documentElement;

	// Multi Screen Popup Positioning (http://stackoverflow.com/a/16861050)
	//   Credit: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html
	// Fixes dual-screen position                         Most browsers      Firefox
	var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
	var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

	var width = window.innerWidth || documentElement.clientWidth || screen.width;
	var height = window.innerHeight || documentElement.clientHeight || screen.height;

	var left = ((width - w) / 2) + dualScreenLeft;
	var top  = ((height - h) / 2) + dualScreenTop;
	var feat = "resizeable=true,height=" + h + ",width=" + w + ",left=" + left + ",top="  + top
	window.open(u, "_blank", feat);
}
`
var redirectTemplate = template.Must(template.New("redirect").Funcs(funcMap).Parse(redirect))
var redirect = `
<html>
<body>
  <script>
	  // First, parse the query string
    var params = {}, queryString = location.search.substring(1),
        regex = /([^&=]+)=([^&]*)/g, m;
    while (m = regex.exec(queryString)) {
      params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
    }

    var req = new XMLHttpRequest();
    var cbid = JSON.parse(params.state).cbid;
    req.open('GET', '{{ .Base }}auth?code='+params.code+"&state="+params.state, true);

    req.onreadystatechange = function (e) {
      if (req.readyState == 4) {
        if(req.status == 200){
           var tok = req.getResponseHeader("Authorization");
           var usr = JSON.parse(req.responseText);
           window.opener[cbid](tok, usr);
           window.close();
        }
        else if(req.status == 400) {
            console.log('There was an error processing the access code:',req.responseText)
            window.opener[cbid](null, null, req);
            window.close();
        }
        else {
          console.log('something other than 200 was returned:',req.responseText)
          window.opener[cbid](null, null, req);
          window.close();
        }
      }
    };
    req.send(null);
	</script>
</body>
</html>
`
<commit_msg>logging output<commit_after>package authkit

import (
	"html/template"
	"strings"
)

var funcMap = template.FuncMap{
	"join": strings.Join,
}

var loginTemplate = template.Must(template.New("login").Funcs(funcMap).Parse(loginJS))
var loginJS = `
var __authkit__state__ = {
  authCallback : "__authkit__"+parseInt(Math.random()*1e12,10).toString(36),
  providers : {}
};

{{ $base := .Base }}
{{ range $key, $value := .Providers }}
__authkit__state__.providers["{{ $value.Network }}"] = {
  network : "{{ $value.Network }}",
  authurl : "{{ $value.AuthURL }}",
  client_id : "{{ $value.ClientID }}",
  scopes : "{{ join $value.Scopes " " }}",
  redirect: "{{ $base }}redirect"
};
{{ end }}

var authkit = {
  providers : function () {
    return __authkit__state__.providers;
  },
  provider : function (p) {
    return __authkit__state__.providers[p];
  },
  login : function (provider,base) {
    var p = authkit.provider(provider);
    if (!p) return;
    if (!base) base = window.location.origin;
    var scopes = encodeURIComponent(p.scopes);
    var redir = encodeURIComponent(base+p.redirect);
    var state = encodeURIComponent(JSON.stringify({network:p.network,redirect_uri:redir,cbid:__authkit__state__.authCallback}));
    var authU = p.authurl+"?redirect_uri="+redir+"&response_type=code&client_id="+p.client_id+"&state="+state;
    if (p.scopes) {
      authU = authU + "&scope="+scopes;
    }
    var self = this;
    self.user = function (cb) { this.authCB = cb; };
    window[__authkit__state__.authCallback] = function (token, usr) {
      console.log(usr);
      self.authCB(usr, token)
    }
    popup(authU, 500, 600);
    return self;
  }
};

function popup (u, w, h) {
  var documentElement = document.documentElement;

	// Multi Screen Popup Positioning (http://stackoverflow.com/a/16861050)
	//   Credit: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html
	// Fixes dual-screen position                         Most browsers      Firefox
	var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
	var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

	var width = window.innerWidth || documentElement.clientWidth || screen.width;
	var height = window.innerHeight || documentElement.clientHeight || screen.height;

	var left = ((width - w) / 2) + dualScreenLeft;
	var top  = ((height - h) / 2) + dualScreenTop;
	var feat = "resizeable=true,height=" + h + ",width=" + w + ",left=" + left + ",top="  + top
	window.open(u, "_blank", feat);
}
`
var redirectTemplate = template.Must(template.New("redirect").Funcs(funcMap).Parse(redirect))
var redirect = `
<html>
<body>
  <script>
	  // First, parse the query string
    var params = {}, queryString = location.search.substring(1),
        regex = /([^&=]+)=([^&]*)/g, m;
    while (m = regex.exec(queryString)) {
      params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
    }

    var req = new XMLHttpRequest();
    var cbid = JSON.parse(params.state).cbid;
    req.open('GET', '{{ .Base }}auth?code='+params.code+"&state="+params.state, true);

    req.onreadystatechange = function (e) {
      if (req.readyState == 4) {
        if(req.status == 200){
           var tok = req.getResponseHeader("Authorization");
           var usr = JSON.parse(req.responseText);
           console.log("window:", window);
           console.log("opener:", window.opener);
           console.log("cbid:", cbid);
           console.log("cb: ", window.opener[cbid]);
           window.opener[cbid](tok, usr);
           window.close();
        }
        else if(req.status == 400) {
            console.log('There was an error processing the access code:',req.responseText)
            window.opener[cbid](null, null, req);
            window.close();
        }
        else {
          console.log('something other than 200 was returned:',req.responseText)
          window.opener[cbid](null, null, req);
          window.close();
        }
      }
    };
    req.send(null);
	</script>
</body>
</html>
`
<|endoftext|>


<commit_before>package deploy

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/flexiant/digger"
	"github.com/flexiant/kdeploy/template"
	"github.com/flexiant/kdeploy/utils"
	"github.com/flexiant/kdeploy/webservice"
)

func Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:   "attribute, a",
			Usage:  "Attribute List",
			Value:  "./examples/attributes.json",
			EnvVar: "KDEPLOY_ATTRIBUTE",
		},
		cli.StringFlag{
			Name:   "kubeware, k",
			Usage:  "Kubeware path",
			Value:  "https://github.com/flexiant/kubeware-guestbook",
			EnvVar: "KDEPLOY_KUBEWARE",
		},
		cli.BoolFlag{
			Name:   "dry-run, d",
			Usage:  "Dry Run of Deploy used for debuging options",
			EnvVar: "KDEPLOY_DRYRUN",
		},
	}
}

func PrepareFlags(c *cli.Context) error {
	if c.IsSet("attribute") {
		os.Setenv("KDEPLOY_ATTRIBUTE", c.String("attribute"))
	}

	if c.IsSet("kubeware") {
		os.Setenv("KDEPLOY_KUBEWARE", c.String("kubeware"))
	}

	if c.Bool("dry-run") {
		os.Setenv("KDEPLOY_DRYRUN", "1")
	}

	return nil
}

func CmdDeploy(c *cli.Context) {
	// Validate if Kubeware is an url or not
	kubewareUrl, _ := url.Parse(c.String("kubeware"))

	if kubewareUrl != nil {
		if kubewareUrl.Host == "github.com" {
			path := strings.Split(kubewareUrl.Path, "/")
			kubewareName := path[2]
			newPath := []string{""}
			newPath = append(newPath, path[1], path[2], "archive", "master.zip")

			kubewareUrl.Path = strings.Join(newPath, "/")

			client, err := webservice.NewSimpleWebClient(kubewareUrl.String())
			utils.CheckError(err)

			tmpDir, err := ioutil.TempDir("", "kdeploy")
			utils.CheckError(err)

			zipFileLocation, err := client.GetFile(kubewareUrl.Path, tmpDir)
			utils.CheckError(err)

			err = utils.Unzip(zipFileLocation, tmpDir)
			utils.CheckError(err)

			os.Setenv("KDEPLOY_KUBEWARE", fmt.Sprintf("%s/%s-master/", tmpDir, kubewareName))

		} else {
			utils.CheckError(errors.New("We currently only support Github urls"))
		}
	}

	log.Debugf("Going to parse kubeware in %s", os.Getenv("KDEPLOY_KUBEWARE"))

	md := template.ParseMetadata(os.Getenv("KDEPLOY_KUBEWARE"))
	defaults, err := md.AttributeDefaults()
	utils.CheckError(err)
	// build attributes merging "role list" to defaults
	attributes := buildAttributes(c.String("attribute"), defaults)
	// get list of services and parse each one
	servicesSpecs, err := md.ParseServices(attributes)
	utils.CheckError(err)
	// get list of replica controllers and parse each one
	controllersSpecs, err := md.ParseControllers(attributes)
	utils.CheckError(err)

	// get services just to check API availability
	// getServices()

	// create each of the services
	err = createServices(servicesSpecs)
	utils.CheckError(err)
	// create each of the controllers
	err = createControllers(controllersSpecs)
	utils.CheckError(err)
}

func getServices() {
	kube, _ := webservice.NewKubeClient()
	services, _ := kube.GetServices()
	fmt.Println("services: ")
	fmt.Println(services)
}

func buildAttributes(filePath string, defaults digger.Digger) digger.Digger {
	roleList, err := ioutil.ReadFile(filePath)
	utils.CheckError(err)

	roleListDigger, err := digger.NewJSONDigger([]byte(roleList))
	utils.CheckError(err)

	attributes, err := digger.NewMultiDigger(
		roleListDigger,
		defaults,
	)
	utils.CheckError(err)

	return attributes
}

func createServices(svcSpecs []string) error {
	kube, err := webservice.NewKubeClient()
	if err != nil {
		return fmt.Errorf("error creating kube client: %v", err)
	}
	for _, spec := range svcSpecs {
		_, err = kube.CreateService("default", []byte(spec))
		if err != nil {
			return fmt.Errorf("error creating services: %v", err)
		}
	}
	return nil
}

func createControllers(rcSpecs []string) error {
	kube, err := webservice.NewKubeClient()
	if err != nil {
		return fmt.Errorf("error creating kube client: %v", err)
	}
	for _, spec := range rcSpecs {
		_, err = kube.CreateReplicaController("default", []byte(spec))
		if err != nil {
			return fmt.Errorf("error creating replication controllers: %v", err)
		}
	}
	return nil
}
<commit_msg>Minor fix<commit_after>package deploy

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/flexiant/digger"
	"github.com/flexiant/kdeploy/template"
	"github.com/flexiant/kdeploy/utils"
	"github.com/flexiant/kdeploy/webservice"
)

func Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:   "attribute, a",
			Usage:  "Attribute List",
			Value:  "./examples/attributes.json",
			EnvVar: "KDEPLOY_ATTRIBUTE",
		},
		cli.StringFlag{
			Name:   "kubeware, k",
			Usage:  "Kubeware path",
			Value:  "https://github.com/flexiant/kubeware-guestbook",
			EnvVar: "KDEPLOY_KUBEWARE",
		},
		cli.BoolFlag{
			Name:   "dry-run, d",
			Usage:  "Dry Run of Deploy used for debuging options",
			EnvVar: "KDEPLOY_DRYRUN",
		},
	}
}

func PrepareFlags(c *cli.Context) error {
	if c.IsSet("attribute") {
		os.Setenv("KDEPLOY_ATTRIBUTE", c.String("attribute"))
	}

	if c.IsSet("kubeware") {
		os.Setenv("KDEPLOY_KUBEWARE", c.String("kubeware"))
	}

	if c.Bool("dry-run") {
		os.Setenv("KDEPLOY_DRYRUN", "1")
	}

	return nil
}

func CmdDeploy(c *cli.Context) {
	kubewareUrl, _ := url.Parse(os.Getenv("KDEPLOY_KUBEWARE"))

	if kubewareUrl != nil {
		if kubewareUrl.Host == "github.com" {
			path := strings.Split(kubewareUrl.Path, "/")
			kubewareName := path[2]
			newPath := []string{""}
			newPath = append(newPath, path[1], path[2], "archive", "master.zip")

			kubewareUrl.Path = strings.Join(newPath, "/")

			client, err := webservice.NewSimpleWebClient(kubewareUrl.String())
			utils.CheckError(err)

			tmpDir, err := ioutil.TempDir("", "kdeploy")
			utils.CheckError(err)

			zipFileLocation, err := client.GetFile(kubewareUrl.Path, tmpDir)
			utils.CheckError(err)

			err = utils.Unzip(zipFileLocation, tmpDir)
			utils.CheckError(err)

			os.Setenv("KDEPLOY_KUBEWARE", fmt.Sprintf("%s/%s-master/", tmpDir, kubewareName))

		} else {
			utils.CheckError(errors.New("We currently only support Github urls"))
		}
	}

	log.Debugf("Going to parse kubeware in %s", os.Getenv("KDEPLOY_KUBEWARE"))

	md := template.ParseMetadata(os.Getenv("KDEPLOY_KUBEWARE"))
	defaults, err := md.AttributeDefaults()
	utils.CheckError(err)
	// build attributes merging "role list" to defaults
	attributes := buildAttributes(c.String("attribute"), defaults)
	// get list of services and parse each one
	servicesSpecs, err := md.ParseServices(attributes)
	utils.CheckError(err)
	// get list of replica controllers and parse each one
	controllersSpecs, err := md.ParseControllers(attributes)
	utils.CheckError(err)

	// get services just to check API availability
	// getServices()

	// create each of the services
	err = createServices(servicesSpecs)
	utils.CheckError(err)
	// create each of the controllers
	err = createControllers(controllersSpecs)
	utils.CheckError(err)
}

func getServices() {
	kube, _ := webservice.NewKubeClient()
	services, _ := kube.GetServices()
	fmt.Println("services: ")
	fmt.Println(services)
}

func buildAttributes(filePath string, defaults digger.Digger) digger.Digger {
	roleList, err := ioutil.ReadFile(filePath)
	utils.CheckError(err)

	roleListDigger, err := digger.NewJSONDigger([]byte(roleList))
	utils.CheckError(err)

	attributes, err := digger.NewMultiDigger(
		roleListDigger,
		defaults,
	)
	utils.CheckError(err)

	return attributes
}

func createServices(svcSpecs []string) error {
	kube, err := webservice.NewKubeClient()
	if err != nil {
		return fmt.Errorf("error creating kube client: %v", err)
	}
	for _, spec := range svcSpecs {
		_, err = kube.CreateService("default", []byte(spec))
		if err != nil {
			return fmt.Errorf("error creating services: %v", err)
		}
	}
	return nil
}

func createControllers(rcSpecs []string) error {
	kube, err := webservice.NewKubeClient()
	if err != nil {
		return fmt.Errorf("error creating kube client: %v", err)
	}
	for _, spec := range rcSpecs {
		_, err = kube.CreateReplicaController("default", []byte(spec))
		if err != nil {
			return fmt.Errorf("error creating replication controllers: %v", err)
		}
	}
	return nil
}
<|endoftext|>


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

import (
	"io/ioutil"
	"os"
	"reflect"
	"testing"

	"k8s.io/apimachinery/pkg/util/diff"
	"k8s.io/apiserver/pkg/apis/audit"
	// import to call webhook's init() function to register audit.Policy to schema
	_ "k8s.io/apiserver/plugin/pkg/audit/webhook"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

const policyDefV1alpha1 = `
apiVersion: audit.k8s.io/v1alpha1
kind: Policy
rules:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
  - level: RequestResponse
    users: ["tim"]
    userGroups: ["testers", "developers"]
    verbs: ["patch", "delete", "create"]
    resources:
      - group: ""
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings"]
    namespaces: ["default", "kube-system"]
  - level: Metadata
`

const policyDefV1beta1 = `
apiVersion: audit.k8s.io/v1beta1
kind: Policy
rules:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
  - level: RequestResponse
    users: ["tim"]
    userGroups: ["testers", "developers"]
    verbs: ["patch", "delete", "create"]
    resources:
      - group: ""
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings"]
    namespaces: ["default", "kube-system"]
  - level: Metadata
`

var expectedPolicy = &audit.Policy{
	Rules: []audit.PolicyRule{{
		Level:           audit.LevelNone,
		NonResourceURLs: []string{"/healthz*", "/version"},
	}, {
		Level:      audit.LevelRequestResponse,
		Users:      []string{"tim"},
		UserGroups: []string{"testers", "developers"},
		Verbs:      []string{"patch", "delete", "create"},
		Resources: []audit.GroupResources{{}, {
			Group:     "rbac.authorization.k8s.io",
			Resources: []string{"clusterroles", "clusterrolebindings"},
		}},
		Namespaces: []string{"default", "kube-system"},
	}, {
		Level: audit.LevelMetadata,
	}},
}

func TestParserV1alpha1(t *testing.T) {
	f, err := writePolicy(policyDefV1alpha1, t)
	require.NoError(t, err)
	defer os.Remove(f)

	policy, err := LoadPolicyFromFile(f)
	require.NoError(t, err)

	assert.Len(t, policy.Rules, 3) // Sanity check.
	if !reflect.DeepEqual(policy, expectedPolicy) {
		t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
	}
}

func TestParserV1beta1(t *testing.T) {
	f, err := writePolicy(policyDefV1beta1, t)
	require.NoError(t, err)
	defer os.Remove(f)

	policy, err := LoadPolicyFromFile(f)
	require.NoError(t, err)

	assert.Len(t, policy.Rules, 3) // Sanity check.
	if !reflect.DeepEqual(policy, expectedPolicy) {
		t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
	}
}

func TestPolicyCntCheck(t *testing.T) {
	//a set of testCases
	var testCases = []struct {
		caseName, policy string
	}{
		{
			"policyWithNoRule",
			`apiVersion: audit.k8s.io/v1beta1
kind: Policy`,
		},
		{"emptyPolicyFile", ""},
	}

	for _, tc := range testCases {
		f, err := writePolicy(tc.policy, t)
		require.NoError(t, err)
		defer os.Remove(f)

		_, err = LoadPolicyFromFile(f)
		assert.Errorf(t, err, "loaded illegal policy with 0 rules from testCase %s", tc.caseName)
	}
}

func writePolicy(policy string, t *testing.T) (string, error) {
	f, err := ioutil.TempFile("", "policy.yaml")
	require.NoError(t, err)

	_, err = f.WriteString(policy)
	require.NoError(t, err)
	require.NoError(t, f.Close())

	return f.Name(), nil
}
<commit_msg>Update the test under audit policy<commit_after>/*
Copyright 2017 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 policy

import (
	"io/ioutil"
	"os"
	"reflect"
	"testing"

	"k8s.io/apimachinery/pkg/util/diff"
	"k8s.io/apiserver/pkg/apis/audit"
	// import to call webhook's init() function to register audit.Policy to schema
	_ "k8s.io/apiserver/plugin/pkg/audit/webhook"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

const policyDefV1alpha1 = `
apiVersion: audit.k8s.io/v1alpha1
kind: Policy
rules:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
  - level: RequestResponse
    users: ["tim"]
    userGroups: ["testers", "developers"]
    verbs: ["patch", "delete", "create"]
    resources:
      - group: ""
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings"]
    namespaces: ["default", "kube-system"]
  - level: Metadata
`

const policyDefV1beta1 = `
apiVersion: audit.k8s.io/v1beta1
kind: Policy
rules:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
  - level: RequestResponse
    users: ["tim"]
    userGroups: ["testers", "developers"]
    verbs: ["patch", "delete", "create"]
    resources:
      - group: ""
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings"]
    namespaces: ["default", "kube-system"]
  - level: Metadata
`

var expectedPolicy = &audit.Policy{
	Rules: []audit.PolicyRule{{
		Level:           audit.LevelNone,
		NonResourceURLs: []string{"/healthz*", "/version"},
	}, {
		Level:      audit.LevelRequestResponse,
		Users:      []string{"tim"},
		UserGroups: []string{"testers", "developers"},
		Verbs:      []string{"patch", "delete", "create"},
		Resources: []audit.GroupResources{{}, {
			Group:     "rbac.authorization.k8s.io",
			Resources: []string{"clusterroles", "clusterrolebindings"},
		}},
		Namespaces: []string{"default", "kube-system"},
	}, {
		Level: audit.LevelMetadata,
	}},
}

func TestParserV1alpha1(t *testing.T) {
	f, err := writePolicy(t, policyDefV1alpha1)
	require.NoError(t, err)
	defer os.Remove(f)

	policy, err := LoadPolicyFromFile(f)
	require.NoError(t, err)

	assert.Len(t, policy.Rules, 3) // Sanity check.
	if !reflect.DeepEqual(policy, expectedPolicy) {
		t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
	}
}

func TestParserV1beta1(t *testing.T) {
	f, err := writePolicy(t, policyDefV1beta1)
	require.NoError(t, err)
	defer os.Remove(f)

	policy, err := LoadPolicyFromFile(f)
	require.NoError(t, err)

	assert.Len(t, policy.Rules, 3) // Sanity check.
	if !reflect.DeepEqual(policy, expectedPolicy) {
		t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
	}
}

func TestPolicyCntCheck(t *testing.T) {
	var testCases = []struct {
		caseName, policy string
	}{
		{
			"policyWithNoRule",
			`apiVersion: audit.k8s.io/v1beta1
kind: Policy`,
		},
		{"emptyPolicyFile", ""},
	}

	for _, tc := range testCases {
		f, err := writePolicy(t, tc.policy)
		require.NoError(t, err)
		defer os.Remove(f)

		_, err = LoadPolicyFromFile(f)
		assert.Errorf(t, err, "loaded illegal policy with 0 rules from testCase %s", tc.caseName)
	}
}

func writePolicy(t *testing.T, policy string) (string, error) {
	f, err := ioutil.TempFile("", "policy.yaml")
	require.NoError(t, err)

	_, err = f.WriteString(policy)
	require.NoError(t, err)
	require.NoError(t, f.Close())

	return f.Name(), nil
}
<|endoftext|>