or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-management.mddata-management.mdindex.mdinstance-operations.mdmaintenance-operations.md

maintenance-operations.mddocs/

0

# Maintenance and Operations

1

2

Advanced instance management including maintenance scheduling, failover operations, Redis version upgrades, and authentication.

3

4

## Capabilities

5

6

### Redis Version Upgrades

7

8

Upgrade a Redis instance to a newer Redis version.

9

10

```python { .api }

11

def upgrade_instance(

12

self,

13

*,

14

name: str,

15

redis_version: str,

16

**kwargs

17

) -> operation.Operation:

18

"""

19

Upgrade a Redis instance to a newer Redis version.

20

21

Args:

22

name: Required. Redis instance resource name using the form:

23

"projects/{project_id}/locations/{location_id}/instances/{instance_id}"

24

redis_version: Required. Specifies the target version of Redis to upgrade to.

25

Format: "REDIS_X_Y" (e.g., "REDIS_6_X", "REDIS_7_X")

26

27

Returns:

28

google.api_core.operation.Operation: A long-running operation object.

29

The result will be an Instance object.

30

31

Raises:

32

google.api_core.exceptions.GoogleAPICallError: If the request failed.

33

google.api_core.exceptions.NotFound: If the instance doesn't exist.

34

google.api_core.exceptions.InvalidArgument: If the version is invalid.

35

"""

36

```

37

38

### Instance Failover

39

40

Initiate a manual failover of a Redis instance to its replica.

41

42

```python { .api }

43

def failover_instance(

44

self,

45

*,

46

name: str,

47

data_protection_mode: Optional[

48

cloud_redis.FailoverInstanceRequest.DataProtectionMode

49

] = cloud_redis.FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS,

50

**kwargs

51

) -> operation.Operation:

52

"""

53

Initiates a failover of the primary node to current replica node for a specific STANDARD_HA Redis instance.

54

55

Args:

56

name: Required. Redis instance resource name using the form:

57

"projects/{project_id}/locations/{location_id}/instances/{instance_id}"

58

data_protection_mode: Optional. Specifies different modes of operation for failover.

59

Defaults to LIMITED_DATA_LOSS.

60

61

Returns:

62

google.api_core.operation.Operation: A long-running operation object.

63

The result will be an Instance object.

64

65

Raises:

66

google.api_core.exceptions.GoogleAPICallError: If the request failed.

67

google.api_core.exceptions.NotFound: If the instance doesn't exist.

68

google.api_core.exceptions.FailedPrecondition: If instance is not STANDARD_HA tier.

69

"""

70

```

71

72

### Authentication String Retrieval

73

74

Get the AUTH string for connecting to a Redis instance with authentication enabled.

75

76

```python { .api }

77

def get_instance_auth_string(

78

self, *, name: str, **kwargs

79

) -> cloud_redis.InstanceAuthString:

80

"""

81

Gets the AUTH string for a Redis instance with AUTH enabled.

82

83

Args:

84

name: Required. Redis instance resource name using the form:

85

"projects/{project_id}/locations/{location_id}/instances/{instance_id}"

86

87

Returns:

88

cloud_redis.InstanceAuthString: The auth string for the instance.

89

90

Raises:

91

google.api_core.exceptions.GoogleAPICallError: If the request failed.

92

google.api_core.exceptions.NotFound: If the instance doesn't exist.

93

google.api_core.exceptions.FailedPrecondition: If AUTH is not enabled.

94

"""

95

```

96

97

### Maintenance Rescheduling

98

99

Reschedule upcoming maintenance for a Redis instance.

100

101

```python { .api }

102

def reschedule_maintenance(

103

self,

104

*,

105

name: str,

106

reschedule_type: cloud_redis.RescheduleMaintenanceRequest.RescheduleType,

107

schedule_time: Optional[timestamp_pb2.Timestamp] = None,

108

**kwargs

109

) -> operation.Operation:

110

"""

111

Reschedule upcoming maintenance of a Redis instance.

112

113

Args:

114

name: Required. Redis instance resource name using the form:

115

"projects/{project_id}/locations/{location_id}/instances/{instance_id}"

116

reschedule_type: Required. If reschedule type is SPECIFIC_TIME, then schedule_time is required.

117

schedule_time: Optional. Timestamp when the maintenance shall be rescheduled to.

118

Required if reschedule_type is SPECIFIC_TIME.

119

120

Returns:

121

google.api_core.operation.Operation: A long-running operation object.

122

The result will be an Instance object.

123

124

Raises:

125

google.api_core.exceptions.GoogleAPICallError: If the request failed.

126

google.api_core.exceptions.NotFound: If the instance doesn't exist.

127

google.api_core.exceptions.InvalidArgument: If schedule_time is invalid.

128

"""

129

```

