123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- // +build amd64
- // Copyright 2015 CoreOS, Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package vmware
- import (
- "errors"
- "fmt"
- "io/ioutil"
- "net"
- "os"
- "reflect"
- "testing"
- "github.com/rancher/os/config/cloudinit/datasource"
- "github.com/rancher/os/pkg/netconf"
- )
- type MockHypervisor map[string]string
- func (h MockHypervisor) ReadConfig(key string) (string, error) {
- fmt.Printf("read(%s) %s\n", key, h[key])
- return h[key], nil
- }
- var fakeDownloader urlDownloadFunction = func(url string) ([]byte, error) {
- mapping := map[string]struct {
- data []byte
- err error
- }{
- "http://good.example.com": {[]byte("test config"), nil},
- "http://bad.example.com": {nil, errors.New("Not found")},
- }
- val := mapping[url]
- return val.data, val.err
- }
- func TestFetchMetadata(t *testing.T) {
- tests := []struct {
- variables MockHypervisor
- metadata datasource.Metadata
- err error
- }{
- {
- variables: map[string]string{
- "hostname": "first",
- "interface.0.mac": "test mac",
- "interface.0.dhcp": "yes",
- },
- metadata: datasource.Metadata{
- Hostname: "first",
- NetworkConfig: netconf.NetworkConfig{
- Interfaces: map[string]netconf.InterfaceConfig{
- "eth0": netconf.InterfaceConfig{
- Match: "mac:test mac",
- DHCP: true,
- Addresses: []string{},
- },
- },
- },
- // NetworkConfig: map[string]string{
- // "interface.0.mac": "test mac",
- // "interface.0.dhcp": "yes",
- // },
- },
- },
- {
- variables: map[string]string{
- "hostname": "second",
- "interface.0.name": "test name",
- "interface.0.dhcp": "yes",
- },
- metadata: datasource.Metadata{
- Hostname: "second",
- NetworkConfig: netconf.NetworkConfig{
- Interfaces: map[string]netconf.InterfaceConfig{
- "eth0": netconf.InterfaceConfig{
- Match: "test name",
- DHCP: true,
- Addresses: []string{},
- },
- },
- },
- // NetworkConfig: map[string]string{
- // "interface.0.name": "test name",
- // "interface.0.dhcp": "yes",
- // },
- },
- },
- {
- variables: map[string]string{
- "hostname": "test host",
- "interface.0.mac": "test mac",
- "interface.0.role": "private",
- "interface.0.ip.0.address": "fe00::100/64",
- "interface.0.route.0.gateway": "fe00::1",
- "interface.0.route.0.destination": "::",
- },
- metadata: datasource.Metadata{
- Hostname: "test host",
- PrivateIPv6: net.ParseIP("fe00::100"),
- NetworkConfig: netconf.NetworkConfig{
- Interfaces: map[string]netconf.InterfaceConfig{
- "eth0": netconf.InterfaceConfig{
- Match: "mac:test mac",
- DHCP: false,
- Addresses: []string{
- "fe00::100/64",
- },
- Gateway: "fe00::1",
- //TODO: Destination
- },
- },
- },
- // NetworkConfig: map[string]string{
- // "interface.0.mac": "test mac",
- // "interface.0.ip.0.address": "fe00::100/64",
- // "interface.0.route.0.gateway": "fe00::1",
- // "interface.0.route.0.destination": "::",
- // },
- },
- },
- {
- variables: map[string]string{
- "hostname": "test host",
- "interface.0.name": "test name",
- "interface.0.role": "public",
- "interface.0.ip.0.address": "10.0.0.100/24",
- "interface.0.ip.1.address": "10.0.0.101/24",
- "interface.0.route.0.gateway": "10.0.0.1",
- "interface.0.route.0.destination": "0.0.0.0",
- "interface.1.mac": "test mac",
- "interface.1.role": "private",
- "interface.1.route.0.gateway": "10.0.0.2",
- "interface.1.route.0.destination": "0.0.0.0",
- "interface.1.ip.0.address": "10.0.0.102/24",
- },
- metadata: datasource.Metadata{
- Hostname: "test host",
- PublicIPv4: net.ParseIP("10.0.0.101"),
- PrivateIPv4: net.ParseIP("10.0.0.102"),
- NetworkConfig: netconf.NetworkConfig{
- Interfaces: map[string]netconf.InterfaceConfig{
- "eth0": netconf.InterfaceConfig{
- Match: "test name",
- DHCP: false,
- Addresses: []string{
- "10.0.0.100/24",
- "10.0.0.101/24",
- },
- Gateway: "10.0.0.1",
- //TODO: Destination
- },
- "eth1": netconf.InterfaceConfig{
- Match: "mac:test mac",
- DHCP: false,
- Addresses: []string{
- "10.0.0.102/24",
- },
- Gateway: "10.0.0.2",
- //TODO: Destination
- },
- },
- },
- // NetworkConfig: map[string]string{
- // "interface.0.name": "test name",
- // "interface.0.ip.0.address": "10.0.0.100/24",
- // "interface.0.ip.1.address": "10.0.0.101/24",
- // "interface.0.route.0.gateway": "10.0.0.1",
- // "interface.0.route.0.destination": "0.0.0.0",
- // "interface.1.mac": "test mac",
- // "interface.1.route.0.gateway": "10.0.0.2",
- // "interface.1.route.0.destination": "0.0.0.0",
- // "interface.1.ip.0.address": "10.0.0.102/24",
- // },
- },
- },
- }
- for i, tt := range tests {
- v := VMWare{readConfig: tt.variables.ReadConfig}
- metadata, err := v.FetchMetadata()
- if !reflect.DeepEqual(tt.err, err) {
- t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
- }
- if !reflect.DeepEqual(tt.metadata, metadata) {
- t.Errorf("bad metadata (#%d): want %#v, got %#v", i, tt.metadata, metadata)
- }
- }
- }
- func TestFetchUserdata(t *testing.T) {
- tests := []struct {
- variables MockHypervisor
- userdata string
- err error
- }{
- {},
- {
- variables: map[string]string{"cloud-init.config.data": "test config"},
- userdata: "test config",
- },
- {
- variables: map[string]string{
- "cloud-init.data.encoding": "",
- "cloud-init.config.data": "test config",
- },
- userdata: "test config",
- },
- {
- variables: map[string]string{
- "cloud-init.data.encoding": "base64",
- "cloud-init.config.data": "dGVzdCBjb25maWc=",
- },
- userdata: "test config",
- },
- {
- variables: map[string]string{
- "cloud-init.data.encoding": "gzip+base64",
- "cloud-init.config.data": "H4sIABaoWlUAAytJLS5RSM7PS8tMBwCQiHNZCwAAAA==",
- },
- userdata: "test config",
- },
- {
- variables: map[string]string{
- "cloud-init.data.encoding": "test encoding",
- },
- err: errors.New(`Unsupported encoding "test encoding"`),
- },
- {
- variables: map[string]string{
- "cloud-init.config.url": "http://good.example.com",
- },
- userdata: "test config",
- },
- {
- variables: map[string]string{
- "cloud-init.config.url": "http://bad.example.com",
- },
- err: errors.New("Not found"),
- },
- }
- for i, tt := range tests {
- v := VMWare{
- readConfig: tt.variables.ReadConfig,
- urlDownload: fakeDownloader,
- }
- userdata, err := v.FetchUserdata()
- if !reflect.DeepEqual(tt.err, err) {
- t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
- }
- if tt.userdata != string(userdata) {
- t.Errorf("bad userdata (#%d): want %q, got %q", i, tt.userdata, userdata)
- }
- }
- }
- func TestFetchUserdataError(t *testing.T) {
- testErr := errors.New("test error")
- _, err := VMWare{readConfig: func(_ string) (string, error) { return "", testErr }}.FetchUserdata()
- if testErr != err {
- t.Errorf("bad error: want %v, got %v", testErr, err)
- }
- }
- func TestOvfTransport(t *testing.T) {
- tests := []struct {
- document string
- metadata datasource.Metadata
- userdata []byte
- }{
- {
- document: `<?xml version="1.0" encoding="UTF-8"?>
- <Environment xmlns="http://schemas.dmtf.org/ovf/environment/1"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
- oe:id="CoreOS-vmw">
- <PlatformSection>
- <Kind>VMware ESXi</Kind>
- <Version>5.5.0</Version>
- <Vendor>VMware, Inc.</Vendor>
- <Locale>en</Locale>
- </PlatformSection>
- <PropertySection>
- <Property oe:key="foo" oe:value="42"/>
- <Property oe:key="guestinfo.cloud-init.config.url" oe:value="http://good.example.com"/>
- <Property oe:key="guestinfo.hostname" oe:value="test host"/>
- <Property oe:key="guestinfo.interface.0.name" oe:value="test name"/>
- <Property oe:key="guestinfo.interface.0.role" oe:value="public"/>
- <Property oe:key="guestinfo.interface.0.ip.0.address" oe:value="10.0.0.100/24"/>
- <Property oe:key="guestinfo.interface.0.ip.1.address" oe:value="10.0.0.101/24"/>
- <Property oe:key="guestinfo.interface.0.route.0.gateway" oe:value="10.0.0.1"/>
- <Property oe:key="guestinfo.interface.0.route.0.destination" oe:value="0.0.0.0"/>
- <Property oe:key="guestinfo.interface.1.mac" oe:value="test mac"/>
- <Property oe:key="guestinfo.interface.1.role" oe:value="private"/>
- <Property oe:key="guestinfo.interface.1.route.0.gateway" oe:value="10.0.0.2"/>
- <Property oe:key="guestinfo.interface.1.route.0.destination" oe:value="0.0.0.0"/>
- <Property oe:key="guestinfo.interface.1.ip.0.address" oe:value="10.0.0.102/24"/>
- </PropertySection>
- </Environment>`,
- metadata: datasource.Metadata{
- Hostname: "test host",
- PublicIPv4: net.ParseIP("10.0.0.101"),
- PrivateIPv4: net.ParseIP("10.0.0.102"),
- NetworkConfig: netconf.NetworkConfig{
- Interfaces: map[string]netconf.InterfaceConfig{
- "eth0": netconf.InterfaceConfig{
- Match: "test name",
- DHCP: false,
- Addresses: []string{
- "10.0.0.100/24",
- "10.0.0.101/24",
- },
- Gateway: "10.0.0.1",
- //TODO: Destination
- },
- "eth1": netconf.InterfaceConfig{
- Match: "mac:test mac",
- DHCP: false,
- Addresses: []string{
- "10.0.0.102/24",
- },
- Gateway: "10.0.0.2",
- //TODO: Destination
- },
- },
- },
- },
- userdata: []byte("test config"),
- },
- }
- for i, tt := range tests {
- file, err := ioutil.TempFile(os.TempDir(), "ovf")
- if err != nil {
- t.Errorf("error creating ovf file (#%d)", i)
- }
- defer os.Remove(file.Name())
- file.WriteString(tt.document)
- v := NewDatasource(file.Name())
- if v == nil {
- continue
- }
- v.urlDownload = fakeDownloader
- metadata, _ := v.FetchMetadata()
- userdata, _ := v.FetchUserdata()
- if !reflect.DeepEqual(tt.metadata, metadata) {
- t.Errorf("bad metadata (#%d): want %#v, got %#v", i, tt.metadata, metadata)
- }
- if !reflect.DeepEqual(tt.userdata, userdata) {
- t.Errorf("bad userdata (#%d): want %#v, got %#v", i, tt.userdata, userdata)
- }
- }
- }
|