api.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package api
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "github.com/mohae/deepcopy"
  9. )
  10. // Strings for VolumeSpec
  11. const (
  12. Name = "name"
  13. SpecNodes = "nodes"
  14. SpecParent = "parent"
  15. SpecEphemeral = "ephemeral"
  16. SpecShared = "shared"
  17. SpecSticky = "sticky"
  18. SpecSecure = "secure"
  19. SpecCompressed = "compressed"
  20. SpecSize = "size"
  21. SpecScale = "scale"
  22. SpecFilesystem = "fs"
  23. SpecBlockSize = "block_size"
  24. SpecHaLevel = "repl"
  25. SpecPriority = "io_priority"
  26. SpecSnapshotInterval = "snap_interval"
  27. SpecSnapshotSchedule = "snap_schedule"
  28. SpecAggregationLevel = "aggregation_level"
  29. SpecDedupe = "dedupe"
  30. SpecPassphrase = "secret_key"
  31. SpecAutoAggregationValue = "auto"
  32. SpecGroup = "group"
  33. SpecGroupEnforce = "fg"
  34. SpecZones = "zones"
  35. SpecRacks = "racks"
  36. SpecRegions = "regions"
  37. SpecLabels = "labels"
  38. SpecPriorityAlias = "priority_io"
  39. SpecIoProfile = "io_profile"
  40. )
  41. // OptionKey specifies a set of recognized query params.
  42. const (
  43. // OptName query parameter used to lookup volume by name.
  44. OptName = "Name"
  45. // OptVolumeID query parameter used to lookup volume by ID.
  46. OptVolumeID = "VolumeID"
  47. // OptSnapID query parameter used to lookup snapshot by ID.
  48. OptSnapID = "SnapID"
  49. // OptLabel query parameter used to lookup volume by set of labels.
  50. OptLabel = "Label"
  51. // OptConfigLabel query parameter used to lookup volume by set of labels.
  52. OptConfigLabel = "ConfigLabel"
  53. // OptCumulative query parameter used to request cumulative stats.
  54. OptCumulative = "Cumulative"
  55. )
  56. // Api client-server Constants
  57. const (
  58. OsdVolumePath = "osd-volumes"
  59. OsdSnapshotPath = "osd-snapshot"
  60. TimeLayout = "Jan 2 15:04:05 UTC 2006"
  61. )
  62. const (
  63. // AutoAggregation value indicates driver to select aggregation level.
  64. AutoAggregation = math.MaxUint32
  65. )
  66. // Node describes the state of a node.
  67. // It includes the current physical state (CPU, memory, storage, network usage) as
  68. // well as the containers running on the system.
  69. type Node struct {
  70. Id string
  71. Cpu float64 // percentage.
  72. MemTotal uint64
  73. MemUsed uint64
  74. MemFree uint64
  75. Avgload int
  76. Status Status
  77. GenNumber uint64
  78. Disks map[string]StorageResource
  79. Pools []StoragePool
  80. MgmtIp string
  81. DataIp string
  82. Timestamp time.Time
  83. StartTime time.Time
  84. Hostname string
  85. NodeData map[string]interface{}
  86. // User defined labels for node. Key Value pairs
  87. NodeLabels map[string]string
  88. }
  89. type FluentDConfig struct {
  90. IP string `json:"ip"`
  91. Port string `json:"port"`
  92. }
  93. type TunnelConfig struct {
  94. Key string `json:"key"`
  95. Cert string `json:"cert"`
  96. Endpoint string `json:"tunnel_endpoint"`
  97. }
  98. // Cluster represents the state of the cluster.
  99. type Cluster struct {
  100. Status Status
  101. // Id is the ID of the cluster.
  102. Id string
  103. // NodeId is the ID of the node on which this cluster object
  104. // is initialized
  105. NodeId string
  106. // Nodes is an array of all the nodes in the cluster.
  107. Nodes []Node
  108. // Logging url for the cluster.
  109. LoggingURL string
  110. // Management url for the cluster
  111. ManagementURL string
  112. // FluentD Host for the cluster
  113. FluentDConfig FluentDConfig
  114. // TunnelConfig for the cluster [key, cert, endpoint]
  115. TunnelConfig TunnelConfig
  116. }
  117. // StatPoint represents the basic structure of a single Stat reported
  118. // TODO: This is the first step to introduce stats in openstorage.
  119. // Follow up task is to introduce an API for logging stats
  120. type StatPoint struct {
  121. // Name of the Stat
  122. Name string
  123. // Tags for the Stat
  124. Tags map[string]string
  125. // Fields and values of the stat
  126. Fields map[string]interface{}
  127. // Timestamp in Unix format
  128. Timestamp int64
  129. }
  130. // DriverTypeSimpleValueOf returns the string format of DriverType
  131. func DriverTypeSimpleValueOf(s string) (DriverType, error) {
  132. obj, err := simpleValueOf("driver_type", DriverType_value, s)
  133. return DriverType(obj), err
  134. }
  135. // SimpleString returns the string format of DriverType
  136. func (x DriverType) SimpleString() string {
  137. return simpleString("driver_type", DriverType_name, int32(x))
  138. }
  139. // FSTypeSimpleValueOf returns the string format of FSType
  140. func FSTypeSimpleValueOf(s string) (FSType, error) {
  141. obj, err := simpleValueOf("fs_type", FSType_value, s)
  142. return FSType(obj), err
  143. }
  144. // SimpleString returns the string format of DriverType
  145. func (x FSType) SimpleString() string {
  146. return simpleString("fs_type", FSType_name, int32(x))
  147. }
  148. // CosTypeSimpleValueOf returns the string format of CosType
  149. func CosTypeSimpleValueOf(s string) (CosType, error) {
  150. obj, exists := CosType_value[strings.ToUpper(s)]
  151. if !exists {
  152. return -1, fmt.Errorf("Invalid cos value: %s", s)
  153. }
  154. return CosType(obj), nil
  155. }
  156. // SimpleString returns the string format of CosType
  157. func (x CosType) SimpleString() string {
  158. return simpleString("cos_type", CosType_name, int32(x))
  159. }
  160. // GraphDriverChangeTypeSimpleValueOf returns the string format of GraphDriverChangeType
  161. func GraphDriverChangeTypeSimpleValueOf(s string) (GraphDriverChangeType, error) {
  162. obj, err := simpleValueOf("graph_driver_change_type", GraphDriverChangeType_value, s)
  163. return GraphDriverChangeType(obj), err
  164. }
  165. // SimpleString returns the string format of GraphDriverChangeType
  166. func (x GraphDriverChangeType) SimpleString() string {
  167. return simpleString("graph_driver_change_type", GraphDriverChangeType_name, int32(x))
  168. }
  169. // VolumeActionParamSimpleValueOf returns the string format of VolumeAction
  170. func VolumeActionParamSimpleValueOf(s string) (VolumeActionParam, error) {
  171. obj, err := simpleValueOf("volume_action_param", VolumeActionParam_value, s)
  172. return VolumeActionParam(obj), err
  173. }
  174. // SimpleString returns the string format of VolumeAction
  175. func (x VolumeActionParam) SimpleString() string {
  176. return simpleString("volume_action_param", VolumeActionParam_name, int32(x))
  177. }
  178. // VolumeStateSimpleValueOf returns the string format of VolumeState
  179. func VolumeStateSimpleValueOf(s string) (VolumeState, error) {
  180. obj, err := simpleValueOf("volume_state", VolumeState_value, s)
  181. return VolumeState(obj), err
  182. }
  183. // SimpleString returns the string format of VolumeState
  184. func (x VolumeState) SimpleString() string {
  185. return simpleString("volume_state", VolumeState_name, int32(x))
  186. }
  187. // VolumeStatusSimpleValueOf returns the string format of VolumeStatus
  188. func VolumeStatusSimpleValueOf(s string) (VolumeStatus, error) {
  189. obj, err := simpleValueOf("volume_status", VolumeStatus_value, s)
  190. return VolumeStatus(obj), err
  191. }
  192. // SimpleString returns the string format of VolumeStatus
  193. func (x VolumeStatus) SimpleString() string {
  194. return simpleString("volume_status", VolumeStatus_name, int32(x))
  195. }
  196. // IoProfileSimpleValueOf returns the string format of IoProfile
  197. func IoProfileSimpleValueOf(s string) (IoProfile, error) {
  198. obj, err := simpleValueOf("io_profile", IoProfile_value, s)
  199. return IoProfile(obj), err
  200. }
  201. // SimpleString returns the string format of IoProfile
  202. func (x IoProfile) SimpleString() string {
  203. return simpleString("io_profile", IoProfile_name, int32(x))
  204. }
  205. func simpleValueOf(typeString string, valueMap map[string]int32, s string) (int32, error) {
  206. obj, ok := valueMap[strings.ToUpper(fmt.Sprintf("%s_%s", typeString, s))]
  207. if !ok {
  208. return 0, fmt.Errorf("no openstorage.%s for %s", strings.ToUpper(typeString), s)
  209. }
  210. return obj, nil
  211. }
  212. func simpleString(typeString string, nameMap map[int32]string, v int32) string {
  213. s, ok := nameMap[v]
  214. if !ok {
  215. return strconv.Itoa(int(v))
  216. }
  217. return strings.TrimPrefix(strings.ToLower(s), fmt.Sprintf("%s_", strings.ToLower(typeString)))
  218. }
  219. func toSec(ms uint64) uint64 {
  220. return ms / 1000
  221. }
  222. // WriteThroughput returns the write throughput
  223. func (v *Stats) WriteThroughput() uint64 {
  224. if v.IntervalMs == 0 {
  225. return 0
  226. }
  227. return (v.WriteBytes) / toSec(v.IntervalMs)
  228. }
  229. // ReadThroughput returns the read throughput
  230. func (v *Stats) ReadThroughput() uint64 {
  231. if v.IntervalMs == 0 {
  232. return 0
  233. }
  234. return (v.ReadBytes) / toSec(v.IntervalMs)
  235. }
  236. // Latency returns latency
  237. func (v *Stats) Latency() uint64 {
  238. ops := v.Writes + v.Reads
  239. if ops == 0 {
  240. return 0
  241. }
  242. return (uint64)((v.IoMs * 1000) / ops)
  243. }
  244. // Read latency returns avg. time required for read operation to complete
  245. func (v *Stats) ReadLatency() uint64 {
  246. if v.Reads == 0 {
  247. return 0
  248. }
  249. return (uint64)((v.ReadMs * 1000) / v.Reads)
  250. }
  251. // Write latency returns avg. time required for write operation to complete
  252. func (v *Stats) WriteLatency() uint64 {
  253. if v.Writes == 0 {
  254. return 0
  255. }
  256. return (uint64)((v.WriteMs * 1000) / v.Writes)
  257. }
  258. // Iops returns iops
  259. func (v *Stats) Iops() uint64 {
  260. if v.IntervalMs == 0 {
  261. return 0
  262. }
  263. return (v.Writes + v.Reads) / toSec(v.IntervalMs)
  264. }
  265. // Scaled returns true if the volume is scaled.
  266. func (v *Volume) Scaled() bool {
  267. return v.Spec.Scale > 1
  268. }
  269. // Contains returns true if mid is a member of volume's replication set.
  270. func (m *Volume) Contains(mid string) bool {
  271. rsets := m.GetReplicaSets()
  272. for _, rset := range rsets {
  273. for _, node := range rset.Nodes {
  274. if node == mid {
  275. return true
  276. }
  277. }
  278. }
  279. return false
  280. }
  281. // Copy makes a deep copy of VolumeSpec
  282. func (s *VolumeSpec) Copy() *VolumeSpec {
  283. spec := *s
  284. if s.VolumeLabels != nil {
  285. spec.VolumeLabels = make(map[string]string)
  286. for k, v := range s.VolumeLabels {
  287. spec.VolumeLabels[k] = v
  288. }
  289. }
  290. if s.ReplicaSet != nil {
  291. spec.ReplicaSet = &ReplicaSet{Nodes: make([]string, len(s.ReplicaSet.Nodes))}
  292. copy(spec.ReplicaSet.Nodes, s.ReplicaSet.Nodes)
  293. }
  294. return &spec
  295. }
  296. // Copy makes a deep copy of Node
  297. func (s *Node) Copy() *Node {
  298. localCopy := deepcopy.Copy(*s)
  299. nodeCopy := localCopy.(Node)
  300. return &nodeCopy
  301. }
  302. func (v Volume) IsClone() bool {
  303. return v.Source != nil && len(v.Source.Parent) != 0 && !v.Readonly
  304. }
  305. func (v Volume) IsSnapshot() bool {
  306. return v.Source != nil && len(v.Source.Parent) != 0 && v.Readonly
  307. }
  308. func (v Volume) DisplayId() string {
  309. if v.Locator != nil {
  310. return fmt.Sprintf("%s (%s)", v.Locator.Name, v.Id)
  311. } else {
  312. return v.Id
  313. }
  314. return ""
  315. }