go/svc/(dc stuff) -> dc/

We want to start keeping codebases separated per 'team'/intent, to then
have simple OWNER files/trees to specify review rules.

This means dc/ stuff can all be OWNED by q3k, and review will only
involve a +1 for style/readability, instead  of a +2 for approval.

Change-Id: I05afbc4e1018944b841ec0d88cd24cc95bec8bf1
diff --git a/dc/arista-proxy/service.go b/dc/arista-proxy/service.go
new file mode 100644
index 0000000..3144ff7
--- /dev/null
+++ b/dc/arista-proxy/service.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+	"context"
+
+	"github.com/golang/glog"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+
+	pb "code.hackerspace.pl/hscloud/dc/arista-proxy/proto"
+)
+
+func (s *server) ShowVersion(ctx context.Context, req *pb.ShowVersionRequest) (*pb.ShowVersionResponse, error) {
+	var version []struct {
+		ModelName        string  `json:"modelName"`
+		InternalVersion  string  `json:"internalVersion"`
+		SystemMacAddress string  `json:"systemMacAddress"`
+		SerialNumber     string  `json:"serialNumber"`
+		MemTotal         int64   `json:"memTotal"`
+		BootupTimestamp  float64 `json:"bootupTimestamp"`
+		MemFree          int64   `json:"memFree"`
+		Version          string  `json:"version"`
+		Architecture     string  `json:"architecture"`
+		InternalBuildId  string  `json:"internalBuildId"`
+		HardwareRevision string  `json:"hardwareRevision"`
+	}
+
+	err := s.arista.structuredCall(&version, "show version")
+	if err != nil {
+		glog.Errorf("EOS Capi: show version: %v", err)
+		return nil, status.Error(codes.Unavailable, "EOS Capi call failed")
+	}
+
+	if len(version) != 1 {
+		glog.Errorf("Expected 1-length result, got %d", len(version))
+		return nil, status.Error(codes.Internal, "Internal error")
+	}
+
+	d := version[0]
+
+	return &pb.ShowVersionResponse{
+		ModelName:        d.ModelName,
+		InternalVersion:  d.InternalVersion,
+		SystemMacAddress: d.SystemMacAddress,
+		SerialNumber:     d.SerialNumber,
+		MemTotal:         d.MemTotal,
+		BootupTimestamp:  d.BootupTimestamp,
+		MemFree:          d.MemFree,
+		Version:          d.Version,
+		Architecture:     d.Architecture,
+		InternalBuildId:  d.InternalBuildId,
+		HardwareRevision: d.HardwareRevision,
+	}, nil
+}
+
+type temperatureSensor struct {
+	InAlertState       bool    `json:"inAlertState"`
+	MaxTemperature     float64 `json:"maxTemperature"`
+	RelPos             int64   `json:"relPos"`
+	Description        string  `json:"description"`
+	Name               string  `json:"name"`
+	AlertCount         int64   `json:"alertCount"`
+	CurrentTemperature float64 `json:"currentTemperature"`
+	OverheatThreshold  float64 `json:"overheatThreshold"`
+	CriticalThreshold  float64 `json:"criticalThreshold"`
+	HwStatus           string  `json:"hwStatus"`
+}
+
+func (s *server) ShowEnvironmentTemperature(ctx context.Context, req *pb.ShowEnvironmentTemperatureRequest) (*pb.ShowEnvironmentTemperatureResponse, error) {
+	var response []struct {
+		PowerSuppplySlots []struct {
+			TempSensors      []temperatureSensor `json:"tempSensors"`
+			EntPhysicalClass string              `json:"entPhysicalClass"`
+			RelPos           int64               `json:"relPos"`
+		} `json:"powerSupplySlots"`
+
+		ShutdownOnOverheat bool                `json:"shutdownOnOverheat"`
+		TempSensors        []temperatureSensor `json:"tempSensors"`
+		SystemStatus       string              `json:"systemStatus"`
+	}
+
+	err := s.arista.structuredCall(&response, "show environment temperature")
+	if err != nil {
+		glog.Errorf("EOS Capi: show environment temperature: %v", err)
+		return nil, status.Error(codes.Unavailable, "EOS Capi call failed")
+	}
+
+	if len(response) != 1 {
+		glog.Errorf("Expected 1-length result, got %d", len(response))
+		return nil, status.Error(codes.Internal, "Internal error")
+	}
+
+	d := response[0]
+	glog.Infof("%+v", d)
+
+	return &pb.ShowEnvironmentTemperatureResponse{}, nil
+}