130

131

## Request Types

132

133

### Upgrade Request

134

135

```python { .api }

136

class UpgradeInstanceRequest:

137

name: str

138

redis_version: str

139

```

140

141

### Failover Request

142

143

```python { .api }

144

class FailoverInstanceRequest:

145

name: str

146

data_protection_mode: FailoverInstanceRequest.DataProtectionMode

147

148

class FailoverInstanceRequest.DataProtectionMode(Enum):

149

DATA_PROTECTION_MODE_UNSPECIFIED = 0

150

LIMITED_DATA_LOSS = 1

151

FORCE_DATA_LOSS = 2

152

```

153

154

### Auth String Request

155

156

```python { .api }

157

class GetInstanceAuthStringRequest:

158

name: str

159

```

160

161

### Maintenance Reschedule Request

162

163

```python { .api }

164

class RescheduleMaintenanceRequest:

165

name: str

166

reschedule_type: RescheduleMaintenanceRequest.RescheduleType

167

schedule_time: Timestamp

168

169

class RescheduleMaintenanceRequest.RescheduleType(Enum):

170

RESCHEDULE_TYPE_UNSPECIFIED = 0

171

IMMEDIATE = 1

172

NEXT_AVAILABLE_WINDOW = 2

173

SPECIFIC_TIME = 3

174

```

175

176

## Response Types

177

178

### Auth String Response

179

180

```python { .api }

181

class InstanceAuthString:

182

auth_string: str

183

"""The AUTH string for the Redis instance."""

184

```

185

186

## Usage Examples

187

188

### Upgrade Redis Version

189

190

```python

191

from google.cloud.redis import CloudRedisClient

192

193

client = CloudRedisClient()

194

instance_name = "projects/my-project/locations/us-central1/instances/my-redis"

195

196

# Check current version and available versions

197

instance = client.get_instance(name=instance_name)

198

print(f"Current version: {instance.redis_version}")

199

print(f"Available versions: {instance.available_maintenance_versions}")

200

201

# Upgrade to Redis 7.x

202

operation = client.upgrade_instance(

203

name=instance_name,

204

redis_version="REDIS_7_X"

205

)

206

207

print(f"Upgrade operation started: {operation.name}")

208

209

# Wait for upgrade to complete (can take 10-30 minutes)

210

try:

211

result = operation.result(timeout=3600) # 1 hour timeout

212

print(f"Upgrade completed successfully")

213

print(f"New version: {result.redis_version}")

214

print(f"Instance state: {result.state}")

215

except Exception as e:

216

print(f"Upgrade failed: {e}")

217

```

218

219

### Perform Manual Failover

220

221

```python

222

from google.cloud.redis import CloudRedisClient, FailoverInstanceRequest

223

224

client = CloudRedisClient()

225

instance_name = "projects/my-project/locations/us-central1/instances/my-ha-redis"

226

227

# Check if instance supports failover (must be STANDARD_HA)

228

instance = client.get_instance(name=instance_name)

229

if instance.tier != instance.Tier.STANDARD_HA:

230

print("Failover is only supported for STANDARD_HA instances")

231

exit(1)

232

233

print(f"Current location: {instance.current_location_id}")

234

print(f"Alternative location: {instance.alternative_location_id}")

235

236

# Perform failover with limited data loss protection

237

operation = client.failover_instance(

238

name=instance_name,

239

data_protection_mode=FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS

240

)

241

242

print(f"Failover operation started: {operation.name}")

243

244

# Wait for failover to complete

245

try:

246

result = operation.result(timeout=1800) # 30 minutes timeout

247

print(f"Failover completed successfully")

248

print(f"New primary location: {result.current_location_id}")

249

except Exception as e:

250

print(f"Failover failed: {e}")

251

```

252

253

### Get Authentication String

254

255

