<commit_before>//  Copyright Istio 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 echo

import (
	"flag"
	"time"

	"istio.io/istio/pkg/test/util/retry"
)

var (
	callTimeout      = 20 * time.Second
	callDelay        = 10 * time.Millisecond
	callConverge     = 3
	readinessTimeout = 10 * time.Minute
	callsPerWorkload = 5
)

// init registers the command-line flags that we can exposed for "go test".
func init() {
	flag.DurationVar(&callTimeout, "istio.test.echo.callTimeout", callTimeout,
		"Specifies the default total timeout used when retrying calls to the Echo service")
	flag.DurationVar(&callDelay, "istio.test.echo.callDelay", callDelay,
		"Specifies the default delay between successive retry attempts when calling the Echo service")
	flag.IntVar(&callConverge, "istio.test.echo.callConverge", callConverge,
		"Specifies the number of successive retry attempts that must be successful when calling the Echo service")
	flag.DurationVar(&readinessTimeout, "istio.test.echo.readinessTimeout", readinessTimeout,
		"Specifies the default timeout for echo readiness check")
	flag.IntVar(&callsPerWorkload, "istio.test.echo.callsPerWorkload", callsPerWorkload,
		"Specifies the number of calls that will be made for each target workload. "+
			"Only applies if the call count is zero (default) and a target was specified for the call")
}

// DefaultCallRetryOptions returns the default call retry options as specified in command-line flags.
func DefaultCallRetryOptions() []retry.Option {
	return []retry.Option{retry.Timeout(callTimeout), retry.BackoffDelay(callDelay), retry.Converge(callConverge)}
}

// DefaultReadinessTimeout returns the default echo readiness check timeout.
func DefaultReadinessTimeout() time.Duration {
	return readinessTimeout
}

// DefaultCallsPerWorkload returns the number of calls that should be made per target workload by default.
func DefaultCallsPerWorkload() int {
	return callsPerWorkload
}
<commit_msg>tf: make requests a bit more leniant (#39910)<commit_after>//  Copyright Istio 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 echo

import (
	"flag"
	"time"

	"istio.io/istio/pkg/test/util/retry"
)

var (
	callTimeout      = 30 * time.Second
	callDelay        = 20 * time.Millisecond
	callConverge     = 3
	readinessTimeout = 10 * time.Minute
	callsPerWorkload = 3
)

// init registers the command-line flags that we can exposed for "go test".
func init() {
	flag.DurationVar(&callTimeout, "istio.test.echo.callTimeout", callTimeout,
		"Specifies the default total timeout used when retrying calls to the Echo service")
	flag.DurationVar(&callDelay, "istio.test.echo.callDelay", callDelay,
		"Specifies the default delay between successive retry attempts when calling the Echo service")
	flag.IntVar(&callConverge, "istio.test.echo.callConverge", callConverge,
		"Specifies the number of successive retry attempts that must be successful when calling the Echo service")
	flag.DurationVar(&readinessTimeout, "istio.test.echo.readinessTimeout", readinessTimeout,
		"Specifies the default timeout for echo readiness check")
	flag.IntVar(&callsPerWorkload, "istio.test.echo.callsPerWorkload", callsPerWorkload,
		"Specifies the number of calls that will be made for each target workload. "+
			"Only applies if the call count is zero (default) and a target was specified for the call")
}

// DefaultCallRetryOptions returns the default call retry options as specified in command-line flags.
func DefaultCallRetryOptions() []retry.Option {
	return []retry.Option{retry.Timeout(callTimeout), retry.BackoffDelay(callDelay), retry.Converge(callConverge)}
}

// DefaultReadinessTimeout returns the default echo readiness check timeout.
func DefaultReadinessTimeout() time.Duration {
	return readinessTimeout
}

// DefaultCallsPerWorkload returns the number of calls that should be made per target workload by default.
func DefaultCallsPerWorkload() int {
	return callsPerWorkload
}
<|endoftext|>


<commit_before>package networkserver

import (
	"testing"

	"github.com/brocaar/lorawan"
	. "github.com/smartystreets/assertions"

	pb_broker "github.com/TheThingsNetwork/ttn/api/broker"
	pb_handler "github.com/TheThingsNetwork/ttn/api/handler"
	pb "github.com/TheThingsNetwork/ttn/api/networkserver"
	pb_protocol "github.com/TheThingsNetwork/ttn/api/protocol"
	pb_lorawan "github.com/TheThingsNetwork/ttn/api/protocol/lorawan"
	"github.com/TheThingsNetwork/ttn/core/networkserver/device"
	"github.com/TheThingsNetwork/ttn/core/types"
)

func TestHandleGetDevices(t *testing.T) {
	a := New(t)

	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	// No Devices
	res, err := ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{1, 2, 3, 4},
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldBeEmpty)

	// Matching Device
	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{1, 2, 3, 4},
		AppEUI:  types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEUI:  types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		FCntUp:  5,
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{1, 2, 3, 4},
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// Non-Matching DevAddr
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{5, 6, 7, 8},
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 0)

	// Non-Matching FCnt
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{1, 2, 3, 4},
		FCnt:    4,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 0)

	// Non-Matching FCnt, but FCnt Check Disabled
	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{5, 6, 7, 8},
		AppEUI:  types.AppEUI{5, 6, 7, 8, 1, 2, 3, 4},
		DevEUI:  types.DevEUI{5, 6, 7, 8, 1, 2, 3, 4},
		FCntUp:  5,
		Options: device.Options{
			DisableFCntCheck: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{5, 6, 7, 8},
		FCnt:    4,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// 32 Bit Frame Counter (A)
	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{2, 2, 3, 4},
		AppEUI:  types.AppEUI{2, 2, 3, 4, 5, 6, 7, 8},
		DevEUI:  types.DevEUI{2, 2, 3, 4, 5, 6, 7, 8},
		FCntUp:  5 + (2 << 16),
		Options: device.Options{
			Uses32BitFCnt: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{2, 2, 3, 4},
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// 32 Bit Frame Counter (B)
	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{2, 2, 3, 4},
		AppEUI:  types.AppEUI{2, 2, 3, 4, 5, 6, 7, 8},
		DevEUI:  types.DevEUI{2, 2, 3, 4, 5, 6, 7, 8},
		FCntUp:  (2 << 16) - 1,
		Options: device.Options{
			Uses32BitFCnt: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &types.DevAddr{2, 2, 3, 4},
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

}

func TestHandlePrepareActivation(t *testing.T) {
	a := New(t)
	ns := &networkServer{}
	resp, err := ns.HandlePrepareActivation(&pb_broker.DeduplicatedDeviceActivationRequest{})
	a.So(err, ShouldBeNil)
	devAddr := resp.ActivationMetadata.GetLorawan().DevAddr
	a.So(devAddr.IsEmpty(), ShouldBeFalse)
	a.So(devAddr[0]&254, ShouldEqual, 19<<1) // 7 MSB should be NetID
}

func TestHandleActivate(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	_, err := ns.HandleActivate(&pb_handler.DeviceActivationResponse{})
	a.So(err, ShouldNotBeNil)

	_, err = ns.HandleActivate(&pb_handler.DeviceActivationResponse{
		ActivationMetadata: &pb_protocol.ActivationMetadata{},
	})
	a.So(err, ShouldNotBeNil)

	_, err = ns.HandleActivate(&pb_handler.DeviceActivationResponse{
		ActivationMetadata: &pb_protocol.ActivationMetadata{Protocol: &pb_protocol.ActivationMetadata_Lorawan{
			Lorawan: &pb_lorawan.ActivationMetadata{
				AppEui:  &types.AppEUI{0, 0, 0, 0, 0, 0, 3, 1},
				DevEui:  &types.DevEUI{0, 0, 0, 0, 0, 0, 3, 1},
				DevAddr: &types.DevAddr{0, 0, 3, 1},
				NwkSKey: &types.NwkSKey{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1},
			},
		}},
	})
	a.So(err, ShouldBeNil)
}

func TestHandleUplink(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	// Device Not Found
	message := &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: []byte{},
	}
	_, err := ns.HandleUplink(message)
	a.So(err, ShouldNotBeNil)

	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{1, 2, 3, 4},
		AppEUI:  types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEUI:  types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
	})

	// Invalid Payload
	message = &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: []byte{},
	}
	_, err = ns.HandleUplink(message)
	a.So(err, ShouldNotBeNil)

	phy := lorawan.PHYPayload{
		MHDR: lorawan.MHDR{
			MType: lorawan.UnconfirmedDataUp,
			Major: lorawan.LoRaWANR1,
		},
		MACPayload: &lorawan.MACPayload{
			FHDR: lorawan.FHDR{
				DevAddr: lorawan.DevAddr([4]byte{1, 2, 3, 4}),
				FCnt:    1,
			},
		},
	}
	bytes, _ := phy.MarshalBinary()

	// Valid Uplink
	message = &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: bytes,
	}
	res, err := ns.HandleUplink(message)
	a.So(err, ShouldBeNil)
	a.So(res.ResponseTemplate, ShouldNotBeNil)

	// Frame Counter should have been updated
	dev, _ := ns.devices.Get(types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8}, types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8})
	a.So(dev.FCntUp, ShouldEqual, 1)
}

func TestHandleDownlink(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	// Device Not Found
	message := &pb_broker.DownlinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: []byte{},
	}
	_, err := ns.HandleDownlink(message)
	a.So(err, ShouldNotBeNil)

	ns.devices.Set(&device.Device{
		DevAddr: types.DevAddr{1, 2, 3, 4},
		AppEUI:  types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEUI:  types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
	})

	// Invalid Payload
	message = &pb_broker.DownlinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: []byte{},
	}
	_, err = ns.HandleDownlink(message)
	a.So(err, ShouldNotBeNil)

	fPort := uint8(3)
	phy := lorawan.PHYPayload{
		MHDR: lorawan.MHDR{
			MType: lorawan.UnconfirmedDataDown,
			Major: lorawan.LoRaWANR1,
		},
		MACPayload: &lorawan.MACPayload{
			FPort: &fPort,
			FHDR: lorawan.FHDR{
				FCtrl: lorawan.FCtrl{
					ACK: true,
				},
			},
		},
	}
	bytes, _ := phy.MarshalBinary()

	message = &pb_broker.DownlinkMessage{
		AppEui:  &types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8},
		DevEui:  &types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8},
		Payload: bytes,
	}
	res, err := ns.HandleDownlink(message)
	a.So(err, ShouldBeNil)

	var phyPayload lorawan.PHYPayload
	phyPayload.UnmarshalBinary(res.Payload)
	macPayload, _ := phyPayload.MACPayload.(*lorawan.MACPayload)
	a.So(*macPayload.FPort, ShouldEqual, 3)
	a.So(macPayload.FHDR.DevAddr, ShouldEqual, lorawan.DevAddr{1, 2, 3, 4})
	a.So(macPayload.FHDR.FCnt, ShouldEqual, 0)                // The first Frame counter is zero
	a.So(phyPayload.MIC, ShouldNotEqual, [4]byte{0, 0, 0, 0}) // MIC should be set, we'll check it with actual examples in the integration test

	dev, _ := ns.devices.Get(types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8}, types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8})
	a.So(dev.FCntDown, ShouldEqual, 1)

}
<commit_msg>Work around go vet errors<commit_after>package networkserver

