Moved all structs exposed by API into apiv1 package
[src/xds/xds-agent.git] / lib / agent / project-pathmap.go
1 package agent
2
3 import (
4         "fmt"
5         "io/ioutil"
6         "os"
7         "strings"
8
9         "github.com/iotbzh/xds-agent/lib/apiv1"
10         common "github.com/iotbzh/xds-common/golib"
11 )
12
13 // IPROJECT interface implementation for native/path mapping projects
14
15 // PathMap .
16 type PathMap struct {
17         *Context
18         server *XdsServer
19         folder *XdsFolderConfig
20 }
21
22 // NewProjectPathMap Create a new instance of PathMap
23 func NewProjectPathMap(ctx *Context, svr *XdsServer) *PathMap {
24         p := PathMap{
25                 Context: ctx,
26                 server:  svr,
27                 folder:  &XdsFolderConfig{},
28         }
29         return &p
30 }
31
32 // Add a new project
33 func (p *PathMap) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
34         var err error
35         var file *os.File
36         errMsg := "ClientPath sanity check error (%d): %v"
37
38         // Sanity check to verify that we have RW permission and path-mapping is correct
39         dir := cfg.ClientPath
40         if !common.Exists(dir) {
41                 // try to create if not existing
42                 if err := os.MkdirAll(dir, 0755); err != nil {
43                         return nil, fmt.Errorf("Cannot create ClientPath directory: %s", dir)
44                 }
45         }
46         if !common.Exists(dir) {
47                 return nil, fmt.Errorf("ClientPath directory is not accessible: %s", dir)
48         }
49         if file, err = ioutil.TempFile(dir, ".xds_pathmap_check"); err != nil {
50                 return nil, fmt.Errorf(errMsg, 1, err)
51         }
52         // Write a specific message that will be check by server during folder add
53         msg := "Pathmap checked message written by xds-agent ID: " + p.Config.AgentUID + "\n"
54         if n, err := file.WriteString(msg); n != len(msg) || err != nil {
55                 return nil, fmt.Errorf(errMsg, 2, err)
56         }
57         defer func() {
58                 if file != nil {
59                         os.Remove(file.Name())
60                         file.Close()
61                 }
62         }()
63
64         // Convert to Xds folder
65         fld := p.server.ProjectToFolder(cfg)
66         fld.DataPathMap.CheckFile = file.Name()
67         fld.DataPathMap.CheckContent = msg
68
69         // Send request to create folder on XDS server side
70         err = p.server.FolderAdd(fld, p.folder)
71         if err != nil {
72                 return nil, fmt.Errorf("Folders mapping verification failure.\n%v", err)
73         }
74
75         // 2nd part of sanity checker
76         // check specific message added by XDS Server during folder add processing
77         content, err := ioutil.ReadFile(file.Name())
78         if err != nil {
79                 return nil, fmt.Errorf(errMsg, 3, err)
80         }
81         if !strings.Contains(string(content),
82                 "Pathmap checked message written by xds-server ID") {
83                 return nil, fmt.Errorf(errMsg, 4, "file content differ")
84         }
85
86         return p.GetProject(), nil
87 }
88
89 // Delete a project
90 func (p *PathMap) Delete() error {
91         return p.server.FolderDelete(p.folder.ID)
92 }
93
94 // GetProject Get public part of project config
95 func (p *PathMap) GetProject() *apiv1.ProjectConfig {
96         prj := p.server.FolderToProject(*p.folder)
97         prj.ServerID = p.server.ID
98         return &prj
99 }
100
101 // UpdateProject Set project config
102 func (p *PathMap) UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
103         p.folder = p.server.ProjectToFolder(prj)
104         np := p.GetProject()
105         if err := p.events.Emit(apiv1.EVTProjectChange, np); err != nil {
106                 return np, err
107         }
108         return np, nil
109 }
110
111 // GetServer Get the XdsServer that holds this project
112 func (p *PathMap) GetServer() *XdsServer {
113         return p.server
114 }
115
116 // Sync Force project files synchronization
117 func (p *PathMap) Sync() error {
118         return nil
119 }
120
121 // IsInSync Check if project files are in-sync
122 func (p *PathMap) IsInSync() (bool, error) {
123         return true, nil
124 }