Add RBAC support with roles, permissions, and session management. Implement middleware for authentication and CSRF protection. Enhance audit logging with additional fields. Update HTTP handlers and routes for new features.
This commit is contained in:
121
internal/infra/iscsi/iscsi.go
Normal file
121
internal/infra/iscsi/iscsi.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package iscsi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/example/storage-appliance/internal/infra/osexec"
|
||||
)
|
||||
|
||||
// Adapter wraps targetcli invocations for LIO (targetcli) management.
|
||||
type Adapter struct {
|
||||
Runner osexec.Runner
|
||||
}
|
||||
|
||||
func NewAdapter(runner osexec.Runner) *Adapter { return &Adapter{Runner: runner} }
|
||||
|
||||
// CreateTarget creates an IQN target via targetcli
|
||||
func (a *Adapter) CreateTarget(ctx context.Context, iqn string) error {
|
||||
// Use a short timeout for cli interactions
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", "/iscsi", "create", iqn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli create target failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli create returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateBackstore creates a block backstore for a zvol device.
|
||||
func (a *Adapter) CreateBackstore(ctx context.Context, name, devpath string) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
// targetcli syntax: /backstores/block create <name> <devpath>
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", "/backstores/block", "create", name, devpath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli create backstore failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli backstore returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateLUN maps backstore into target's TPG1 LUNs
|
||||
func (a *Adapter) CreateLUN(ctx context.Context, iqn, backstoreName string, lunID int) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
bsPath := fmt.Sprintf("/backstores/block/%s", backstoreName)
|
||||
tpgPath := fmt.Sprintf("/iscsi/%s/tpg1/luns", iqn)
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", tpgPath, "create", bsPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli create lun failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli create lun returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteLUN unmaps a LUN from a target; if the LUN is mapped fail unless forced.
|
||||
func (a *Adapter) DeleteLUN(ctx context.Context, iqn string, lunID int) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
tpgPath := fmt.Sprintf("/iscsi/%s/tpg1/luns", iqn)
|
||||
// delete by numeric id
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", tpgPath, "delete", fmt.Sprintf("%d", lunID))
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli delete lun failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli delete lun returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Adapter) AddPortal(ctx context.Context, iqn, address string, port int) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
tpgPath := fmt.Sprintf("/iscsi/%s/tpg1/portals", iqn)
|
||||
addr := fmt.Sprintf("%s:%d", address, port)
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", tpgPath, "create", addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli add portal failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli add portal returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Adapter) AddACL(ctx context.Context, iqn, initiator string) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
aclPath := fmt.Sprintf("/iscsi/%s/tpg1/acls", iqn)
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", aclPath, "create", initiator)
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli add acl failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli add acl returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save writes the configuration to storage (saving targetcli config)
|
||||
func (a *Adapter) Save(ctx context.Context) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
_, stderr, code, err := osexec.ExecWithRunner(a.Runner, ctx, "targetcli", "saveconfig")
|
||||
if err != nil {
|
||||
return fmt.Errorf("targetcli save failed: %v %s", err, stderr)
|
||||
}
|
||||
if code != 0 {
|
||||
return fmt.Errorf("targetcli save returned: %s", stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user