blob: 40aa8b3b416bd20d82d2a6bc71e83577cb16449f [file] [log] [blame]
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package node
18
19import (
20 "flag"
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010021
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020022 "git.monogon.dev/source/nexantic.git/core/internal/api"
23 "git.monogon.dev/source/nexantic.git/core/internal/common"
24 "git.monogon.dev/source/nexantic.git/core/internal/consensus"
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010025 "git.monogon.dev/source/nexantic.git/core/internal/kubernetes"
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020026 "git.monogon.dev/source/nexantic.git/core/internal/storage"
Leopold Schabel68c58752019-11-14 21:00:59 +010027 "os"
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020028
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020029 "github.com/google/uuid"
30 "go.uber.org/zap"
31)
32
33type (
34 SmalltownNode struct {
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010035 Api *api.Server
36 Consensus *consensus.Service
37 Storage *storage.Manager
38 Kubernetes *kubernetes.Service
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020039
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010040 logger *zap.Logger
41 state common.SmalltownState
42 joinToken string
43 hostname string
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020044 }
45)
46
47func NewSmalltownNode(logger *zap.Logger, apiPort, consensusPort uint16) (*SmalltownNode, error) {
48 flag.Parse()
49 logger.Info("Creating Smalltown node")
50
Leopold Schabel68c58752019-11-14 21:00:59 +010051 hostname, err := os.Hostname()
52 if err != nil {
53 panic(err)
54 }
55
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020056 storageManager, err := storage.Initialize(logger.With(zap.String("component", "storage")))
57 if err != nil {
58 logger.Error("Failed to initialize storage manager", zap.Error(err))
59 return nil, err
60 }
61
62 consensusService, err := consensus.NewConsensusService(consensus.Config{
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010063 Name: hostname,
64 ListenPort: consensusPort,
65 ListenHost: "0.0.0.0",
66 ExternalHost: "10.0.2.15", // TODO: Once Multi-Node setups are actually used, this needs to be corrected
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020067 }, logger.With(zap.String("module", "consensus")))
68 if err != nil {
69 return nil, err
70 }
71
72 s := &SmalltownNode{
73 Consensus: consensusService,
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020074 Storage: storageManager,
Leopold Schabel68c58752019-11-14 21:00:59 +010075 logger: logger,
76 hostname: hostname,
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020077 }
78
79 apiService, err := api.NewApiServer(&api.Config{
80 Port: apiPort,
81 }, logger.With(zap.String("module", "api")), s, s.Consensus)
82 if err != nil {
83 return nil, err
84 }
85
86 s.Api = apiService
87
Lorenz Brun6e8f69c2019-11-18 10:44:24 +010088 s.Kubernetes = kubernetes.New(logger.With(zap.String("module", "kubernetes")), consensusService)
89
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020090 logger.Info("Created SmalltownNode")
91
92 return s, nil
93}
94
95func (s *SmalltownNode) Start() error {
96 s.logger.Info("Starting Smalltown node")
97
98 if s.Consensus.IsProvisioned() {
99 s.logger.Info("Consensus is provisioned")
100 err := s.startFull()
101 if err != nil {
102 return err
103 }
104 } else {
Leopold Schabel68c58752019-11-14 21:00:59 +0100105 s.logger.Info("Consensus is not provisioned, starting provisioning...")
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +0200106 err := s.startForSetup()
107 if err != nil {
108 return err
109 }
110 }
111
112 return nil
113}
114
115func (s *SmalltownNode) startForSetup() error {
116 s.logger.Info("Initializing subsystems for setup mode")
117 s.state = common.StateSetupMode
118 s.joinToken = uuid.New().String()
119
120 err := s.Api.Start()
121 if err != nil {
122 s.logger.Error("Failed to start the API service", zap.Error(err))
123 return err
124 }
125
126 return nil
127}
128
129func (s *SmalltownNode) startFull() error {
130 s.logger.Info("Initializing subsystems for production")
131 s.state = common.StateConfigured
132
133 err := s.SetupBackend()
134 if err != nil {
135 return err
136 }
137
138 err = s.Consensus.Start()
139 if err != nil {
140 return err
141 }
142
143 err = s.Api.Start()
144 if err != nil {
145 s.logger.Error("Failed to start the API service", zap.Error(err))
146 return err
147 }
148
Lorenz Brun6e8f69c2019-11-18 10:44:24 +0100149 err = s.Kubernetes.Start()
150 if err != nil {
151 s.logger.Error("Failed to start the Kubernetes Service", zap.Error(err))
152 }
153
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +0200154 return nil
155}
156
157func (s *SmalltownNode) Stop() error {
158 s.logger.Info("Stopping Smalltown node")
159 return nil
160}
161
162func (s *SmalltownNode) SetupBackend() error {
163 s.logger.Debug("Creating trust backend")
164
165 return nil
166}