Skip to content

Commit 1e3db9f

Browse files
ndas7Pattela JAYARAGINI
authored andcommitted
gNSI:Add sonic service client support for Credentialz
Signed-off-by: Pattela JAYARAGINI <pattelaj@google.com>
1 parent 3b31e4b commit 1e3db9f

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

common_utils/context.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ const (
4848
GNOI_HEALTHZ_ACK
4949
GNOI_HEALTHZ_CHECK
5050
GNOI_HEALTHZ_COLLECT
51+
GNSI_CREDZ_SET
52+
GNSI_CREDZ_CHECKPOINT
5153
DBUS
5254
DBUS_FAIL
5355
DBUS_APPLY_PATCH_DB
@@ -92,6 +94,10 @@ func (c CounterType) String() string {
9294
return "GNOI Healthz Check"
9395
case GNOI_HEALTHZ_COLLECT:
9496
return "GNOI Healthz Collect"
97+
case GNSI_CREDZ_SET:
98+
return "GNSI Credz Set"
99+
case GNSI_CREDZ_CHECKPOINT:
100+
return "GNSI Credz Checkpoint"
95101
case DBUS:
96102
return "DBUS"
97103
case DBUS_FAIL:

sonic_service_client/dbus_client.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package host_service
22

33
import (
4+
"context"
45
"fmt"
56
"reflect"
67
"strings"
@@ -49,15 +50,49 @@ type Service interface {
4950
// Docker services APIs
5051
LoadDockerImage(image string) error
5152
InstallOS(req string) (string, error)
53+
//Credentialz service APIs
54+
SSHMgmtSet(cmd string) error
55+
GLOMEConfigSet(ctx context.Context, cmd string) error
56+
SSHCheckpoint(action CredzCheckpointAction) error
57+
GLOMERestoreCheckpoint(ctx context.Context) error
58+
ConsoleSet(cmd string) error
59+
ConsoleCheckpoint(action CredzCheckpointAction) error
5260
}
5361

62+
type CredzCheckpointAction string
63+
64+
const (
65+
CredzCPCreate CredzCheckpointAction = ".create_checkpoint"
66+
CredzCPDelete CredzCheckpointAction = ".delete_checkpoint"
67+
CredzCPRestore CredzCheckpointAction = ".restore_checkpoint"
68+
CredzGlomePushConfig CredzCheckpointAction = ".push_config"
69+
NamePrefix = "org.SONiC.HostService."
70+
PathPrefix = "/org/SONiC/HostService/"
71+
)
72+
5473
type DbusClient struct {
5574
busNamePrefix string
5675
busPathPrefix string
5776
intNamePrefix string
5877
channel chan struct{}
5978
}
6079

80+
type Caller interface {
81+
DbusApi(busName string, busPath string, intName string, timeout int, args ...interface{}) (interface{}, error)
82+
}
83+
84+
type DbusCaller struct{}
85+
86+
type FakeDbusCaller struct {
87+
Msg string
88+
}
89+
90+
type FailDbusCaller struct{}
91+
92+
type SpyDbusCaller struct {
93+
Command chan []string
94+
}
95+
6196
func NewDbusClient() (Service, error) {
6297
log.Infof("DbusClient: NewDbusClient")
6398

@@ -80,6 +115,81 @@ func (c *DbusClient) Close() error {
80115
return nil
81116
}
82117

118+
func (_ *FailDbusCaller) DbusApi(busName string, busPath string, intName string, timeout int, args ...interface{}) (interface{}, error) {
119+
return "", fmt.Errorf("%v %v", intName, args)
120+
}
121+
122+
func (c *SpyDbusCaller) DbusApi(busName string, busPath string, intName string, timeout int, args ...interface{}) (interface{}, error) {
123+
resp := []string{intName}
124+
for _, el := range args {
125+
resp = append(resp, fmt.Sprintf("%v", el))
126+
}
127+
c.Command <- resp
128+
return "", nil
129+
}
130+
131+
func (_ *DbusCaller) DbusApi(busName string, busPath string, intName string, timeout int, args ...interface{}) (interface{}, error) {
132+
common_utils.IncCounter(common_utils.DBUS)
133+
conn, err := dbus.SystemBus()
134+
log.V(2).Infof("DBUS Call: %v %v", intName, args)
135+
if err != nil {
136+
log.V(2).Infof("Failed to connect to system bus: %v", err)
137+
common_utils.IncCounter(common_utils.DBUS_FAIL)
138+
return nil, err
139+
}
140+
141+
ch := make(chan *dbus.Call, 1)
142+
obj := conn.Object(busName, dbus.ObjectPath(busPath))
143+
obj.Go(intName, 0, ch, args...)
144+
145+
select {
146+
case call := <-ch:
147+
if call.Err != nil {
148+
common_utils.IncCounter(common_utils.DBUS_FAIL)
149+
return nil, call.Err
150+
}
151+
result := call.Body
152+
if len(result) == 0 {
153+
common_utils.IncCounter(common_utils.DBUS_FAIL)
154+
return nil, fmt.Errorf("Dbus result is empty %v", result)
155+
}
156+
if ret, ok := result[0].(int32); ok {
157+
if ret == 0 {
158+
if len(result) != 2 {
159+
common_utils.IncCounter(common_utils.DBUS_FAIL)
160+
return nil, fmt.Errorf("Dbus result is invalid %v", result)
161+
}
162+
if _, ok := result[1].(string); !ok {
163+
return nil, fmt.Errorf("Dbus result is invalid: second element is not string.")
164+
}
165+
return result[1], nil
166+
} else {
167+
if len(result) != 2 {
168+
common_utils.IncCounter(common_utils.DBUS_FAIL)
169+
return nil, fmt.Errorf("Dbus result is invalid %v", result)
170+
}
171+
if msg, check := result[1].(string); check {
172+
common_utils.IncCounter(common_utils.DBUS_FAIL)
173+
return nil, fmt.Errorf(msg)
174+
} else if msg, check := result[1].(map[string]string); check {
175+
common_utils.IncCounter(common_utils.DBUS_FAIL)
176+
return nil, fmt.Errorf(msg["error"])
177+
} else {
178+
common_utils.IncCounter(common_utils.DBUS_FAIL)
179+
return nil, fmt.Errorf("Invalid result message type %v %v", result[1], reflect.TypeOf(result[1]))
180+
}
181+
}
182+
} else {
183+
common_utils.IncCounter(common_utils.DBUS_FAIL)
184+
return nil, fmt.Errorf("Invalid result type %v %v", result[0], reflect.TypeOf(result[0]))
185+
}
186+
case <-time.After(time.Duration(timeout) * time.Second):
187+
log.V(2).Infof("DbusApi: timeout")
188+
common_utils.IncCounter(common_utils.DBUS_FAIL)
189+
return nil, fmt.Errorf("Timeout %v", timeout)
190+
}
191+
}
192+
83193
func DbusApi(busName string, busPath string, intName string, timeout int, args ...interface{}) (interface{}, error) {
84194
common_utils.IncCounter(common_utils.DBUS)
85195
conn, err := dbus.SystemBus()
@@ -424,3 +534,96 @@ func (c *DbusClient) HealthzAck(req string) (string, error) {
424534
}
425535
return strResult, nil
426536
}
537+
538+
func (c *DbusClient) ConsoleSet(cmd string) error {
539+
modName := "gnsi_console"
540+
busName := c.busNamePrefix + modName
541+
busPath := c.busPathPrefix + modName
542+
intName := c.intNamePrefix + modName + ".set"
543+
544+
common_utils.IncCounter(common_utils.GNSI_CREDZ_SET)
545+
_, err := DbusApi(busName, busPath, intName, 10, []string{cmd})
546+
return err
547+
}
548+
549+
func (c *DbusClient) SSHMgmtSet(cmd string) error {
550+
modName := "ssh_mgmt"
551+
busName := c.busNamePrefix + modName
552+
busPath := c.busPathPrefix + modName
553+
intName := c.intNamePrefix + modName + ".set"
554+
555+
common_utils.IncCounter(common_utils.GNSI_CREDZ_SET)
556+
_, err := DbusApi(busName, busPath, intName, 10, []string{cmd})
557+
return err
558+
}
559+
560+
// GLOMEConfigSet is used to write the GLOME config in the host service file system.
561+
func (c *DbusClient) GLOMEConfigSet(ctx context.Context, cmd string) error {
562+
modName := "glome"
563+
busName := c.busNamePrefix + modName
564+
busPath := c.busPathPrefix + modName
565+
intName := c.intNamePrefix + modName + string(CredzGlomePushConfig)
566+
567+
common_utils.IncCounter(common_utils.GNSI_CREDZ_SET)
568+
timeout := 10 // Default timeout in seconds.
569+
if deadline, ok := ctx.Deadline(); ok {
570+
remaining := time.Until(deadline)
571+
if remaining <= 0 {
572+
return context.DeadlineExceeded
573+
}
574+
timeout = int(remaining.Seconds())
575+
if timeout > 10 {
576+
timeout = 10
577+
}
578+
}
579+
_, err := DbusApi(busName, busPath, intName, timeout, cmd)
580+
return err
581+
}
582+
583+
func (c *DbusClient) ConsoleCheckpoint(action CredzCheckpointAction) error {
584+
modName := "gnsi_console"
585+
busName := c.busNamePrefix + modName
586+
busPath := c.busPathPrefix + modName
587+
intName := c.intNamePrefix + modName + string(action)
588+
589+
common_utils.IncCounter(common_utils.GNSI_CREDZ_CHECKPOINT)
590+
_, err := DbusApi(busName, busPath, intName, 10, "")
591+
return err
592+
}
593+
594+
func (c *DbusClient) SSHCheckpoint(action CredzCheckpointAction) error {
595+
modName := "ssh_mgmt"
596+
busName := c.busNamePrefix + modName
597+
busPath := c.busPathPrefix + modName
598+
intName := c.intNamePrefix + modName + string(action)
599+
600+
common_utils.IncCounter(common_utils.GNSI_CREDZ_CHECKPOINT)
601+
_, err := DbusApi(busName, busPath, intName, 10, "")
602+
return err
603+
}
604+
605+
// GLOMERestoreCheckpoint is used to restore the GLOME config metadata to the
606+
// checkpoint state. This is used to rollback the GLOME config in the host
607+
// service file system.
608+
func (c *DbusClient) GLOMERestoreCheckpoint(ctx context.Context) error {
609+
modName := "glome"
610+
busName := c.busNamePrefix + modName
611+
busPath := c.busPathPrefix + modName
612+
intName := c.intNamePrefix + modName + string(CredzCPRestore)
613+
614+
common_utils.IncCounter(common_utils.GNSI_CREDZ_CHECKPOINT)
615+
// Default timeout in seconds. Set to 5 minutes to give enough time for rollback.
616+
timeout := 300
617+
if deadline, ok := ctx.Deadline(); ok {
618+
remaining := time.Until(deadline)
619+
if remaining <= 0 {
620+
return context.DeadlineExceeded
621+
}
622+
timeout = int(remaining.Seconds())
623+
if timeout > 10 {
624+
timeout = 10
625+
}
626+
}
627+
_, err := DbusApi(busName, busPath, intName, timeout)
628+
return err
629+
}

sonic_service_client/dbus_fake_client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package host_service
22

33
import (
4+
"context"
45
"errors"
56
"fmt"
67
)
@@ -90,3 +91,10 @@ func (f *FakeClient) HealthzAck(req string) (string, error) {
9091
func (f *FakeClientWithError) HealthzAck(req string) (string, error) {
9192
return "", fmt.Errorf("simulated dbus error")
9293
}
94+
95+
func (f *FakeClient) ConsoleCheckpoint(CredzCheckpointAction) error { return nil }
96+
func (f *FakeClient) ConsoleSet(cmd string) error { return nil }
97+
func (f *FakeClient) SSHCheckpoint(CredzCheckpointAction) error { return nil }
98+
func (f *FakeClient) SSHMgmtSet(cmd string) error { return nil }
99+
func (f *FakeClient) GLOMEConfigSet(ctx context.Context, cmd string) error { return nil }
100+
func (f *FakeClient) GLOMERestoreCheckpoint(ctx context.Context) error { return nil }

0 commit comments

Comments
 (0)