import (
	"testing"

	"github.com/brocaar/lorawan"
	. "github.com/smartystreets/assertions"

	pb_broker "github.com/TheThingsNetwork/ttn/api/broker"
	pb_handler "github.com/TheThingsNetwork/ttn/api/handler"
	pb "github.com/TheThingsNetwork/ttn/api/networkserver"
	pb_protocol "github.com/TheThingsNetwork/ttn/api/protocol"
	pb_lorawan "github.com/TheThingsNetwork/ttn/api/protocol/lorawan"
	"github.com/TheThingsNetwork/ttn/core/networkserver/device"
	"github.com/TheThingsNetwork/ttn/core/types"
)

func getDevAddr(bytes ...byte) (addr types.DevAddr) {
	copy(addr[:], bytes[:4])
	return
}

func getEUI(bytes ...byte) (eui types.EUI64) {
	copy(eui[:], bytes[:8])
	return
}

func TestHandleGetDevices(t *testing.T) {
	a := New(t)

	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	// No Devices
	devAddr1 := getDevAddr(1, 2, 3, 4)
	res, err := ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr1,
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldBeEmpty)

	// Matching Device
	ns.devices.Set(&device.Device{
		DevAddr: getDevAddr(1, 2, 3, 4),
		AppEUI:  types.AppEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8)),
		DevEUI:  types.DevEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8)),
		FCntUp:  5,
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr1,
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// Non-Matching DevAddr
	devAddr2 := getDevAddr(5, 6, 7, 8)
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr2,
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 0)

	// Non-Matching FCnt
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr1,
		FCnt:    4,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 0)

	// Non-Matching FCnt, but FCnt Check Disabled
	ns.devices.Set(&device.Device{
		DevAddr: getDevAddr(5, 6, 7, 8),
		AppEUI:  types.AppEUI(getEUI(5, 6, 7, 8, 1, 2, 3, 4)),
		DevEUI:  types.DevEUI(getEUI(5, 6, 7, 8, 1, 2, 3, 4)),
		FCntUp:  5,
		Options: device.Options{
			DisableFCntCheck: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr2,
		FCnt:    4,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// 32 Bit Frame Counter (A)
	devAddr3 := getDevAddr(2, 2, 3, 4)
	ns.devices.Set(&device.Device{
		DevAddr: getDevAddr(2, 2, 3, 4),
		AppEUI:  types.AppEUI(getEUI(2, 2, 3, 4, 5, 6, 7, 8)),
		DevEUI:  types.DevEUI(getEUI(2, 2, 3, 4, 5, 6, 7, 8)),
		FCntUp:  5 + (2 << 16),
		Options: device.Options{
			Uses32BitFCnt: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr3,
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

	// 32 Bit Frame Counter (B)
	ns.devices.Set(&device.Device{
		DevAddr: devAddr3,
		AppEUI:  types.AppEUI(getEUI(2, 2, 3, 4, 5, 6, 7, 8)),
		DevEUI:  types.DevEUI(getEUI(2, 2, 3, 4, 5, 6, 7, 8)),
		FCntUp:  (2 << 16) - 1,
		Options: device.Options{
			Uses32BitFCnt: true,
		},
	})
	res, err = ns.HandleGetDevices(&pb.DevicesRequest{
		DevAddr: &devAddr3,
		FCnt:    5,
	})
	a.So(err, ShouldBeNil)
	a.So(res.Results, ShouldHaveLength, 1)

}

func TestHandlePrepareActivation(t *testing.T) {
	a := New(t)
	ns := &networkServer{}
	resp, err := ns.HandlePrepareActivation(&pb_broker.DeduplicatedDeviceActivationRequest{})
	a.So(err, ShouldBeNil)
	devAddr := resp.ActivationMetadata.GetLorawan().DevAddr
	a.So(devAddr.IsEmpty(), ShouldBeFalse)
	a.So(devAddr[0]&254, ShouldEqual, 19<<1) // 7 MSB should be NetID
}

func TestHandleActivate(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	_, err := ns.HandleActivate(&pb_handler.DeviceActivationResponse{})
	a.So(err, ShouldNotBeNil)

	_, err = ns.HandleActivate(&pb_handler.DeviceActivationResponse{
		ActivationMetadata: &pb_protocol.ActivationMetadata{},
	})
	a.So(err, ShouldNotBeNil)

	devAddr := getDevAddr(0, 0, 3, 1)
	var nwkSKey types.NwkSKey
	copy(nwkSKey[:], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1})
	appEUI := types.AppEUI(getEUI(0, 0, 0, 0, 0, 0, 3, 1))
	devEUI := types.DevEUI(getEUI(0, 0, 0, 0, 0, 0, 3, 1))
	_, err = ns.HandleActivate(&pb_handler.DeviceActivationResponse{
		ActivationMetadata: &pb_protocol.ActivationMetadata{Protocol: &pb_protocol.ActivationMetadata_Lorawan{
			Lorawan: &pb_lorawan.ActivationMetadata{
				AppEui:  &appEUI,
				DevEui:  &devEUI,
				DevAddr: &devAddr,
				NwkSKey: &nwkSKey,
			},
		}},
	})
	a.So(err, ShouldBeNil)
}

func TestHandleUplink(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	appEUI := types.AppEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
	devEUI := types.DevEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
	devAddr := getDevAddr(1, 2, 3, 4)

	// Device Not Found
	message := &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: []byte{},
	}
	_, err := ns.HandleUplink(message)
	a.So(err, ShouldNotBeNil)

	ns.devices.Set(&device.Device{
		DevAddr: devAddr,
		AppEUI:  appEUI,
		DevEUI:  devEUI,
	})

	// Invalid Payload
	message = &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: []byte{},
	}
	_, err = ns.HandleUplink(message)
	a.So(err, ShouldNotBeNil)

	phy := lorawan.PHYPayload{
		MHDR: lorawan.MHDR{
			MType: lorawan.UnconfirmedDataUp,
			Major: lorawan.LoRaWANR1,
		},
		MACPayload: &lorawan.MACPayload{
			FHDR: lorawan.FHDR{
				DevAddr: lorawan.DevAddr([4]byte{1, 2, 3, 4}),
				FCnt:    1,
			},
		},
	}
	bytes, _ := phy.MarshalBinary()

	// Valid Uplink
	message = &pb_broker.DeduplicatedUplinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: bytes,
	}
	res, err := ns.HandleUplink(message)
	a.So(err, ShouldBeNil)
	a.So(res.ResponseTemplate, ShouldNotBeNil)

	// Frame Counter should have been updated
	dev, _ := ns.devices.Get(appEUI, devEUI)
	a.So(dev.FCntUp, ShouldEqual, 1)
}

func TestHandleDownlink(t *testing.T) {
	a := New(t)
	ns := &networkServer{
		devices: device.NewDeviceStore(),
	}

	appEUI := types.AppEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
	devEUI := types.DevEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
	devAddr := getDevAddr(1, 2, 3, 4)

	// Device Not Found
	message := &pb_broker.DownlinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: []byte{},
	}
	_, err := ns.HandleDownlink(message)
	a.So(err, ShouldNotBeNil)

	ns.devices.Set(&device.Device{
		DevAddr: devAddr,
		AppEUI:  appEUI,
		DevEUI:  devEUI,
	})

	// Invalid Payload
	message = &pb_broker.DownlinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: []byte{},
	}
	_, err = ns.HandleDownlink(message)
	a.So(err, ShouldNotBeNil)

	fPort := uint8(3)
	phy := lorawan.PHYPayload{
		MHDR: lorawan.MHDR{
			MType: lorawan.UnconfirmedDataDown,
			Major: lorawan.LoRaWANR1,
		},
		MACPayload: &lorawan.MACPayload{
			FPort: &fPort,
			FHDR: lorawan.FHDR{
				FCtrl: lorawan.FCtrl{
					ACK: true,
				},
			},
		},
	}
	bytes, _ := phy.MarshalBinary()

	message = &pb_broker.DownlinkMessage{
		AppEui:  &appEUI,
		DevEui:  &devEUI,
		Payload: bytes,
	}
	res, err := ns.HandleDownlink(message)
	a.So(err, ShouldBeNil)

	var phyPayload lorawan.PHYPayload
	phyPayload.UnmarshalBinary(res.Payload)
	macPayload, _ := phyPayload.MACPayload.(*lorawan.MACPayload)
	a.So(*macPayload.FPort, ShouldEqual, 3)
	a.So(macPayload.FHDR.DevAddr, ShouldEqual, lorawan.DevAddr{1, 2, 3, 4})
	a.So(macPayload.FHDR.FCnt, ShouldEqual, 0)                // The first Frame counter is zero
	a.So(phyPayload.MIC, ShouldNotEqual, [4]byte{0, 0, 0, 0}) // MIC should be set, we'll check it with actual examples in the integration test

	dev, _ := ns.devices.Get(appEUI, devEUI)
	a.So(dev.FCntDown, ShouldEqual, 1)

}
<|endoftext|>


<commit_before>package junos

// To View the entire configuration, use the keyword "full" for the first
// argument. If anything else outside of "full" is specified, it will return
// the configuration of the specified top-level stanza only. So "security"
// would return everything under the "security" stanza.
func ExampleJunos_viewConfiguration() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// Output format can be "text" or "xml".
	config, err := jnpr.GetConfig("full", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config)
}

// Comparing and working with rollback configurations.
func ExampleJunos_rollbackConfigurations() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// If you want to view the difference between the current configuration and a rollback
	// one, then you can use the ConfigDiff() function to specify a previous config:
	diff, err := jnpr.ConfigDiff(3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(diff)

	// You can rollback to a previous state, or the rescue configuration by using
	// the RollbackConfig() function:
	err := jnpr.RollbackConfig(3)
	if err != nil {
		fmt.Println(err)
	}

	// Create a rescue config from the active configuration.
	jnpr.Rescue("save")

	// You can also delete a rescue config.
	jnpr.Rescue("delete")

	// Rollback to the "rescue" configuration.
	err := jnpr.RollbackConfig("rescue")
	if err != nil {
		fmt.Println(err)
	}
}

