Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions codeagent/codeagent_and_gitlab/codeagent_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/bin/bash
set -e

# CodeAgent Setup Script
# This script configures CodeAgent with GitLab integration

LOG_FILE="/var/log/codeagent_setup.log"
exec > >(tee -a "$LOG_FILE") 2>&1

# Variables passed from Terraform
MODEL_API_KEY='${model_api_key}'
GITLAB_BASE_URL='${gitlab_base_url}'
GITLAB_WEBHOOK_SECRET='${gitlab_webhook_secret}'
GITLAB_TOKEN='${gitlab_token}'

echo "=========================================="
echo "Starting CodeAgent configuration..."
echo "Log file: $LOG_FILE"
echo "=========================================="


# Step 1: Update API_KEY in supervisor config
echo "----------------------------------------"
echo "Step 1: Updating API_KEY in supervisor config..."
echo "----------------------------------------"

SUPERVISOR_CONF="/etc/supervisor/conf.d/codeagent.conf"
if [ ! -f "$SUPERVISOR_CONF" ]; then
echo "ERROR: $SUPERVISOR_CONF not found!"
exit 1
fi

echo "Found supervisor config at: $SUPERVISOR_CONF"
sed -i.bak "s/\"fake_token\"/\"$MODEL_API_KEY\"/g" "$SUPERVISOR_CONF"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 SECURITY: Command Injection Risk

