package api import ( "context" "encoding/json" "net/http" "sync" "github.com/rs/zerolog" "git.omukk.dev/wrenn/sandbox/envd/internal/execcontext" "git.omukk.dev/wrenn/sandbox/envd/internal/host" "git.omukk.dev/wrenn/sandbox/envd/internal/utils" ) // MMDSClient provides access to MMDS metadata. type MMDSClient interface { GetAccessTokenHash(ctx context.Context) (string, error) } // DefaultMMDSClient is the production implementation that calls the real MMDS endpoint. type DefaultMMDSClient struct{} func (c *DefaultMMDSClient) GetAccessTokenHash(ctx context.Context) (string, error) { return host.GetAccessTokenHashFromMMDS(ctx) } type API struct { isNotFC bool logger *zerolog.Logger accessToken *SecureToken defaults *execcontext.Defaults mmdsChan chan *host.MMDSOpts hyperloopLock sync.Mutex mmdsClient MMDSClient lastSetTime *utils.AtomicMax initLock sync.Mutex } func New(l *zerolog.Logger, defaults *execcontext.Defaults, mmdsChan chan *host.MMDSOpts, isNotFC bool) *API { return &API{ logger: l, defaults: defaults, mmdsChan: mmdsChan, isNotFC: isNotFC, mmdsClient: &DefaultMMDSClient{}, lastSetTime: utils.NewAtomicMax(), accessToken: &SecureToken{}, } } func (a *API) GetHealth(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() a.logger.Trace().Msg("Health check") w.Header().Set("Cache-Control", "no-store") w.Header().Set("Content-Type", "") w.WriteHeader(http.StatusNoContent) } func (a *API) GetMetrics(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() a.logger.Trace().Msg("Get metrics") w.Header().Set("Cache-Control", "no-store") w.Header().Set("Content-Type", "application/json") metrics, err := host.GetMetrics() if err != nil { a.logger.Error().Err(err).Msg("Failed to get metrics") w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) if err := json.NewEncoder(w).Encode(metrics); err != nil { a.logger.Error().Err(err).Msg("Failed to encode metrics") } } func (a *API) getLogger(err error) *zerolog.Event { if err != nil { return a.logger.Error().Err(err) //nolint:zerologlint // this is only prep } return a.logger.Info() //nolint:zerologlint // this is only prep }