// Configuring devices.
func ExampleJunos_configuringDevices() {
	// Use the LoadConfig() function to load the configuration from a file.

	// When configuring a device, it is good practice to lock the configuration database,
	// load the config, commit the configuration, and then unlock the configuration database.
	// You can do this with the following functions: Lock(), Commit(), Unlock().

	// Multiple ways to commit a configuration.

	// Commit the configuration as normal.
	Commit()

	// Check the configuration for any syntax errors (NOTE: you must still issue a
	// Commit() afterwards).
	CommitCheck()

	// Commit at a later time, i.e. 4:30 PM.
	CommitAt("16:30:00")

	// Rollback configuration if a Commit() is not issued within the given <minutes>.
	CommitConfirm(15)

	// You can configure the Junos device by uploading a local file, or pulling from an
	// FTP/HTTP server. The LoadConfig() function takes three arguments:

	// filename or URL, format, and a boolean (true/false) "commit-on-load".

	// If you specify a URL, it must be in the following format:

	// ftp://<username>:<password>@hostname/pathname/file-name
	// http://<username>:<password>@hostname/pathname/file-name

	// Note: The default value for the FTP path variable is the user’s home directory. Thus,
	// by default the file path to the configuration file is relative to the user directory.
	// To specify an absolute path when using FTP, start the path with the characters %2F;
	// for example: ftp://username:password@hostname/%2Fpath/filename.

	// The format of the commands within the file must be one of the following types:

	// set
	// system name-server 1.1.1.1

	// text
	// system {
	//     name-server 1.1.1.1;
	// }

	// xml
	// <system>
	//     <name-server>
	//         <name>1.1.1.1</name>
	//     </name-server>
	// </system>

	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// If the third option is "true" then after the configuration is loaded, a commit
	// will be issued. If set to "false," you will have to commit the configuration
	// using one of the Commit() functions.
	jnpr.Lock()
	err := jnpr.LoadConfig("path-to-file.txt", "set", true)
	if err != nil {
		fmt.Println(err)
	}
	jnpr.Unlock()
}

// Running operational mode commands on a device.
func ExampleJunos_runningCommands() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// You can run operational mode commands such as "show" and "request" by using the
	// Command() function. Output formats can be "text" or "xml".

	// Results returned in text format.
	txtOutput, err := jnpr.Command("show chassis hardware", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(txtOutput)

	// Results returned in XML format.
	xmlOutput, err := jnpr.Command("show chassis hardware", "xml")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(xmlOutput)
}

// Viewing basic information about the device.
func ExampleJunos_deviceInformation() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// When you call the PrintFacts() function, it just prints out the platform
	// and software information to the console.
	jnpr.PrintFacts()

	// You can also loop over the struct field that contains this information yourself:
	fmt.Printf("Hostname: %s", jnpr.Hostname)
	for _, data := range jnpr.Platform {
		fmt.Printf("Model: %s, Version: %s", data.Model, data.Version)
	}
	// Output: Model: SRX240H2, Version: 12.1X47-D10.4
}

// Establishing a connection to Junos Space and working with devices.
func ExampleJunosSpace_devices() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Get the list of devices.
	devices, err := space.Devices()
	if err != nil {
		fmt.Println(err)
	}

	// Iterate over our device list and display some information about them.
	for _, device := range devices.Devices {
		fmt.Printf("Name: %s, IP Address: %s, Platform: %s\n", device.Name, device.IP, device.Platform)
	}

	// Add a device to Junos Space.
	jobID, err = space.AddDevice("sdubs-fw", "admin", "juniper123")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(jobID)
	// Output: 1345283

	// Remove a device from Junos Space.
	err = space.RemoveDevice("sdubs-fw")
	if err != nil {
		fmt.Println(err)
	}
}

// Software upgrades using Junos Space.
func ExampleJunosSpace_softwareUpgrade() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Staging software on a device. The last parameter is whether or not to remove any
	// existing images from the device; boolean.
	//
	// This will not upgrade the device, but only place the image there to be used at a later
	// time.
	jobID, err := space.StageSoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz", false)
	if err != nil {
		fmt.Println(err)
	}

	// If you want to issue a software upgrade to the device, here's how:

	// Configure our options, such as whether or not to reboot the device, etc.
	options := &junos.SoftwareUpgrade{
		UseDownloaded: true,
		Validate:      false,
		Reboot:        false,
		RebootAfter:   0,
		Cleanup:       false,
		RemoveAfter:   false,
	}

	jobID, err := space.DeploySoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz", options)
	if err != nil {
		fmt.Println(err)
	}

	// Remove a staged image from the device.
	jobID, err := space.RemoveStagedSoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz")
	if err != nil {
		fmt.Println(err)
	}
}

// Viewing information about Security Director devices (SRX, J-series, etc.).
func ExampleJunosSpace_securityDirectorDevices() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// List all security devices:
	devices, err := space.SecurityDevices()
	if err != nil {
		fmt.Println(err)
	}

	for _, device := range devices.Devices {
		fmt.Printf("%+v\n", device)
	}
}

// Working with address and service objects.
func ExampleJunosSpace_addressObjects() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// To view the address and service objects, you use the Addresses() and Services() functions. Both of them
	// take a "filter" parameter, which lets you search for objects matching your filter.

	//If you leave the parameter blank (e.g. ""), or specify "all", then every object is returned.

	// Address objects
	addresses, err := space.Addresses("all")
	if err != nil {
		fmt.Println(err)
	}

	for _, address := range addresses.Addresses {
		fmt.Printf("%+v\n", address)
	}

	// Service objects
	services, err := space.Services("all")
	if err != nil {
		fmt.Println(err)
	}

	for _, service := range services.Services {
		fmt.Printf("%+v\n", service)
	}

	// Add an address group. "true" as the first parameter means that we assume the
	// group is going to be an address group.
	space.AddGroup(true, "Blacklist-IPs", "Blacklisted IP addresses")

	// Add a service group. We do this by specifying "false" as the first parameter.
	space.AddGroup(false, "Web-Protocols", "All web-based protocols and ports")

	// Add an address object
	space.AddAddress("my-laptop", "2.2.2.2", "My personal laptop")

	// Add a network
	space.AddAddress("corporate-users", "192.168.1.0/24", "People on campus")

	// Add a service object with an 1800 second inactivity timeout (using "0" disables this feature)
	space.AddService("udp", "udp-5000", 5000, 5000, "UDP port 5000", 1800)

	// Add a service object with a port range
	space.AddService("tcp", "high-port-range", 40000, 65000, "TCP high ports", 0)

	// If you want to modify an existing object group, you do this with the ModifyObject() function. The
	// first parameter is whether the object is an address group (true) or a service group (false).

	// Add a service to a group
	space.ModifyObject(false, "add", "service-group", "service-name")

	// Remove an address object from a group
	space.ModifyObject(true, "remove", "Whitelisted-Addresses", "bad-ip")

	// Rename an object
	space.ModifyObject(false, "rename", "Web-Services", "Web-Ports")

	// Delete an object
	space.ModifyObject(true, "delete", "my-laptop")
}

// Working with polymorphic (variable) objects.
func ExampleJunosSpace_variables() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Add a variable
	// The parameters are as follows: variable-name, description, default-value
	space.AddVariable("test-variable", "Our test variable", "default-object")

	// Create our session state for modifying variables
	v, err := space.ModifyVariable()
	if err != nil {
		log.Fatal(err)
	}

	// Adding objects to the variable
	v.Add("test-variable", "srx-1", "user-pc")
	v.Add("test-variable", "corp-firewall", "db-server")

	// Delete a variable
	space.DeleteVariable("test-variable")
}

// Working with policies.
func ExampleJunosSpace_policies() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// List all security policies Junos Space manages:
	policies, err := space.Policies()
	if err != nil {
		fmt.Println(err)
	}

	for _, policy := range policies.Policies {
		fmt.Printf("%s\n", policy.Name)
	}

	// For example, say we have been adding and removing objects in a group, and that group
	// is referenced in a firewall policy. Here's how to update the policy:

	// Update the policy. If "false" is specified, then the policy is only published, and the
	// device is not updated.
	job, err := space.PublishPolicy("Internet-Firewall-Policy", true)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Job ID: %d\n", job)

	// Let's update a device knowing that we have some previously published services.
	job, err := space.UpdateDevice("firewall-1.company.com")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Job ID: %d\n", job)
}
<commit_msg>Added example for Resync()<commit_after>package junos

// To View the entire configuration, use the keyword "full" for the first
// argument. If anything else outside of "full" is specified, it will return
// the configuration of the specified top-level stanza only. So "security"
// would return everything under the "security" stanza.
func ExampleJunos_viewConfiguration() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// Output format can be "text" or "xml".
	config, err := jnpr.GetConfig("full", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config)
}

// Comparing and working with rollback configurations.
func ExampleJunos_rollbackConfigurations() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// If you want to view the difference between the current configuration and a rollback
	// one, then you can use the ConfigDiff() function to specify a previous config:
	diff, err := jnpr.ConfigDiff(3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(diff)

	// You can rollback to a previous state, or the rescue configuration by using
	// the RollbackConfig() function:
	err := jnpr.RollbackConfig(3)
	if err != nil {
		fmt.Println(err)
	}

	// Create a rescue config from the active configuration.
	jnpr.Rescue("save")

	// You can also delete a rescue config.
	jnpr.Rescue("delete")

	// Rollback to the "rescue" configuration.
	err := jnpr.RollbackConfig("rescue")
	if err != nil {
		fmt.Println(err)
	}
}

