Skip to content

Commit aad93c5

Browse files
tamilmani1989sharmasushant
authored andcommitted
Fixed review comments
1 parent 1669082 commit aad93c5

File tree

5 files changed

+251
-399
lines changed

5 files changed

+251
-399
lines changed

cni/network/plugin/main.go

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,51 +23,60 @@ const (
2323
// Version is populated by make during build.
2424
var version string
2525

26+
// If report write succeeded, mark the report flag state to false.
27+
func markSendReport(reportManager *telemetry.ReportManager) {
28+
if err := reportManager.Report.SetReportState(); err != nil {
29+
log.Printf("SetReportState failed due to %v", err)
30+
reportManager.Report.ErrorMessage = err.Error()
31+
32+
if reportManager.SendReport() != nil {
33+
log.Printf("SendReport failed due to %v", err)
34+
}
35+
}
36+
}
37+
38+
// send error report to hostnetagent if CNI encounters any error.
39+
func reportPluginError(reportManager *telemetry.ReportManager, err error) {
40+
log.Printf("Report plugin error")
41+
reportManager.GetReport(pluginName, version)
42+
reportManager.Report.ErrorMessage = err.Error()
43+
44+
if err = reportManager.SendReport(); err != nil {
45+
log.Printf("SendReport failed due to %v", err)
46+
} else {
47+
markSendReport(reportManager)
48+
}
49+
}
50+
2651
// Main is the entry point for CNI network plugin.
2752
func main() {
2853
var config common.PluginConfig
2954
var err error
3055
config.Version = version
31-
32-
reportManager := &telemetry.ReportManager{HostNetAgentURL: hostNetAgentURL, IpamQueryURL: ipamQueryURL, ReportType: reportType}
33-
34-
reportManager.Report, err = reportManager.GetReport(pluginName, config.Version)
35-
if err != nil {
36-
log.Printf("GetReport failed due to %v", err)
37-
reportManager.Report.ErrorMessage = err.Error()
56+
reportManager := &telemetry.ReportManager{
57+
HostNetAgentURL: hostNetAgentURL,
58+
IpamQueryURL: ipamQueryURL,
59+
ReportType: reportType,
60+
Report: &telemetry.Report{},
3861
}
3962

40-
report := reportManager.Report
41-
42-
if !report.GetReportState() {
63+
if !reportManager.Report.GetReportState() {
4364
log.Printf("GetReport state file didn't exist. Setting flag to true")
44-
45-
report.Context = "AzureCNI"
65+
reportManager.GetReport(pluginName, config.Version)
66+
reportManager.Report.Context = "AzureCNI"
4667

4768
err = reportManager.SendReport()
4869
if err != nil {
4970
log.Printf("SendReport failed due to %v", err)
5071
} else {
51-
if err = report.SetReportState(); err != nil {
52-
log.Printf("SetReportState failed due to %v", err)
53-
54-
report.ErrorMessage = err.Error()
55-
if reportManager.SendReport() != nil {
56-
log.Printf("SendReport failed due to %v", err)
57-
}
58-
}
72+
markSendReport(reportManager)
5973
}
6074
}
6175

6276
netPlugin, err := network.NewPlugin(&config)
6377
if err != nil {
6478
log.Printf("Failed to create network plugin, err:%v.\n", err)
65-
66-
report.ErrorMessage = err.Error()
67-
if err = reportManager.SendReport(); err != nil {
68-
log.Printf("SendReport failed due to %v", err)
69-
}
70-
79+
reportPluginError(reportManager, err)
7180
os.Exit(1)
7281
}
7382

@@ -76,21 +85,14 @@ func main() {
7685
err = netPlugin.Start(&config)
7786
if err != nil {
7887
log.Printf("Failed to start network plugin, err:%v.\n", err)
79-
80-
report.ErrorMessage = err.Error()
81-
if err = reportManager.SendReport(); err != nil {
82-
log.Printf("SendReport failed due to %v", err)
83-
}
84-
88+
reportPluginError(reportManager, err)
8589
os.Exit(1)
8690
}
8791

8892
err = netPlugin.Execute(cni.PluginApi(netPlugin))
8993
if err != nil {
90-
report.ErrorMessage = err.Error()
91-
if err = reportManager.SendReport(); err != nil {
92-
log.Printf("SendReport failed due to %v", err)
93-
}
94+
log.Printf("Failed to execute network plugin, err:%v.\n", err)
95+
reportPluginError(reportManager, err)
9496
}
9597

9698
netPlugin.Stop()

telemetry/telemetry.go

Lines changed: 166 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
package telemetry
55

66
import (
7+
"bufio"
78
"bytes"
89
"encoding/json"
10+
"encoding/xml"
911
"fmt"
12+
"io"
1013
"log"
14+
"net"
1115
"net/http"
1216
"os"
17+
"os/exec"
18+
"strings"
19+
20+
"github.com/Azure/azure-container-networking/common"
1321
)
1422

1523
// OS Details structure.
@@ -18,6 +26,7 @@ type OSInfo struct {
1826
OSVersion string
1927
KernelVersion string
2028
OSDistribution string
29+
ErrorMessage string
2130
}
2231

2332
// System Details structure.
@@ -28,6 +37,7 @@ type SystemInfo struct {
2837
DiskVMTotal uint64
2938
DiskVMFree uint64
3039
CPUCount int
40+
ErrorMessage string
3141
}
3242

3343
// Interface Details structure.
@@ -39,34 +49,37 @@ type InterfaceInfo struct {
3949
Name string
4050
SecondaryCATotalCount int
4151
SecondaryCAUsedCount int
52+
ErrorMessage string
4253
}
4354

4455
// CNI Bridge Details structure.
4556
type BridgeInfo struct {
46-
NetworkMode string
47-
BridgeName string
57+
NetworkMode string
58+
BridgeName string
59+
ErrorMessage string
4860
}
4961

5062
// Orchestrator Details structure.
5163
type OrchsestratorInfo struct {
5264
OrchestratorName string
5365
OrchestratorVersion string
66+
ErrorMessage string
5467
}
5568

5669
// Azure CNI Telemetry Report structure.
5770
type Report struct {
5871
StartFlag bool
5972
Name string
6073
Version string
74+
ErrorMessage string
75+
Context string
76+
SubContext string
77+
VnetAddressSpace []string
6178
OrchestratorDetails *OrchsestratorInfo
6279
OSDetails *OSInfo
6380
SystemDetails *SystemInfo
6481
InterfaceDetails *InterfaceInfo
6582
BridgeDetails *BridgeInfo
66-
VnetAddressSpace []string
67-
ErrorMessage string
68-
Context string
69-
SubContext string
7083
}
7184

7285
// ReportManager structure.
@@ -77,31 +90,47 @@ type ReportManager struct {
7790
Report *Report
7891
}
7992

80-
// GetReport retrieves orchestrator, system, OS and Interface details and create a report structure.
81-
func (reportMgr *ReportManager) GetReport(name string, version string) (*Report, error) {
82-
var err error
83-
report := &Report{}
84-
85-
report.Name = name
86-
report.Version = version
87-
report.OrchestratorDetails = GetOrchestratorDetails()
93+
// Read file line by line and return array of lines.
94+
func ReadFileByLines(filename string) ([]string, error) {
95+
var (
96+
lineStrArr []string
97+
)
8898

89-
report.SystemDetails, err = GetSystemDetails()
99+
f, err := os.Open(filename)
90100
if err != nil {
91-
return report, err
101+
return nil, fmt.Errorf("Error opening %s file error %v", filename, err)
92102
}
93103

94-
report.OSDetails, err = GetOSDetails()
95-
if err != nil {
96-
return report, err
104+
r := bufio.NewReader(f)
105+
106+
for {
107+
lineStr, err := r.ReadString('\n')
108+
if err != nil {
109+
if err != io.EOF {
110+
return nil, fmt.Errorf("Error reading %s file error %v", filename, err)
111+
}
112+
break
113+
}
114+
lineStrArr = append(lineStrArr, lineStr)
97115
}
98116

99-
report.InterfaceDetails, err = GetInterfaceDetails(reportMgr.IpamQueryURL)
117+
err = f.Close()
100118
if err != nil {
101-
return report, err
119+
return nil, fmt.Errorf("Error closing %s file error %v", filename, err)
102120
}
103121

104-
return report, nil
122+
return lineStrArr, nil
123+
}
124+
125+
// GetReport retrieves orchestrator, system, OS and Interface details and create a report structure.
126+
func (reportMgr *ReportManager) GetReport(name string, version string) {
127+
reportMgr.Report.Name = name
128+
reportMgr.Report.Version = version
129+
130+
reportMgr.Report.GetOrchestratorDetails()
131+
reportMgr.Report.GetSystemDetails()
132+
reportMgr.Report.GetOSDetails()
133+
reportMgr.Report.GetInterfaceDetails(reportMgr.IpamQueryURL)
105134
}
106135

107136
// This function will send telemetry report to HostNetAgent.
@@ -112,9 +141,17 @@ func (reportMgr *ReportManager) SendReport() error {
112141
json.NewEncoder(&body).Encode(reportMgr.Report)
113142

114143
log.Printf("Going to send Telemetry report to hostnetagent %v", reportMgr.HostNetAgentURL)
115-
log.Printf("Flag %v Name %v Version %v orchestname %s ErrorMessage %v SystemDetails %v OSDetails %v InterfaceDetails %v",
116-
reportMgr.Report.StartFlag, reportMgr.Report.Name, reportMgr.Report.Version, reportMgr.Report.OrchestratorDetails, reportMgr.Report.ErrorMessage,
117-
reportMgr.Report.SystemDetails, reportMgr.Report.OSDetails, reportMgr.Report.InterfaceDetails)
144+
145+
log.Printf(`"Start Flag %v Name %v Version %v ErrorMessage %v vnet %v
146+
Context %v SubContext %v"`, reportMgr.Report.StartFlag, reportMgr.Report.Name,
147+
reportMgr.Report.Version, reportMgr.Report.ErrorMessage, reportMgr.Report.VnetAddressSpace,
148+
reportMgr.Report.Context, reportMgr.Report.SubContext)
149+
150+
log.Printf("OrchestratorDetails %v", reportMgr.Report.OrchestratorDetails)
151+
log.Printf("OSDetails %v", reportMgr.Report.OSDetails)
152+
log.Printf("SystemDetails %v", reportMgr.Report.SystemDetails)
153+
log.Printf("InterfaceDetails %v", reportMgr.Report.InterfaceDetails)
154+
log.Printf("BridgeDetails %v", reportMgr.Report.BridgeDetails)
118155

119156
res, err := httpc.Post(reportMgr.HostNetAgentURL, reportMgr.ReportType, &body)
120157
if err != nil {
@@ -166,3 +203,107 @@ func (report *Report) GetReportState() bool {
166203

167204
return true
168205
}
206+
207+
// This function creates a report with interface details(ip, mac, name, secondaryca count).
208+
func (report *Report) GetInterfaceDetails(queryUrl string) {
209+
210+
var (
211+
macAddress string
212+
secondaryCACount int
213+
primaryCA string
214+
subnet string
215+
ifName string
216+
)
217+
218+
if queryUrl == "" {
219+
report.InterfaceDetails.ErrorMessage = "IpamQueryUrl is null"
220+
return
221+
}
222+
223+
interfaces, err := net.Interfaces()
224+
if err != nil {
225+
report.InterfaceDetails = &InterfaceInfo{}
226+
report.InterfaceDetails.ErrorMessage = "Getting all interfaces failed due to " + err.Error()
227+
return
228+
}
229+
230+
resp, err := http.Get(queryUrl)
231+
if err != nil {
232+
report.InterfaceDetails = &InterfaceInfo{}
233+
report.InterfaceDetails.ErrorMessage = "Http get failed in getting interface details " + err.Error()
234+
return
235+
}
236+
237+
defer resp.Body.Close()
238+
239+
// Decode XML document.
240+
var doc common.XmlDocument
241+
decoder := xml.NewDecoder(resp.Body)
242+
err = decoder.Decode(&doc)
243+
if err != nil {
244+
report.InterfaceDetails = &InterfaceInfo{}
245+
report.InterfaceDetails.ErrorMessage = "xml decode failed due to " + err.Error()
246+
return
247+
}
248+
249+
// For each interface...
250+
for _, i := range doc.Interface {
251+
i.MacAddress = strings.ToLower(i.MacAddress)
252+
253+
if i.IsPrimary {
254+
// Find the interface with the matching MacAddress.
255+
for _, iface := range interfaces {
256+
macAddr := strings.Replace(iface.HardwareAddr.String(), ":", "", -1)
257+
macAddr = strings.ToLower(macAddr)
258+
if macAddr == i.MacAddress {
259+
ifName = iface.Name
260+
macAddress = iface.HardwareAddr.String()
261+
}
262+
}
263+
264+
for _, s := range i.IPSubnet {
265+
for _, ip := range s.IPAddress {
266+
if ip.IsPrimary {
267+
primaryCA = ip.Address
268+
subnet = s.Prefix
269+
} else {
270+
secondaryCACount += 1
271+
}
272+
}
273+
}
274+
275+
break
276+
}
277+
}
278+
279+
report.InterfaceDetails = &InterfaceInfo{
280+
InterfaceType: "Primary",
281+
MAC: macAddress,
282+
Subnet: subnet,
283+
Name: ifName,
284+
PrimaryCA: primaryCA,
285+
SecondaryCATotalCount: secondaryCACount,
286+
}
287+
}
288+
289+
// This function creates a report with orchestrator details(name, version).
290+
func (report *Report) GetOrchestratorDetails() {
291+
out, err := exec.Command("kubectl", "--version").Output()
292+
if err != nil {
293+
report.OrchestratorDetails = &OrchsestratorInfo{}
294+
report.OrchestratorDetails.ErrorMessage = "kubectl command failed due to " + err.Error()
295+
return
296+
}
297+
298+
outStr := string(out)
299+
outStr = strings.TrimLeft(outStr, " ")
300+
report.OrchestratorDetails = &OrchsestratorInfo{}
301+
302+
resultArray := strings.Split(outStr, " ")
303+
if len(resultArray) >= 2 {
304+
report.OrchestratorDetails.OrchestratorName = resultArray[0]
305+
report.OrchestratorDetails.OrchestratorVersion = resultArray[1]
306+
} else {
307+
report.OrchestratorDetails.ErrorMessage = "Length of array is less than 2"
308+
}
309+
}

0 commit comments

Comments
 (0)