```python

256

from google.cloud.redis import CloudRedisClient

257

258

client = CloudRedisClient()

259

instance_name = "projects/my-project/locations/us-central1/instances/my-secure-redis"

260

261

# Check if AUTH is enabled

262

instance = client.get_instance(name=instance_name)

263

if not instance.auth_enabled:

264

print("AUTH is not enabled for this instance")

265

exit(1)

266

267

# Get the AUTH string

268

try:

269

auth_info = client.get_instance_auth_string(name=instance_name)

270

auth_string = auth_info.auth_string

271

272

print(f"AUTH string retrieved successfully")

273

print(f"Use this string to authenticate: {auth_string}")

274

275

# Example connection with AUTH

276

print(f"\nConnection example:")

277

print(f"redis-cli -h {instance.host} -p {instance.port} -a {auth_string}")

278

279

except Exception as e:

280

print(f"Failed to get AUTH string: {e}")

281

```

282

283

### Reschedule Maintenance

284

285

```python

286

from google.cloud.redis import CloudRedisClient, RescheduleMaintenanceRequest

287

from google.protobuf.timestamp_pb2 import Timestamp

288

from datetime import datetime, timedelta

289

290

client = CloudRedisClient()

291

instance_name = "projects/my-project/locations/us-central1/instances/my-redis"

292

293

# Check current maintenance schedule

294

instance = client.get_instance(name=instance_name)

295

if instance.maintenance_schedule:

296

schedule = instance.maintenance_schedule

297

print(f"Current maintenance scheduled for: {schedule.start_time}")

298

print(f"Can reschedule: {schedule.can_reschedule}")

299

300

if not schedule.can_reschedule:

301

print("Maintenance cannot be rescheduled")

302

exit(1)

303

else:

304

print("No maintenance currently scheduled")

305

exit(1)

306

307

# Option 1: Reschedule to next available window

308

operation = client.reschedule_maintenance(

309

name=instance_name,

310

reschedule_type=RescheduleMaintenanceRequest.RescheduleType.NEXT_AVAILABLE_WINDOW

311

)

312

313

print(f"Rescheduling to next available window: {operation.name}")

314

315

# Option 2: Reschedule to specific time (uncomment to use)

316

# future_time = datetime.now() + timedelta(days=7) # 1 week from now

317

# schedule_timestamp = Timestamp()

318

# schedule_timestamp.FromDatetime(future_time)

319

#

320

# operation = client.reschedule_maintenance(

321

# name=instance_name,

322

# reschedule_type=RescheduleMaintenanceRequest.RescheduleType.SPECIFIC_TIME,

323

# schedule_time=schedule_timestamp

324

# )

325

326

# Wait for reschedule operation

327

try:

328

result = operation.result(timeout=300) # 5 minutes timeout

329

print(f"Maintenance rescheduled successfully")

330

if result.maintenance_schedule:

331

new_schedule = result.maintenance_schedule

332

print(f"New maintenance time: {new_schedule.start_time}")

333

except Exception as e:

334

print(f"Failed to reschedule maintenance: {e}")

335

```

336

337

### Monitor Instance Health

338

339

```python

340

from google.cloud.redis import CloudRedisClient

341

import time

342

343

def monitor_instance_health(instance_name: str, check_interval: int = 60):

344

"""Monitor Redis instance health and maintenance status."""

345

client = CloudRedisClient()

346

347

print(f"Monitoring instance: {instance_name}")

348

print(f"Check interval: {check_interval} seconds")

349

print("-" * 50)

350

351

while True:

352

try:

353

instance = client.get_instance(name=instance_name)

354

355

print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

356

print(f"State: {instance.state}")

357

print(f"Current Location: {instance.current_location_id}")

358

359

if instance.status_message:

360

print(f"Status: {instance.status_message}")

361

362

# Check maintenance schedule

363

if instance.maintenance_schedule:

364

schedule = instance.maintenance_schedule

365

print(f"Maintenance: {schedule.start_time} - {schedule.end_time}")

366

print(f"Can reschedule: {schedule.can_reschedule}")

367

368

# Check for suspension reasons

369

if instance.suspension_reasons:

370

print(f"Suspension reasons: {instance.suspension_reasons}")

371

372

print("-" * 50)

373

374

# Alert on critical states

375

if instance.state in [instance.State.REPAIRING, instance.State.MAINTENANCE]:

376

print(f"ALERT: Instance in {instance.state} state")

377

elif instance.suspension_reasons:

378

print(f"ALERT: Instance suspended - {instance.suspension_reasons}")

379

380

time.sleep(check_interval)

381

382

except KeyboardInterrupt:

383

print("Monitoring stopped by user")

384

break

385

except Exception as e:

386

print(f"Error monitoring instance: {e}")

387

time.sleep(check_interval)

388

389

# Start monitoring

390

instance_name = "projects/my-project/locations/us-central1/instances/production-redis"

391

monitor_instance_health(instance_name, check_interval=120) # Check every 2 minutes

392

```