// Configuring devices.
func ExampleJunos_configuringDevices() {
	// Use the LoadConfig() function to load the configuration from a file.

	// When configuring a device, it is good practice to lock the configuration database,
	// load the config, commit the configuration, and then unlock the configuration database.
	// You can do this with the following functions: Lock(), Commit(), Unlock().

	// Multiple ways to commit a configuration.

	// Commit the configuration as normal.
	Commit()

	// Check the configuration for any syntax errors (NOTE: you must still issue a
	// Commit() afterwards).
	CommitCheck()

	// Commit at a later time, i.e. 4:30 PM.
	CommitAt("16:30:00")

	// Rollback configuration if a Commit() is not issued within the given <minutes>.
	CommitConfirm(15)

	// You can configure the Junos device by uploading a local file, or pulling from an
	// FTP/HTTP server. The LoadConfig() function takes three arguments:

	// filename or URL, format, and a boolean (true/false) "commit-on-load".

	// If you specify a URL, it must be in the following format:

	// ftp://<username>:<password>@hostname/pathname/file-name
	// http://<username>:<password>@hostname/pathname/file-name

	// Note: The default value for the FTP path variable is the user’s home directory. Thus,
	// by default the file path to the configuration file is relative to the user directory.
	// To specify an absolute path when using FTP, start the path with the characters %2F;
	// for example: ftp://username:password@hostname/%2Fpath/filename.

	// The format of the commands within the file must be one of the following types:

	// set
	// system name-server 1.1.1.1

	// text
	// system {
	//     name-server 1.1.1.1;
	// }

	// xml
	// <system>
	//     <name-server>
	//         <name>1.1.1.1</name>
	//     </name-server>
	// </system>

	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// If the third option is "true" then after the configuration is loaded, a commit
	// will be issued. If set to "false," you will have to commit the configuration
	// using one of the Commit() functions.
	jnpr.Lock()
	err := jnpr.LoadConfig("path-to-file.txt", "set", true)
	if err != nil {
		fmt.Println(err)
	}
	jnpr.Unlock()
}

// Running operational mode commands on a device.
func ExampleJunos_runningCommands() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// You can run operational mode commands such as "show" and "request" by using the
	// Command() function. Output formats can be "text" or "xml".

	// Results returned in text format.
	txtOutput, err := jnpr.Command("show chassis hardware", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(txtOutput)

	// Results returned in XML format.
	xmlOutput, err := jnpr.Command("show chassis hardware", "xml")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(xmlOutput)
}

// Viewing basic information about the device.
func ExampleJunos_deviceInformation() {
	// Establish our session first.
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()

	// When you call the PrintFacts() function, it just prints out the platform
	// and software information to the console.
	jnpr.PrintFacts()

	// You can also loop over the struct field that contains this information yourself:
	fmt.Printf("Hostname: %s", jnpr.Hostname)
	for _, data := range jnpr.Platform {
		fmt.Printf("Model: %s, Version: %s", data.Model, data.Version)
	}
	// Output: Model: SRX240H2, Version: 12.1X47-D10.4
}

// Establishing a connection to Junos Space and working with devices.
func ExampleJunosSpace_devices() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Get the list of devices.
	devices, err := space.Devices()
	if err != nil {
		fmt.Println(err)
	}

	// Iterate over our device list and display some information about them.
	for _, device := range devices.Devices {
		fmt.Printf("Name: %s, IP Address: %s, Platform: %s\n", device.Name, device.IP, device.Platform)
	}

	// Add a device to Junos Space.
	jobID, err = space.AddDevice("sdubs-fw", "admin", "juniper123")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(jobID)
	// Output: 1345283

	// Remove a device from Junos Space.
	err = space.RemoveDevice("sdubs-fw")
	if err != nil {
		fmt.Println(err)
	}

	// Resynchronize a device. A good option if you do a lot of configuration to a device
	// outside of Junos Space.
	job, err := space.Resync("firewall-A")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Job ID: %d\n", job)
}

// Software upgrades using Junos Space.
func ExampleJunosSpace_softwareUpgrade() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Staging software on a device. The last parameter is whether or not to remove any
	// existing images from the device; boolean.
	//
	// This will not upgrade the device, but only place the image there to be used at a later
	// time.
	jobID, err := space.StageSoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz", false)
	if err != nil {
		fmt.Println(err)
	}

	// If you want to issue a software upgrade to the device, here's how:

	// Configure our options, such as whether or not to reboot the device, etc.
	options := &junos.SoftwareUpgrade{
		UseDownloaded: true,
		Validate:      false,
		Reboot:        false,
		RebootAfter:   0,
		Cleanup:       false,
		RemoveAfter:   false,
	}

	jobID, err := space.DeploySoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz", options)
	if err != nil {
		fmt.Println(err)
	}

	// Remove a staged image from the device.
	jobID, err := space.RemoveStagedSoftware("sdubs-fw", "junos-srxsme-12.1X46-D30.2-domestic.tgz")
	if err != nil {
		fmt.Println(err)
	}
}

// Viewing information about Security Director devices (SRX, J-series, etc.).
func ExampleJunosSpace_securityDirectorDevices() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// List all security devices:
	devices, err := space.SecurityDevices()
	if err != nil {
		fmt.Println(err)
	}

	for _, device := range devices.Devices {
		fmt.Printf("%+v\n", device)
	}
}

// Working with address and service objects.
func ExampleJunosSpace_addressObjects() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// To view the address and service objects, you use the Addresses() and Services() functions. Both of them
	// take a "filter" parameter, which lets you search for objects matching your filter.

	//If you leave the parameter blank (e.g. ""), or specify "all", then every object is returned.

	// Address objects
	addresses, err := space.Addresses("all")
	if err != nil {
		fmt.Println(err)
	}

	for _, address := range addresses.Addresses {
		fmt.Printf("%+v\n", address)
	}

	// Service objects
	services, err := space.Services("all")
	if err != nil {
		fmt.Println(err)
	}

	for _, service := range services.Services {
		fmt.Printf("%+v\n", service)
	}

	// Add an address group. "true" as the first parameter means that we assume the
	// group is going to be an address group.
	space.AddGroup(true, "Blacklist-IPs", "Blacklisted IP addresses")

	// Add a service group. We do this by specifying "false" as the first parameter.
	space.AddGroup(false, "Web-Protocols", "All web-based protocols and ports")

	// Add an address object
	space.AddAddress("my-laptop", "2.2.2.2", "My personal laptop")

	// Add a network
	space.AddAddress("corporate-users", "192.168.1.0/24", "People on campus")

	// Add a service object with an 1800 second inactivity timeout (using "0" disables this feature)
	space.AddService("udp", "udp-5000", 5000, 5000, "UDP port 5000", 1800)

	// Add a service object with a port range
	space.AddService("tcp", "high-port-range", 40000, 65000, "TCP high ports", 0)

	// If you want to modify an existing object group, you do this with the ModifyObject() function. The
	// first parameter is whether the object is an address group (true) or a service group (false).

	// Add a service to a group
	space.ModifyObject(false, "add", "service-group", "service-name")

	// Remove an address object from a group
	space.ModifyObject(true, "remove", "Whitelisted-Addresses", "bad-ip")

	// Rename an object
	space.ModifyObject(false, "rename", "Web-Services", "Web-Ports")

	// Delete an object
	space.ModifyObject(true, "delete", "my-laptop")
}

// Working with polymorphic (variable) objects.
func ExampleJunosSpace_variables() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// Add a variable
	// The parameters are as follows: variable-name, description, default-value
	space.AddVariable("test-variable", "Our test variable", "default-object")

	// Create our session state for modifying variables
	v, err := space.ModifyVariable()
	if err != nil {
		log.Fatal(err)
	}

	// Adding objects to the variable
	v.Add("test-variable", "srx-1", "user-pc")
	v.Add("test-variable", "corp-firewall", "db-server")

	// Delete a variable
	space.DeleteVariable("test-variable")
}

// Working with policies.
func ExampleJunosSpace_policies() {
	// Establish a connection to a Junos Space server.
	space := junos.NewServer("space.company.com", "admin", "juniper123")

	// List all security policies Junos Space manages:
	policies, err := space.Policies()
	if err != nil {
		fmt.Println(err)
	}

	for _, policy := range policies.Policies {
		fmt.Printf("%s\n", policy.Name)
	}

	// For example, say we have been adding and removing objects in a group, and that group
	// is referenced in a firewall policy. Here's how to update the policy:

	// Update the policy. If "false" is specified, then the policy is only published, and the
	// device is not updated.
	job, err := space.PublishPolicy("Internet-Firewall-Policy", true)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Job ID: %d\n", job)

	// Let's update a device knowing that we have some previously published services.
	job, err := space.UpdateDevice("firewall-1.company.com")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Job ID: %d\n", job)
}
<|endoftext|>


<commit_before>package junos

// Establishing a session
func Example() {
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()
}
<commit_msg>Added more examples<commit_after>package junos

// Establishing a session
func Example() {
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()
}

// To View the entire configuration, use the keyword "full" for the first
// argument. If anything else outside of "full" is specified, it will return
// the configuration of the specified top-level stanza only. So "security" would return everything
// under the "security" stanza.
func Example_viewConfiguration() {
	// Output format can be "text" or "xml"
	config, err := jnpr.GetConfig("full", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config)
}
<|endoftext|>


<commit_before>/*
	Android Compile Server for Skia Bots.
*/

package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"net/http"
	"path/filepath"
	"runtime"
	"strconv"
	"time"

	"cloud.google.com/go/datastore"
	"github.com/gorilla/mux"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/login"
	"go.skia.org/infra/go/skiaversion"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/webhook"
)

const (
	// OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow.
	OAUTH2_CALLBACK_PATH = "/oauth2callback/"

	REGISTER_RUN_POST_URI = "/_/register"
	GET_TASK_STATUS_URI   = "/get_task_status"

	PROD_URI = "https://android-compile.skia.org"
)

var (
	// Flags
	host         = flag.String("host", "localhost", "HTTP service host")
	promPort     = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':20000')")
	port         = flag.String("port", ":8002", "HTTP service port (e.g., ':8002')")
	local        = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	workdir      = flag.String("workdir", ".", "Directory to use for scratch work.")
	resourcesDir = flag.String("resources_dir", "", "The directory to find compile.sh, templates, JS, and CSS files.  If blank then the directory two directories up from this source file will be used.")
	numCheckouts = flag.Int("num_checkouts", 10, "The number of checkouts the Android compile server should maintain.")

	// Datastore params
	namespace   = flag.String("namespace", "android-compile", "The Cloud Datastore namespace, such as 'android-compile'.")
	projectName = flag.String("project_name", "google.com:skia-buildbots", "The Google Cloud project name.")

	// OAUTH params
	authWhiteList = flag.String("auth_whitelist", "google.com", "White space separated list of domains and email addresses that are allowed to login.")
	redirectURL   = flag.String("redirect_url", "https://leasing.skia.org/oauth2callback/", "OAuth2 redirect url. Only used when local=false.")

	// indexTemplate is the main index.html page we serve.
	indexTemplate *template.Template = nil

	serverURL string
)

