package resource import ( "context" "fmt" "log" "strings" "github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler" "github.com/aws/aws-sdk-go/aws" "github.com/google/go-github/github" "golang.org/x/oauth2" ) func makeGitHubClient(token string) *github.Client { ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: token}, ) tc := oauth2.NewClient(context.Background(), ts) return github.NewClient(tc) } func parseURL(url string) (string, string) { parts := strings.Split(url, "/") return parts[len(parts)-2], parts[len(parts)-1] } // Create handles the Create event from the Cloudformation service. func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler.ProgressEvent, error) { client := makeGitHubClient(*currentModel.OauthToken) log.Printf("Attempting to create repository: %s/%s", *currentModel.Owner, *currentModel.Name) repo, resp, err := client.Repositories.Create(context.Background(), "", &github.Repository{ Name: currentModel.Name, Homepage: currentModel.Homepage, Description: currentModel.Description, Owner: &github.User{ Name: currentModel.Owner, }, }) if err != nil { return handler.ProgressEvent{}, err } if resp.StatusCode != 201 { log.Printf("Got a non-201 error code: %v", resp.Status) return handler.ProgressEvent{}, fmt.Errorf("Status Code: %d, Status: %v", resp.StatusCode, resp.Status) } currentModel.URL = aws.String(repo.GetURL()) return handler.ProgressEvent{ OperationStatus: handler.Success, Message: "Create Complete", ResourceModel: currentModel, }, nil } // Read handles the Read event from the Cloudformation service. func Read(req handler.Request, prevModel *Model, currentModel *Model) (handler.ProgressEvent, error) { owner, repoName := parseURL(*currentModel.URL) log.Printf("Looking for repository: %s/%s", *currentModel.Owner, *currentModel.Name) client := makeGitHubClient(*currentModel.OauthToken) repo, resp, err := client.Repositories.Get(context.Background(), owner, repoName) if err != nil { return handler.ProgressEvent{}, err } if resp.StatusCode != 200 { log.Printf("Unable to find repository: %s", resp.Status) return handler.ProgressEvent{}, fmt.Errorf("Status Code: %d, Status: %v", resp.StatusCode, resp.Status) } currentModel.Name = repo.Name currentModel.Owner = repo.Owner.Name currentModel.Description = repo.Description currentModel.Homepage = repo.Homepage return handler.ProgressEvent{ OperationStatus: handler.Success, Message: "Read Complete", ResourceModel: currentModel, }, nil } // Update handles the Update event from the Cloudformation service. func Update(req handler.Request, prevModel *Model, currentModel *Model) (handler.ProgressEvent, error) { owner, repoName := parseURL(*currentModel.URL) log.Printf("Looking for repository: %s/%s", *currentModel.Owner, *currentModel.Name) client := makeGitHubClient(*currentModel.OauthToken) _, resp, err := client.Repositories.Edit(context.Background(), owner, repoName, &github.Repository{ Homepage: currentModel.Homepage, Description: currentModel.Description, }) if err != nil { return handler.ProgressEvent{}, err } if resp.StatusCode != 200 { log.Printf("Unable to find repository: %s", resp.Status) return handler.ProgressEvent{}, fmt.Errorf("Status Code: %d, Status: %v", resp.StatusCode, resp.Status) } return handler.ProgressEvent{ OperationStatus: handler.Success, Message: "Update Complete", ResourceModel: currentModel, }, nil } // Delete handles the Delete event from the Cloudformation service. func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler.ProgressEvent, error) { owner, repoName := parseURL(*currentModel.URL) log.Printf("Looking for repository: %s/%s", *currentModel.Owner, *currentModel.Name) client := makeGitHubClient(*currentModel.OauthToken) resp, err := client.Repositories.Delete(context.Background(), owner, repoName) if err != nil { return handler.ProgressEvent{}, err } if resp.StatusCode != 200 { log.Printf("Unable to find repository: %s", resp.Status) return handler.ProgressEvent{}, fmt.Errorf("Status Code: %d, Status: %v", resp.StatusCode, resp.Status) } return handler.ProgressEvent{ OperationStatus: handler.Success, Message: "Delete Complete", ResourceModel: currentModel, }, nil } // List handles the List event from the Cloudformation service. func List(req handler.Request, prevModel *Model, currentModel *Model) (handler.ProgressEvent, error) { return handler.ProgressEvent{ OperationStatus: handler.Success, Message: "List Complete", ResourceModel: currentModel, }, nil }