393

394

### Emergency Force Failover

395

396

```python

397

from google.cloud.redis import CloudRedisClient, FailoverInstanceRequest

398

399

def emergency_failover(instance_name: str, force: bool = False):

400

"""Perform emergency failover with data loss protection options."""

401

client = CloudRedisClient()

402

403

try:

404

# Get current instance state

405

instance = client.get_instance(name=instance_name)

406

407

if instance.tier != instance.Tier.STANDARD_HA:

408

raise ValueError("Emergency failover only available for STANDARD_HA instances")

409

410

if instance.state != instance.State.READY:

411

print(f"WARNING: Instance state is {instance.state}, not READY")

412

413

print(f"Current primary: {instance.current_location_id}")

414

print(f"Failover target: {instance.alternative_location_id}")

415

416

# Choose data protection mode

417

if force:

418

data_protection_mode = FailoverInstanceRequest.DataProtectionMode.FORCE_DATA_LOSS

419

print("WARNING: Forcing failover - potential data loss!")

420

else:

421

data_protection_mode = FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS

422

print("Using limited data loss protection")

423

424

# Confirm before proceeding

425

if not force:

426

confirm = input("Proceed with failover? (yes/no): ")

427

if confirm.lower() != 'yes':

428

print("Failover cancelled")

429

return

430

431

# Start failover

432

operation = client.failover_instance(

433

name=instance_name,

434

data_protection_mode=data_protection_mode

435

)

436

437

print(f"Emergency failover initiated: {operation.name}")

438

439

# Monitor progress

440

start_time = time.time()

441

while not operation.done():

442

elapsed = time.time() - start_time

443

print(f"Failover in progress... ({elapsed:.0f}s elapsed)")

444

time.sleep(10)

445

operation.reload()

446

447

# Check result

448

if operation.error:

449

print(f"Failover failed: {operation.error}")

450

else:

451

result = operation.result()

452

print(f"Failover completed successfully!")

453

print(f"New primary location: {result.current_location_id}")

454

print(f"Instance state: {result.state}")

455

456

except Exception as e:

457

print(f"Emergency failover error: {e}")

458

459

# Usage for emergency situations

460

instance_name = "projects/my-project/locations/us-central1/instances/critical-redis"

461

462

# Normal failover with data protection

463

emergency_failover(instance_name, force=False)

464

465

# Force failover (use only in extreme emergencies)

466

# emergency_failover(instance_name, force=True)

467

```

468

469

## Best Practices

470

471

### Pre-Upgrade Checklist

472

473

```python

474

def pre_upgrade_checklist(instance_name: str, target_version: str):

475

"""Perform pre-upgrade validation and preparation."""

476

client = CloudRedisClient()

477

478

print("Pre-upgrade checklist:")

479

print("-" * 30)

480

481

# Get instance details

482

instance = client.get_instance(name=instance_name)

483

484

# Check 1: Instance state

485

if instance.state != instance.State.READY:

486

print(f"❌ Instance state: {instance.state} (should be READY)")

487

return False

488

print(f"✅ Instance state: {instance.state}")

489

490

# Check 2: Available versions

491

if target_version not in instance.available_maintenance_versions:

492

print(f"❌ Target version {target_version} not available")

493

print(f" Available: {instance.available_maintenance_versions}")

494

return False

495

print(f"✅ Target version {target_version} is available")

496

497

# Check 3: No pending maintenance

498

if instance.maintenance_schedule:

499

print(f"⚠️ Maintenance scheduled: {instance.maintenance_schedule.start_time}")

500

else:

501

print("✅ No pending maintenance")

502

503

# Check 4: Backup recommendation

504

print("⚠️ Recommendation: Create backup before upgrade")

505

506

print("-" * 30)

507

return True

508

509

# Run checklist before upgrade

510

if pre_upgrade_checklist(instance_name, "REDIS_7_X"):

511

print("Ready for upgrade!")

512

else:

513

print("Resolve issues before upgrading")

514

```