func reloadTemplates() {
	if *resourcesDir == "" {
		// If resourcesDir is not specified then consider the directory two directories up from this
		// source file as the resourcesDir.
		_, filename, _, _ := runtime.Caller(0)
		*resourcesDir = filepath.Join(filepath.Dir(filename), "../..")
	}
	indexTemplate = template.Must(template.ParseFiles(
		filepath.Join(*resourcesDir, "templates/index.html"),
		filepath.Join(*resourcesDir, "templates/header.html"),
	))
}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, login.LoginURL(w, r), http.StatusFound)
	return
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	if *local {
		reloadTemplates()
	}
	w.Header().Set("Content-Type", "text/html")

	waitingTasks, runningTasks, err := GetCompileTasks()
	if err != nil {
		httputils.ReportError(w, r, err, "Failed to get compile tasks")
		return
	}

	var templateTasks = struct {
		WaitingTasks []*CompileTask
		RunningTasks []*CompileTask
	}{
		WaitingTasks: waitingTasks,
		RunningTasks: runningTasks,
	}

	if err := indexTemplate.Execute(w, templateTasks); err != nil {
		httputils.ReportError(w, r, err, "Failed to expand template")
		return
	}
	return
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	_, err := webhook.AuthenticateRequest(r)
	if err != nil {
		httputils.ReportError(w, r, err, "Authentication failure")
		return
	}
	w.Header().Set("Content-Type", "application/json")

	taskParam := r.FormValue("task")
	if taskParam == "" {
		httputils.ReportError(w, r, nil, "Missing task parameter")
		return
	}
	taskID, err := strconv.ParseInt(taskParam, 10, 64)
	if err != nil {
		httputils.ReportError(w, r, err, "Invalid task parameter")
		return
	}

	_, t, err := GetDSTask(taskID)
	if err != nil {
		httputils.ReportError(w, r, err, "Could not find task")
		return
	}

	if err := json.NewEncoder(w).Encode(t); err != nil {
		httputils.ReportError(w, r, err, "Failed to encode JSON")
		return

	}

	return
}

func registerRunHandler(w http.ResponseWriter, r *http.Request) {
	data, err := webhook.AuthenticateRequest(r)
	if err != nil {
		httputils.ReportError(w, r, err, "Authentication failure")
		return
	}
	w.Header().Set("Content-Type", "application/json")

	task := CompileTask{}
	if err := json.Unmarshal(data, &task); err != nil {
		httputils.ReportError(w, r, err, "Failed to parse request.")
		return
	}

	// Either hash or (issue & patchset) must be specified.
	if task.Hash == "" && (task.Issue == 0 || task.PatchSet == 0) {
		httputils.ReportError(w, r, nil, "Either hash or (issue & patchset) must be specified")
		return
	}

	// Check to see if this task has already been requested and is currently
	// running. If it is then return the existing ID without triggering a new
	// task. This is done to avoid creating unnecessary duplicate tasks.
	_, runningTasksAndKeys, err := GetCompileTasksAndKeys()
	if err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Failed to retrieve currently running compile tasks and keys: %s", err))
		return
	}
	for _, runningTaskAndKey := range runningTasksAndKeys {
		if (task.Hash != "" && task.Hash == runningTaskAndKey.task.Hash) ||
			(task.Issue == runningTaskAndKey.task.Issue && task.PatchSet == runningTaskAndKey.task.PatchSet) {
			if err := json.NewEncoder(w).Encode(map[string]interface{}{"taskID": runningTaskAndKey.key.ID}); err != nil {
				httputils.ReportError(w, r, err, "Failed to encode JSON")
				return
			}
			sklog.Infof("Got request for already running task [hash: %s, issue: %d, patchset: %d]. Returning existing ID: %d", task.Hash, task.Issue, task.PatchSet, runningTaskAndKey.key.ID)
			return
		}
	}

	key := GetNewDSKey()
	task.Created = time.Now()
	ctx := context.Background()
	datastoreKey, err := PutDSTask(ctx, key, &task)
	if err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Error putting task in datastore: %v", err))
		return
	}

	// Kick off the task and return the task ID.
	triggerCompileTask(ctx, &task, datastoreKey)
	if err := json.NewEncoder(w).Encode(map[string]interface{}{"taskID": datastoreKey.ID}); err != nil {
		httputils.ReportError(w, r, err, "Failed to encode JSON")
		return
	}
}

// triggerCompileTask runs the specified CompileTask in a goroutine. After
// completion the task is marked as Done and updated in the Datastore.
func triggerCompileTask(ctx context.Context, task *CompileTask, datastoreKey *datastore.Key) {
	go func() {
		pathToCompileScript := filepath.Join(*resourcesDir, "compile.sh")
		if err := RunCompileTask(ctx, task, datastoreKey, pathToCompileScript); err != nil {
			task.InfraFailure = true
			sklog.Errorf("Error when compiling task with ID %d: %s", datastoreKey.ID, err)
		}
		task.Done = true
		task.Completed = time.Now()
		if _, err := UpdateDSTask(ctx, datastoreKey, task); err != nil {
			sklog.Errorf("Could not update compile task with ID %d: %s", datastoreKey.ID, err)
		}
	}()
}

func runServer() {
	r := mux.NewRouter()
	r.PathPrefix("/res/").HandlerFunc(httputils.MakeResourceHandler(*resourcesDir))
	r.HandleFunc("/", indexHandler)
	r.HandleFunc(REGISTER_RUN_POST_URI, registerRunHandler).Methods("POST")
	r.HandleFunc(GET_TASK_STATUS_URI, statusHandler)

	r.HandleFunc("/json/version", skiaversion.JsonHandler)
	r.HandleFunc(OAUTH2_CALLBACK_PATH, login.OAuth2CallbackHandler)
	r.HandleFunc("/login/", loginHandler)
	r.HandleFunc("/logout/", login.LogoutHandler)
	r.HandleFunc("/loginstatus/", login.StatusHandler)
	http.Handle("/", httputils.LoggingGzipRequestResponse(r))
	sklog.AddLogsRedirect(r)
	sklog.Infof("Ready to serve on %s", serverURL)
	sklog.Fatal(http.ListenAndServe(*port, nil))
}

func main() {
	flag.Parse()

	if *local {
		// Dont log to cloud in local mode.
		common.InitWithMust(
			"android_compile",
			common.PrometheusOpt(promPort),
		)
		reloadTemplates()
	} else {
		common.InitWithMust(
			"android_compile",
			common.PrometheusOpt(promPort),
			common.CloudLoggingOpt(),
		)
	}
	defer common.Defer()
	skiaversion.MustLogVersion()

	reloadTemplates()
	serverURL = "https://" + *host
	if *local {
		serverURL = "http://" + *host + *port
	}

	useRedirectURL := fmt.Sprintf("http://localhost%s/oauth2callback/", *port)
	if !*local {
		useRedirectURL = *redirectURL
	}
	if err := login.Init(useRedirectURL, *authWhiteList); err != nil {
		sklog.Fatal(fmt.Errorf("Problem setting up server OAuth: %s", err))
	}

	// Initialize cloud datastore.
	if err := DatastoreInit(*projectName, *namespace); err != nil {
		sklog.Fatalf("Failed to init cloud datastore: %s", err)
	}

	// Initialize checkouts.
	if err := CheckoutsInit(*numCheckouts, *workdir); err != nil {
		sklog.Fatalf("Failed to init checkouts: %s", err)
	}

	// Initialize webhooks.
	if *local {
		webhook.InitRequestSaltForTesting()
	} else {
		webhook.MustInitRequestSaltFromMetadata("ac_webhook_request_salt")
	}

	// Find and reschedule all CompileTasks that are in "running" state. Any
	// "running" CompileTasks means that the server was restarted in the middle
	// of run(s).
	ctx := context.Background()
	_, runningTasksAndKeys, err := GetCompileTasksAndKeys()
	if err != nil {
		sklog.Fatalf("Failed to retrieve compile tasks and keys: %s", err)
	}
	for _, taskAndKey := range runningTasksAndKeys {
		sklog.Infof("Found orphaned task %d. Retriggering it...", taskAndKey.key.ID)
		triggerCompileTask(ctx, taskAndKey.task, taskAndKey.key)
	}

	runServer()
}
<commit_msg>[Android Compile Server] Fixes to prevent duplicate tasks from running<commit_after>/*
	Android Compile Server for Skia Bots.
*/

package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"net/http"
	"path/filepath"
	"runtime"
	"strconv"
	"time"

	"cloud.google.com/go/datastore"
	"github.com/gorilla/mux"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/login"
	"go.skia.org/infra/go/skiaversion"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/webhook"
)

const (
	// OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow.
	OAUTH2_CALLBACK_PATH = "/oauth2callback/"

	REGISTER_RUN_POST_URI = "/_/register"
	GET_TASK_STATUS_URI   = "/get_task_status"

	PROD_URI = "https://android-compile.skia.org"
)

var (
	// Flags
	host         = flag.String("host", "localhost", "HTTP service host")
	promPort     = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':20000')")
	port         = flag.String("port", ":8002", "HTTP service port (e.g., ':8002')")
	local        = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	workdir      = flag.String("workdir", ".", "Directory to use for scratch work.")
	resourcesDir = flag.String("resources_dir", "", "The directory to find compile.sh, templates, JS, and CSS files.  If blank then the directory two directories up from this source file will be used.")
	numCheckouts = flag.Int("num_checkouts", 10, "The number of checkouts the Android compile server should maintain.")

	// Datastore params
	namespace   = flag.String("namespace", "android-compile", "The Cloud Datastore namespace, such as 'android-compile'.")
	projectName = flag.String("project_name", "google.com:skia-buildbots", "The Google Cloud project name.")

	// OAUTH params
	authWhiteList = flag.String("auth_whitelist", "google.com", "White space separated list of domains and email addresses that are allowed to login.")
	redirectURL   = flag.String("redirect_url", "https://leasing.skia.org/oauth2callback/", "OAuth2 redirect url. Only used when local=false.")

	// indexTemplate is the main index.html page we serve.
	indexTemplate *template.Template = nil

	serverURL string
)

