metadata.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2015 CoreOS, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cloudstack
  15. import (
  16. "net"
  17. "strconv"
  18. "strings"
  19. "github.com/rancher/os/netconf"
  20. "github.com/rancher/os/config/cloudinit/datasource"
  21. "github.com/rancher/os/config/cloudinit/datasource/metadata"
  22. "github.com/rancher/os/config/cloudinit/pkg"
  23. "github.com/rancher/os/log"
  24. )
  25. const (
  26. apiVersion = "latest/"
  27. userdataPath = apiVersion + "user-data"
  28. metadataPath = apiVersion + "meta-data/"
  29. serverIdentifier = "dhcp_server_identifier"
  30. )
  31. type MetadataService struct {
  32. metadata.Service
  33. }
  34. func NewDatasource(root string) []*MetadataService {
  35. roots := make([]string, 0, 5)
  36. if root == "" {
  37. if links, err := netconf.GetValidLinkList(); err == nil {
  38. log.Infof("Checking to see if a cloudstack server-identifier is available")
  39. for _, link := range links {
  40. linkName := link.Attrs().Name
  41. log.Infof("searching for cloudstack server %s on %s", serverIdentifier, linkName)
  42. lease := netconf.GetDhcpLease(linkName)
  43. if server, ok := lease[serverIdentifier]; ok {
  44. log.Infof("found cloudstack server '%s'", server)
  45. server = "http://" + server + "/"
  46. roots = append(roots, server)
  47. }
  48. }
  49. } else {
  50. log.Errorf("error getting LinkList: %s", err)
  51. }
  52. } else {
  53. roots = append(roots, root)
  54. }
  55. sources := make([]*MetadataService, 0, len(roots))
  56. for _, server := range roots {
  57. datasource := metadata.NewDatasourceWithCheckPath(server, apiVersion, metadataPath, userdataPath, metadataPath, nil)
  58. sources = append(sources, &MetadataService{datasource})
  59. }
  60. return sources
  61. }
  62. func (ms MetadataService) AvailabilityChanges() bool {
  63. // TODO: if it can't find the network, maybe we can start it?
  64. return false
  65. }
  66. func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
  67. metadata := datasource.Metadata{}
  68. if sshKeys, err := ms.FetchAttributes("public-keys"); err == nil {
  69. metadata.SSHPublicKeys = map[string]string{}
  70. for i, sshkey := range sshKeys {
  71. log.Printf("Found SSH key %d", i)
  72. metadata.SSHPublicKeys[strconv.Itoa(i)] = sshkey
  73. }
  74. } else if _, ok := err.(pkg.ErrNotFound); !ok {
  75. return metadata, err
  76. }
  77. if hostname, err := ms.FetchAttribute("local-hostname"); err == nil {
  78. metadata.Hostname = strings.Split(hostname, " ")[0]
  79. } else if _, ok := err.(pkg.ErrNotFound); !ok {
  80. return metadata, err
  81. }
  82. if localAddr, err := ms.FetchAttribute("local-ipv4"); err == nil {
  83. metadata.PrivateIPv4 = net.ParseIP(localAddr)
  84. } else if _, ok := err.(pkg.ErrNotFound); !ok {
  85. return metadata, err
  86. }
  87. if publicAddr, err := ms.FetchAttribute("public-ipv4"); err == nil {
  88. metadata.PublicIPv4 = net.ParseIP(publicAddr)
  89. } else if _, ok := err.(pkg.ErrNotFound); !ok {
  90. return metadata, err
  91. }
  92. return metadata, nil
  93. }
  94. func (ms MetadataService) Type() string {
  95. return "cloudstack-metadata-service"
  96. }