Beispiel #1
1
// LogRequests logs the requests to the embedded logger.
func LogRequests(h httpx.Handler) httpx.Handler {
	return httpx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		logger.Info(ctx, "request.start",
			"method", r.Method,
			"path", r.URL.Path,
		)

		err := h.ServeHTTPContext(ctx, w, r)

		logger.Info(ctx, "request.complete")

		return err
	})
}
Beispiel #2
0
// ServeHTTPContext implements the httpx.Handler interface. It will ensure that
// there is a Bearer token present and that it is valid.
func (h *Authentication) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	token, ok := extractToken(r)
	if !ok {
		return ErrUnauthorized
	}

	at, err := h.findAccessToken(token)
	if err != nil {
		return err
	}

	// Token is invalid or not found.
	if at == nil {
		return ErrUnauthorized
	}

	user := at.User

	// Embed the associated user into the context.
	ctx = empire.WithUser(ctx, user)

	logger.Info(ctx,
		"authenticated",
		"user", user.Name,
	)

	reporter.AddContext(ctx, "user", user.Name)

	return h.handler.ServeHTTPContext(ctx, w, r)
}
Beispiel #3
0
func (h *Logger) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	rw := NewResponseWriter(w)

	logger.Info(ctx, "request.start",
		"method", r.Method,
		"path", r.URL.Path,
	)

	err := h.handler.ServeHTTPContext(ctx, rw, r)

	logger.Info(ctx, "request.complete",
		"status", rw.Status(),
	)

	return err
}
Beispiel #4
0
func (m *LoggedManager) CreateLoadBalancer(ctx context.Context, o CreateLoadBalancerOpts) (*LoadBalancer, error) {
	var dnsName, name string
	lb, err := m.Manager.CreateLoadBalancer(ctx, o)
	if err == nil && lb != nil {
		name = lb.Name
		dnsName = lb.DNSName
	}

	logger.Info(ctx, "creating load balancer",
		"err", err,
		"name", name,
		"external", o.External,
		"dns-name", dnsName,
		"cert", o.SSLCert,
	)
	return lb, err
}
Beispiel #5
0
// ServeHTTPContext implements the httpx.Handler interface. It will ensure that
// there is a Bearer token present and that it is valid.
func (h *Authentication) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	username, password, ok := r.BasicAuth()
	if !ok {
		return ErrUnauthorized
	}

	user, err := h.authenticator.Authenticate(username, password, r.Header.Get(HeaderTwoFactor))
	if err != nil {
		switch err {
		case auth.ErrTwoFactor:
			return ErrTwoFactor
		case auth.ErrForbidden:
			return ErrUnauthorized
		}

		if err, ok := err.(*auth.UnauthorizedError); ok {
			return errUnauthorized(err)
		}

		return &ErrorResource{
			Status:  http.StatusForbidden,
			ID:      "forbidden",
			Message: err.Error(),
		}
	}

	// Embed the associated user into the context.
	ctx = WithUser(ctx, user)

	logger.Info(ctx,
		"authenticated",
		"user", user.Name,
	)

	reporter.AddContext(ctx, "user", user.Name)

	return h.handler.ServeHTTPContext(ctx, w, r)
}
Beispiel #6
0
// Handle handles a single sqs.Message to perform the provisioning.
func (c *CustomResourceProvisioner) Handle(ctx context.Context, message *sqs.Message) error {
	var m Message
	err := json.Unmarshal([]byte(*message.Body), &m)
	if err != nil {
		return fmt.Errorf("error unmarshalling sqs message body: %v", err)
	}

	var req customresources.Request
	err = json.Unmarshal([]byte(m.Message), &req)
	if err != nil {
		return fmt.Errorf("error unmarshalling to cloudformation request: %v", err)
	}

	logger.Info(ctx, "cloudformation.provision.request",
		"request_id", req.RequestId,
		"stack_id", req.StackId,
		"request_type", req.RequestType,
		"resource_type", req.ResourceType,
		"logical_resource_id", req.LogicalResourceId,
		"physical_resource_id", req.PhysicalResourceId,
	)

	resp := customresources.NewResponseFromRequest(req)

	// CloudFormation is weird. PhysicalResourceId is required when creating
	// a resource, but if the creation fails, how would we have a physical
	// resource id? In cases where a Create request fails, we set the
	// physical resource id to `failed/Create`. When a delete request comes
	// in to delete that resource, we just send back a SUCCESS response so
	// CloudFormation is happy.
	if req.RequestType == customresources.Delete && req.PhysicalResourceId == fmt.Sprintf("failed/%s", customresources.Create) {
		resp.PhysicalResourceId = req.PhysicalResourceId
	} else {
		resp.PhysicalResourceId, resp.Data, err = c.provision(ctx, m, req)
	}

	// Allow provisioners to just return "" to indicate that the physical
	// resource id did not change.
	if resp.PhysicalResourceId == "" && req.PhysicalResourceId != "" {
		resp.PhysicalResourceId = req.PhysicalResourceId
	}

	switch err {
	case nil:
		resp.Status = customresources.StatusSuccess
		logger.Info(ctx, "cloudformation.provision.success",
			"request_id", req.RequestId,
			"stack_id", req.StackId,
			"physical_resource_id", resp.PhysicalResourceId,
		)
	default:
		// A physical resource id is required, so if a Create request
		// fails, and there's no physical resource id, CloudFormation
		// will only say `Invalid PhysicalResourceId` in the status
		// Reason instead of the actual error that caused the Create to
		// fail.
		if req.RequestType == customresources.Create && resp.PhysicalResourceId == "" {
			resp.PhysicalResourceId = fmt.Sprintf("failed/%s", req.RequestType)
		}

		resp.Status = customresources.StatusFailed
		resp.Reason = err.Error()
		logger.Error(ctx, "cloudformation.provision.error",
			"request_id", req.RequestId,
			"stack_id", req.StackId,
			"err", err.Error(),
		)
	}

	return c.sendResponse(req, resp)
}
Beispiel #7
0
func (m *LoggedManager) DestroyLoadBalancer(ctx context.Context, lb *LoadBalancer) error {
	err := m.Manager.DestroyLoadBalancer(ctx, lb)
	logger.Info(ctx, "destroying load balancer", "err", err, "name", lb.Name)
	return err
}