func reloadTemplates() {
	if *resourcesDir == "" {
		// If resourcesDir is not specified then consider the directory two directories up from this
		// source file as the resourcesDir.
		_, filename, _, _ := runtime.Caller(0)
		*resourcesDir = filepath.Join(filepath.Dir(filename), "../..")
	}
	indexTemplate = template.Must(template.ParseFiles(
		filepath.Join(*resourcesDir, "templates/index.html"),
		filepath.Join(*resourcesDir, "templates/header.html"),
	))
}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, login.LoginURL(w, r), http.StatusFound)
	return
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	if *local {
		reloadTemplates()
	}
	w.Header().Set("Content-Type", "text/html")

	waitingTasks, runningTasks, err := GetCompileTasks()
	if err != nil {
		httputils.ReportError(w, r, err, "Failed to get compile tasks")
		return
	}

	var templateTasks = struct {
		WaitingTasks []*CompileTask
		RunningTasks []*CompileTask
	}{
		WaitingTasks: waitingTasks,
		RunningTasks: runningTasks,
	}

	if err := indexTemplate.Execute(w, templateTasks); err != nil {
		httputils.ReportError(w, r, err, "Failed to expand template")
		return
	}
	return
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	_, err := webhook.AuthenticateRequest(r)
	if err != nil {
		httputils.ReportError(w, r, err, "Authentication failure")
		return
	}
	w.Header().Set("Content-Type", "application/json")

	taskParam := r.FormValue("task")
	if taskParam == "" {
		httputils.ReportError(w, r, nil, "Missing task parameter")
		return
	}
	taskID, err := strconv.ParseInt(taskParam, 10, 64)
	if err != nil {
		httputils.ReportError(w, r, err, "Invalid task parameter")
		return
	}

	_, t, err := GetDSTask(taskID)
	if err != nil {
		httputils.ReportError(w, r, err, "Could not find task")
		return
	}

	if err := json.NewEncoder(w).Encode(t); err != nil {
		httputils.ReportError(w, r, err, "Failed to encode JSON")
		return

	}

	return
}

func registerRunHandler(w http.ResponseWriter, r *http.Request) {
	data, err := webhook.AuthenticateRequest(r)
	if err != nil {
		httputils.ReportError(w, r, err, "Authentication failure")
		return
	}
	w.Header().Set("Content-Type", "application/json")

	task := CompileTask{}
	if err := json.Unmarshal(data, &task); err != nil {
		httputils.ReportError(w, r, err, "Failed to parse request.")
		return
	}

	// Either hash or (issue & patchset) must be specified.
	if task.Hash == "" && (task.Issue == 0 || task.PatchSet == 0) {
		httputils.ReportError(w, r, nil, "Either hash or (issue & patchset) must be specified")
		return
	}

	// Check to see if this task has already been requested and is currently
	// waiting/running. If it is then return the existing ID without triggering
	// a new task. This is done to avoid creating unnecessary duplicate tasks.
	waitingTasksAndKeys, runningTasksAndKeys, err := GetCompileTasksAndKeys()
	if err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Failed to retrieve currently waiting/running compile tasks and keys: %s", err))
		return
	}
	for _, existingTaskAndKey := range append(waitingTasksAndKeys, runningTasksAndKeys...) {
		if (task.Hash != "" && task.Hash == existingTaskAndKey.task.Hash) ||
			(task.Hash == "" && task.Issue == existingTaskAndKey.task.Issue && task.PatchSet == existingTaskAndKey.task.PatchSet) {
			if err := json.NewEncoder(w).Encode(map[string]interface{}{"taskID": existingTaskAndKey.key.ID}); err != nil {
				httputils.ReportError(w, r, err, "Failed to encode JSON")
				return
			}
			sklog.Infof("Got request for already existing task [hash: %s, issue: %d, patchset: %d]. Returning existing ID: %d", task.Hash, task.Issue, task.PatchSet, existingTaskAndKey.key.ID)
			return
		}
	}

	key := GetNewDSKey()
	task.Created = time.Now()
	ctx := context.Background()
	datastoreKey, err := PutDSTask(ctx, key, &task)
	if err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Error putting task in datastore: %v", err))
		return
	}

	// Kick off the task and return the task ID.
	triggerCompileTask(ctx, &task, datastoreKey)
	if err := json.NewEncoder(w).Encode(map[string]interface{}{"taskID": datastoreKey.ID}); err != nil {
		httputils.ReportError(w, r, err, "Failed to encode JSON")
		return
	}
}

// triggerCompileTask runs the specified CompileTask in a goroutine. After
// completion the task is marked as Done and updated in the Datastore.
func triggerCompileTask(ctx context.Context, task *CompileTask, datastoreKey *datastore.Key) {
	go func() {
		pathToCompileScript := filepath.Join(*resourcesDir, "compile.sh")
		if err := RunCompileTask(ctx, task, datastoreKey, pathToCompileScript); err != nil {
			task.InfraFailure = true
			sklog.Errorf("Error when compiling task with ID %d: %s", datastoreKey.ID, err)
		}
		task.Done = true
		task.Completed = time.Now()
		if _, err := UpdateDSTask(ctx, datastoreKey, task); err != nil {
			sklog.Errorf("Could not update compile task with ID %d: %s", datastoreKey.ID, err)
		}
	}()
}

func runServer() {
	r := mux.NewRouter()
	r.PathPrefix("/res/").HandlerFunc(httputils.MakeResourceHandler(*resourcesDir))
	r.HandleFunc("/", indexHandler)
	r.HandleFunc(REGISTER_RUN_POST_URI, registerRunHandler).Methods("POST")
	r.HandleFunc(GET_TASK_STATUS_URI, statusHandler)

	r.HandleFunc("/json/version", skiaversion.JsonHandler)
	r.HandleFunc(OAUTH2_CALLBACK_PATH, login.OAuth2CallbackHandler)
	r.HandleFunc("/login/", loginHandler)
	r.HandleFunc("/logout/", login.LogoutHandler)
	r.HandleFunc("/loginstatus/", login.StatusHandler)
	http.Handle("/", httputils.LoggingGzipRequestResponse(r))
	sklog.AddLogsRedirect(r)
	sklog.Infof("Ready to serve on %s", serverURL)
	sklog.Fatal(http.ListenAndServe(*port, nil))
}

func main() {
	flag.Parse()

	if *local {
		// Dont log to cloud in local mode.
		common.InitWithMust(
			"android_compile",
			common.PrometheusOpt(promPort),
		)
		reloadTemplates()
	} else {
		common.InitWithMust(
			"android_compile",
			common.PrometheusOpt(promPort),
			common.CloudLoggingOpt(),
		)
	}
	defer common.Defer()
	skiaversion.MustLogVersion()

	reloadTemplates()
	serverURL = "https://" + *host
	if *local {
		serverURL = "http://" + *host + *port
	}

	useRedirectURL := fmt.Sprintf("http://localhost%s/oauth2callback/", *port)
	if !*local {
		useRedirectURL = *redirectURL
	}
	if err := login.Init(useRedirectURL, *authWhiteList); err != nil {
		sklog.Fatal(fmt.Errorf("Problem setting up server OAuth: %s", err))
	}

	// Initialize cloud datastore.
	if err := DatastoreInit(*projectName, *namespace); err != nil {
		sklog.Fatalf("Failed to init cloud datastore: %s", err)
	}

	// Initialize checkouts.
	if err := CheckoutsInit(*numCheckouts, *workdir); err != nil {
		sklog.Fatalf("Failed to init checkouts: %s", err)
	}

	// Initialize webhooks.
	if *local {
		webhook.InitRequestSaltForTesting()
	} else {
		webhook.MustInitRequestSaltFromMetadata("ac_webhook_request_salt")
	}

	// Find and reschedule all CompileTasks that are in "running" state. Any
	// "running" CompileTasks means that the server was restarted in the middle
	// of run(s).
	ctx := context.Background()
	_, runningTasksAndKeys, err := GetCompileTasksAndKeys()
	if err != nil {
		sklog.Fatalf("Failed to retrieve compile tasks and keys: %s", err)
	}
	for _, taskAndKey := range runningTasksAndKeys {
		sklog.Infof("Found orphaned task %d. Retriggering it...", taskAndKey.key.ID)
		triggerCompileTask(ctx, taskAndKey.task, taskAndKey.key)
	}

	runServer()
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/autoscaling"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsAutoscalingAttachment_basic(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
				),
			},
			// Add in one association
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_associated,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
				),
			},
			// Test adding a 2nd
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_double_associated,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 2),
				),
			},
			// Now remove that newest one
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_associated,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
				),
			},
			// Now remove them both
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
				),
			},
		},
	})
}

func testAccCheckAWSAutocalingAttachmentExists(asgname string, loadBalancerCount int) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[asgname]
		if !ok {
			return fmt.Errorf("Not found: %s", asgname)
		}

		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		asg := rs.Primary.ID

		actual, err := conn.DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{
			AutoScalingGroupNames: []*string{aws.String(asg)},
		})

		if err != nil {
			return fmt.Errorf("Recieved an error when attempting to load %s:  %s", asg, err)
		}

		if loadBalancerCount != len(actual.AutoScalingGroups[0].LoadBalancerNames) {
			return fmt.Errorf("Error: ASG has the wrong number of load balacners associated.  Expected [%d] but got [%d]", loadBalancerCount, len(actual.AutoScalingGroups[0].LoadBalancerNames))
		}

		return nil
	}
}

const testAccAWSAutoscalingAttachment_basic = `
resource "aws_elb" "foo" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
}

resource "aws_elb" "bar" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
}

resource "aws_launch_configuration" "as_conf" {
    name = "test_config"
    image_id = "ami-f34032c3"
    instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "asg" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
  name = "asg-lb-assoc-terraform-test"
  max_size = 1
  min_size = 0
  desired_capacity = 0
  health_check_grace_period = 300
  force_delete = true
  launch_configuration = "${aws_launch_configuration.as_conf.name}"

  tag {
    key = "Name"
    value = "terraform-asg-lg-assoc-test"
    propagate_at_launch = true
  }
}

`

const testAccAWSAutoscalingAttachment_associated = testAccAWSAutoscalingAttachment_basic + `
resource "aws_autoscaling_attachment" "asg_attachment_foo" {
  autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
  elb                    = "${aws_elb.foo.id}"
}

`

const testAccAWSAutoscalingAttachment_double_associated = testAccAWSAutoscalingAttachment_associated + `
resource "aws_autoscaling_attachment" "asg_attachment_bar" {
  autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
  elb                    = "${aws_elb.bar.id}"
}

`
<commit_msg>provider/aws: Update Autoscaling attachment test<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/autoscaling"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsAutoscalingAttachment_basic(t *testing.T) {

	rInt := acctest.RandInt()

	resource.Test(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_basic(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
				),
			},
			// Add in one association
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_associated(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
				),
			},
			// Test adding a 2nd
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_double_associated(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 2),
				),
			},
			// Now remove that newest one
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_associated(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
				),
			},
			// Now remove them both
			resource.TestStep{
				Config: testAccAWSAutoscalingAttachment_basic(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
				),
			},
		},
	})
}

