blob: 8354f593b4f08b4765ea6225de14f62475f40b11 [file] [log] [blame]
David K. Bainbridgedf9df632016-07-07 18:47:46 -07001// Copyright 2016 Open Networking Laboratory
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
David K. Bainbridgef694f5a2016-06-10 16:21:27 -070014package main
15
16import (
17 "bufio"
18 "fmt"
19 "net/url"
20 "os"
21 "strings"
22)
23
24func NewAddressSource(spec string) (AddressSource, error) {
25 u, err := url.Parse(spec)
26 if err != nil {
27 return nil, err
28 }
29
30 switch u.Scheme {
31 case "file":
32 return NewFileAddressSource(u)
33 default:
34 }
35 return nil, fmt.Errorf("Unknown address source scheme specified '%s'", spec)
36}
37
38type AddressRec struct {
39 Name string
40 IP string
41 MAC string
42}
43
44type AddressSource interface {
45 GetAddresses() ([]AddressRec, error)
46}
47
48type FileAddressSource struct {
49 Path string
50}
51
52func NewFileAddressSource(connect *url.URL) (AddressSource, error) {
53 // Validate file exists before returning a source
54 if _, err := os.Stat(connect.Path); os.IsNotExist(err) {
55 return nil, err
56 }
57 source := FileAddressSource{}
58 source.Path = connect.Path
59 return &source, nil
60}
61
62func (s *FileAddressSource) GetAddresses() ([]AddressRec, error) {
63 // Read the file
64 file, err := os.Open(s.Path)
65 defer file.Close()
66 if err != nil {
67 return nil, err
68 }
69
70 capacity := 20
71 result := make([]AddressRec, capacity)
72 idx := 0
73
74 scanner := bufio.NewScanner(file)
75 for scanner.Scan() {
76 parts := strings.Fields(scanner.Text())
77
78 // Only process lines with the correct number of parts
79 if len(parts) == 6 {
80 result[idx].Name = parts[0]
81 result[idx].IP = parts[3]
82 result[idx].MAC = parts[5]
83 idx += 1
84 if idx >= capacity {
85 capacity += 20
David K. Bainbridgeaebe11b2016-06-29 10:45:39 -070086 var tmp []AddressRec
87 tmp, result = result, make([]AddressRec, capacity)
David K. Bainbridgef694f5a2016-06-10 16:21:27 -070088 copy(result, tmp)
89 }
90 }
91 }
92
93 if err := scanner.Err(); err != nil {
94 return nil, err
95 }
96
97 return result[:idx], nil
98}