Variables are not properly escaped in sed commands. If variables contain special characters (/, ", |), the command will fail or behave unexpectedly.

Fix: Properly escape variables:

# Safe escaping function
escape_for_sed() {
    printf '%s\n' "$1" | sed -e 's/[\/&]/\\&/g'
}

MODEL_API_KEY_ESCAPED=$(escape_for_sed "$MODEL_API_KEY")
sed -i.bak "s/\"fake_token\"/\"${MODEL_API_KEY_ESCAPED}\"/g" "$SUPERVISOR_CONF"

References: CWE-78 (OS Command Injection)

echo "✓ API_KEY updated successfully"

# Step 2: Update GitLab configuration in codeagent.yaml
echo "----------------------------------------"
echo "Step 2: Updating GitLab configuration..."
echo "----------------------------------------"

CODEAGENT_CONF="/home/codeagent/codeagent/_package/conf/codeagent.yaml"
if [ ! -f "$CODEAGENT_CONF" ]; then
echo "ERROR: $CODEAGENT_CONF not found!"
exit 1
fi

echo "Found CodeAgent config at: $CODEAGENT_CONF"
cp "$CODEAGENT_CONF" "$CODEAGENT_CONF.bak"

# Replace base_url
sed -i "s|base_url: https://gitlab.com|base_url: $GITLAB_BASE_URL|g" "$CODEAGENT_CONF"
echo "✓ Updated base_url to: $GITLAB_BASE_URL"

# Replace webhook_secret
sed -i "s|webhook_secret: \".*\"|webhook_secret: \"$GITLAB_WEBHOOK_SECRET\"|g" "$CODEAGENT_CONF"
echo "✓ Updated webhook_secret"

# Replace token
sed -i "s|token: \"glpat-.*\"|token: \"$GITLAB_TOKEN\"|g" "$CODEAGENT_CONF"
echo "✓ Updated GitLab token"

echo "✓ GitLab configuration updated successfully"

# Step 3: Restart CodeAgent service
echo "----------------------------------------"
echo "Step 3: Restarting CodeAgent service..."
echo "----------------------------------------"

if ! command -v supervisorctl &> /dev/null; then
echo "ERROR: supervisorctl command not found!"
exit 1
fi

supervisorctl reread
supervisorctl update
echo "✓ CodeAgent service restarted successfully"

# Step 4: Verify services
echo "----------------------------------------"
echo "Step 4: Verifying services..."
echo "----------------------------------------"

echo "Supervisor status:"
supervisorctl status codeagent

echo ""
echo "=========================================="
echo "CodeAgent configuration completed!"
echo "=========================================="
echo ""
echo "Configuration:"
echo " - GitLab URL: $GITLAB_BASE_URL"
echo " - CodeAgent service is running"
echo ""
echo "Next Steps:"
echo " 1. Check service status: supervisorctl status codeagent"
echo " 2. View service logs: supervisorctl tail -f codeagent"
echo " 3. View setup log: cat $LOG_FILE"
echo "=========================================="
68 changes: 68 additions & 0 deletions codeagent/codeagent_and_gitlab/configure_webhook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/bash
set -e

# GitLab Webhook Configuration Script
# This script waits for GitLab to be ready and creates a webhook for CodeAgent

GITLAB_URL="${gitlab_url}"
CODEAGENT_IP="${codeagent_ip}"
TOKEN="${gitlab_token}"
WEBHOOK_SECRET="${webhook_secret}"
PROJECT_ID="${project_id}"

echo "============================================"
echo "Configuring GitLab Webhook"
echo "GitLab URL: $GITLAB_URL"
echo "CodeAgent IP: $CODEAGENT_IP"
echo "Project ID: $PROJECT_ID"
echo "============================================"

# Create webhook with retry (GitLab will be checked as part of the API call)
echo "Creating webhook for project ID $PROJECT_ID..."

max_retry=30
retry=0

while [ $retry -lt $max_retry ]; do
echo "Attempt $((retry + 1))/$max_retry..."

response=$(curl -s -w "\n%%{http_code}" --request POST \
--header "PRIVATE-TOKEN: $TOKEN" \
--data "url=http://$CODEAGENT_IP:8889/hook" \
--data "push_events=true" \
--data "merge_requests_events=true" \
--data "issues_events=true" \
--data "confidential_issues_events=true" \
--data "note_events=true" \
--data "confidential_note_events=true" \
--data "enable_ssl_verification=false" \
--data "token=$WEBHOOK_SECRET" \
"$GITLAB_URL/api/v4/projects/$PROJECT_ID/hooks" 2>/dev/null)

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" = "201" ]; then
echo "✓ Webhook created successfully!"
echo "Response: $body"
exit 0
elif echo "$body" | grep -q "already exists"; then
echo "✓ Webhook already exists"
exit 0
else
echo "Got response code: $http_code"
retry=$((retry + 1))
if [ $retry -lt $max_retry ]; then
echo "Retrying in 10 seconds..."
sleep 10
fi
fi
done

echo ""
echo "WARNING: Failed to create webhook after $max_retry attempts"
echo "You can manually create it later with:"
echo " curl --request POST --header \"PRIVATE-TOKEN: $TOKEN\" \\"
echo " --data \"url=http://$CODEAGENT_IP:8889/hook\" --data \"token=$WEBHOOK_SECRET\" \\"
echo " \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/hooks\""
exit 0
74 changes: 74 additions & 0 deletions codeagent/codeagent_and_gitlab/gitlab_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
set -e

# GitLab Setup Script
# This script configures GitLab with the public IP

LOG_FILE="/var/log/gitlab_setup.log"
exec > >(tee -a "$LOG_FILE") 2>&1

# Variables passed from Terraform
PUBLIC_IP='${public_ip}'

echo "=========================================="
echo "Starting GitLab configuration..."
echo "Log file: $LOG_FILE"
echo "Public IP: $PUBLIC_IP"
echo "=========================================="

# Wait for cloud-init to complete
echo "Waiting for cloud-init to complete..."
cloud-init status --wait || true
echo "Cloud-init completed."

# Update GitLab external_url
echo "----------------------------------------"
echo "Step 1: Updating GitLab external_url..."
echo "----------------------------------------"

GITLAB_CONF="/etc/gitlab/gitlab.rb"
if [ ! -f "$GITLAB_CONF" ]; then
echo "ERROR: $GITLAB_CONF not found!"
exit 1
fi

echo "Found GitLab config at: $GITLAB_CONF"
cp "$GITLAB_CONF" "$GITLAB_CONF.bak"

# Replace external_url
sed -i "s|external_url '.*'|external_url 'http://$PUBLIC_IP'|g" "$GITLAB_CONF"
echo "✓ Updated external_url to http://$PUBLIC_IP"

# Reconfigure GitLab
echo "----------------------------------------"
echo "Step 2: Reconfiguring GitLab..."
echo "----------------------------------------"

if ! command -v gitlab-ctl &> /dev/null; then
echo "ERROR: gitlab-ctl command not found!"
exit 1
fi

gitlab-ctl reconfigure
echo "✓ GitLab reconfigured successfully"

# Verify GitLab status
echo "----------------------------------------"
echo "Step 3: Verifying GitLab status..."
echo "----------------------------------------"

gitlab-ctl status | head -n 5

echo ""
echo "=========================================="
echo "GitLab configuration completed!"
echo "=========================================="
echo ""
echo "Access Information:"
echo " - GitLab URL: http://$PUBLIC_IP"
echo ""
echo "Next Steps:"
echo " 1. Wait 5-10 minutes for GitLab to fully start"
echo " 2. Access GitLab at http://$PUBLIC_IP"
echo " 3. Get root password: cat /etc/gitlab/initial_root_password"
echo "=========================================="
122 changes: 122 additions & 0 deletions codeagent/codeagent_and_gitlab/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Generate random passwords
resource "random_password" "gitlab_instance_password" {
length = 16
special = true
lower = true
upper = true
numeric = true
}

resource "random_password" "codeagent_instance_password" {
length = 16
special = true
lower = true
upper = true
numeric = true
}

# Step 1: Create GitLab instance first
resource "qiniu_compute_instance" "gitlab_instance" {
instance_type = var.gitlab_instance_type
name = format("gitlab-%s", local.instance_suffix)
description = format("GitLab instance %s", local.instance_suffix)
image_id = var.gitlab_image_id
system_disk_size = var.gitlab_system_disk_size
internet_max_bandwidth = var.gitlab_internet_max_bandwidth
password = random_password.gitlab_instance_password.result

timeouts {
create = "30m"
update = "20m"
delete = "10m"
}
}

# Use null_resource to configure GitLab with actual public IP via SSH
resource "null_resource" "configure_gitlab" {
depends_on = [qiniu_compute_instance.gitlab_instance]

connection {
type = "ssh"
user = "root"
password = random_password.gitlab_instance_password.result
host = qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4
timeout = "10m"
agent = false
host_key = null
Comment on lines +40 to +46

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

connection 块存在两个严重的安全问题:

  1. 使用密码认证: password 字段使密码可能被存储在 state 文件中,存在泄露风险。应改用更安全的 SSH 密钥认证。
  2. 禁用主机密钥验证: host_key = null 会禁用 SSH 主机密钥验证,使连接容易受到中间人攻击(MITM)。

建议使用 SSH 密钥,并删除 host_key = null 以启用默认的主机密钥验证。

    type        = "ssh"
    user        = "root"
    private_key = file("~/.ssh/id_rsa") # Or path to your private key
    host        = qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4
    timeout     = "10m"
    agent       = false

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 SECURITY: SSH Host Key Verification Disabled

Setting host_key = null disables SSH host key verification, making this vulnerable to Man-in-the-Middle (MITM) attacks. Sensitive credentials (API keys, tokens) are transmitted during provisioning.

Recommendation: Use SSH keys instead of passwords:

resource "tls_private_key" "provisioning" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

connection {
  type        = "ssh"
  user        = "root"
  private_key = tls_private_key.provisioning.private_key_pem
  host        = qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4
  timeout     = "5m"
  # Remove host_key = null
}

References: CWE-295 (Improper Certificate Validation)

}

# Upload the setup script
provisioner "file" {
content = templatefile("${path.module}/gitlab_setup.sh", {
public_ip = qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4
})
destination = "/tmp/gitlab_setup.sh"
}

# Execute the script
provisioner "remote-exec" {
inline = [
"chmod +x /tmp/gitlab_setup.sh",
"/tmp/gitlab_setup.sh"
]
}
}

# Step 2: Create CodeAgent instance after GitLab is configured
resource "qiniu_compute_instance" "codeagent_instance" {
depends_on = [null_resource.configure_gitlab]

instance_type = var.codeagent_instance_type
name = format("codeagent-%s", local.instance_suffix)
description = format("CodeAgent instance %s", local.instance_suffix)
image_id = var.codeagent_image_id
system_disk_size = var.codeagent_system_disk_size
internet_max_bandwidth = var.codeagent_internet_max_bandwidth
password = random_password.codeagent_instance_password.result

# Configure CodeAgent with GitLab URL
user_data = base64encode(templatefile("${path.module}/codeagent_setup.sh", {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 SECURITY: Secrets Exposed via user_data

Passing sensitive credentials through user_data exposes them in:

  • Instance metadata service (http://169.254.169.254/)
  • Cloud provider console/logs
  • Terraform state files (plaintext)

Recommendation: Use the same SSH provisioner approach as GitLab configuration instead of user_data for sensitive operations.

References: CWE-522 (Insufficiently Protected Credentials)

model_api_key = var.model_api_key
gitlab_base_url = format("http://%s", qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4)
gitlab_webhook_secret = local.gitlab_webhook_secret
gitlab_token = local.gitlab_token
}))

timeouts {
create = "30m"
update = "20m"
delete = "10m"
}
}

# Step 3: Configure GitLab webhook after CodeAgent is ready
resource "null_resource" "configure_gitlab_webhook" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depends_on = [qiniu_compute_instance.codeagent_instance]

provisioner "local-exec" {
command = templatefile("${path.module}/configure_webhook.sh", {
gitlab_url = format("http://%s", qiniu_compute_instance.gitlab_instance.public_ip_addresses[0].ipv4)
codeagent_ip = qiniu_compute_instance.codeagent_instance.public_ip_addresses[0].ipv4
gitlab_token = local.gitlab_token
webhook_secret = local.gitlab_webhook_secret
project_id = "1"
})
interpreter = ["/bin/bash", "-c"]
}
}

resource "random_string" "resource_suffix" {
length = 6
upper = false
lower = true
special = false
}

locals {
instance_suffix = random_string.resource_suffix.result

# Hardcoded GitLab configuration for CodeAgent
gitlab_webhook_secret = "7Xk9pL2qNvR" #gitlab 内置测试项目配置的webhook_secret密钥,仅做测试用,请勿用于真实环境
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这两个参数是不是应该动态生成或者外部传入?

gitlab_token = "glpat-vkEFt2B0j-bFbEJaUmfWcm86MQp1OjIH.01.0w1yp1q9m" #gitlab 内置配置的codeagent的token ,仅做测试用,请勿用于真实环境
}
Loading