func testAccCheckAWSAutocalingAttachmentExists(asgname string, loadBalancerCount int) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[asgname]
		if !ok {
			return fmt.Errorf("Not found: %s", asgname)
		}

		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		asg := rs.Primary.ID

		actual, err := conn.DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{
			AutoScalingGroupNames: []*string{aws.String(asg)},
		})

		if err != nil {
			return fmt.Errorf("Recieved an error when attempting to load %s:  %s", asg, err)
		}

		if loadBalancerCount != len(actual.AutoScalingGroups[0].LoadBalancerNames) {
			return fmt.Errorf("Error: ASG has the wrong number of load balacners associated.  Expected [%d] but got [%d]", loadBalancerCount, len(actual.AutoScalingGroups[0].LoadBalancerNames))
		}

		return nil
	}
}

func testAccAWSAutoscalingAttachment_basic(rInt int) string {
	return fmt.Sprintf(`
resource "aws_elb" "foo" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
}

resource "aws_elb" "bar" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
}

resource "aws_launch_configuration" "as_conf" {
    name = "test_config_%d"
    image_id = "ami-f34032c3"
    instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "asg" {
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
  name = "asg-lb-assoc-terraform-test_%d"
  max_size = 1
  min_size = 0
  desired_capacity = 0
  health_check_grace_period = 300
  force_delete = true
  launch_configuration = "${aws_launch_configuration.as_conf.name}"

  tag {
    key = "Name"
    value = "terraform-asg-lg-assoc-test"
    propagate_at_launch = true
  }
}`, rInt, rInt)
}

func testAccAWSAutoscalingAttachment_associated(rInt int) string {
	return testAccAWSAutoscalingAttachment_basic(rInt) + `
resource "aws_autoscaling_attachment" "asg_attachment_foo" {
  autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
  elb                    = "${aws_elb.foo.id}"
}`
}

func testAccAWSAutoscalingAttachment_double_associated(rInt int) string {
	return testAccAWSAutoscalingAttachment_associated(rInt) + `
resource "aws_autoscaling_attachment" "asg_attachment_bar" {
  autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
  elb                    = "${aws_elb.bar.id}"
}`
}
<|endoftext|>


<commit_before>package properties

import (
    "testing"
    "strings"
    "bytes"
    "fmt"
    "os"
)

func Test_Load(t *testing.T) {
    s := `
    a=aa
    b=bbb
    c ccc = cccc
    dd
    ee: r-rt rr
    `
    file, err := os.Open("test1.properties")
    if nil != err {
        return
    }
    //p, err := Load(strings.NewReader(s))
    if nil != err {
        t.Error("加载失败")
        return
    }

    v := ""

    v = p.String("a")
    if "aa" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("b")
    if "bbb" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("Z")
    if "" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("c ccc")
    if "cccc" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("dd")
    if "" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("ee")
    if "r-rt rr" != v {
        t.Error("Get string failed")
        return
    }
}

func Test_LoadFromFile(t *testing.T) {
    file, err := os.Open("test1.properties")
    if nil != err {
        return
    }

    doc, err := Load(file)
    if nil != err {
        t.Error("加载失败")
        return
    }

    fmt.Println(doc.String("key"))
}

func Test_New(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a comment for a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a comment for a\na=aaa\n" != buf.String() {
        fmt.Println("Dump failed:[" + buf.String() + "]")
        t.Error("Dump failed")
        return
    }
}

func Test_Save(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a comment for a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a comment for a\na=aaa\n" != buf.String() {
        t.Error("Dump failed")
        return
    }
}

func Test_Comment(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a \ncomment \nfor a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a \n#comment \n#for a\na=aaa\n" != buf.String() {
        t.Error("Dump failed")
        return
    }
}

<commit_msg>编译失败，将修改错误的地方还原<commit_after>package properties

import (
    "testing"
    "strings"
    "bytes"
    "fmt"
    "os"
)

func Test_Load(t *testing.T) {
    s := `
    a=aa
    b=bbb
    c ccc = cccc
    dd
    ee: r-rt rr
    `

    p, err := Load(strings.NewReader(s))
    if nil != err {
        t.Error("加载失败")
        return
    }

    v := ""

    v = p.String("a")
    if "aa" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("b")
    if "bbb" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("Z")
    if "" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("c ccc")
    if "cccc" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("dd")
    if "" != v {
        t.Error("Get string failed")
        return
    }

    v = p.String("ee")
    if "r-rt rr" != v {
        t.Error("Get string failed")
        return
    }
}

func Test_LoadFromFile(t *testing.T) {
    file, err := os.Open("test1.properties")
    if nil != err {
        return
    }

    doc, err := Load(file)
    if nil != err {
        t.Error("加载失败")
        return
    }

    fmt.Println(doc.String("key"))
}

func Test_New(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a comment for a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a comment for a\na=aaa\n" != buf.String() {
        fmt.Println("Dump failed:[" + buf.String() + "]")
        t.Error("Dump failed")
        return
    }
}

func Test_Save(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a comment for a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a comment for a\na=aaa\n" != buf.String() {
        t.Error("Dump failed")
        return
    }
}

func Test_Comment(t *testing.T) {
    doc := New()
    doc.Set("a", "aaa")
    doc.Comment("a", "This is a \ncomment \nfor a")

    buf := bytes.NewBufferString("")
    Save(doc, buf)

    if "#This is a \n#comment \n#for a\na=aaa\n" != buf.String() {
        t.Error("Dump failed")
        return
    }
}

<|endoftext|>


<commit_before>package drouter

import (
	"net"
	"strconv"
	"errors"
	"strings"
	//"os/exec"
	//"fmt"
	"time"
	"os"
	"bufio"
	//"os/signal"
	//"syscall"
	//"bytes"
	//"io/ioutil"

	log "github.com/Sirupsen/logrus"
	//"github.com/samalba/dockerclient"
	dockerclient "github.com/docker/engine-api/client"
	dockertypes "github.com/docker/engine-api/types"
	dockerfilters "github.com/docker/engine-api/types/filters"
	dockernetworks "github.com/docker/engine-api/types/network"
	"golang.org/x/net/context"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	"github.com/ziutek/utils/netaddr"
)

var (
	docker                *dockerclient.Client
	self_container        dockertypes.ContainerJSON
	networks              = make(map[string]bool)
	host_ns_h             *netlink.Handle
	self_ns_h             *netlink.Handle
	host_route_link_index int
	host_route_gw		    net.IP
	my_pid                = os.Getpid()
)

func init() {
	var err error

	if my_pid == 1 {
		log.Fatal("Running as Pid 1. drouter must be run with --pid=host")
	}

	defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
	docker, err = dockerclient.NewClient("unix:///var/run/docker.sock", "v1.23", nil, defaultHeaders)
	if err != nil {
		log.Error("Error connecting to docker socket")
		log.Fatal(err)
	}
	self_container, err = getSelf()
	if err != nil {
		log.Error("Error getting self container. Is this processs running in a container? Is the docker socket passed through?")
		log.Fatal(err)
	}

	// Prepopulate networks that this container is a member of
	for _, settings := range self_container.NetworkSettings.Networks {
		networks[settings.NetworkID] = true
	}

	self_ns, err := netns.Get()
	if err != nil {
		log.Error("Error getting self namespace.")
		log.Fatal(err)
	}
	self_ns_h, err = netlink.NewHandleAt(self_ns)
	if err != nil {
		log.Error("Error getting handle at self namespace.")
		log.Fatal(err)
	}
	host_ns, err := netns.GetFromPid(1)
	if err != nil {
		log.Error("Error getting host namespace. Is this container running in priveleged mode?")
		log.Fatal(err)
	}
	host_ns_h, err = netlink.NewHandleAt(host_ns)
	if err != nil {
		log.Error("Error getting handle at host namespace.")
		log.Fatal(err)
	}
}

// Loop to watch for new networks created and create interfaces when needed
func WatchNetworks() {
	log.Info("Watching Networks")
	for {
		nets, err := docker.NetworkList(context.Background(), dockertypes.NetworkListOptions{ Filters: dockerfilters.NewArgs(), })
		if err != nil {
			log.Error("Error getting network list")
			log.Error(err)
		}
		for i := range nets {
			drouter_str := nets[i].Options["drouter"]
			drouter := false
			if drouter_str != "" {
				drouter, err = strconv.ParseBool(drouter_str)
				if err != nil {
					log.Errorf("Error parsing drouter option: %v", drouter_str)
					log.Error(err)
				}
			}

			if drouter && !networks[nets[i].ID] {
				log.Debugf("Joining Net: %+v", nets[i])
				err := joinNet(&nets[i])
				if err != nil {
					log.Errorf("Error joining network: %v", nets[i])
					log.Error(err)
				}
			} else if !drouter && networks[nets[i].ID] {
				log.Debugf("Leaving Net: %+v", nets[i])
				err := leaveNet(&nets[i])
				if err != nil {
					log.Errorf("Error leaving network: %v", nets[i])
					log.Error(err)
				}
			}
		}
		time.Sleep(5 * time.Second)
	}
}

func WatchEvents() {
	for {
		time.Sleep(1 * time.Second)
	}
}

func joinNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkConnect(context.Background(), net.ID, self_container.ID, &dockernetworks.EndpointSettings{})
	if err != nil {
		return err
	}
	networks[net.ID] = true
	return nil
}

func leaveNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkDisconnect(context.Background(), net.ID, self_container.ID, true)
	if err != nil {
		return err
	}
	networks[net.ID] = false
	return nil
}

func getSelf() (dockertypes.ContainerJSON, error) {
	cgroup, err := os.Open("/proc/self/cgroup")
	if err != nil {
		return dockertypes.ContainerJSON{}, err
	}
	defer cgroup.Close()

	scanner := bufio.NewScanner(cgroup)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "/")
		id := line[len(line) - 1]
		containerInfo, err := docker.ContainerInspect(context.Background(), id)
		if err != nil {
			log.Warnf("Error inspecting container: %v", id)
			log.Warn(err)
			continue
		}
		return containerInfo, nil
	}
	return dockertypes.ContainerJSON{}, errors.New("Container not found")
}

