Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
g4ze committed Jun 25, 2024
1 parent 078b8e3 commit 9adfc30
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 167 deletions.
41 changes: 0 additions & 41 deletions fe/app/api/route.ts

This file was deleted.

5 changes: 3 additions & 2 deletions fe/app/service/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TabButton, ActiveTaskButton } from "@/components/TabButton";
import CreateService from '@/components/CreateService';
import Services from '@/components/Services';
import {Service} from '@/types';
import ServiceForm from '@/components/ServiceForm';

export default function ServicePage() {
const [activeService, setActiveService] = useState('create-deployment');
Expand Down Expand Up @@ -96,9 +97,9 @@ export default function ServicePage() {

<div className="col-span-9 overflow-y-auto">
<section id="create-deployment" className="h-screen items-center justify-center">
<CreateService/>
<ServiceForm services={services} setServices={setServices} setActiveService={setActiveService}/>
</section>
<Services services={services}/>
<Services services={services} setActiveService={setActiveService}/>
</div>
</div>
</>
Expand Down
3 changes: 2 additions & 1 deletion fe/components/CreateService.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"use client"
import { Dispatch, SetStateAction } from "react";
import Earth3D from "./Earth3D";
import ServiceForm from "./ServiceForm";

export default function CreateService() {
return (
<div className="relative z-10 flex h-screen w-100">
<div className="flex justify-center pt-8 w-screen bg-black bg-opacity-50">
<ServiceForm/>
{/* <ServiceForm/> */}
</div>
</div>
)
Expand Down
39 changes: 30 additions & 9 deletions fe/components/ServiceForm.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import React, { useState } from 'react';
import { Heading } from './Heading';
import { Field } from './Field';
import Image from 'next/image';
import exclamationImg from '@/public/exclamation.png'
import { Env } from '@/types';
import { time } from 'console';
import { Env, Service } from '@/types';
import { uniqueNamesGenerator, Config, adjectives, animals } from 'unique-names-generator';


const ServiceForm = () => {
import React, { Dispatch, SetStateAction } from 'react';
import { useState } from 'react';
const ServiceForm = ({services, setServices, setActiveService}:{services: Service[],
setServices: Dispatch<SetStateAction<Service[]>>, setActiveService:Dispatch<SetStateAction<string>>}) => {

const customConfig: Config = {
dictionaries: [adjectives, animals],
Expand All @@ -25,7 +23,7 @@ const ServiceForm = () => {
const [error, setError] = useState('');
// const [env, setEnv] = useState(Env);
// const [region, setRegion] = useState('US East (Ohio)');

const handleSubmit = (e:any) => {
(async () => {
// Handle form submission logic here
Expand All @@ -45,7 +43,30 @@ const ServiceForm = () => {
'deploymentName': deploymentName,
}),
});
console.log(resp.text());
setIsLoading(false);
if (resp.ok) {
// Redirect to the service page
console.log(resp)

const data = await resp.json();
console.log(data);
setServices([...services, data]);
const scrollToService = (serviceName: string) => {
setActiveService(serviceName);
// can do better prop drilling
localStorage.setItem('activeService', serviceName);
const element = document.getElementById(serviceName);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
};
scrollToService(data.name);
} else {
const data = await resp.json();
setIsLoading(false);
setError(data.message);

}
})();
}

Expand Down
122 changes: 68 additions & 54 deletions fe/components/Services.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,81 @@
import { Service } from "@/types";
import { Heading } from "./Heading";
import { useState } from "react";
export default function Services({ services }: { services: Service[] }) {
import { Dispatch, SetStateAction, useState } from "react";
export default function Services({ services, setActiveService }: { services: Service[], setActiveService: Dispatch<SetStateAction<string>> }) {
console.log("services from services maping component: ", services);
const HOST_PROXY = process.env.HOST_PROXY || "localhost:80";
const [isLoading, setIsLoading] = useState(false);
const [isDeleted, setIsDeleted] = useState(false);
return (
<>

{services.map((service) => (
service.createdAt && localStorage.setItem(service.slug, service.createdAt.toString()),
<section id={service.name} className="">
<div className=" max-w-400 mx-10 text-white h-screen bg-black bg-opacity-50 items-center justify-center">
<Heading label="Deployment Name: " className="font-bold text-sm pt-6 "/>
<Heading
label={service.deploymentName}
className="font-bold text-4xl pt-2 mb-3"
/>
<Heading label="Image Link: " className="font-bold text-sm pt-6 "/>
<Heading
label={service.image}
className="text-2xl pt-2 mb-3"
/>
<Heading label="DNS A" className="font-bold text-sm pt-6 "/>
<p
className="text-2xl pt-2 mb-3"
><a href={"http://"+service.loadbalancerDNS}>{service.loadbalancerDNS}</a></p>
<Heading label="Created At: " className="font-bold text-sm pt-6 "/>
<Heading
label={service.createdAt.toString()}
className="text-2xl pt-2 mb-3"
/>
<Heading label="URL: " className="font-bold text-sm pt-6 "/>
<Heading label={"https://"+service.slug+"."+HOST_PROXY} className="text-2xl pt-2 mb-3"/>
<Heading label="logs:" className="font-bold text-sm pt-6 "/>
<Heading
label={service.logs}
className="text-2xl pt-2 mb-3"
/>
<button className="text-white px-3 py-2 focus:border-r-2 rounded hover:border-r-2 hover:shadow-[inset_-32px_0_32px_-15px_rgba(255,255,255,0.2)] transition-shadow duration-150 outline-none shadow-[inset_-32px_0_20px_-15px_rgba(255,255,255,0.2)] transition-shadow duration-300"
onClick={async () =>{
setIsLoading(true)
<div className=" max-w-400 mx-10 text-white h-screen bg-black bg-opacity-50 items-center justify-center">
<Heading label="Deployment Name: " className="font-bold text-sm pt-6 " />
<Heading
label={service.deploymentName}
className="font-bold text-4xl pt-2 mb-3"
/>
<Heading label="Image Link: " className="font-bold text-sm pt-6 " />
<Heading
label={service.image}
className="text-2xl pt-2 mb-3"
/>
<Heading label="DNS A" className="font-bold text-sm pt-6 " />
<p
className="text-2xl pt-2 mb-3"
><a href={"http://" + service.loadbalancerDNS}>{service.loadbalancerDNS}</a></p>
<Heading label="Created At: " className="font-bold text-sm pt-6 " />
<Heading
label={service.createdAt?.toString()||localStorage.getItem(service.slug)?.toString()||"recently"}
className="text-2xl pt-2 mb-3"
/>
<Heading label="URL: " className="font-bold text-sm pt-6 " />
<Heading label={"https://" + service.slug + "." + HOST_PROXY} className="text-2xl pt-2 mb-3" />
<Heading label="logs:" className="font-bold text-sm pt-6 " />
<Heading
label={service.logs}
className="text-2xl pt-2 mb-3"
/>
<button className="text-white px-3 py-2 focus:border-r-2 rounded hover:border-r-2 hover:shadow-[inset_-32px_0_32px_-15px_rgba(255,255,255,0.2)] transition-shadow duration-150 outline-none shadow-[inset_-32px_0_20px_-15px_rgba(255,255,255,0.2)] transition-shadow duration-300"
onClick={async () => {
setIsLoading(true)

await fetch(`http://localhost:2001/v1/delete-container`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + localStorage.getItem("token"),
},
body: JSON.stringify({
"image": service.image,
"userName": service.userName,
}),
}
)
setIsLoading(false)
setIsDeleted(true)
// better prop drilling can be done
const scrollToService = (serviceName: string) => {
setActiveService(serviceName);
// can do better prop drilling
localStorage.setItem('activeService', serviceName);
const element = document.getElementById(serviceName);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
};
scrollToService("create-deployment")
window.location.reload()
}
}>{
isLoading ? "Deleting..." : isDeleted? "Deleted" : "Delete"
}
</button>
</div>

await fetch(`http://localhost:3001/v1/delete-container/`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + localStorage.getItem("token"),
},
body: JSON.stringify({
"image" :service.image,
"userName": service.userName,
}),
}
)
setIsLoading(false)
window.location.reload()
}
}>{
isLoading ? "Deleting..." : "Delete"
}
</button>
</div>


</section>
))}
Expand Down
2 changes: 1 addition & 1 deletion fe/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function middleware(request: NextRequest) {
const response = await fetch(apiUrl);
if (response.ok) {
const data = await response.json();
url.hostname = data.lbDns;
url.hostname = data.dns;
url.pathname = paths.slice(3).join('/');
url.port = ''
console.info(`Redirecting to: ${url.toString()}`);
Expand Down
12 changes: 2 additions & 10 deletions pkg/controllers/deploy-container.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/g4ze/byoc/pkg/core"
byocTypes "github.com/g4ze/byoc/pkg/types"
"github.com/joho/godotenv"
"github.com/sio/coolname"
)

// Deploy the container
Expand Down Expand Up @@ -62,16 +61,9 @@ func Deploy_container(newDeployment *byocTypes.DeployContainerPayload) (*byocTyp
return nil, nil
}

service.Slug, err = GenerateSlug(newDeployment.UserName)
if err != nil {
return nil, err
}
service.Slug = (newDeployment.DeploymentName)

log.Printf("returning service: %+v", service)
return service, nil

}
func GenerateSlug(UserName string) (string, error) {
slug, err := coolname.SlugN(3)
slug += "-" + UserName
return slug, err
}
2 changes: 1 addition & 1 deletion pkg/core/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func TestService(t *testing.T) {

CreateTaskDefinition(svc, "test", img, 80, nil)
log.Printf("Creating service")
service, err := CreateService(svc, elbSvc, "test", img, int32(80), []types.KeyValuePair{{Name: aws.String("test"), Value: aws.String("test")}})
service, err := CreateService(svc, elbSvc, "test", img, int32(80), []types.KeyValuePair{{Name: aws.String("test"), Value: aws.String("test")}}, "test")
if err != nil {
log.Fatalf("Error creating service: %v", err)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/core/service-ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
Expand All @@ -16,7 +17,7 @@ import (
func CreateService(svc *ecs.Client, elbSvc *elbv2.ELBV2, UserName string, Image string, Port int32, Environment []types.KeyValuePair, DeploymentName string) (*byocTypes.Service, error) {
var desiredCount int32 = 2
containerName := generateName(UserName, Image, "container")
serviceName := generateNameFromImage(Image)
serviceName := strings.ReplaceAll(DeploymentName, " ", "-")
Family := generateName(UserName, Image, "task")
isService, serviceStatus, err := ServiceExists(svc, serviceName, UserName)
if err != nil {
Expand Down Expand Up @@ -56,12 +57,12 @@ func CreateService(svc *ecs.Client, elbSvc *elbv2.ELBV2, UserName string, Image
}
log.Printf("Creating service %s", serviceName)
// this needs a change, we cant keep creating load balancers
// based on the image name, we need to create a unique name
loadBalancerArn, lbdns, err := CreateLoadBalancer(elbSvc, Image)
// based on the service/deploymeny name, we need to create a unique name
loadBalancerArn, lbdns, err := CreateLoadBalancer(elbSvc, serviceName)
if err != nil {
return nil, fmt.Errorf("failed to create load balancer: %+v", err)
}
targetGroupArn, err := CreateTargetGroup(elbSvc, Image)
targetGroupArn, err := CreateTargetGroup(elbSvc, serviceName)
if err != nil {
return nil, fmt.Errorf("failed to create target group: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/core/target-group-ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/aws/aws-sdk-go/service/elbv2"
)

func CreateTargetGroup(elbSvc *elbv2.ELBV2, Image string) (*string, error) {
targetGroupName := generateName("", Image, "tg")
func CreateTargetGroup(elbSvc *elbv2.ELBV2, deploymentName string) (*string, error) {
targetGroupName := generateName("", deploymentName, "tg")

// Define target group input
createInput := &elbv2.CreateTargetGroupInput{
Expand Down
Loading

0 comments on commit 9adfc30

Please sign in to comment.