func MakeP2PLink(p2p_addr string) error {
	host_link_veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: "drouter_veth0"},
		PeerName:  "drouter_veth1",
	}
	err := host_ns_h.LinkAdd(host_link_veth)
	if err != nil {
		return err
	}
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	host_route_link_index = host_link.Attrs().Index

	int_link, err := host_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}
	err = host_ns_h.LinkSetNsPid(int_link, my_pid)
	if err != nil {
		return err
	}
	int_link, err = self_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}

	_, p2p_net, err := net.ParseCIDR(p2p_addr)
	if err != nil {
		return err
	}

	host_addr := *p2p_net
	host_addr.IP = netaddr.IPAdd(host_addr.IP, 1)
	host_netlink_addr := &netlink.Addr{
		IPNet: &host_addr,
		Label: "",
	}
	err = host_ns_h.AddrAdd(host_link, host_netlink_addr)
	if err != nil {
		return err
	}

	int_addr := *p2p_net
	int_addr.IP = netaddr.IPAdd(int_addr.IP, 2)
	int_netlink_addr := &netlink.Addr{
		IPNet: &int_addr,
		Label: "",
	}
	err = self_ns_h.AddrAdd(int_link, int_netlink_addr)
	if err != nil {
		return err
	}

	host_route_gw = int_addr.IP

	err = self_ns_h.LinkSetUp(int_link)
	if err != nil {
		return err
	}

	err = host_ns_h.LinkSetUp(host_link)
	if err != nil {
		return err
	}

	return nil
}

func Cleanup() error {
	log.Info("Cleaning Up")
	return removeP2PLink()
}

func removeP2PLink() error {
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	return host_ns_h.LinkDel(host_link)
}

<commit_msg>add route<commit_after>package drouter

import (
	"net"
	"strconv"
	"errors"
	"strings"
	//"os/exec"
	//"fmt"
	"time"
	"os"
	"bufio"
	//"os/signal"
	//"syscall"
	//"bytes"
	//"io/ioutil"

	log "github.com/Sirupsen/logrus"
	//"github.com/samalba/dockerclient"
	dockerclient "github.com/docker/engine-api/client"
	dockertypes "github.com/docker/engine-api/types"
	dockerfilters "github.com/docker/engine-api/types/filters"
	dockernetworks "github.com/docker/engine-api/types/network"
	"golang.org/x/net/context"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	"github.com/ziutek/utils/netaddr"
)

var (
	docker                *dockerclient.Client
	self_container        dockertypes.ContainerJSON
	networks              = make(map[string]bool)
	host_ns_h             *netlink.Handle
	self_ns_h             *netlink.Handle
	host_route_link_index int
	host_route_gw		    net.IP
	my_pid                = os.Getpid()
)

func init() {
	var err error

	if my_pid == 1 {
		log.Fatal("Running as Pid 1. drouter must be run with --pid=host")
	}

	defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
	docker, err = dockerclient.NewClient("unix:///var/run/docker.sock", "v1.23", nil, defaultHeaders)
	if err != nil {
		log.Error("Error connecting to docker socket")
		log.Fatal(err)
	}
	self_container, err = getSelf()
	if err != nil {
		log.Error("Error getting self container. Is this processs running in a container? Is the docker socket passed through?")
		log.Fatal(err)
	}

	// Prepopulate networks that this container is a member of
	for _, settings := range self_container.NetworkSettings.Networks {
		networks[settings.NetworkID] = true
	}

	self_ns, err := netns.Get()
	if err != nil {
		log.Error("Error getting self namespace.")
		log.Fatal(err)
	}
	self_ns_h, err = netlink.NewHandleAt(self_ns)
	if err != nil {
		log.Error("Error getting handle at self namespace.")
		log.Fatal(err)
	}
	host_ns, err := netns.GetFromPid(1)
	if err != nil {
		log.Error("Error getting host namespace. Is this container running in priveleged mode?")
		log.Fatal(err)
	}
	host_ns_h, err = netlink.NewHandleAt(host_ns)
	if err != nil {
		log.Error("Error getting handle at host namespace.")
		log.Fatal(err)
	}
}

// Loop to watch for new networks created and create interfaces when needed
func WatchNetworks() {
	log.Info("Watching Networks")
	for {
		nets, err := docker.NetworkList(context.Background(), dockertypes.NetworkListOptions{ Filters: dockerfilters.NewArgs(), })
		if err != nil {
			log.Error("Error getting network list")
			log.Error(err)
		}
		for i := range nets {
			drouter_str := nets[i].Options["drouter"]
			drouter := false
			if drouter_str != "" {
				drouter, err = strconv.ParseBool(drouter_str)
				if err != nil {
					log.Errorf("Error parsing drouter option: %v", drouter_str)
					log.Error(err)
				}
			}

			if drouter && !networks[nets[i].ID] {
				log.Debugf("Joining Net: %+v", nets[i])
				err := joinNet(&nets[i])
				if err != nil {
					log.Errorf("Error joining network: %v", nets[i])
					log.Error(err)
				}
			} else if !drouter && networks[nets[i].ID] {
				log.Debugf("Leaving Net: %+v", nets[i])
				err := leaveNet(&nets[i])
				if err != nil {
					log.Errorf("Error leaving network: %v", nets[i])
					log.Error(err)
				}
			}
		}
		time.Sleep(5 * time.Second)
	}
}

func WatchEvents() {
	for {
		time.Sleep(1 * time.Second)
	}
}

func joinNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkConnect(context.Background(), net.ID, self_container.ID, &dockernetworks.EndpointSettings{})
	if err != nil {
		return err
	}
	networks[net.ID] = true
	_, dst, err := net.ParseCIDR(net.IPAM.Config.Subnet)
	if err != nil {
		return err
	}
	route := &netlink.Route{
		LinkIndex: host_route_link_index,
		Gw: host_route_gw,
		Dst: dst,
	}
	err := host_ns_h.RouteAdd(route)
	if err != nil {
		return err
	}
	return nil
}

func leaveNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkDisconnect(context.Background(), net.ID, self_container.ID, true)
	if err != nil {
		return err
	}
	networks[net.ID] = false
	return nil
}

func getSelf() (dockertypes.ContainerJSON, error) {
	cgroup, err := os.Open("/proc/self/cgroup")
	if err != nil {
		return dockertypes.ContainerJSON{}, err
	}
	defer cgroup.Close()

	scanner := bufio.NewScanner(cgroup)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "/")
		id := line[len(line) - 1]
		containerInfo, err := docker.ContainerInspect(context.Background(), id)
		if err != nil {
			log.Warnf("Error inspecting container: %v", id)
			log.Warn(err)
			continue
		}
		return containerInfo, nil
	}
	return dockertypes.ContainerJSON{}, errors.New("Container not found")
}

func MakeP2PLink(p2p_addr string) error {
	host_link_veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: "drouter_veth0"},
		PeerName:  "drouter_veth1",
	}
	err := host_ns_h.LinkAdd(host_link_veth)
	if err != nil {
		return err
	}
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	host_route_link_index = host_link.Attrs().Index

	int_link, err := host_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}
	err = host_ns_h.LinkSetNsPid(int_link, my_pid)
	if err != nil {
		return err
	}
	int_link, err = self_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}

	_, p2p_net, err := net.ParseCIDR(p2p_addr)
	if err != nil {
		return err
	}

	host_addr := *p2p_net
	host_addr.IP = netaddr.IPAdd(host_addr.IP, 1)
	host_netlink_addr := &netlink.Addr{
		IPNet: &host_addr,
		Label: "",
	}
	err = host_ns_h.AddrAdd(host_link, host_netlink_addr)
	if err != nil {
		return err
	}

	int_addr := *p2p_net
	int_addr.IP = netaddr.IPAdd(int_addr.IP, 2)
	int_netlink_addr := &netlink.Addr{
		IPNet: &int_addr,
		Label: "",
	}
	err = self_ns_h.AddrAdd(int_link, int_netlink_addr)
	if err != nil {
		return err
	}

	host_route_gw = int_addr.IP

	err = self_ns_h.LinkSetUp(int_link)
	if err != nil {
		return err
	}

	err = host_ns_h.LinkSetUp(host_link)
	if err != nil {
		return err
	}

	return nil
}

func Cleanup() error {
	log.Info("Cleaning Up")
	return removeP2PLink()
}

func removeP2PLink() error {
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	return host_ns_h.LinkDel(host_link)
}

<|endoftext|>


<commit_before>package firewall

import (
	"net"

	deviceConfig "github.com/lxc/lxd/lxd/device/config"
)

// Firewall represents an LXD firewall.
type Firewall interface {
	String() string
	Compat() (bool, error)

	NetworkSetupForwardingPolicy(networkName string, ipVersion uint, allow bool) error
	NetworkSetupOutboundNAT(networkName string, subnet *net.IPNet, srcIP net.IP, append bool) error
	NetworkSetupDHCPDNSAccess(networkName string, ipVersion uint) error
	NetworkSetupDHCPv4Checksum(networkName string) error
	NetworkClear(networkName string, ipVersion uint) error

	InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4 net.IP, IPv6 net.IP) error
	InstanceClearBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4 net.IP, IPv6 net.IP) error

	InstanceSetupProxyNAT(projectName string, instanceName string, deviceName string, listen *deviceConfig.ProxyAddress, connect *deviceConfig.ProxyAddress) error
	InstanceClearProxyNAT(projectName string, instanceName string, deviceName string) error

	InstanceSetupRPFilter(projectName string, instanceName string, deviceName string, hostName string) error
	InstanceClearRPFilter(projectName string, instanceName string, deviceName string) error
}
<commit_msg>lxd/firewall: LXD is pronounced lex-dee<commit_after>package firewall

import (
	"net"

	deviceConfig "github.com/lxc/lxd/lxd/device/config"
)

// Firewall represents a LXD firewall.
type Firewall interface {
	String() string
	Compat() (bool, error)

	NetworkSetupForwardingPolicy(networkName string, ipVersion uint, allow bool) error
	NetworkSetupOutboundNAT(networkName string, subnet *net.IPNet, srcIP net.IP, append bool) error
	NetworkSetupDHCPDNSAccess(networkName string, ipVersion uint) error
	NetworkSetupDHCPv4Checksum(networkName string) error
	NetworkClear(networkName string, ipVersion uint) error

	InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4 net.IP, IPv6 net.IP) error
	InstanceClearBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4 net.IP, IPv6 net.IP) error

	InstanceSetupProxyNAT(projectName string, instanceName string, deviceName string, listen *deviceConfig.ProxyAddress, connect *deviceConfig.ProxyAddress) error
	InstanceClearProxyNAT(projectName string, instanceName string, deviceName string) error

	InstanceSetupRPFilter(projectName string, instanceName string, deviceName string, hostName string) error
	InstanceClearRPFilter(projectName string, instanceName string, deviceName string) error
}
<|endoftext|>